LLVMFuzzerTestOneInput:
    6|  6.08k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    7|  6.08k|  std::string jpeg_data(reinterpret_cast<const char*>(data), size);
    8|       |
    9|       |  // Ignore large images, to prevent timeouts.
   10|  6.08k|  guetzli::JPEGData jpg_header;
   11|  6.08k|  if (!guetzli::ReadJpeg(data, size, guetzli::JPEG_READ_HEADER, &jpg_header)) {
  ------------------
  |  Branch (11:7): [True: 837, False: 5.24k]
  ------------------
   12|    837|    return 0;
   13|    837|  }
   14|  5.24k|  static constexpr int kMaxPixels = 10000;
   15|  5.24k|  if (static_cast<int64_t>(jpg_header.width) * jpg_header.height > kMaxPixels) {
  ------------------
  |  Branch (15:7): [True: 21, False: 5.22k]
  ------------------
   16|     21|    return 0;
   17|     21|  }
   18|       |
   19|       |  // TODO(robryk): Use nondefault parameters.
   20|  5.22k|  guetzli::Params params;
   21|  5.22k|  std::string jpeg_out;
   22|  5.22k|  (void)guetzli::Process(params, nullptr, jpeg_data, &jpeg_out);
   23|       |  // TODO(robryk): Verify output distance if Process() succeeded.
   24|  5.22k|  return 0;
   25|  5.24k|}

_ZN7guetzli21ButteraugliComparatorC2EiiPKNSt3__16vectorIhNS1_9allocatorIhEEEEfPNS_12ProcessStatsE:
   61|  3.10k|      stats_(stats) {}
_ZN7guetzli21ButteraugliComparator7CompareERKNS_11OutputImageE:
   63|   163k|void ButteraugliComparator::Compare(const OutputImage& img) {
   64|   163k|  std::vector<ImageF> rgb0 =
   65|   163k|      ::butteraugli::OpsinDynamicsImage(LinearRgb(width_, height_, rgb_orig_));
   66|   163k|  std::vector<std::vector<float> > rgb(3, std::vector<float>(width_ * height_));
   67|   163k|  img.ToLinearRGB(&rgb);
   68|   163k|  const std::vector<ImageF> rgb_planes = PlanesFromPacked(width_, height_, rgb);
   69|   163k|  std::vector<float>(width_ * height_).swap(distmap_);
   70|   163k|  ImageF distmap;
   71|   163k|  comparator_.Diffmap(rgb_planes, distmap);
   72|   163k|  CopyToPacked(distmap, &distmap_);
   73|   163k|  distance_ = ::butteraugli::ButteraugliScoreFromDiffmap(distmap);
   74|   163k|  GUETZLI_LOG(stats_, " BA[100.00%%] D[%6.4f]", distance_);
  ------------------
  |  |   29|   163k|  do {                                                             \
  |  |   30|   163k|    char debug_string[1024];                                       \
  |  |   31|   163k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |   32|   163k|                       __VA_ARGS__);                               \
  |  |   33|   163k|    assert(res > 0 && "expected successful printing");             \
  |  |   34|   163k|    (void)res;                                                     \
  |  |   35|   163k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |   36|   163k|    ::guetzli::PrintDebug(                      \
  |  |   37|   163k|         stats, std::string(debug_string));        \
  |  |   38|   163k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   75|   163k|}
_ZN7guetzli21ButteraugliComparator21StartBlockComparisonsEv:
  415|  5.01k|void ButteraugliComparator::StartBlockComparisons() {
  416|  5.01k|  std::vector<ImageF> dummy(3);
  417|  5.01k|  std::vector<ImageF> rgb0 =
  418|  5.01k|      ::butteraugli::OpsinDynamicsImage(LinearRgb(width_, height_, rgb_orig_));
  419|  5.01k|  ::butteraugli::Mask(rgb0, rgb0,
  420|  5.01k|                      &mask_xyz_, &dummy);
  421|  5.01k|}
_ZN7guetzli21ButteraugliComparator22FinishBlockComparisonsEv:
  423|  5.01k|void ButteraugliComparator::FinishBlockComparisons() {
  424|  5.01k|  mask_xyz_.clear();
  425|  5.01k|}
_ZN7guetzli21ButteraugliComparator11SwitchBlockEiiii:
  428|   177k|                                        int factor_x, int factor_y) {
  429|   177k|  block_x_ = block_x;
  430|   177k|  block_y_ = block_y;
  431|   177k|  factor_x_ = factor_x;
  432|   177k|  factor_y_ = factor_y;
  433|   177k|  per_block_pregamma_.resize(factor_x_ * factor_y_);
  434|   177k|  const double* lut = Srgb8ToLinearTable();
  435|   383k|  for (int off_y = 0, bx = 0; off_y < factor_y_; ++off_y) {
  ------------------
  |  Branch (435:31): [True: 206k, False: 177k]
  ------------------
  436|   470k|    for (int off_x = 0; off_x < factor_x_; ++off_x, ++bx) {
  ------------------
  |  Branch (436:25): [True: 264k, False: 206k]
  ------------------
  437|   264k|      per_block_pregamma_[bx].resize(3, std::vector<float>(kDCTBlockSize));
  438|   264k|      int block_xx = block_x_ * factor_x_ + off_x;
  439|   264k|      int block_yy = block_y_ * factor_y_ + off_y;
  440|  2.37M|      for (int iy = 0, i = 0; iy < 8; ++iy) {
  ------------------
  |  Branch (440:31): [True: 2.11M, False: 264k]
  ------------------
  441|  19.0M|        for (int ix = 0; ix < 8; ++ix, ++i) {
  ------------------
  |  Branch (441:26): [True: 16.9M, False: 2.11M]
  ------------------
  442|  16.9M|          int x = std::min(8 * block_xx + ix, width_ - 1);
  443|  16.9M|          int y = std::min(8 * block_yy + iy, height_ - 1);
  444|  16.9M|          int px = y * width_ + x;
  445|  67.6M|          for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (445:27): [True: 50.7M, False: 16.9M]
  ------------------
  446|  50.7M|            per_block_pregamma_[bx][c][i] = lut[rgb_orig_[3 * px + c]];
  447|  50.7M|          }
  448|  16.9M|        }
  449|  2.11M|      }
  450|   264k|      per_block_pregamma_[bx] =
  451|   264k|          ::butteraugli::PackedFromPlanes(::butteraugli::OpsinDynamicsImage(
  452|   264k|              ::butteraugli::PlanesFromPacked(8, 8, per_block_pregamma_[bx])));
  453|   264k|    }
  454|   206k|  }
  455|   177k|}
_ZNK7guetzli21ButteraugliComparator12CompareBlockERKNS_11OutputImageEii:
  458|  7.43M|                                           int off_x, int off_y) const {
  459|  7.43M|  int block_x = block_x_ * factor_x_ + off_x;
  460|  7.43M|  int block_y = block_y_ * factor_y_ + off_y;
  461|  7.43M|  int xmin = 8 * block_x;
  462|  7.43M|  int ymin = 8 * block_y;
  463|  7.43M|  int block_ix = off_y * factor_x_ + off_x;
  464|  7.43M|  const std::vector<std::vector<float> >& rgb0 =
  465|  7.43M|      per_block_pregamma_[block_ix];
  466|       |
  467|  7.43M|  std::vector<std::vector<float> > rgb1(3, std::vector<float>(kDCTBlockSize));
  468|  7.43M|  img.ToLinearRGB(xmin, ymin, 8, 8, &rgb1);
  469|  7.43M|  rgb1 = ::butteraugli::PackedFromPlanes(::butteraugli::OpsinDynamicsImage(
  470|  7.43M|      ::butteraugli::PlanesFromPacked(8, 8, rgb1)));
  471|       |
  472|  7.43M|  double b0[3 * kDCTBlockSize];
  473|  7.43M|  double b1[3 * kDCTBlockSize];
  474|  29.7M|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (474:19): [True: 22.2M, False: 7.43M]
  ------------------
  475|  1.44G|    for (int ix = 0; ix < kDCTBlockSize; ++ix) {
  ------------------
  |  Branch (475:22): [True: 1.42G, False: 22.2M]
  ------------------
  476|  1.42G|      b0[c * kDCTBlockSize + ix] = rgb0[c][ix];
  477|  1.42G|      b1[c * kDCTBlockSize + ix] = rgb1[c][ix];
  478|  1.42G|    }
  479|  22.2M|  }
  480|  7.43M|  double diff_xyz[3] = { 0.0 };
  481|  7.43M|  ButteraugliBlockDiff(b0, b1, diff_xyz);
  482|       |
  483|  7.43M|  double diff = 0.0;
  484|  29.7M|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (484:19): [True: 22.2M, False: 7.43M]
  ------------------
  485|  22.2M|    diff += diff_xyz[c] * mask_xyz_[c].Row(ymin)[xmin];
  486|  22.2M|  }
  487|  7.43M|  return sqrt(diff);
  488|  7.43M|}
_ZNK7guetzli21ButteraugliComparator15BlockErrorLimitEv:
  490|  1.87M|float ButteraugliComparator::BlockErrorLimit() const {
  491|  1.87M|  return target_distance_;
  492|  1.87M|}
_ZN7guetzli21ButteraugliComparator34ComputeBlockErrorAdjustmentWeightsEiidiiRKNSt3__16vectorIfNS1_9allocatorIfEEEEPS5_:
  500|   154k|      std::vector<float>* block_weight) {
  501|   154k|  const double target_distance = target_distance_ * target_mul;
  502|   154k|  const int sizex = 8 * factor_x;
  503|   154k|  const int sizey = 8 * factor_y;
  504|   154k|  const int block_width = (width_ + sizex - 1) / sizex;
  505|   154k|  const int block_height = (height_ + sizey - 1) / sizey;
  506|   154k|  std::vector<float> max_dist_per_block(block_width * block_height);
  507|  1.04M|  for (int block_y = 0; block_y < block_height; ++block_y) {
  ------------------
  |  Branch (507:25): [True: 885k, False: 154k]
  ------------------
  508|  8.37M|    for (int block_x = 0; block_x < block_width; ++block_x) {
  ------------------
  |  Branch (508:27): [True: 7.49M, False: 885k]
  ------------------
  509|  7.49M|      int block_ix = block_y * block_width + block_x;
  510|  7.49M|      int x_max = std::min(width_, sizex * (block_x + 1));
  511|  7.49M|      int y_max = std::min(height_, sizey * (block_y + 1));
  512|  7.49M|      float max_dist = 0.0;
  513|  66.1M|      for (int y = sizey * block_y; y < y_max; ++y) {
  ------------------
  |  Branch (513:37): [True: 58.7M, False: 7.49M]
  ------------------
  514|   541M|        for (int x = sizex * block_x; x < x_max; ++x) {
  ------------------
  |  Branch (514:39): [True: 483M, False: 58.7M]
  ------------------
  515|   483M|          max_dist = std::max(max_dist, distmap[y * width_ + x]);
  516|   483M|        }
  517|  58.7M|      }
  518|  7.49M|      max_dist_per_block[block_ix] = max_dist;
  519|  7.49M|    }
  520|   885k|  }
  521|  1.04M|  for (int block_y = 0; block_y < block_height; ++block_y) {
  ------------------
  |  Branch (521:25): [True: 885k, False: 154k]
  ------------------
  522|  8.37M|    for (int block_x = 0; block_x < block_width; ++block_x) {
  ------------------
  |  Branch (522:27): [True: 7.49M, False: 885k]
  ------------------
  523|  7.49M|      int block_ix = block_y * block_width + block_x;
  524|  7.49M|      float max_local_dist = static_cast<float>(target_distance);
  525|  7.49M|      int x_min = std::max(0, block_x - max_block_dist);
  526|  7.49M|      int y_min = std::max(0, block_y - max_block_dist);
  527|  7.49M|      int x_max = std::min(block_width, block_x + 1 + max_block_dist);
  528|  7.49M|      int y_max = std::min(block_height, block_y + 1 + max_block_dist);
  529|  30.1M|      for (int y = y_min; y < y_max; ++y) {
  ------------------
  |  Branch (529:27): [True: 22.6M, False: 7.49M]
  ------------------
  530|  99.9M|        for (int x = x_min; x < x_max; ++x) {
  ------------------
  |  Branch (530:29): [True: 77.2M, False: 22.6M]
  ------------------
  531|  77.2M|          max_local_dist =
  532|  77.2M|              std::max(max_local_dist, max_dist_per_block[y * block_width + x]);
  533|  77.2M|        }
  534|  22.6M|      }
  535|  7.49M|      if (direction > 0) {
  ------------------
  |  Branch (535:11): [True: 813k, False: 6.67M]
  ------------------
  536|   813k|        if (max_dist_per_block[block_ix] <= target_distance &&
  ------------------
  |  Branch (536:13): [True: 499k, False: 314k]
  ------------------
  537|   813k|            max_local_dist <= 1.1 * target_distance) {
  ------------------
  |  Branch (537:13): [True: 436k, False: 62.1k]
  ------------------
  538|   436k|          (*block_weight)[block_ix] = 1.0;
  539|   436k|        }
  540|  6.67M|      } else {
  541|  6.67M|        constexpr double kLocalMaxWeight = 0.5;
  542|  6.67M|        if (max_dist_per_block[block_ix] <=
  ------------------
  |  Branch (542:13): [True: 4.16M, False: 2.50M]
  ------------------
  543|  6.67M|            (1 - kLocalMaxWeight) * target_distance +
  544|  6.67M|            kLocalMaxWeight * max_local_dist) {
  545|  4.16M|          continue;
  546|  4.16M|        }
  547|  9.35M|        for (int y = y_min; y < y_max; ++y) {
  ------------------
  |  Branch (547:29): [True: 6.84M, False: 2.50M]
  ------------------
  548|  26.1M|          for (int x = x_min; x < x_max; ++x) {
  ------------------
  |  Branch (548:31): [True: 19.2M, False: 6.84M]
  ------------------
  549|  19.2M|            int d = std::max(std::abs(y - block_y), std::abs(x - block_x));
  550|  19.2M|            int ix = y * block_width + x;
  551|  19.2M|            (*block_weight)[ix] = std::max<float>(
  552|  19.2M|                (*block_weight)[ix], 1.0f / (d + 1.0f));
  553|  19.2M|          }
  554|  6.84M|        }
  555|  2.50M|      }
  556|  7.49M|    }
  557|   885k|  }
  558|   154k|}
_ZNK7guetzli21ButteraugliComparator15ScoreOutputSizeEi:
  560|   163k|double ButteraugliComparator::ScoreOutputSize(int size) const {
  561|   163k|  return ScoreJPEG(distance_, size, target_distance_);
  562|   163k|}
butteraugli_comparator.cc:_ZN7guetzli12_GLOBAL__N_19LinearRgbEmmRKNSt3__16vectorIhNS1_9allocatorIhEEEE:
   34|   171k|                              const std::vector<uint8_t>& rgb) {
   35|   171k|  const double* lut = Srgb8ToLinearTable();
   36|   171k|  std::vector<ImageF> planes = CreatePlanes<float>(xsize, ysize, 3);
   37|   686k|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (37:19): [True: 514k, False: 171k]
  ------------------
   38|  25.0M|    for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (38:24): [True: 24.5M, False: 514k]
  ------------------
   39|  24.5M|      const uint8_t* const BUTTERAUGLI_RESTRICT row_in = &rgb[3 * xsize * y];
   40|  24.5M|      float* const BUTTERAUGLI_RESTRICT row_out = planes[c].Row(y);
   41|  1.58G|      for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (41:26): [True: 1.55G, False: 24.5M]
  ------------------
   42|  1.55G|        row_out[x] = lut[row_in[3 * x + c]];
   43|  1.55G|      }
   44|  24.5M|    }
   45|   514k|  }
   46|   171k|  return planes;
   47|   171k|}
butteraugli_comparator.cc:_ZN7guetzli12_GLOBAL__N_120ButteraugliBlockDiffEPdS1_S1_:
  384|  7.43M|                          double* diff_xyb) {
  385|  7.43M|  const double *csf8x8 = GetContrastSensitivityMatrix();
  386|  7.43M|  double avgdiff_xyb[3] = {0.0};
  387|  1.43G|  for (int i = 0; i < 3 * kBlockSize; ++i) {
  ------------------
  |  Branch (387:19): [True: 1.42G, False: 7.43M]
  ------------------
  388|  1.42G|    avgdiff_xyb[i / kBlockSize] += xyb0[i] - xyb1[i];
  389|  1.42G|  }
  390|  29.7M|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (390:19): [True: 22.2M, False: 7.43M]
  ------------------
  391|  22.2M|    double avgdiff = avgdiff_xyb[c] / kBlockSize;
  392|  22.2M|    diff_xyb[c] += 4.0 * avgdiff * avgdiff;
  393|  22.2M|  }
  394|  7.43M|  double x_diff[kBlockSize];
  395|  7.43M|  double y_diff[kBlockSize];
  396|  7.43M|  double b_diff[kBlockSize];
  397|   483M|  for (int i = 0; i < kBlockSize; ++i) {
  ------------------
  |  Branch (397:19): [True: 475M, False: 7.43M]
  ------------------
  398|   475M|    x_diff[i] = (xyb0[i] - xyb1[i]);
  399|   475M|    y_diff[i] = (xyb0[kBlockSize + i] - xyb1[kBlockSize + i]);
  400|   475M|    b_diff[i] = (xyb0[2 * kBlockSize + i] - xyb1[2 * kBlockSize + i]);
  401|   475M|  }
  402|  7.43M|  ButteraugliFFTSquared(x_diff);
  403|  7.43M|  ButteraugliFFTSquared(y_diff);
  404|  7.43M|  ButteraugliFFTSquared(b_diff);
  405|   252M|  for (size_t i = kBlockEdgeHalf; i < kBlockHalf + kBlockEdgeHalf + 1; ++i) {
  ------------------
  |  Branch (405:35): [True: 245M, False: 7.43M]
  ------------------
  406|   245M|    double d = csf8x8[i];
  407|   245M|    diff_xyb[0] += d * x_diff[i];
  408|   245M|    diff_xyb[1] += d * y_diff[i];
  409|   245M|    diff_xyb[2] += d * b_diff[i];
  410|   245M|  }
  411|  7.43M|}
butteraugli_comparator.cc:_ZN7guetzli12_GLOBAL__N_128GetContrastSensitivityMatrixEv:
   93|  7.43M|static const double *GetContrastSensitivityMatrix() {
   94|  7.43M|  static double csf8x8[kBlockHalf + kBlockEdgeHalf + 1] = {
   95|  7.43M|    0.0,  // no 8x8 dc, enough 'dc' is calculated from low/mid freq images.
   96|  7.43M|    0.0,
   97|  7.43M|    0.0,
   98|  7.43M|    0.0,
   99|  7.43M|    0.3831134973,
  100|  7.43M|    0.676303603859,
  101|  7.43M|    1.1550451483,
  102|  7.43M|    8,
  103|  7.43M|    8,
  104|  7.43M|    0.692062533689,
  105|  7.43M|    0.847511538605,
  106|  7.43M|    0.498250875965,
  107|  7.43M|    0.36198671102,
  108|  7.43M|    0.308982169883,
  109|  7.43M|    0.1312701920435,
  110|  7.43M|    4.71274312228,
  111|  7.43M|    1.1550451483,
  112|  7.43M|    0.847511538605,
  113|  7.43M|    4.71274312228,
  114|  7.43M|    0.991205724152,
  115|  7.43M|    1.30229591239,
  116|  7.43M|    0.627264168628,
  117|  7.43M|    0.4,
  118|  7.43M|    0.1312701920435,
  119|  7.43M|    0.676303603859,
  120|  7.43M|    0.498250875965,
  121|  7.43M|    0.991205724152,
  122|  7.43M|    0.5,
  123|  7.43M|    0.3831134973,
  124|  7.43M|    0.349686450518,
  125|  7.43M|    0.627264168628,
  126|  7.43M|    0.308982169883,
  127|  7.43M|    0.3831134973,
  128|  7.43M|    0.36198671102,
  129|  7.43M|    1.30229591239,
  130|  7.43M|    0.3831134973,
  131|  7.43M|    0.323078800177,
  132|  7.43M|  };
  133|  7.43M|  return &csf8x8[0];
  134|  7.43M|}
butteraugli_comparator.cc:_ZN7guetzli12_GLOBAL__N_121ButteraugliFFTSquaredEPd:
  357|  22.2M|void ButteraugliFFTSquared(double block[kBlockSize]) {
  358|  22.2M|  double global_mul = 0.000064;
  359|  22.2M|  Complex block_c[kBlockSize];
  360|  22.2M|  assert(kBlockEdge == 8);
  361|   200M|  for (int y = 0; y < kBlockEdge; ++y) {
  ------------------
  |  Branch (361:19): [True: 178M, False: 22.2M]
  ------------------
  362|   178M|    RealFFT8(block + y * kBlockEdge, block_c + y * kBlockEdge);
  363|   178M|  }
  364|  22.2M|  TransposeBlock(block_c);
  365|  22.2M|  double r0[kBlockEdge];
  366|  22.2M|  double r1[kBlockEdge];
  367|   200M|  for (int x = 0; x < kBlockEdge; ++x) {
  ------------------
  |  Branch (367:19): [True: 178M, False: 22.2M]
  ------------------
  368|   178M|    r0[x] = block_c[x].real;
  369|   178M|    r1[x] = block_c[kBlockHalf + x].real;
  370|   178M|  }
  371|  22.2M|  RealFFT8(r0, block_c);
  372|  22.2M|  RealFFT8(r1, block_c + kBlockHalf);
  373|  89.1M|  for (int y = 1; y < kBlockEdgeHalf; ++y) {
  ------------------
  |  Branch (373:19): [True: 66.8M, False: 22.2M]
  ------------------
  374|  66.8M|    FFT8(block_c + y * kBlockEdge);
  375|  66.8M|  }
  376|   758M|  for (int i = kBlockEdgeHalf; i < kBlockHalf + kBlockEdgeHalf + 1; ++i) {
  ------------------
  |  Branch (376:32): [True: 735M, False: 22.2M]
  ------------------
  377|   735M|    block[i] = abssq(block_c[i]);
  378|   735M|    block[i] *= global_mul;
  379|   735M|  }
  380|  22.2M|}
butteraugli_comparator.cc:_ZN7guetzli12_GLOBAL__N_18RealFFT8EPKdPNS0_7ComplexE:
  282|   222M|void RealFFT8(const double* in, Complex* out) {
  283|   222M|  double t1, t2, t3, t5, t6, t7, t8;
  284|   222M|  t8 = in[6];
  285|   222M|  t5 = in[2] - t8;
  286|   222M|  t8 += in[2];
  287|   222M|  out[2].real = t8;
  288|   222M|  out[6].imag = -t5;
  289|   222M|  out[4].imag = t5;
  290|   222M|  t8 = in[4];
  291|   222M|  t3 = in[0] - t8;
  292|   222M|  t8 += in[0];
  293|   222M|  out[0].real = t8;
  294|   222M|  out[4].real = t3;
  295|   222M|  out[6].real = t3;
  296|   222M|  t7 = in[5];
  297|   222M|  t3 = in[1] - t7;
  298|   222M|  t7 += in[1];
  299|   222M|  out[1].real = t7;
  300|   222M|  t8 = in[7];
  301|   222M|  t5 = in[3] - t8;
  302|   222M|  t8 += in[3];
  303|   222M|  out[3].real = t8;
  304|   222M|  t2 = -t5;
  305|   222M|  t6 = t3 - t5;
  306|   222M|  t8 = kSqrtHalf;
  307|   222M|  t6 *= t8;
  308|   222M|  out[5].real = out[4].real - t6;
  309|   222M|  t1 = t3 + t5;
  310|   222M|  t1 *= t8;
  311|   222M|  out[5].imag = out[4].imag - t1;
  312|   222M|  t6 += out[4].real;
  313|   222M|  out[4].real = t6;
  314|   222M|  t1 += out[4].imag;
  315|   222M|  out[4].imag = t1;
  316|   222M|  t5 = t2 - t3;
  317|   222M|  t5 *= t8;
  318|   222M|  out[7].imag = out[6].imag - t5;
  319|   222M|  t2 += t3;
  320|   222M|  t2 *= t8;
  321|   222M|  out[7].real = out[6].real - t2;
  322|   222M|  t2 += out[6].real;
  323|   222M|  out[6].real = t2;
  324|   222M|  t5 += out[6].imag;
  325|   222M|  out[6].imag = t5;
  326|   222M|  t5 = out[2].real;
  327|   222M|  t1 = out[0].real - t5;
  328|   222M|  t7 = out[3].real;
  329|   222M|  t5 += out[0].real;
  330|   222M|  t3 = out[1].real - t7;
  331|   222M|  t7 += out[1].real;
  332|   222M|  t8 = t5 + t7;
  333|   222M|  out[0].real = t8;
  334|   222M|  t5 -= t7;
  335|   222M|  out[1].real = t5;
  336|   222M|  out[2].imag = t3;
  337|   222M|  out[3].imag = -t3;
  338|   222M|  out[3].real = t1;
  339|   222M|  out[2].real = t1;
  340|   222M|  out[0].imag = 0;
  341|   222M|  out[1].imag = 0;
  342|       |
  343|       |  // Reorder to the correct output order.
  344|       |  // TODO(szabadka): Modify the above computation so that this is not needed.
  345|   222M|  Complex tmp = out[2];
  346|   222M|  out[2] = out[3];
  347|   222M|  out[3] = out[5];
  348|   222M|  out[5] = out[7];
  349|   222M|  out[7] = out[4];
  350|   222M|  out[4] = out[1];
  351|   222M|  out[1] = out[6];
  352|   222M|  out[6] = tmp;
  353|   222M|}
butteraugli_comparator.cc:_ZN7guetzli12_GLOBAL__N_114TransposeBlockEPNS0_7ComplexE:
  145|  22.2M|static void TransposeBlock(Complex data[kBlockSize]) {
  146|   200M|  for (int i = 0; i < kBlockEdge; i++) {
  ------------------
  |  Branch (146:19): [True: 178M, False: 22.2M]
  ------------------
  147|   802M|    for (int j = 0; j < i; j++) {
  ------------------
  |  Branch (147:21): [True: 624M, False: 178M]
  ------------------
  148|   624M|      std::swap(data[kBlockEdge * i + j], data[kBlockEdge * j + i]);
  149|   624M|    }
  150|   178M|  }
  151|  22.2M|}
butteraugli_comparator.cc:_ZN7guetzli12_GLOBAL__N_14FFT8EPNS0_7ComplexE:
  186|  66.8M|void FFT8(Complex* a) {
  187|  66.8M|  double t1, t2, t3, t4, t5, t6, t7, t8;
  188|       |
  189|  66.8M|  t7 = a[4].imag;
  190|  66.8M|  t4 = a[0].imag - t7;
  191|  66.8M|  t7 += a[0].imag;
  192|  66.8M|  a[0].imag = t7;
  193|       |
  194|  66.8M|  t8 = a[6].real;
  195|  66.8M|  t5 = a[2].real - t8;
  196|  66.8M|  t8 += a[2].real;
  197|  66.8M|  a[2].real = t8;
  198|       |
  199|  66.8M|  t7 = a[6].imag;
  200|  66.8M|  a[6].imag = t4 - t5;
  201|  66.8M|  t4 += t5;
  202|  66.8M|  a[4].imag = t4;
  203|       |
  204|  66.8M|  t6 = a[2].imag - t7;
  205|  66.8M|  t7 += a[2].imag;
  206|  66.8M|  a[2].imag = t7;
  207|       |
  208|  66.8M|  t8 = a[4].real;
  209|  66.8M|  t3 = a[0].real - t8;
  210|  66.8M|  t8 += a[0].real;
  211|  66.8M|  a[0].real = t8;
  212|       |
  213|  66.8M|  a[4].real = t3 - t6;
  214|  66.8M|  t3 += t6;
  215|  66.8M|  a[6].real = t3;
  216|       |
  217|  66.8M|  t7 = a[5].real;
  218|  66.8M|  t3 = a[1].real - t7;
  219|  66.8M|  t7 += a[1].real;
  220|  66.8M|  a[1].real = t7;
  221|       |
  222|  66.8M|  t8 = a[7].imag;
  223|  66.8M|  t6 = a[3].imag - t8;
  224|  66.8M|  t8 += a[3].imag;
  225|  66.8M|  a[3].imag = t8;
  226|  66.8M|  t1 = t3 - t6;
  227|  66.8M|  t3 += t6;
  228|       |
  229|  66.8M|  t7 = a[5].imag;
  230|  66.8M|  t4 = a[1].imag - t7;
  231|  66.8M|  t7 += a[1].imag;
  232|  66.8M|  a[1].imag = t7;
  233|       |
  234|  66.8M|  t8 = a[7].real;
  235|  66.8M|  t5 = a[3].real - t8;
  236|  66.8M|  t8 += a[3].real;
  237|  66.8M|  a[3].real = t8;
  238|       |
  239|  66.8M|  t2 = t4 - t5;
  240|  66.8M|  t4 += t5;
  241|       |
  242|  66.8M|  t6 = t1 - t4;
  243|  66.8M|  t8 = kSqrtHalf;
  244|  66.8M|  t6 *= t8;
  245|  66.8M|  a[5].real = a[4].real - t6;
  246|  66.8M|  t1 += t4;
  247|  66.8M|  t1 *= t8;
  248|  66.8M|  a[5].imag = a[4].imag - t1;
  249|  66.8M|  t6 += a[4].real;
  250|  66.8M|  a[4].real = t6;
  251|  66.8M|  t1 += a[4].imag;
  252|  66.8M|  a[4].imag = t1;
  253|       |
  254|  66.8M|  t5 = t2 - t3;
  255|  66.8M|  t5 *= t8;
  256|  66.8M|  a[7].imag = a[6].imag - t5;
  257|  66.8M|  t2 += t3;
  258|  66.8M|  t2 *= t8;
  259|  66.8M|  a[7].real = a[6].real - t2;
  260|  66.8M|  t2 += a[6].real;
  261|  66.8M|  a[6].real = t2;
  262|  66.8M|  t5 += a[6].imag;
  263|  66.8M|  a[6].imag = t5;
  264|       |
  265|  66.8M|  FFT4(a);
  266|       |
  267|       |  // Reorder to the correct output order.
  268|       |  // TODO(szabadka): Modify the above computation so that this is not needed.
  269|  66.8M|  Complex tmp = a[2];
  270|  66.8M|  a[2] = a[3];
  271|  66.8M|  a[3] = a[5];
  272|  66.8M|  a[5] = a[7];
  273|  66.8M|  a[7] = a[4];
  274|  66.8M|  a[4] = a[1];
  275|  66.8M|  a[1] = a[6];
  276|  66.8M|  a[6] = tmp;
  277|  66.8M|}
butteraugli_comparator.cc:_ZN7guetzli12_GLOBAL__N_14FFT4EPNS0_7ComplexE:
  154|  66.8M|inline void FFT4(Complex* a) {
  155|  66.8M|  double t1, t2, t3, t4, t5, t6, t7, t8;
  156|  66.8M|  t5 = a[2].real;
  157|  66.8M|  t1 = a[0].real - t5;
  158|  66.8M|  t7 = a[3].real;
  159|  66.8M|  t5 += a[0].real;
  160|  66.8M|  t3 = a[1].real - t7;
  161|  66.8M|  t7 += a[1].real;
  162|  66.8M|  t8 = t5 + t7;
  163|  66.8M|  a[0].real = t8;
  164|  66.8M|  t5 -= t7;
  165|  66.8M|  a[1].real = t5;
  166|  66.8M|  t6 = a[2].imag;
  167|  66.8M|  t2 = a[0].imag - t6;
  168|  66.8M|  t6 += a[0].imag;
  169|  66.8M|  t5 = a[3].imag;
  170|  66.8M|  a[2].imag = t2 + t3;
  171|  66.8M|  t2 -= t3;
  172|  66.8M|  a[3].imag = t2;
  173|  66.8M|  t4 = a[1].imag - t5;
  174|  66.8M|  a[3].real = t1 + t4;
  175|  66.8M|  t1 -= t4;
  176|  66.8M|  a[2].real = t1;
  177|  66.8M|  t5 += a[1].imag;
  178|  66.8M|  a[0].imag = t6 + t5;
  179|  66.8M|  t6 -= t5;
  180|  66.8M|  a[1].imag = t6;
  181|  66.8M|}
butteraugli_comparator.cc:_ZN7guetzli12_GLOBAL__N_15abssqERKNS0_7ComplexE:
  141|   735M|inline double abssq(const Complex& c) {
  142|   735M|  return c.real * c.real + c.imag * c.imag;
  143|   735M|}

_ZNK7guetzli21ButteraugliComparator10DistanceOKEd:
   51|  51.1k|  bool DistanceOK(double target_mul) const override {
   52|  51.1k|    return distance_ <= target_mul * target_distance_;
   53|  51.1k|  }
_ZNK7guetzli21ButteraugliComparator7distmapEv:
   55|   138k|  const std::vector<float> distmap() const override { return distmap_; }

_ZN7guetzli24ColorTransformYCbCrToRGBEPh:
  211|   981M|inline void ColorTransformYCbCrToRGB(uint8_t* pixel) {
  212|   981M|  int y  = pixel[0];
  213|   981M|  int cb = pixel[1];
  214|   981M|  int cr = pixel[2];
  215|   981M|  pixel[0] = kRangeLimit[y + kCrToRedTable[cr]];
  216|   981M|  pixel[1] = kRangeLimit[y +
  217|   981M|                         ((kCrToGreenTable[cr] + kCbToGreenTable[cb]) >> 16)];
  218|   981M|  pixel[2] = kRangeLimit[y + kCbToBlueTable[cb]];
  219|   981M|}

_ZN7guetzli10ComparatorC2Ev:
   31|  3.10k|  Comparator() {}
_ZN7guetzli10ComparatorD2Ev:
   32|  3.10k|  virtual ~Comparator() {}

_ZN7guetzli10PrintDebugEPNS_12ProcessStatsENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   21|  11.4M|void PrintDebug(ProcessStats* stats, std::string s) {
   22|  11.4M|  if (stats->debug_output) {
  ------------------
  |  Branch (22:7): [True: 0, False: 11.4M]
  ------------------
   23|      0|    stats->debug_output->append(s);
   24|      0|  }
   25|  11.4M|  if (stats->debug_output_file) {
  ------------------
  |  Branch (25:7): [True: 0, False: 11.4M]
  ------------------
   26|      0|    fprintf(stats->debug_output_file, "%s", s.c_str());
   27|      0|  }
   28|  11.4M|}

_ZN7guetzli8SetDepthEiPNS_11HuffmanTreeEPhi:
   26|  2.91M|bool SetDepth(int p0, HuffmanTree *pool, uint8_t *depth, int max_depth) {
   27|  2.91M|  int stack[17];
   28|  2.91M|  int level = 0;
   29|  2.91M|  int p = p0;
   30|  2.91M|  assert(max_depth <= 16);
   31|      0|  stack[0] = -1;
   32|  75.2M|  while (true) {
  ------------------
  |  Branch (32:10): [Folded - Ignored]
  ------------------
   33|  75.2M|    if (pool[p].index_left_ >= 0) {
  ------------------
  |  Branch (33:9): [True: 36.1M, False: 39.0M]
  ------------------
   34|  36.1M|      level++;
   35|  36.1M|      if (level > max_depth) return false;
  ------------------
  |  Branch (35:11): [True: 0, False: 36.1M]
  ------------------
   36|  36.1M|      stack[level] = pool[p].index_right_or_value_;
   37|  36.1M|      p = pool[p].index_left_;
   38|  36.1M|      continue;
   39|  39.0M|    } else {
   40|  39.0M|      depth[pool[p].index_right_or_value_] = static_cast<uint8_t>(level);
   41|  39.0M|    }
   42|  78.1M|    while (level >= 0 && stack[level] == -1) level--;
  ------------------
  |  Branch (42:12): [True: 75.2M, False: 2.91M]
  |  Branch (42:26): [True: 39.0M, False: 36.1M]
  ------------------
   43|  39.0M|    if (level < 0) return true;
  ------------------
  |  Branch (43:9): [True: 2.91M, False: 36.1M]
  ------------------
   44|  36.1M|    p = stack[level];
   45|  36.1M|    stack[level] = -1;
   46|  36.1M|  }
   47|  2.91M|}
_ZN7guetzli17CreateHuffmanTreeEPKjmiPNS_11HuffmanTreeEPh:
   77|  2.92M|                       uint8_t *depth) {
   78|       |  // For block sizes below 64 kB, we never need to do a second iteration
   79|       |  // of this loop. Probably all of our block sizes will be smaller than
   80|       |  // that, so this loop is mostly of academic interest. If we actually
   81|       |  // would need this, we would be better off with the Katajainen algorithm.
   82|  2.92M|  for (uint32_t count_limit = 1; ; count_limit *= 2) {
   83|  2.92M|    size_t n = 0;
   84|   754M|    for (size_t i = length; i != 0;) {
  ------------------
  |  Branch (84:29): [True: 751M, False: 2.92M]
  ------------------
   85|   751M|      --i;
   86|   751M|      if (data[i]) {
  ------------------
  |  Branch (86:11): [True: 39.0M, False: 712M]
  ------------------
   87|  39.0M|        const uint32_t count = std::max<uint32_t>(data[i], count_limit);
   88|  39.0M|        tree[n++] = HuffmanTree(count, -1, static_cast<int16_t>(i));
   89|  39.0M|      }
   90|   751M|    }
   91|       |
   92|  2.92M|    if (n == 1) {
  ------------------
  |  Branch (92:9): [True: 7.32k, False: 2.91M]
  ------------------
   93|  7.32k|      depth[tree[0].index_right_or_value_] = 1;      // Only one element.
   94|  7.32k|      break;
   95|  7.32k|    }
   96|       |
   97|  2.91M|    std::sort(tree, tree + n, SortHuffmanTree);
   98|       |
   99|       |    // The nodes are:
  100|       |    // [0, n): the sorted leaf nodes that we start with.
  101|       |    // [n]: we add a sentinel here.
  102|       |    // [n + 1, 2n): new parent nodes are added here, starting from
  103|       |    //              (n+1). These are naturally in ascending order.
  104|       |    // [2n]: we add a sentinel at the end as well.
  105|       |    // There will be (2n+1) elements at the end.
  106|  2.91M|    const HuffmanTree sentinel(~static_cast<uint32_t>(0), -1, -1);
  107|  2.91M|    tree[n] = sentinel;
  108|  2.91M|    tree[n + 1] = sentinel;
  109|       |
  110|  2.91M|    size_t i = 0;      // Points to the next leaf node.
  111|  2.91M|    size_t j = n + 1;  // Points to the next non-leaf node.
  112|  39.0M|    for (size_t k = n - 1; k != 0; --k) {
  ------------------
  |  Branch (112:28): [True: 36.1M, False: 2.91M]
  ------------------
  113|  36.1M|      size_t left, right;
  114|  36.1M|      if (tree[i].total_count_ <= tree[j].total_count_) {
  ------------------
  |  Branch (114:11): [True: 19.3M, False: 16.8M]
  ------------------
  115|  19.3M|        left = i;
  116|  19.3M|        ++i;
  117|  19.3M|      } else {
  118|  16.8M|        left = j;
  119|  16.8M|        ++j;
  120|  16.8M|      }
  121|  36.1M|      if (tree[i].total_count_ <= tree[j].total_count_) {
  ------------------
  |  Branch (121:11): [True: 19.7M, False: 16.3M]
  ------------------
  122|  19.7M|        right = i;
  123|  19.7M|        ++i;
  124|  19.7M|      } else {
  125|  16.3M|        right = j;
  126|  16.3M|        ++j;
  127|  16.3M|      }
  128|       |
  129|       |      // The sentinel node becomes the parent node.
  130|  36.1M|      size_t j_end = 2 * n - k;
  131|  36.1M|      tree[j_end].total_count_ =
  132|  36.1M|          tree[left].total_count_ + tree[right].total_count_;
  133|  36.1M|      tree[j_end].index_left_ = static_cast<int16_t>(left);
  134|  36.1M|      tree[j_end].index_right_or_value_ = static_cast<int16_t>(right);
  135|       |
  136|       |      // Add back the last sentinel node.
  137|  36.1M|      tree[j_end + 1] = sentinel;
  138|  36.1M|    }
  139|  2.91M|    if (SetDepth(static_cast<int>(2 * n - 1), &tree[0], depth, tree_limit)) {
  ------------------
  |  Branch (139:9): [True: 2.91M, False: 0]
  ------------------
  140|       |      /* We need to pack the Huffman tree in tree_limit bits. If this was not
  141|       |         successful, add fake entities to the lowest values and retry. */
  142|  2.91M|      break;
  143|  2.91M|    }
  144|  2.91M|  }
  145|  2.92M|}
entropy_encode.cc:_ZN7guetzliL15SortHuffmanTreeERKNS_11HuffmanTreeES2_:
   51|   142M|                                   const HuffmanTree& v1) {
   52|   142M|  if (v0.total_count_ != v1.total_count_) {
  ------------------
  |  Branch (52:7): [True: 107M, False: 34.7M]
  ------------------
   53|   107M|    return v0.total_count_ < v1.total_count_;
   54|   107M|  }
   55|  34.7M|  return v0.index_right_or_value_ > v1.index_right_or_value_;
   56|   142M|}

_ZN7guetzli11HuffmanTreeC2Ev:
   29|  1.50G|  HuffmanTree() {}
_ZN7guetzli11HuffmanTreeC2Ejss:
   33|  42.0M|        index_right_or_value_(right) {
   34|  42.0M|  }

_ZN7guetzli16Log2FloorNonZeroEj:
   24|   456M|inline int Log2FloorNonZero(uint32_t n) {
   25|   456M|#ifdef __GNUC__
   26|   456M|  return 31 ^ __builtin_clz(n);
   27|       |#else
   28|       |  unsigned int result = 0;
   29|       |  while (n >>= 1) result++;
   30|       |  return result;
   31|       |#endif
   32|   456M|}
_ZN7guetzli9Log2FloorEj:
   34|  34.9M|inline int Log2Floor(uint32_t n) {
   35|  34.9M|  return n == 0 ? -1 : Log2FloorNonZero(n);
  ------------------
  |  Branch (35:10): [True: 28.9M, False: 5.95M]
  ------------------
   36|  34.9M|}

_ZN7guetzli21NewSrgb8ToLinearTableEv:
   23|      1|const double* NewSrgb8ToLinearTable() {
   24|      1|  double* table = new double[256];
   25|      1|  int i = 0;
   26|     12|  for (; i < 11; ++i) {
  ------------------
  |  Branch (26:10): [True: 11, False: 1]
  ------------------
   27|     11|    table[i] = i / 12.92;
   28|     11|  }
   29|    246|  for (; i < 256; ++i) {
  ------------------
  |  Branch (29:10): [True: 245, False: 1]
  ------------------
   30|    245|    table[i] = 255.0 * std::pow(((i / 255.0) + 0.055) / 1.055, 2.4);
   31|    245|  }
   32|      1|  return table;
   33|      1|}
_ZN7guetzli18Srgb8ToLinearTableEv:
   35|  7.94M|const double* Srgb8ToLinearTable() {
   36|  7.94M|  static const double* const kSrgb8ToLinearTable = NewSrgb8ToLinearTable();
   37|  7.94M|  return kSrgb8ToLinearTable;
   38|  7.94M|}

_ZN7guetzli16ComputeBlockIDCTEPKsPh:
  139|  20.4M|void ComputeBlockIDCT(const coeff_t* block, uint8_t* out) {
  140|  20.4M|  coeff_t colidcts[kDCTBlockSize];
  141|  20.4M|  const int kColScale = 11;
  142|  20.4M|  const int kColRound = 1 << (kColScale - 1);
  143|   184M|  for (int x = 0; x < 8; ++x) {
  ------------------
  |  Branch (143:19): [True: 163M, False: 20.4M]
  ------------------
  144|   163M|    int colbuf[8] = { 0 };
  145|   163M|    Compute1dIDCT(&block[x], 8, colbuf);
  146|  1.47G|    for (int y = 0; y < 8; ++y) {
  ------------------
  |  Branch (146:21): [True: 1.30G, False: 163M]
  ------------------
  147|  1.30G|      colidcts[8 * y + x] = (colbuf[y] + kColRound) >> kColScale;
  148|  1.30G|    }
  149|   163M|  }
  150|  20.4M|  const int kRowScale = 18;
  151|  20.4M|  const int kRowRound = 257 << (kRowScale - 1);  // includes offset by 128
  152|   184M|  for (int y = 0; y < 8; ++y) {
  ------------------
  |  Branch (152:19): [True: 163M, False: 20.4M]
  ------------------
  153|   163M|    const int rowidx = 8 * y;
  154|   163M|    int rowbuf[8] = { 0 };
  155|   163M|    Compute1dIDCT(&colidcts[rowidx], 1, rowbuf);
  156|  1.47G|    for (int x = 0; x < 8; ++x) {
  ------------------
  |  Branch (156:21): [True: 1.30G, False: 163M]
  ------------------
  157|  1.30G|      out[rowidx + x] =
  158|  1.30G|          std::max(0, std::min(255, (rowbuf[x] + kRowRound) >> kRowScale));
  159|  1.30G|    }
  160|   163M|  }
  161|  20.4M|}
_ZN7guetzli13Compute1dIDCTEPKsiPi:
   41|   327M|inline void Compute1dIDCT(const coeff_t* in, const int stride, int out[8]) {
   42|   327M|  int tmp0, tmp1, tmp2, tmp3, tmp4;
   43|       |
   44|   327M|  tmp1 = kIDCTMatrix[0] * in[0];
   45|   327M|  out[0] = out[1] = out[2] = out[3] = out[4] = out[5] = out[6] = out[7] = tmp1;
   46|       |
   47|   327M|  tmp0 = in[stride];
   48|   327M|  tmp1 = kIDCTMatrix[ 1] * tmp0;
   49|   327M|  tmp2 = kIDCTMatrix[ 9] * tmp0;
   50|   327M|  tmp3 = kIDCTMatrix[17] * tmp0;
   51|   327M|  tmp4 = kIDCTMatrix[25] * tmp0;
   52|   327M|  out[0] += tmp1;
   53|   327M|  out[1] += tmp2;
   54|   327M|  out[2] += tmp3;
   55|   327M|  out[3] += tmp4;
   56|   327M|  out[4] -= tmp4;
   57|   327M|  out[5] -= tmp3;
   58|   327M|  out[6] -= tmp2;
   59|   327M|  out[7] -= tmp1;
   60|       |
   61|   327M|  tmp0 = in[2 * stride];
   62|   327M|  tmp1 = kIDCTMatrix[ 2] * tmp0;
   63|   327M|  tmp2 = kIDCTMatrix[10] * tmp0;
   64|   327M|  out[0] += tmp1;
   65|   327M|  out[1] += tmp2;
   66|   327M|  out[2] -= tmp2;
   67|   327M|  out[3] -= tmp1;
   68|   327M|  out[4] -= tmp1;
   69|   327M|  out[5] -= tmp2;
   70|   327M|  out[6] += tmp2;
   71|   327M|  out[7] += tmp1;
   72|       |
   73|   327M|  tmp0 = in[3 * stride];
   74|   327M|  tmp1 = kIDCTMatrix[ 3] * tmp0;
   75|   327M|  tmp2 = kIDCTMatrix[11] * tmp0;
   76|   327M|  tmp3 = kIDCTMatrix[19] * tmp0;
   77|   327M|  tmp4 = kIDCTMatrix[27] * tmp0;
   78|   327M|  out[0] += tmp1;
   79|   327M|  out[1] += tmp2;
   80|   327M|  out[2] += tmp3;
   81|   327M|  out[3] += tmp4;
   82|   327M|  out[4] -= tmp4;
   83|   327M|  out[5] -= tmp3;
   84|   327M|  out[6] -= tmp2;
   85|   327M|  out[7] -= tmp1;
   86|       |
   87|   327M|  tmp0 = in[4 * stride];
   88|   327M|  tmp1 = kIDCTMatrix[ 4] * tmp0;
   89|   327M|  out[0] += tmp1;
   90|   327M|  out[1] -= tmp1;
   91|   327M|  out[2] -= tmp1;
   92|   327M|  out[3] += tmp1;
   93|   327M|  out[4] += tmp1;
   94|   327M|  out[5] -= tmp1;
   95|   327M|  out[6] -= tmp1;
   96|   327M|  out[7] += tmp1;
   97|       |
   98|   327M|  tmp0 = in[5 * stride];
   99|   327M|  tmp1 = kIDCTMatrix[ 5] * tmp0;
  100|   327M|  tmp2 = kIDCTMatrix[13] * tmp0;
  101|   327M|  tmp3 = kIDCTMatrix[21] * tmp0;
  102|   327M|  tmp4 = kIDCTMatrix[29] * tmp0;
  103|   327M|  out[0] += tmp1;
  104|   327M|  out[1] += tmp2;
  105|   327M|  out[2] += tmp3;
  106|   327M|  out[3] += tmp4;
  107|   327M|  out[4] -= tmp4;
  108|   327M|  out[5] -= tmp3;
  109|   327M|  out[6] -= tmp2;
  110|   327M|  out[7] -= tmp1;
  111|       |
  112|   327M|  tmp0 = in[6 * stride];
  113|   327M|  tmp1 = kIDCTMatrix[ 6] * tmp0;
  114|   327M|  tmp2 = kIDCTMatrix[14] * tmp0;
  115|   327M|  out[0] += tmp1;
  116|   327M|  out[1] += tmp2;
  117|   327M|  out[2] -= tmp2;
  118|   327M|  out[3] -= tmp1;
  119|   327M|  out[4] -= tmp1;
  120|   327M|  out[5] -= tmp2;
  121|   327M|  out[6] += tmp2;
  122|   327M|  out[7] += tmp1;
  123|       |
  124|   327M|  tmp0 = in[7 * stride];
  125|   327M|  tmp1 = kIDCTMatrix[ 7] * tmp0;
  126|   327M|  tmp2 = kIDCTMatrix[15] * tmp0;
  127|   327M|  tmp3 = kIDCTMatrix[23] * tmp0;
  128|   327M|  tmp4 = kIDCTMatrix[31] * tmp0;
  129|   327M|  out[0] += tmp1;
  130|   327M|  out[1] += tmp2;
  131|   327M|  out[2] += tmp3;
  132|   327M|  out[3] += tmp4;
  133|   327M|  out[4] -= tmp4;
  134|   327M|  out[5] -= tmp3;
  135|   327M|  out[6] -= tmp2;
  136|   327M|  out[7] -= tmp1;
  137|   327M|}

_ZN7guetzli9BitWriterC2Em:
   38|   163k|                                      overflow(false) {}
_ZN7guetzli9BitWriter9WriteBitsEim:
   40|   351M|  void WriteBits(int nbits, uint64_t bits) {
   41|   351M|    put_bits -= nbits;
   42|   351M|    put_buffer |= (bits << put_bits);
   43|   351M|    if (put_bits <= 16) {
  ------------------
  |  Branch (43:9): [True: 17.2M, False: 333M]
  ------------------
   44|       |      // At this point we are ready to emit the most significant 6 bytes of
   45|       |      // put_buffer_ to the output.
   46|       |      // The JPEG format requires that after every 0xff byte in the entropy
   47|       |      // coded section, there is a zero byte, therefore we first check if any of
   48|       |      // the 6 most significant bytes of put_buffer_ is 0xff.
   49|  17.2M|      if (HasZeroByte(~put_buffer | 0xffff)) {
  ------------------
  |  Branch (49:11): [True: 324k, False: 16.9M]
  ------------------
   50|       |        // We have a 0xff byte somewhere, examine each byte and append a zero
   51|       |        // byte if necessary.
   52|   324k|        EmitByte((put_buffer >> 56) & 0xff);
   53|   324k|        EmitByte((put_buffer >> 48) & 0xff);
   54|   324k|        EmitByte((put_buffer >> 40) & 0xff);
   55|   324k|        EmitByte((put_buffer >> 32) & 0xff);
   56|   324k|        EmitByte((put_buffer >> 24) & 0xff);
   57|   324k|        EmitByte((put_buffer >> 16) & 0xff);
   58|  16.9M|      } else if (pos + 6 < len) {
  ------------------
  |  Branch (58:18): [True: 16.9M, False: 0]
  ------------------
   59|       |        // We don't have any 0xff bytes, output all 6 bytes without checking.
   60|  16.9M|        data[pos] = (put_buffer >> 56) & 0xff;
   61|  16.9M|        data[pos + 1] = (put_buffer >> 48) & 0xff;
   62|  16.9M|        data[pos + 2] = (put_buffer >> 40) & 0xff;
   63|  16.9M|        data[pos + 3] = (put_buffer >> 32) & 0xff;
   64|  16.9M|        data[pos + 4] = (put_buffer >> 24) & 0xff;
   65|  16.9M|        data[pos + 5] = (put_buffer >> 16) & 0xff;
   66|  16.9M|        pos += 6;
   67|  16.9M|      } else {
   68|      0|        overflow = true;
   69|      0|      }
   70|  17.2M|      put_buffer <<= 48;
   71|  17.2M|      put_bits += 48;
   72|  17.2M|    }
   73|   351M|  }
_ZN7guetzli11HasZeroByteEm:
   27|  17.2M|inline uint64_t HasZeroByte(uint64_t x) {
   28|  17.2M|  return (x - 0x0101010101010101ULL) & ~x & 0x8080808080808080ULL;
   29|  17.2M|}
_ZN7guetzli9BitWriter8EmitByteEi:
   76|  2.83M|  void EmitByte(int byte) {
   77|  2.83M|    if (pos < len) {
  ------------------
  |  Branch (77:9): [True: 2.83M, False: 0]
  ------------------
   78|  2.83M|      data[pos++] = byte;
   79|  2.83M|    } else {
   80|      0|      overflow = true;
   81|      0|    }
   82|  2.83M|    if (byte == 0xff) {
  ------------------
  |  Branch (82:9): [True: 335k, False: 2.49M]
  ------------------
   83|   335k|      EmitByte(0);
   84|   335k|    }
   85|  2.83M|  }
_ZN7guetzli9BitWriter18JumpToByteBoundaryEv:
   87|   163k|  void JumpToByteBoundary() {
   88|   572k|    while (put_bits <= 56) {
  ------------------
  |  Branch (88:12): [True: 408k, False: 163k]
  ------------------
   89|   408k|      int c = (put_buffer >> 56) & 0xff;
   90|   408k|      EmitByte(c);
   91|   408k|      put_buffer <<= 8;
   92|   408k|      put_bits += 8;
   93|   408k|    }
   94|   163k|    if (put_bits < 64) {
  ------------------
  |  Branch (94:9): [True: 141k, False: 22.5k]
  ------------------
   95|   141k|      int padmask = 0xff >> (64 - put_bits);
   96|   141k|      int c = ((put_buffer >> 56) & ~padmask) | padmask;
   97|   141k|      EmitByte(c);
   98|   141k|    }
   99|   163k|    put_buffer = 0;
  100|   163k|    put_bits = 64;
  101|   163k|  }

_ZNK7guetzli8JPEGData5Is420Ev:
   24|  5.83k|bool JPEGData::Is420() const {
   25|  5.83k|  return (components.size() == 3 &&
  ------------------
  |  Branch (25:11): [True: 5.83k, False: 0]
  ------------------
   26|  5.83k|          max_h_samp_factor == 2 &&
  ------------------
  |  Branch (26:11): [True: 5.34k, False: 489]
  ------------------
   27|  5.83k|          max_v_samp_factor == 2 &&
  ------------------
  |  Branch (27:11): [True: 5.34k, False: 6]
  ------------------
   28|  5.83k|          components[0].h_samp_factor == 2 &&
  ------------------
  |  Branch (28:11): [True: 5.34k, False: 1]
  ------------------
   29|  5.83k|          components[0].v_samp_factor == 2 &&
  ------------------
  |  Branch (29:11): [True: 5.34k, False: 1]
  ------------------
   30|  5.83k|          components[1].h_samp_factor == 1 &&
  ------------------
  |  Branch (30:11): [True: 5.34k, False: 1]
  ------------------
   31|  5.83k|          components[1].v_samp_factor == 1 &&
  ------------------
  |  Branch (31:11): [True: 5.33k, False: 2]
  ------------------
   32|  5.83k|          components[2].h_samp_factor == 1 &&
  ------------------
  |  Branch (32:11): [True: 5.33k, False: 1]
  ------------------
   33|  5.83k|          components[2].v_samp_factor == 1);
  ------------------
  |  Branch (33:11): [True: 5.33k, False: 1]
  ------------------
   34|  5.83k|}
_ZNK7guetzli8JPEGData5Is444Ev:
   36|  3.65k|bool JPEGData::Is444() const {
   37|  3.65k|  return (components.size() == 3 &&
  ------------------
  |  Branch (37:11): [True: 3.65k, False: 0]
  ------------------
   38|  3.65k|          max_h_samp_factor == 1 &&
  ------------------
  |  Branch (38:11): [True: 966, False: 2.68k]
  ------------------
   39|  3.65k|          max_v_samp_factor == 1 &&
  ------------------
  |  Branch (39:11): [True: 960, False: 6]
  ------------------
   40|  3.65k|          components[0].h_samp_factor == 1 &&
  ------------------
  |  Branch (40:11): [True: 960, False: 0]
  ------------------
   41|  3.65k|          components[0].v_samp_factor == 1 &&
  ------------------
  |  Branch (41:11): [True: 960, False: 0]
  ------------------
   42|  3.65k|          components[1].h_samp_factor == 1 &&
  ------------------
  |  Branch (42:11): [True: 960, False: 0]
  ------------------
   43|  3.65k|          components[1].v_samp_factor == 1 &&
  ------------------
  |  Branch (43:11): [True: 960, False: 0]
  ------------------
   44|  3.65k|          components[2].h_samp_factor == 1 &&
  ------------------
  |  Branch (44:11): [True: 960, False: 0]
  ------------------
   45|  3.65k|          components[2].v_samp_factor == 1);
  ------------------
  |  Branch (45:11): [True: 960, False: 0]
  ------------------
   46|  3.65k|}
_ZN7guetzli15SaveQuantTablesEPA64_KiPNS_8JPEGDataE:
   70|   174k|void SaveQuantTables(const int q[3][kDCTBlockSize], JPEGData* jpg) {
   71|   174k|  const size_t kTableSize = kDCTBlockSize * sizeof(q[0][0]);
   72|   174k|  jpg->quant.clear();
   73|   174k|  int num_tables = 0;
   74|   639k|  for (size_t i = 0; i < jpg->components.size(); ++i) {
  ------------------
  |  Branch (74:22): [True: 465k, False: 174k]
  ------------------
   75|   465k|    JPEGComponent* comp = &jpg->components[i];
   76|       |    // Check if we have this quant table already.
   77|   465k|    bool found = false;
   78|   531k|    for (int j = 0; j < num_tables; ++j) {
  ------------------
  |  Branch (78:21): [True: 324k, False: 207k]
  ------------------
   79|   324k|      if (memcmp(&q[i][0], &jpg->quant[j].values[0], kTableSize) == 0) {
  ------------------
  |  Branch (79:11): [True: 257k, False: 66.2k]
  ------------------
   80|   257k|        comp->quant_idx = j;
   81|   257k|        found = true;
   82|   257k|        break;
   83|   257k|      }
   84|   324k|    }
   85|   465k|    if (!found) {
  ------------------
  |  Branch (85:9): [True: 207k, False: 257k]
  ------------------
   86|   207k|      JPEGQuantTable table;
   87|   207k|      memcpy(&table.values[0], &q[i][0], kTableSize);
   88|   207k|      table.precision = 0;
   89|  13.4M|      for (int k = 0; k < kDCTBlockSize; ++k) {
  ------------------
  |  Branch (89:23): [True: 13.2M, False: 207k]
  ------------------
   90|  13.2M|        assert(table.values[k] >= 0);
   91|      0|        assert(table.values[k] < (1 << 16));
   92|  13.2M|        if (table.values[k] > 0xff) {
  ------------------
  |  Branch (92:13): [True: 4.09k, False: 13.2M]
  ------------------
   93|  4.09k|          table.precision = 1;
   94|  4.09k|        }
   95|  13.2M|      }
   96|   207k|      table.index = num_tables;
   97|   207k|      comp->quant_idx = num_tables;
   98|   207k|      jpg->quant.push_back(table);
   99|   207k|      ++num_tables;
  100|   207k|    }
  101|   465k|  }
  102|   174k|}

_ZN7guetzli8JPEGDataC2Ev:
  179|  11.3k|               error(JPEG_OK) {}
_ZN7guetzli14JPEGQuantTableC2Ev:
   87|   215k|                     index(0), is_last(true) {}
_ZN7guetzli15JPEGHuffmanCodeC2Ev:
  104|   447k|                      is_last(true) {}
_ZN7guetzli13JPEGComponentC2Ev:
  147|  25.6k|                    height_in_blocks(0) {}

_ZN7guetzli18HasYCbCrColorSpaceERKNS_8JPEGDataE:
   25|  6.32k|bool HasYCbCrColorSpace(const JPEGData& jpg) {
   26|  6.32k|  bool has_Adobe_marker = false;
   27|  6.32k|  uint8_t Adobe_transform = 0;
   28|   379k|  for (const std::string& app : jpg.app_data) {
  ------------------
  |  Branch (28:31): [True: 379k, False: 5.68k]
  ------------------
   29|   379k|    if (static_cast<uint8_t>(app[0]) == 0xe0) {
  ------------------
  |  Branch (29:9): [True: 642, False: 378k]
  ------------------
   30|    642|      return true;
   31|   378k|    } else if (static_cast<uint8_t>(app[0]) == 0xee && app.size() >= 15) {
  ------------------
  |  Branch (31:16): [True: 1.65k, False: 377k]
  |  Branch (31:56): [True: 1.08k, False: 574]
  ------------------
   32|  1.08k|      has_Adobe_marker = true;
   33|  1.08k|      Adobe_transform = app[14];
   34|  1.08k|    }
   35|   379k|  }
   36|  5.68k|  if (has_Adobe_marker) {
  ------------------
  |  Branch (36:7): [True: 60, False: 5.62k]
  ------------------
   37|     60|    return (Adobe_transform != 0);
   38|     60|  }
   39|  5.62k|  const int cid0 = jpg.components[0].id;
   40|  5.62k|  const int cid1 = jpg.components[1].id;
   41|  5.62k|  const int cid2 = jpg.components[2].id;
   42|  5.62k|  return (cid0 != 'R' || cid1 != 'G' || cid2 != 'B');
  ------------------
  |  Branch (42:11): [True: 5.61k, False: 11]
  |  Branch (42:26): [True: 4, False: 7]
  |  Branch (42:41): [True: 6, False: 1]
  ------------------
   43|  5.68k|}
_ZN7guetzli15DecodeJpegToRGBERKNS_8JPEGDataE:
   45|  3.26k|std::vector<uint8_t> DecodeJpegToRGB(const JPEGData& jpg) {
   46|  3.26k|  if (jpg.components.size() == 1 ||
  ------------------
  |  Branch (46:7): [True: 86, False: 3.17k]
  ------------------
   47|  3.26k|      (jpg.components.size() == 3 &&
  ------------------
  |  Branch (47:8): [True: 3.17k, False: 2]
  ------------------
   48|  3.23k|       HasYCbCrColorSpace(jpg) && (jpg.Is420() || jpg.Is444()))) {
  ------------------
  |  Branch (48:8): [True: 3.17k, False: 5]
  |  Branch (48:36): [True: 2.66k, False: 502]
  |  Branch (48:51): [True: 480, False: 22]
  ------------------
   49|  3.23k|    OutputImage img(jpg.width, jpg.height);
   50|  3.23k|    img.CopyFromJpegData(jpg);
   51|  3.23k|    return img.ToSRGB();
   52|  3.23k|  }
   53|     29|  return std::vector<uint8_t>();
   54|  3.26k|}

_ZN7guetzli8ReadJpegEPKhmNS_12JpegReadModeEPNS_8JPEGDataE:
  932|  11.3k|              JPEGData* jpg) {
  933|  11.3k|  size_t pos = 0;
  934|       |  // Check SOI marker.
  935|  11.3k|  EXPECT_MARKER();
  ------------------
  |  |   57|  11.3k|  if (pos + 2 > len || data[pos] != 0xff) {                             \
  |  |  ------------------
  |  |  |  Branch (57:7): [True: 1, False: 11.3k]
  |  |  |  Branch (57:24): [True: 15, False: 11.2k]
  |  |  ------------------
  |  |   58|     16|    fprintf(stderr, "Marker byte (0xff) expected, found: %d "           \
  |  |   59|     16|            "pos=%d len=%d\n",                                          \
  |  |   60|     16|            (pos < len ? data[pos] : 0), static_cast<int>(pos),         \
  |  |  ------------------
  |  |  |  Branch (60:14): [True: 16, False: 0]
  |  |  ------------------
  |  |   61|     16|            static_cast<int>(len));                                     \
  |  |   62|     16|    jpg->error = JPEG_MARKER_BYTE_NOT_FOUND;                            \
  |  |   63|     16|    return false;                                                       \
  |  |   64|     16|  }
  ------------------
  936|  11.2k|  int marker = data[pos + 1];
  937|  11.2k|  pos += 2;
  938|  11.2k|  if (marker != 0xd8) {
  ------------------
  |  Branch (938:7): [True: 12, False: 11.2k]
  ------------------
  939|     12|    fprintf(stderr, "Did not find expected SOI marker, actual=%d\n", marker);
  940|     12|    jpg->error = JPEG_SOI_NOT_FOUND;
  941|     12|    return false;
  942|     12|  }
  943|  11.2k|  int lut_size = kMaxHuffmanTables * kJpegHuffmanLutSize;
  944|  11.2k|  std::vector<HuffmanTableEntry> dc_huff_lut(lut_size);
  945|  11.2k|  std::vector<HuffmanTableEntry> ac_huff_lut(lut_size);
  946|  11.2k|  bool found_sof = false;
  947|  11.2k|  uint16_t scan_progression[kMaxComponents][kDCTBlockSize] = { { 0 } };
  948|       |
  949|  11.2k|  bool is_progressive = false;   // default
  950|  8.09M|  do {
  951|       |    // Read next marker.
  952|  8.09M|    size_t num_skipped = FindNextMarker(data, len, pos);
  953|  8.09M|    if (num_skipped > 0) {
  ------------------
  |  Branch (953:9): [True: 7.64M, False: 452k]
  ------------------
  954|       |      // Add a fake marker to indicate arbitrary in-between-markers data.
  955|  7.64M|      jpg->marker_order.push_back(0xff);
  956|  7.64M|      jpg->inter_marker_data.push_back(
  957|  7.64M|          std::string(reinterpret_cast<const char*>(&data[pos]),
  958|  7.64M|                                      num_skipped));
  959|  7.64M|      pos += num_skipped;
  960|  7.64M|    }
  961|  8.09M|    EXPECT_MARKER();
  ------------------
  |  |   57|  8.09M|  if (pos + 2 > len || data[pos] != 0xff) {                             \
  |  |  ------------------
  |  |  |  Branch (57:7): [True: 601, False: 8.09M]
  |  |  |  Branch (57:24): [True: 0, False: 8.09M]
  |  |  ------------------
  |  |   58|    601|    fprintf(stderr, "Marker byte (0xff) expected, found: %d "           \
  |  |   59|    601|            "pos=%d len=%d\n",                                          \
  |  |   60|    601|            (pos < len ? data[pos] : 0), static_cast<int>(pos),         \
  |  |  ------------------
  |  |  |  Branch (60:14): [True: 293, False: 308]
  |  |  ------------------
  |  |   61|    601|            static_cast<int>(len));                                     \
  |  |   62|    601|    jpg->error = JPEG_MARKER_BYTE_NOT_FOUND;                            \
  |  |   63|    601|    return false;                                                       \
  |  |   64|    601|  }
  ------------------
  962|  8.09M|    marker = data[pos + 1];
  963|  8.09M|    pos += 2;
  964|  8.09M|    bool ok = true;
  965|  8.09M|    switch (marker) {
  966|  1.02k|      case 0xc0:
  ------------------
  |  Branch (966:7): [True: 1.02k, False: 8.09M]
  ------------------
  967|  2.80k|      case 0xc1:
  ------------------
  |  Branch (967:7): [True: 1.78k, False: 8.09M]
  ------------------
  968|  10.5k|      case 0xc2:
  ------------------
  |  Branch (968:7): [True: 7.77k, False: 8.09M]
  ------------------
  969|  10.5k|        is_progressive = (marker == 0xc2);
  970|  10.5k|        ok = ProcessSOF(data, len, mode, &pos, jpg);
  971|  10.5k|        found_sof = true;
  972|  10.5k|        break;
  973|  24.7k|      case 0xc4:
  ------------------
  |  Branch (973:7): [True: 24.7k, False: 8.07M]
  ------------------
  974|  24.7k|        ok = ProcessDHT(data, len, mode, &dc_huff_lut, &ac_huff_lut, &pos, jpg);
  975|  24.7k|        break;
  976|  4.66M|      case 0xd0:
  ------------------
  |  Branch (976:7): [True: 4.66M, False: 3.42M]
  ------------------
  977|  4.68M|      case 0xd1:
  ------------------
  |  Branch (977:7): [True: 11.2k, False: 8.08M]
  ------------------
  978|  4.68M|      case 0xd2:
  ------------------
  |  Branch (978:7): [True: 2.51k, False: 8.09M]
  ------------------
  979|  4.71M|      case 0xd3:
  ------------------
  |  Branch (979:7): [True: 28.2k, False: 8.07M]
  ------------------
  980|  4.71M|      case 0xd4:
  ------------------
  |  Branch (980:7): [True: 715, False: 8.09M]
  ------------------
  981|  4.71M|      case 0xd5:
  ------------------
  |  Branch (981:7): [True: 685, False: 8.09M]
  ------------------
  982|  5.09M|      case 0xd6:
  ------------------
  |  Branch (982:7): [True: 383k, False: 7.71M]
  ------------------
  983|  5.94M|      case 0xd7:
  ------------------
  |  Branch (983:7): [True: 853k, False: 7.24M]
  ------------------
  984|       |        // RST markers do not have any data.
  985|  5.94M|        break;
  986|  3.31k|      case 0xd9:
  ------------------
  |  Branch (986:7): [True: 3.31k, False: 8.09M]
  ------------------
  987|       |        // Found end marker.
  988|  3.31k|        break;
  989|  8.68k|      case 0xda:
  ------------------
  |  Branch (989:7): [True: 8.68k, False: 8.08M]
  ------------------
  990|  8.68k|        if (mode == JPEG_READ_ALL) {
  ------------------
  |  Branch (990:13): [True: 8.46k, False: 213]
  ------------------
  991|  8.46k|          ok = ProcessScan(data, len, dc_huff_lut, ac_huff_lut,
  992|  8.46k|                           scan_progression, is_progressive, &pos, jpg);
  993|  8.46k|        }
  994|  8.68k|        break;
  995|  8.51k|      case 0xdb:
  ------------------
  |  Branch (995:7): [True: 8.51k, False: 8.08M]
  ------------------
  996|  8.51k|        ok = ProcessDQT(data, len, &pos, jpg);
  997|  8.51k|        break;
  998|    600|      case 0xdd:
  ------------------
  |  Branch (998:7): [True: 600, False: 8.09M]
  ------------------
  999|    600|        ok = ProcessDRI(data, len, &pos, jpg);
 1000|    600|        break;
 1001|   206k|      case 0xe0:
  ------------------
  |  Branch (1001:7): [True: 206k, False: 7.89M]
  ------------------
 1002|   713k|      case 0xe1:
  ------------------
  |  Branch (1002:7): [True: 506k, False: 7.59M]
  ------------------
 1003|   714k|      case 0xe2:
  ------------------
  |  Branch (1003:7): [True: 979, False: 8.09M]
  ------------------
 1004|   723k|      case 0xe3:
  ------------------
  |  Branch (1004:7): [True: 9.21k, False: 8.08M]
  ------------------
 1005|   756k|      case 0xe4:
  ------------------
  |  Branch (1005:7): [True: 33.2k, False: 8.06M]
  ------------------
 1006|   917k|      case 0xe5:
  ------------------
  |  Branch (1006:7): [True: 161k, False: 7.93M]
  ------------------
 1007|   917k|      case 0xe6:
  ------------------
  |  Branch (1007:7): [True: 337, False: 8.09M]
  ------------------
 1008|   918k|      case 0xe7:
  ------------------
  |  Branch (1008:7): [True: 699, False: 8.09M]
  ------------------
 1009|   919k|      case 0xe8:
  ------------------
  |  Branch (1009:7): [True: 1.05k, False: 8.09M]
  ------------------
 1010|  1.21M|      case 0xe9:
  ------------------
  |  Branch (1010:7): [True: 298k, False: 7.79M]
  ------------------
 1011|  1.21M|      case 0xea:
  ------------------
  |  Branch (1011:7): [True: 534, False: 8.09M]
  ------------------
 1012|  1.22M|      case 0xeb:
  ------------------
  |  Branch (1012:7): [True: 9.99k, False: 8.08M]
  ------------------
 1013|  1.22M|      case 0xec:
  ------------------
  |  Branch (1013:7): [True: 449, False: 8.09M]
  ------------------
 1014|  1.22M|      case 0xed:
  ------------------
  |  Branch (1014:7): [True: 383, False: 8.09M]
  ------------------
 1015|  1.23M|      case 0xee:
  ------------------
  |  Branch (1015:7): [True: 1.95k, False: 8.09M]
  ------------------
 1016|  1.69M|      case 0xef:
  ------------------
  |  Branch (1016:7): [True: 460k, False: 7.63M]
  ------------------
 1017|  1.69M|        if (mode != JPEG_READ_TABLES) {
  ------------------
  |  Branch (1017:13): [True: 1.69M, False: 0]
  ------------------
 1018|  1.69M|          ok = ProcessAPP(data, len, &pos, jpg);
 1019|  1.69M|        }
 1020|  1.69M|        break;
 1021|   400k|      case 0xfe:
  ------------------
  |  Branch (1021:7): [True: 400k, False: 7.69M]
  ------------------
 1022|   400k|        if (mode != JPEG_READ_TABLES) {
  ------------------
  |  Branch (1022:13): [True: 400k, False: 0]
  ------------------
 1023|   400k|          ok = ProcessCOM(data, len, &pos, jpg);
 1024|   400k|        }
 1025|   400k|        break;
 1026|      0|      default:
  ------------------
  |  Branch (1026:7): [True: 0, False: 8.09M]
  ------------------
 1027|      0|        fprintf(stderr, "Unsupported marker: %d pos=%d len=%d\n",
 1028|      0|                marker, static_cast<int>(pos), static_cast<int>(len));
 1029|      0|        jpg->error = JPEG_UNSUPPORTED_MARKER;
 1030|      0|        ok = false;
 1031|      0|        break;
 1032|  8.09M|    }
 1033|  8.09M|    if (!ok) {
  ------------------
  |  Branch (1033:9): [True: 2.11k, False: 8.09M]
  ------------------
 1034|  2.11k|      return false;
 1035|  2.11k|    }
 1036|  8.09M|    jpg->marker_order.push_back(marker);
 1037|  8.09M|    if (mode == JPEG_READ_HEADER && found_sof) {
  ------------------
  |  Branch (1037:9): [True: 4.38M, False: 3.71M]
  |  Branch (1037:37): [True: 5.24k, False: 4.37M]
  ------------------
 1038|  5.24k|      break;
 1039|  5.24k|    }
 1040|  8.09M|  } while (marker != 0xd9);
  ------------------
  |  Branch (1040:12): [True: 8.08M, False: 3.31k]
  ------------------
 1041|       |
 1042|  8.56k|  if (!found_sof) {
  ------------------
  |  Branch (1042:7): [True: 3, False: 8.55k]
  ------------------
 1043|      3|    fprintf(stderr, "Missing SOF marker.\n");
 1044|      3|    jpg->error = JPEG_SOF_NOT_FOUND;
 1045|      3|    return false;
 1046|      3|  }
 1047|       |
 1048|       |  // Supplemental checks.
 1049|  8.55k|  if (mode == JPEG_READ_ALL) {
  ------------------
  |  Branch (1049:7): [True: 3.31k, False: 5.24k]
  ------------------
 1050|  3.31k|    if (pos < len) {
  ------------------
  |  Branch (1050:9): [True: 387, False: 2.92k]
  ------------------
 1051|    387|      jpg->tail_data.assign(reinterpret_cast<const char*>(&data[pos]),
 1052|    387|                            len - pos);
 1053|    387|    }
 1054|  3.31k|    if (!FixupIndexes(jpg)) {
  ------------------
  |  Branch (1054:9): [True: 30, False: 3.28k]
  ------------------
 1055|     30|      return false;
 1056|     30|    }
 1057|  3.28k|    if (jpg->huffman_code.size() == 0) {
  ------------------
  |  Branch (1057:9): [True: 7, False: 3.27k]
  ------------------
 1058|       |      // Section B.2.4.2: "If a table has never been defined for a particular
 1059|       |      // destination, then when this destination is specified in a scan header,
 1060|       |      // the results are unpredictable."
 1061|      7|      fprintf(stderr, "Need at least one Huffman code table.\n");
 1062|      7|      jpg->error = JPEG_HUFFMAN_TABLE_ERROR;
 1063|      7|      return false;
 1064|      7|    }
 1065|  3.27k|    if (jpg->huffman_code.size() >= kMaxDHTMarkers) {
  ------------------
  |  Branch (1065:9): [True: 2, False: 3.27k]
  ------------------
 1066|      2|      fprintf(stderr, "Too many Huffman tables.\n");
 1067|      2|      jpg->error = JPEG_HUFFMAN_TABLE_ERROR;
 1068|      2|      return false;
 1069|      2|    }
 1070|  3.27k|  }
 1071|  8.51k|  return true;
 1072|  8.55k|}
_ZN7guetzli8ReadJpegERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS_12JpegReadModeEPNS_8JPEGDataE:
 1075|  5.22k|              JPEGData* jpg) {
 1076|  5.22k|  return ReadJpeg(reinterpret_cast<const uint8_t*>(data.data()),
 1077|  5.22k|                  static_cast<const size_t>(data.size()),
 1078|  5.22k|                  mode, jpg);
 1079|  5.22k|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_114FindNextMarkerEPKhmm:
  911|  8.09M|size_t FindNextMarker(const uint8_t* data, const size_t len, size_t pos) {
  912|       |  // kIsValidMarker[i] == 1 means (0xc0 + i) is a valid marker.
  913|  8.09M|  static const uint8_t kIsValidMarker[] = {
  914|  8.09M|    1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  915|  8.09M|    1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0,
  916|  8.09M|    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  917|  8.09M|    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
  918|  8.09M|  };
  919|  8.09M|  size_t num_skipped = 0;
  920|  58.9M|  while (pos + 1 < len &&
  ------------------
  |  Branch (920:10): [True: 58.9M, False: 601]
  ------------------
  921|  58.9M|         (data[pos] != 0xff || data[pos + 1] < 0xc0 ||
  ------------------
  |  Branch (921:11): [True: 46.9M, False: 11.9M]
  |  Branch (921:32): [True: 498k, False: 11.4M]
  ------------------
  922|  58.9M|          !kIsValidMarker[data[pos + 1] - 0xc0])) {
  ------------------
  |  Branch (922:11): [True: 3.34M, False: 8.09M]
  ------------------
  923|  50.8M|    ++pos;
  924|  50.8M|    ++num_skipped;
  925|  50.8M|  }
  926|  8.09M|  return num_skipped;
  927|  8.09M|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_110ProcessSOFEPKhmNS_12JpegReadModeEPmPNS_8JPEGDataE:
   88|  10.5k|                JpegReadMode mode, size_t* pos, JPEGData* jpg) {
   89|  10.5k|  if (jpg->width != 0) {
  ------------------
  |  Branch (89:7): [True: 29, False: 10.5k]
  ------------------
   90|     29|    fprintf(stderr, "Duplicate SOF marker.\n");
   91|     29|    jpg->error = JPEG_DUPLICATE_SOF;
   92|     29|    return false;
   93|     29|  }
   94|  10.5k|  const size_t start_pos = *pos;
   95|  10.5k|  VERIFY_LEN(8);
  ------------------
  |  |   32|  10.5k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 10, False: 10.5k]
  |  |  ------------------
  |  |   33|     10|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     10|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|     10|            static_cast<int>(len));                                     \
  |  |   36|     10|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     10|    return false;                                                       \
  |  |   38|     10|  }
  ------------------
   96|  10.5k|  size_t marker_len = ReadUint16(data, pos);
   97|  10.5k|  int precision = ReadUint8(data, pos);
   98|  10.5k|  int height = ReadUint16(data, pos);
   99|  10.5k|  int width = ReadUint16(data, pos);
  100|  10.5k|  int num_components = ReadUint8(data, pos);
  101|  10.5k|  VERIFY_INPUT(precision, 8, 8, PRECISION);
  ------------------
  |  |   41|  10.5k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 5, False: 10.5k]
  |  |  |  Branch (41:20): [True: 9, False: 10.5k]
  |  |  ------------------
  |  |   42|     14|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|     14|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|     14|        return false;                                                   \
  |  |   45|     14|  }
  ------------------
  102|  10.5k|  VERIFY_INPUT(height, 1, 65535, HEIGHT);
  ------------------
  |  |   41|  10.5k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 1, False: 10.5k]
  |  |  |  Branch (41:20): [True: 0, False: 10.5k]
  |  |  ------------------
  |  |   42|      1|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|      1|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|      1|        return false;                                                   \
  |  |   45|      1|  }
  ------------------
  103|  10.5k|  VERIFY_INPUT(width, 1, 65535, WIDTH);
  ------------------
  |  |   41|  10.5k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 1, False: 10.5k]
  |  |  |  Branch (41:20): [True: 0, False: 10.5k]
  |  |  ------------------
  |  |   42|      1|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|      1|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|      1|        return false;                                                   \
  |  |   45|      1|  }
  ------------------
  104|  10.5k|  VERIFY_INPUT(num_components, 1, kMaxComponents, NUMCOMP);
  ------------------
  |  |   41|  10.5k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 2, False: 10.5k]
  |  |  |  Branch (41:20): [True: 13, False: 10.5k]
  |  |  ------------------
  |  |   42|     15|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|     15|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|     15|        return false;                                                   \
  |  |   45|     15|  }
  ------------------
  105|  10.5k|  VERIFY_LEN(3 * num_components);
  ------------------
  |  |   32|  10.5k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 9, False: 10.5k]
  |  |  ------------------
  |  |   33|      9|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|      9|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|      9|            static_cast<int>(len));                                     \
  |  |   36|      9|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|      9|    return false;                                                       \
  |  |   38|      9|  }
  ------------------
  106|  10.5k|  jpg->height = height;
  107|  10.5k|  jpg->width = width;
  108|  10.5k|  jpg->components.resize(num_components);
  109|       |
  110|       |  // Read sampling factors and quant table index for each component.
  111|  10.5k|  std::vector<bool> ids_seen(256, false);
  112|  36.1k|  for (size_t i = 0; i < jpg->components.size(); ++i) {
  ------------------
  |  Branch (112:22): [True: 25.6k, False: 10.4k]
  ------------------
  113|  25.6k|    const int id = ReadUint8(data, pos);
  114|  25.6k|    if (ids_seen[id]) {   // (cf. section B.2.2, syntax of Ci)
  ------------------
  |  Branch (114:9): [True: 1, False: 25.6k]
  ------------------
  115|      1|      fprintf(stderr, "Duplicate ID %d in SOF.\n", id);
  116|      1|      jpg->error = JPEG_DUPLICATE_COMPONENT_ID;
  117|      1|      return false;
  118|      1|    }
  119|  25.6k|    ids_seen[id] = true;
  120|  25.6k|    jpg->components[i].id = id;
  121|  25.6k|    int factor = ReadUint8(data, pos);
  122|  25.6k|    int h_samp_factor = factor >> 4;
  123|  25.6k|    int v_samp_factor = factor & 0xf;
  124|  25.6k|    VERIFY_INPUT(h_samp_factor, 1, 15, SAMP_FACTOR);
  ------------------
  |  |   41|  25.6k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 6, False: 25.6k]
  |  |  |  Branch (41:20): [True: 0, False: 25.6k]
  |  |  ------------------
  |  |   42|      6|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|      6|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|      6|        return false;                                                   \
  |  |   45|      6|  }
  ------------------
  125|  25.6k|    VERIFY_INPUT(v_samp_factor, 1, 15, SAMP_FACTOR);
  ------------------
  |  |   41|  25.6k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 1, False: 25.6k]
  |  |  |  Branch (41:20): [True: 0, False: 25.6k]
  |  |  ------------------
  |  |   42|      1|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|      1|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|      1|        return false;                                                   \
  |  |   45|      1|  }
  ------------------
  126|  25.6k|    jpg->components[i].h_samp_factor = h_samp_factor;
  127|  25.6k|    jpg->components[i].v_samp_factor = v_samp_factor;
  128|  25.6k|    jpg->components[i].quant_idx = ReadUint8(data, pos);
  129|  25.6k|    jpg->max_h_samp_factor = std::max(jpg->max_h_samp_factor, h_samp_factor);
  130|  25.6k|    jpg->max_v_samp_factor = std::max(jpg->max_v_samp_factor, v_samp_factor);
  131|  25.6k|  }
  132|       |
  133|       |  // We have checked above that none of the sampling factors are 0, so the max
  134|       |  // sampling factors can not be 0.
  135|  10.4k|  jpg->MCU_rows = DivCeil(jpg->height, jpg->max_v_samp_factor * 8);
  136|  10.4k|  jpg->MCU_cols = DivCeil(jpg->width, jpg->max_h_samp_factor * 8);
  137|       |  // Compute the block dimensions for each component.
  138|  10.4k|  if (mode == JPEG_READ_ALL) {
  ------------------
  |  Branch (138:7): [True: 5.21k, False: 5.27k]
  ------------------
  139|  17.9k|    for (size_t i = 0; i < jpg->components.size(); ++i) {
  ------------------
  |  Branch (139:24): [True: 12.7k, False: 5.18k]
  ------------------
  140|  12.7k|      JPEGComponent* c = &jpg->components[i];
  141|  12.7k|      if (jpg->max_h_samp_factor % c->h_samp_factor != 0 ||
  ------------------
  |  Branch (141:11): [True: 21, False: 12.7k]
  ------------------
  142|  12.7k|          jpg->max_v_samp_factor % c->v_samp_factor != 0) {
  ------------------
  |  Branch (142:11): [True: 10, False: 12.7k]
  ------------------
  143|     31|        fprintf(stderr, "Non-integral subsampling ratios.\n");
  144|     31|        jpg->error = JPEG_INVALID_SAMPLING_FACTORS;
  145|     31|        return false;
  146|     31|      }
  147|  12.7k|      c->width_in_blocks = jpg->MCU_cols * c->h_samp_factor;
  148|  12.7k|      c->height_in_blocks = jpg->MCU_rows * c->v_samp_factor;
  149|  12.7k|      const uint64_t num_blocks =
  150|  12.7k|          static_cast<uint64_t>(c->width_in_blocks) * c->height_in_blocks;
  151|  12.7k|      if (num_blocks > (1ull << 21)) {
  ------------------
  |  Branch (151:11): [True: 0, False: 12.7k]
  ------------------
  152|       |        // Refuse to allocate more than 1 GB of memory for the coefficients,
  153|       |        // that is 2M blocks x 64 coeffs x 2 bytes per coeff x max 4 components.
  154|       |        // TODO(user) Add this limit to a GuetzliParams struct.
  155|      0|        fprintf(stderr, "Image too large.\n");
  156|      0|        jpg->error = JPEG_IMAGE_TOO_LARGE;
  157|      0|        return false;
  158|      0|      }
  159|  12.7k|      c->num_blocks = static_cast<int>(num_blocks);
  160|  12.7k|      c->coeffs.resize(c->num_blocks * kDCTBlockSize);
  161|  12.7k|    }
  162|  5.21k|  }
  163|  10.4k|  VERIFY_MARKER_END();
  ------------------
  |  |   48|  10.4k|  if (start_pos + marker_len != *pos) {                                 \
  |  |  ------------------
  |  |  |  Branch (48:7): [True: 29, False: 10.4k]
  |  |  ------------------
  |  |   49|     29|    fprintf(stderr, "Invalid marker length: declared=%d actual=%d\n",   \
  |  |   50|     29|            static_cast<int>(marker_len),                               \
  |  |   51|     29|            static_cast<int>(*pos - start_pos));                        \
  |  |   52|     29|    jpg->error = JPEG_WRONG_MARKER_SIZE;                                \
  |  |   53|     29|    return false;                                                       \
  |  |   54|     29|  }
  ------------------
  164|  10.4k|  return true;
  165|  10.4k|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_110ReadUint16EPKhPm:
   79|  2.18M|inline int ReadUint16(const uint8_t* data, size_t* pos) {
   80|  2.18M|  int v = (data[*pos] << 8) + data[*pos + 1];
   81|  2.18M|  *pos += 2;
   82|  2.18M|  return v;
   83|  2.18M|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_19ReadUint8EPKhPm:
   75|  8.58M|inline int ReadUint8(const uint8_t* data, size_t* pos) {
   76|  8.58M|  return data[(*pos)++];
   77|  8.58M|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_17DivCeilEii:
   71|  35.9k|inline int DivCeil(int a, int b) {
   72|  35.9k|  return (a + b - 1) / b;
   73|  35.9k|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_110ProcessDHTEPKhmNS_12JpegReadModeEPNSt3__16vectorINS_17HuffmanTableEntryENS4_9allocatorIS6_EEEESA_PmPNS_8JPEGDataE:
  256|  24.7k|                JPEGData* jpg) {
  257|  24.7k|  const size_t start_pos = *pos;
  258|  24.7k|  VERIFY_LEN(2);
  ------------------
  |  |   32|  24.7k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 19, False: 24.7k]
  |  |  ------------------
  |  |   33|     19|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     19|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|     19|            static_cast<int>(len));                                     \
  |  |   36|     19|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     19|    return false;                                                       \
  |  |   38|     19|  }
  ------------------
  259|  24.7k|  size_t marker_len = ReadUint16(data, pos);
  260|  24.7k|  if (marker_len == 2) {
  ------------------
  |  Branch (260:7): [True: 2, False: 24.7k]
  ------------------
  261|      2|    fprintf(stderr, "DHT marker: no Huffman table found\n");
  262|      2|    jpg->error = JPEG_EMPTY_DHT;
  263|      2|    return false;
  264|      2|  }
  265|   472k|  while (*pos < start_pos + marker_len) {
  ------------------
  |  Branch (265:10): [True: 447k, False: 24.4k]
  ------------------
  266|   447k|    VERIFY_LEN(1 + kJpegHuffmanMaxBitLength);
  ------------------
  |  |   32|   447k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 219, False: 447k]
  |  |  ------------------
  |  |   33|    219|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|    219|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|    219|            static_cast<int>(len));                                     \
  |  |   36|    219|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|    219|    return false;                                                       \
  |  |   38|    219|  }
  ------------------
  267|   447k|    JPEGHuffmanCode huff;
  268|   447k|    huff.slot_id = ReadUint8(data, pos);
  269|   447k|    int huffman_index = huff.slot_id;
  270|   447k|    int is_ac_table = (huff.slot_id & 0x10) != 0;
  271|   447k|    HuffmanTableEntry* huff_lut;
  272|   447k|    if (is_ac_table) {
  ------------------
  |  Branch (272:9): [True: 17.9k, False: 429k]
  ------------------
  273|  17.9k|      huffman_index -= 0x10;
  274|  17.9k|      VERIFY_INPUT(huffman_index, 0, 3, HUFFMAN_INDEX);
  ------------------
  |  |   41|  17.9k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 0, False: 17.9k]
  |  |  |  Branch (41:20): [True: 10, False: 17.9k]
  |  |  ------------------
  |  |   42|     10|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|     10|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|     10|        return false;                                                   \
  |  |   45|     10|  }
  ------------------
  275|  17.9k|      huff_lut = &(*ac_huff_lut)[huffman_index * kJpegHuffmanLutSize];
  276|   429k|    } else {
  277|   429k|      VERIFY_INPUT(huffman_index, 0, 3, HUFFMAN_INDEX);
  ------------------
  |  |   41|   429k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 0, False: 429k]
  |  |  |  Branch (41:20): [True: 10, False: 429k]
  |  |  ------------------
  |  |   42|     10|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|     10|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|     10|        return false;                                                   \
  |  |   45|     10|  }
  ------------------
  278|   429k|      huff_lut = &(*dc_huff_lut)[huffman_index * kJpegHuffmanLutSize];
  279|   429k|    }
  280|   447k|    huff.counts[0] = 0;
  281|   447k|    int total_count = 0;
  282|   447k|    int space = 1 << kJpegHuffmanMaxBitLength;
  283|   447k|    int max_depth = 1;
  284|  7.60M|    for (int i = 1; i <= kJpegHuffmanMaxBitLength; ++i) {
  ------------------
  |  Branch (284:21): [True: 7.16M, False: 447k]
  ------------------
  285|  7.16M|      int count = ReadUint8(data, pos);
  286|  7.16M|      if (count != 0) {
  ------------------
  |  Branch (286:11): [True: 131k, False: 7.02M]
  ------------------
  287|   131k|        max_depth = i;
  288|   131k|      }
  289|  7.16M|      huff.counts[i] = count;
  290|  7.16M|      total_count += count;
  291|  7.16M|      space -= count * (1 << (kJpegHuffmanMaxBitLength - i));
  292|  7.16M|    }
  293|   447k|    if (is_ac_table) {
  ------------------
  |  Branch (293:9): [True: 17.9k, False: 429k]
  ------------------
  294|  17.9k|      VERIFY_INPUT(total_count, 0, kJpegHuffmanAlphabetSize, HUFFMAN_CODE);
  ------------------
  |  |   41|  17.9k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 0, False: 17.9k]
  |  |  |  Branch (41:20): [True: 19, False: 17.9k]
  |  |  ------------------
  |  |   42|     19|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|     19|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|     19|        return false;                                                   \
  |  |   45|     19|  }
  ------------------
  295|   429k|    } else {
  296|   429k|      VERIFY_INPUT(total_count, 0, kJpegDCAlphabetSize, HUFFMAN_CODE);
  ------------------
  |  |   41|   429k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 0, False: 429k]
  |  |  |  Branch (41:20): [True: 43, False: 429k]
  |  |  ------------------
  |  |   42|     43|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|     43|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|     43|        return false;                                                   \
  |  |   45|     43|  }
  ------------------
  297|   429k|    }
  298|   447k|    VERIFY_LEN(total_count);
  ------------------
  |  |   32|   447k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 24, False: 447k]
  |  |  ------------------
  |  |   33|     24|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     24|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|     24|            static_cast<int>(len));                                     \
  |  |   36|     24|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     24|    return false;                                                       \
  |  |   38|     24|  }
  ------------------
  299|   447k|    std::vector<bool> values_seen(256, false);
  300|   740k|    for (int i = 0; i < total_count; ++i) {
  ------------------
  |  Branch (300:21): [True: 292k, False: 447k]
  ------------------
  301|   292k|      uint8_t value = ReadUint8(data, pos);
  302|   292k|      if (!is_ac_table) {
  ------------------
  |  Branch (302:11): [True: 74.9k, False: 217k]
  ------------------
  303|  74.9k|        VERIFY_INPUT(value, 0, kJpegDCAlphabetSize - 1, HUFFMAN_CODE);
  ------------------
  |  |   41|  74.9k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 0, False: 74.9k]
  |  |  |  Branch (41:20): [True: 8, False: 74.9k]
  |  |  ------------------
  |  |   42|      8|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|      8|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|      8|        return false;                                                   \
  |  |   45|      8|  }
  ------------------
  304|  74.9k|      }
  305|   292k|      if (values_seen[value]) {
  ------------------
  |  Branch (305:11): [True: 15, False: 292k]
  ------------------
  306|     15|        fprintf(stderr, "Duplicate Huffman code value %d\n", value);
  307|     15|        jpg->error = JPEG_INVALID_HUFFMAN_CODE;
  308|     15|        return false;
  309|     15|      }
  310|   292k|      values_seen[value] = true;
  311|   292k|      huff.values[i] = value;
  312|   292k|    }
  313|       |    // Add an invalid symbol that will have the all 1 code.
  314|   447k|    ++huff.counts[max_depth];
  315|   447k|    huff.values[total_count] = kJpegHuffmanAlphabetSize;
  316|   447k|    space -= (1 << (kJpegHuffmanMaxBitLength - max_depth));
  317|   447k|    if (space < 0) {
  ------------------
  |  Branch (317:9): [True: 24, False: 447k]
  ------------------
  318|     24|      fprintf(stderr, "Invalid Huffman code lengths.\n");
  319|     24|      jpg->error = JPEG_INVALID_HUFFMAN_CODE;
  320|     24|      return false;
  321|   447k|    } else if (space > 0 && huff_lut[0].value != 0xffff) {
  ------------------
  |  Branch (321:16): [True: 437k, False: 9.86k]
  |  Branch (321:29): [True: 243k, False: 193k]
  ------------------
  322|       |      // Re-initialize the values to an invalid symbol so that we can recognize
  323|       |      // it when reading the bit stream using a Huffman code with space > 0.
  324|   184M|      for (int i = 0; i < kJpegHuffmanLutSize; ++i) {
  ------------------
  |  Branch (324:23): [True: 184M, False: 243k]
  ------------------
  325|   184M|        huff_lut[i].bits = 0;
  326|   184M|        huff_lut[i].value = 0xffff;
  327|   184M|      }
  328|   243k|    }
  329|   447k|    huff.is_last = (*pos == start_pos + marker_len);
  330|   447k|    if (mode == JPEG_READ_ALL &&
  ------------------
  |  Branch (330:9): [True: 256k, False: 191k]
  ------------------
  331|   447k|        !BuildJpegHuffmanTable(&huff.counts[0], &huff.values[0], huff_lut)) {
  ------------------
  |  Branch (331:9): [True: 0, False: 256k]
  ------------------
  332|      0|      fprintf(stderr, "Failed to build Huffman table.\n");
  333|      0|      jpg->error = JPEG_INVALID_HUFFMAN_CODE;
  334|      0|      return false;
  335|      0|    }
  336|   447k|    jpg->huffman_code.push_back(huff);
  337|   447k|  }
  338|  24.4k|  VERIFY_MARKER_END();
  ------------------
  |  |   48|  24.4k|  if (start_pos + marker_len != *pos) {                                 \
  |  |  ------------------
  |  |  |  Branch (48:7): [True: 68, False: 24.3k]
  |  |  ------------------
  |  |   49|     68|    fprintf(stderr, "Invalid marker length: declared=%d actual=%d\n",   \
  |  |   50|     68|            static_cast<int>(marker_len),                               \
  |  |   51|     68|            static_cast<int>(*pos - start_pos));                        \
  |  |   52|     68|    jpg->error = JPEG_WRONG_MARKER_SIZE;                                \
  |  |   53|     68|    return false;                                                       \
  |  |   54|     68|  }
  ------------------
  339|  24.3k|  return true;
  340|  24.4k|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_111ProcessScanEPKhmRKNSt3__16vectorINS_17HuffmanTableEntryENS3_9allocatorIS5_EEEESA_PA64_tbPmPNS_8JPEGDataE:
  761|  8.46k|                 JPEGData* jpg) {
  762|  8.46k|  if (!ProcessSOS(data, len, pos, jpg)) {
  ------------------
  |  Branch (762:7): [True: 222, False: 8.24k]
  ------------------
  763|    222|    return false;
  764|    222|  }
  765|  8.24k|  JPEGScanInfo* scan_info = &jpg->scan_info.back();
  766|  8.24k|  bool is_interleaved = (scan_info->components.size() > 1);
  767|  8.24k|  int MCUs_per_row;
  768|  8.24k|  int MCU_rows;
  769|  8.24k|  if (is_interleaved) {
  ------------------
  |  Branch (769:7): [True: 768, False: 7.47k]
  ------------------
  770|    768|    MCUs_per_row = jpg->MCU_cols;
  771|    768|    MCU_rows = jpg->MCU_rows;
  772|  7.47k|  } else {
  773|  7.47k|    const JPEGComponent& c = jpg->components[scan_info->components[0].comp_idx];
  774|  7.47k|    MCUs_per_row =
  775|  7.47k|        DivCeil(jpg->width * c.h_samp_factor, 8 * jpg->max_h_samp_factor);
  776|  7.47k|    MCU_rows =
  777|  7.47k|        DivCeil(jpg->height * c.v_samp_factor, 8 * jpg->max_v_samp_factor);
  778|  7.47k|  }
  779|  8.24k|  coeff_t last_dc_coeff[kMaxComponents] = {0};
  780|  8.24k|  BitReaderState br(data, len, *pos);
  781|  8.24k|  int restarts_to_go = jpg->restart_interval;
  782|  8.24k|  int next_restart_marker = 0;
  783|  8.24k|  int eobrun = -1;
  784|  8.24k|  int block_scan_index = 0;
  785|  8.24k|  const int Al = is_progressive ? scan_info->Al : 0;
  ------------------
  |  Branch (785:18): [True: 7.60k, False: 638]
  ------------------
  786|  8.24k|  const int Ah = is_progressive ? scan_info->Ah : 0;
  ------------------
  |  Branch (786:18): [True: 7.60k, False: 638]
  ------------------
  787|  8.24k|  const int Ss = is_progressive ? scan_info->Ss : 0;
  ------------------
  |  Branch (787:18): [True: 7.60k, False: 638]
  ------------------
  788|  8.24k|  const int Se = is_progressive ? scan_info->Se : 63;
  ------------------
  |  Branch (788:18): [True: 7.60k, False: 638]
  ------------------
  789|  8.24k|  const uint16_t scan_bitmask = Ah == 0 ? (0xffff << Al) : (1u << Al);
  ------------------
  |  Branch (789:33): [True: 5.67k, False: 2.57k]
  ------------------
  790|  8.24k|  const uint16_t refinement_bitmask = (1 << Al) - 1;
  791|  17.8k|  for (size_t i = 0; i < scan_info->components.size(); ++i) {
  ------------------
  |  Branch (791:22): [True: 9.70k, False: 8.17k]
  ------------------
  792|  9.70k|    int comp_idx = scan_info->components[i].comp_idx;
  793|   215k|    for (int k = Ss; k <= Se; ++k) {
  ------------------
  |  Branch (793:22): [True: 205k, False: 9.63k]
  ------------------
  794|   205k|      if (scan_progression[comp_idx][k] & scan_bitmask) {
  ------------------
  |  Branch (794:11): [True: 62, False: 205k]
  ------------------
  795|     62|        fprintf(stderr, "Overlapping scans: component=%d k=%d prev_mask=%d "
  796|     62|                "cur_mask=%d\n", comp_idx, k, scan_progression[i][k],
  797|     62|                scan_bitmask);
  798|     62|        jpg->error = JPEG_OVERLAPPING_SCANS;
  799|     62|        return false;
  800|     62|      }
  801|   205k|      if (scan_progression[comp_idx][k] & refinement_bitmask) {
  ------------------
  |  Branch (801:11): [True: 14, False: 205k]
  ------------------
  802|     14|        fprintf(stderr, "Invalid scan order, a more refined scan was already "
  803|     14|                "done: component=%d k=%d prev_mask=%d cur_mask=%d\n", comp_idx,
  804|     14|                k, scan_progression[i][k], scan_bitmask);
  805|     14|        jpg->error = JPEG_INVALID_SCAN_ORDER;
  806|     14|        return false;
  807|     14|      }
  808|   205k|      scan_progression[comp_idx][k] |= scan_bitmask;
  809|   205k|    }
  810|  9.70k|  }
  811|  8.17k|  if (Al > 10) {
  ------------------
  |  Branch (811:7): [True: 5, False: 8.16k]
  ------------------
  812|      5|    fprintf(stderr, "Scan parameter Al=%d is not supported in guetzli.\n", Al);
  813|      5|    jpg->error = JPEG_NON_REPRESENTABLE_AC_COEFF;
  814|      5|    return false;
  815|      5|  }
  816|   108k|  for (int mcu_y = 0; mcu_y < MCU_rows; ++mcu_y) {
  ------------------
  |  Branch (816:23): [True: 100k, False: 7.71k]
  ------------------
  817|   305k|    for (int mcu_x = 0; mcu_x < MCUs_per_row; ++mcu_x) {
  ------------------
  |  Branch (817:25): [True: 204k, False: 100k]
  ------------------
  818|       |      // Handle the restart intervals.
  819|   204k|      if (jpg->restart_interval > 0) {
  ------------------
  |  Branch (819:11): [True: 9.33k, False: 195k]
  ------------------
  820|  9.33k|        if (restarts_to_go == 0) {
  ------------------
  |  Branch (820:13): [True: 187, False: 9.14k]
  ------------------
  821|    187|          if (ProcessRestart(data, len,
  ------------------
  |  Branch (821:15): [True: 81, False: 106]
  ------------------
  822|    187|                             &next_restart_marker, &br, jpg)) {
  823|     81|            restarts_to_go = jpg->restart_interval;
  824|     81|            memset(last_dc_coeff, 0, sizeof(last_dc_coeff));
  825|     81|            if (eobrun > 0) {
  ------------------
  |  Branch (825:17): [True: 5, False: 76]
  ------------------
  826|      5|              fprintf(stderr, "End-of-block run too long.\n");
  827|      5|              jpg->error = JPEG_EOB_RUN_TOO_LONG;
  828|      5|              return false;
  829|      5|            }
  830|     76|            eobrun = -1;   // fresh start
  831|    106|          } else {
  832|    106|            return false;
  833|    106|          }
  834|    187|        }
  835|  9.22k|        --restarts_to_go;
  836|  9.22k|      }
  837|       |      // Decode one MCU.
  838|   445k|      for (size_t i = 0; i < scan_info->components.size(); ++i) {
  ------------------
  |  Branch (838:26): [True: 240k, False: 204k]
  ------------------
  839|   240k|        JPEGComponentScanInfo* si = &scan_info->components[i];
  840|   240k|        JPEGComponent* c = &jpg->components[si->comp_idx];
  841|   240k|        const HuffmanTableEntry* dc_lut =
  842|   240k|            &dc_huff_lut[si->dc_tbl_idx * kJpegHuffmanLutSize];
  843|   240k|        const HuffmanTableEntry* ac_lut =
  844|   240k|            &ac_huff_lut[si->ac_tbl_idx * kJpegHuffmanLutSize];
  845|   240k|        int nblocks_y = is_interleaved ? c->v_samp_factor : 1;
  ------------------
  |  Branch (845:25): [True: 58.2k, False: 182k]
  ------------------
  846|   240k|        int nblocks_x = is_interleaved ? c->h_samp_factor : 1;
  ------------------
  |  Branch (846:25): [True: 58.2k, False: 182k]
  ------------------
  847|   682k|        for (int iy = 0; iy < nblocks_y; ++iy) {
  ------------------
  |  Branch (847:26): [True: 442k, False: 240k]
  ------------------
  848|  1.14M|          for (int ix = 0; ix < nblocks_x; ++ix) {
  ------------------
  |  Branch (848:28): [True: 702k, False: 442k]
  ------------------
  849|   702k|            int block_y = mcu_y * nblocks_y + iy;
  850|   702k|            int block_x = mcu_x * nblocks_x + ix;
  851|   702k|            int block_idx = block_y * c->width_in_blocks + block_x;
  852|   702k|            coeff_t* coeffs = &c->coeffs[block_idx * kDCTBlockSize];
  853|   702k|            if (Ah == 0) {
  ------------------
  |  Branch (853:17): [True: 341k, False: 361k]
  ------------------
  854|   341k|              if (!DecodeDCTBlock(dc_lut, ac_lut, Ss, Se, Al, &eobrun, &br, jpg,
  ------------------
  |  Branch (854:19): [True: 192, False: 341k]
  ------------------
  855|   341k|                                  &last_dc_coeff[si->comp_idx], coeffs)) {
  856|    192|                return false;
  857|    192|              }
  858|   361k|            } else {
  859|   361k|              if (!RefineDCTBlock(ac_lut, Ss, Se, Al,
  ------------------
  |  Branch (859:19): [True: 152, False: 361k]
  ------------------
  860|   361k|                                  &eobrun, &br, jpg, coeffs)) {
  861|    152|                return false;
  862|    152|              }
  863|   361k|            }
  864|   702k|            ++block_scan_index;
  865|   702k|          }
  866|   442k|        }
  867|   240k|      }
  868|   204k|    }
  869|   100k|  }
  870|  7.71k|  if (eobrun > 0) {
  ------------------
  |  Branch (870:7): [True: 92, False: 7.61k]
  ------------------
  871|     92|    fprintf(stderr, "End-of-block run too long.\n");
  872|     92|    jpg->error = JPEG_EOB_RUN_TOO_LONG;
  873|     92|    return false;
  874|     92|  }
  875|  7.61k|  if (!br.FinishStream(pos)) {
  ------------------
  |  Branch (875:7): [True: 319, False: 7.30k]
  ------------------
  876|    319|    jpg->error = JPEG_INVALID_SCAN;
  877|    319|    return false;
  878|    319|  }
  879|  7.30k|  if (*pos > len) {
  ------------------
  |  Branch (879:7): [True: 0, False: 7.30k]
  ------------------
  880|      0|    fprintf(stderr, "Unexpected end of file during scan. pos=%d len=%d\n",
  881|      0|            static_cast<int>(*pos), static_cast<int>(len));
  882|      0|    jpg->error = JPEG_UNEXPECTED_EOF;
  883|      0|    return false;
  884|      0|  }
  885|  7.30k|  return true;
  886|  7.30k|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_110ProcessSOSEPKhmPmPNS_8JPEGDataE:
  170|  8.46k|                JPEGData* jpg) {
  171|  8.46k|  const size_t start_pos = *pos;
  172|  8.46k|  VERIFY_LEN(3);
  ------------------
  |  |   32|  8.46k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 17, False: 8.45k]
  |  |  ------------------
  |  |   33|     17|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     17|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|     17|            static_cast<int>(len));                                     \
  |  |   36|     17|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     17|    return false;                                                       \
  |  |   38|     17|  }
  ------------------
  173|  8.45k|  size_t marker_len = ReadUint16(data, pos);
  174|  8.45k|  int comps_in_scan = ReadUint8(data, pos);
  175|  8.45k|  VERIFY_INPUT(comps_in_scan, 1, static_cast<int>(jpg->components.size()),
  ------------------
  |  |   41|  8.45k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 5, False: 8.44k]
  |  |  |  Branch (41:20): [True: 16, False: 8.43k]
  |  |  ------------------
  |  |   42|     21|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|     21|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|     21|        return false;                                                   \
  |  |   45|     21|  }
  ------------------
  176|  8.45k|               COMPS_IN_SCAN);
  177|       |
  178|  8.43k|  JPEGScanInfo scan_info;
  179|  8.43k|  scan_info.components.resize(comps_in_scan);
  180|  8.43k|  VERIFY_LEN(2 * comps_in_scan);
  ------------------
  |  |   32|  8.43k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 17, False: 8.41k]
  |  |  ------------------
  |  |   33|     17|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     17|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|     17|            static_cast<int>(len));                                     \
  |  |   36|     17|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     17|    return false;                                                       \
  |  |   38|     17|  }
  ------------------
  181|  8.41k|  std::vector<bool> ids_seen(256, false);
  182|  18.3k|  for (int i = 0; i < comps_in_scan; ++i) {
  ------------------
  |  Branch (182:19): [True: 9.98k, False: 8.36k]
  ------------------
  183|  9.98k|    int id = ReadUint8(data, pos);
  184|  9.98k|    if (ids_seen[id]) {   // (cf. section B.2.3, regarding CSj)
  ------------------
  |  Branch (184:9): [True: 3, False: 9.97k]
  ------------------
  185|      3|      fprintf(stderr, "Duplicate ID %d in SOS.\n", id);
  186|      3|      jpg->error = JPEG_DUPLICATE_COMPONENT_ID;
  187|      3|      return false;
  188|      3|    }
  189|  9.97k|    ids_seen[id] = true;
  190|  9.97k|    bool found_index = false;
  191|  37.2k|    for (size_t j = 0; j < jpg->components.size(); ++j) {
  ------------------
  |  Branch (191:24): [True: 27.2k, False: 9.97k]
  ------------------
  192|  27.2k|      if (jpg->components[j].id == id) {
  ------------------
  |  Branch (192:11): [True: 9.94k, False: 17.2k]
  ------------------
  193|  9.94k|        scan_info.components[i].comp_idx = j;
  194|  9.94k|        found_index = true;
  195|  9.94k|      }
  196|  27.2k|    }
  197|  9.97k|    if (!found_index) {
  ------------------
  |  Branch (197:9): [True: 33, False: 9.94k]
  ------------------
  198|     33|      fprintf(stderr, "SOS marker: Could not find component with id %d\n", id);
  199|     33|      jpg->error = JPEG_COMPONENT_NOT_FOUND;
  200|     33|      return false;
  201|     33|    }
  202|  9.94k|    int c = ReadUint8(data, pos);
  203|  9.94k|    int dc_tbl_idx = c >> 4;
  204|  9.94k|    int ac_tbl_idx = c & 0xf;
  205|  9.94k|    VERIFY_INPUT(dc_tbl_idx, 0, 3, HUFFMAN_INDEX);
  ------------------
  |  |   41|  9.94k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 0, False: 9.94k]
  |  |  |  Branch (41:20): [True: 4, False: 9.94k]
  |  |  ------------------
  |  |   42|      4|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|      4|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|      4|        return false;                                                   \
  |  |   45|      4|  }
  ------------------
  206|  9.94k|    VERIFY_INPUT(ac_tbl_idx, 0, 3, HUFFMAN_INDEX);
  ------------------
  |  |   41|  9.94k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 0, False: 9.94k]
  |  |  |  Branch (41:20): [True: 8, False: 9.93k]
  |  |  ------------------
  |  |   42|      8|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|      8|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|      8|        return false;                                                   \
  |  |   45|      8|  }
  ------------------
  207|  9.93k|    scan_info.components[i].dc_tbl_idx = dc_tbl_idx;
  208|  9.93k|    scan_info.components[i].ac_tbl_idx = ac_tbl_idx;
  209|  9.93k|  }
  210|  8.36k|  VERIFY_LEN(3);
  ------------------
  |  |   32|  8.36k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 25, False: 8.34k]
  |  |  ------------------
  |  |   33|     25|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     25|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|     25|            static_cast<int>(len));                                     \
  |  |   36|     25|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     25|    return false;                                                       \
  |  |   38|     25|  }
  ------------------
  211|  8.34k|  scan_info.Ss = ReadUint8(data, pos);
  212|  8.34k|  scan_info.Se = ReadUint8(data, pos);
  213|  8.34k|  VERIFY_INPUT(scan_info.Ss, 0, 63, START_OF_SCAN);
  ------------------
  |  |   41|  8.34k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 0, False: 8.34k]
  |  |  |  Branch (41:20): [True: 6, False: 8.33k]
  |  |  ------------------
  |  |   42|      6|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|      6|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|      6|        return false;                                                   \
  |  |   45|      6|  }
  ------------------
  214|  8.33k|  VERIFY_INPUT(scan_info.Se, scan_info.Ss, 63, END_OF_SCAN);
  ------------------
  |  |   41|  8.33k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 4, False: 8.33k]
  |  |  |  Branch (41:20): [True: 7, False: 8.32k]
  |  |  ------------------
  |  |   42|     11|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|     11|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|     11|        return false;                                                   \
  |  |   45|     11|  }
  ------------------
  215|  8.32k|  int c = ReadUint8(data, pos);
  216|  8.32k|  scan_info.Ah = c >> 4;
  217|  8.32k|  scan_info.Al = c & 0xf;
  218|       |  // Check that all the Huffman tables needed for this scan are defined.
  219|  18.1k|  for (int i = 0; i < comps_in_scan; ++i) {
  ------------------
  |  Branch (219:19): [True: 9.84k, False: 8.29k]
  ------------------
  220|  9.84k|    bool found_dc_table = false;
  221|  9.84k|    bool found_ac_table = false;
  222|   434k|    for (size_t j = 0; j < jpg->huffman_code.size(); ++j) {
  ------------------
  |  Branch (222:24): [True: 424k, False: 9.84k]
  ------------------
  223|   424k|      int slot_id = jpg->huffman_code[j].slot_id;
  224|   424k|      if (slot_id == scan_info.components[i].dc_tbl_idx) {
  ------------------
  |  Branch (224:11): [True: 287k, False: 137k]
  ------------------
  225|   287k|        found_dc_table = true;
  226|   287k|      } else if (slot_id == scan_info.components[i].ac_tbl_idx + 16) {
  ------------------
  |  Branch (226:18): [True: 80.0k, False: 57.6k]
  ------------------
  227|  80.0k|        found_ac_table = true;
  228|  80.0k|      }
  229|   424k|    }
  230|  9.84k|    if (scan_info.Ss == 0 && !found_dc_table) {
  ------------------
  |  Branch (230:9): [True: 2.84k, False: 6.99k]
  |  Branch (230:30): [True: 12, False: 2.83k]
  ------------------
  231|     12|      fprintf(stderr, "SOS marker: Could not find DC Huffman table with index "
  232|     12|              "%d\n", scan_info.components[i].dc_tbl_idx);
  233|     12|      jpg->error = JPEG_HUFFMAN_TABLE_NOT_FOUND;
  234|     12|      return false;
  235|     12|    }
  236|  9.82k|    if (scan_info.Se > 0 && !found_ac_table) {
  ------------------
  |  Branch (236:9): [True: 8.56k, False: 1.26k]
  |  Branch (236:29): [True: 20, False: 8.54k]
  ------------------
  237|     20|      fprintf(stderr, "SOS marker: Could not find AC Huffman table with index "
  238|     20|              "%d\n", scan_info.components[i].ac_tbl_idx);
  239|     20|      jpg->error = JPEG_HUFFMAN_TABLE_NOT_FOUND;
  240|     20|      return false;
  241|     20|    }
  242|  9.82k|  }
  243|  8.29k|  jpg->scan_info.push_back(scan_info);
  244|  8.29k|  VERIFY_MARKER_END();
  ------------------
  |  |   48|  8.29k|  if (start_pos + marker_len != *pos) {                                 \
  |  |  ------------------
  |  |  |  Branch (48:7): [True: 45, False: 8.24k]
  |  |  ------------------
  |  |   49|     45|    fprintf(stderr, "Invalid marker length: declared=%d actual=%d\n",   \
  |  |   50|     45|            static_cast<int>(marker_len),                               \
  |  |   51|     45|            static_cast<int>(*pos - start_pos));                        \
  |  |   52|     45|    jpg->error = JPEG_WRONG_MARKER_SIZE;                                \
  |  |   53|     45|    return false;                                                       \
  |  |   54|     45|  }
  ------------------
  245|  8.24k|  return true;
  246|  8.29k|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_114BitReaderStateC2EPKhmm:
  427|  8.24k|      : data_(data), len_(len) {
  428|  8.24k|    Reset(pos);
  429|  8.24k|  }
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_114BitReaderState5ResetEm:
  431|  8.32k|  void Reset(size_t pos) {
  432|  8.32k|    pos_ = pos;
  433|  8.32k|    val_ = 0;
  434|  8.32k|    bits_left_ = 0;
  435|  8.32k|    next_marker_pos_ = len_ - 2;
  436|  8.32k|    FillBitWindow();
  437|  8.32k|  }
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_114BitReaderState13FillBitWindowEv:
  459|  33.9M|  void FillBitWindow() {
  460|  33.9M|    if (bits_left_ <= 16) {
  ------------------
  |  Branch (460:9): [True: 4.23M, False: 29.7M]
  ------------------
  461|  30.0M|      while (bits_left_ <= 56) {
  ------------------
  |  Branch (461:14): [True: 25.8M, False: 4.23M]
  ------------------
  462|  25.8M|        val_ <<= 8;
  463|  25.8M|        val_ |= (uint64_t)GetNextByte();
  464|  25.8M|        bits_left_ += 8;
  465|  25.8M|      }
  466|  4.23M|    }
  467|  33.9M|  }
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_114BitReaderState11GetNextByteEv:
  440|  25.8M|  uint8_t GetNextByte() {
  441|  25.8M|    if (pos_ >= next_marker_pos_) {
  ------------------
  |  Branch (441:9): [True: 24.7M, False: 1.12M]
  ------------------
  442|  24.7M|      ++pos_;
  443|  24.7M|      return 0;
  444|  24.7M|    }
  445|  1.12M|    uint8_t c = data_[pos_++];
  446|  1.12M|    if (c == 0xff) {
  ------------------
  |  Branch (446:9): [True: 7.92k, False: 1.11M]
  ------------------
  447|  7.92k|      uint8_t escape = data_[pos_];
  448|  7.92k|      if (escape == 0) {
  ------------------
  |  Branch (448:11): [True: 3.91k, False: 4.01k]
  ------------------
  449|  3.91k|        ++pos_;
  450|  4.01k|      } else {
  451|       |        // 0xff was followed by a non-zero byte, which means that we found the
  452|       |        // start of the next marker segment.
  453|  4.01k|        next_marker_pos_ = pos_ - 1;
  454|  4.01k|      }
  455|  7.92k|    }
  456|  1.12M|    return c;
  457|  25.8M|  }
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_114ProcessRestartEPKhmPiPNS0_14BitReaderStateEPNS_8JPEGDataE:
  734|    187|                    JPEGData* jpg) {
  735|    187|  size_t pos = 0;
  736|    187|  if (!br->FinishStream(&pos)) {
  ------------------
  |  Branch (736:7): [True: 38, False: 149]
  ------------------
  737|     38|    jpg->error = JPEG_INVALID_SCAN;
  738|     38|    return false;
  739|     38|  }
  740|    149|  int expected_marker = 0xd0 + *next_restart_marker;
  741|    149|  EXPECT_MARKER();
  ------------------
  |  |   57|    149|  if (pos + 2 > len || data[pos] != 0xff) {                             \
  |  |  ------------------
  |  |  |  Branch (57:7): [True: 0, False: 149]
  |  |  |  Branch (57:24): [True: 47, False: 102]
  |  |  ------------------
  |  |   58|     47|    fprintf(stderr, "Marker byte (0xff) expected, found: %d "           \
  |  |   59|     47|            "pos=%d len=%d\n",                                          \
  |  |   60|     47|            (pos < len ? data[pos] : 0), static_cast<int>(pos),         \
  |  |  ------------------
  |  |  |  Branch (60:14): [True: 47, False: 0]
  |  |  ------------------
  |  |   61|     47|            static_cast<int>(len));                                     \
  |  |   62|     47|    jpg->error = JPEG_MARKER_BYTE_NOT_FOUND;                            \
  |  |   63|     47|    return false;                                                       \
  |  |   64|     47|  }
  ------------------
  742|    102|  int marker = data[pos + 1];
  743|    102|  if (marker != expected_marker) {
  ------------------
  |  Branch (743:7): [True: 21, False: 81]
  ------------------
  744|     21|    fprintf(stderr, "Did not find expected restart marker %d actual=%d\n",
  745|     21|            expected_marker, marker);
  746|     21|    jpg->error = JPEG_WRONG_RESTART_MARKER;
  747|     21|    return false;
  748|     21|  }
  749|     81|  br->Reset(pos + 2);
  750|     81|  *next_restart_marker += 1;
  751|     81|  *next_restart_marker &= 0x7;
  752|     81|  return true;
  753|    102|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_114DecodeDCTBlockEPKNS_17HuffmanTableEntryES3_iiiPiPNS0_14BitReaderStateEPNS_8JPEGDataEPsS9_:
  538|   341k|                    coeff_t* coeffs) {
  539|   341k|  int s;
  540|   341k|  int r;
  541|   341k|  bool eobrun_allowed = Ss > 0;
  542|   341k|  if (Ss == 0) {
  ------------------
  |  Branch (542:7): [True: 92.5k, False: 248k]
  ------------------
  543|  92.5k|    s = ReadSymbol(dc_huff, br);
  544|  92.5k|    if (s >= kJpegDCAlphabetSize) {
  ------------------
  |  Branch (544:9): [True: 69, False: 92.4k]
  ------------------
  545|     69|      fprintf(stderr, "Invalid Huffman symbol %d for DC coefficient.\n", s);
  546|     69|      jpg->error = JPEG_INVALID_SYMBOL;
  547|     69|      return false;
  548|     69|    }
  549|  92.4k|    if (s > 0) {
  ------------------
  |  Branch (549:9): [True: 40.4k, False: 51.9k]
  ------------------
  550|  40.4k|      r = br->ReadBits(s);
  551|  40.4k|      s = HuffExtend(r, s);
  552|  40.4k|    }
  553|  92.4k|    s += *last_dc_coeff;
  554|  92.4k|    const int dc_coeff = SignedLeftshift(s, Al);
  555|  92.4k|    coeffs[0] = dc_coeff;
  556|  92.4k|    if (dc_coeff != coeffs[0]) {
  ------------------
  |  Branch (556:9): [True: 28, False: 92.4k]
  ------------------
  557|     28|      fprintf(stderr, "Invalid DC coefficient %d\n", dc_coeff);
  558|     28|      jpg->error = JPEG_NON_REPRESENTABLE_DC_COEFF;
  559|     28|      return false;
  560|     28|    }
  561|  92.4k|    *last_dc_coeff = s;
  562|  92.4k|    ++Ss;
  563|  92.4k|  }
  564|   341k|  if (Ss > Se) {
  ------------------
  |  Branch (564:7): [True: 11.9k, False: 329k]
  ------------------
  565|  11.9k|    return true;
  566|  11.9k|  }
  567|   329k|  if (*eobrun > 0) {
  ------------------
  |  Branch (567:7): [True: 42.5k, False: 286k]
  ------------------
  568|  42.5k|    --(*eobrun);
  569|  42.5k|    return true;
  570|  42.5k|  }
  571|  10.2M|  for (int k = Ss; k <= Se; k++) {
  ------------------
  |  Branch (571:20): [True: 10.0M, False: 206k]
  ------------------
  572|  10.0M|    s = ReadSymbol(ac_huff, br);
  573|  10.0M|    if (s >= kJpegHuffmanAlphabetSize) {
  ------------------
  |  Branch (573:9): [True: 76, False: 10.0M]
  ------------------
  574|     76|      fprintf(stderr, "Invalid Huffman symbol %d for AC coefficient %d\n",
  575|     76|              s, k);
  576|     76|      jpg->error = JPEG_INVALID_SYMBOL;
  577|     76|      return false;
  578|     76|    }
  579|  10.0M|    r = s >> 4;
  580|  10.0M|    s &= 15;
  581|  10.0M|    if (s > 0) {
  ------------------
  |  Branch (581:9): [True: 9.99M, False: 83.4k]
  ------------------
  582|  9.99M|      k += r;
  583|  9.99M|      if (k > Se) {
  ------------------
  |  Branch (583:11): [True: 13, False: 9.99M]
  ------------------
  584|     13|        fprintf(stderr, "Out-of-band coefficient %d band was %d-%d\n",
  585|     13|                k, Ss, Se);
  586|     13|        jpg->error = JPEG_OUT_OF_BAND_COEFF;
  587|     13|        return false;
  588|     13|      }
  589|  9.99M|      if (s + Al >= kJpegDCAlphabetSize) {
  ------------------
  |  Branch (589:11): [True: 4, False: 9.99M]
  ------------------
  590|      4|        fprintf(stderr, "Out of range AC coefficient value: s=%d Al=%d k=%d\n",
  591|      4|                s, Al, k);
  592|      4|        jpg->error = JPEG_NON_REPRESENTABLE_AC_COEFF;
  593|      4|        return false;
  594|      4|      }
  595|  9.99M|      r = br->ReadBits(s);
  596|  9.99M|      s = HuffExtend(r, s);
  597|  9.99M|      coeffs[kJPEGNaturalOrder[k]] = SignedLeftshift(s, Al);
  598|  9.99M|    } else if (r == 15) {
  ------------------
  |  Branch (598:16): [True: 2.99k, False: 80.4k]
  ------------------
  599|  2.99k|      k += 15;
  600|  80.4k|    } else {
  601|  80.4k|      *eobrun = 1 << r;
  602|  80.4k|      if (r > 0) {
  ------------------
  |  Branch (602:11): [True: 18.0k, False: 62.4k]
  ------------------
  603|  18.0k|        if (!eobrun_allowed) {
  ------------------
  |  Branch (603:13): [True: 2, False: 18.0k]
  ------------------
  604|      2|          fprintf(stderr, "End-of-block run crossing DC coeff.\n");
  605|      2|          jpg->error = JPEG_EOB_RUN_TOO_LONG;
  606|      2|          return false;
  607|      2|        }
  608|  18.0k|        *eobrun += br->ReadBits(r);
  609|  18.0k|      }
  610|  80.4k|      break;
  611|  80.4k|    }
  612|  10.0M|  }
  613|   286k|  --(*eobrun);
  614|   286k|  return true;
  615|   286k|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_110ReadSymbolEPKNS_17HuffmanTableEntryEPNS0_14BitReaderStateE:
  508|  16.9M|int ReadSymbol(const HuffmanTableEntry* table, BitReaderState* br) {
  509|  16.9M|  int nbits;
  510|  16.9M|  br->FillBitWindow();
  511|  16.9M|  int val = (br->val_ >> (br->bits_left_ - 8)) & 0xff;
  512|  16.9M|  table += val;
  513|  16.9M|  nbits = table->bits - 8;
  514|  16.9M|  if (nbits > 0) {
  ------------------
  |  Branch (514:7): [True: 11.5M, False: 5.45M]
  ------------------
  515|  11.5M|    br->bits_left_ -= 8;
  516|  11.5M|    table += table->value;
  517|  11.5M|    val = (br->val_ >> (br->bits_left_ - nbits)) & ((1 << nbits) - 1);
  518|  11.5M|    table += val;
  519|  11.5M|  }
  520|  16.9M|  br->bits_left_ -= table->bits;
  521|  16.9M|  return table->value;
  522|  16.9M|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_114BitReaderState8ReadBitsEi:
  469|  16.9M|  int ReadBits(int nbits) {
  470|  16.9M|    FillBitWindow();
  471|  16.9M|    uint64_t val = (val_ >> (bits_left_ - nbits)) & ((1ULL << nbits) - 1);
  472|  16.9M|    bits_left_ -= nbits;
  473|  16.9M|    return val;
  474|  16.9M|  }
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_110HuffExtendEii:
  526|  10.0M|int HuffExtend(int x, int s) {
  527|  10.0M|  return (x < (1 << (s - 1)) ? x - (1 << s) + 1 : x);
  ------------------
  |  Branch (527:11): [True: 9.53M, False: 500k]
  ------------------
  528|  10.0M|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_115SignedLeftshiftEii:
   66|  10.0M|inline int SignedLeftshift(int v, int s) {
   67|  10.0M|  return (v >= 0) ? (v << s) : -((-v) << s);
  ------------------
  |  Branch (67:10): [True: 532k, False: 9.55M]
  ------------------
   68|  10.0M|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_114RefineDCTBlockEPKNS_17HuffmanTableEntryEiiiPiPNS0_14BitReaderStateEPNS_8JPEGDataEPs:
  622|   361k|                    coeff_t* coeffs) {
  623|   361k|  bool eobrun_allowed = Ss > 0;
  624|   361k|  if (Ss == 0) {
  ------------------
  |  Branch (624:7): [True: 80.4k, False: 281k]
  ------------------
  625|  80.4k|    int s = br->ReadBits(1);
  626|  80.4k|    coeff_t dc_coeff = coeffs[0];
  627|  80.4k|    dc_coeff |= s << Al;
  628|  80.4k|    coeffs[0] = dc_coeff;
  629|  80.4k|    ++Ss;
  630|  80.4k|  }
  631|   361k|  if (Ss > Se) {
  ------------------
  |  Branch (631:7): [True: 79.6k, False: 281k]
  ------------------
  632|  79.6k|    return true;
  633|  79.6k|  }
  634|   281k|  int p1 = 1 << Al;
  635|   281k|  int m1 = -(1 << Al);
  636|   281k|  int k = Ss;
  637|   281k|  int r;
  638|   281k|  int s;
  639|   281k|  bool in_zero_run = false;
  640|   281k|  if (*eobrun <= 0) {
  ------------------
  |  Branch (640:7): [True: 221k, False: 60.5k]
  ------------------
  641|  6.98M|    for (; k <= Se; k++) {
  ------------------
  |  Branch (641:12): [True: 6.80M, False: 180k]
  ------------------
  642|  6.80M|      s = ReadSymbol(ac_huff, br);
  643|  6.80M|      if (s >= kJpegHuffmanAlphabetSize) {
  ------------------
  |  Branch (643:11): [True: 112, False: 6.80M]
  ------------------
  644|    112|        fprintf(stderr, "Invalid Huffman symbol %d for AC coefficient %d\n",
  645|    112|                s, k);
  646|    112|        jpg->error = JPEG_INVALID_SYMBOL;
  647|    112|        return false;
  648|    112|      }
  649|  6.80M|      r = s >> 4;
  650|  6.80M|      s &= 15;
  651|  6.80M|      if (s) {
  ------------------
  |  Branch (651:11): [True: 6.76M, False: 40.7k]
  ------------------
  652|  6.76M|        if (s != 1) {
  ------------------
  |  Branch (652:13): [True: 14, False: 6.76M]
  ------------------
  653|     14|          fprintf(stderr, "Invalid Huffman symbol %d for AC coefficient %d\n",
  654|     14|                  s, k);
  655|     14|          jpg->error = JPEG_INVALID_SYMBOL;
  656|     14|          return false;
  657|     14|        }
  658|  6.76M|        s = br->ReadBits(1) ? p1 : m1;
  ------------------
  |  Branch (658:13): [True: 30.2k, False: 6.73M]
  ------------------
  659|  6.76M|        in_zero_run = false;
  660|  6.76M|      } else {
  661|  40.7k|        if (r != 15) {
  ------------------
  |  Branch (661:13): [True: 40.5k, False: 250]
  ------------------
  662|  40.5k|          *eobrun = 1 << r;
  663|  40.5k|          if (r > 0) {
  ------------------
  |  Branch (663:15): [True: 16.9k, False: 23.5k]
  ------------------
  664|  16.9k|            if (!eobrun_allowed) {
  ------------------
  |  Branch (664:17): [True: 2, False: 16.9k]
  ------------------
  665|      2|              fprintf(stderr, "End-of-block run crossing DC coeff.\n");
  666|      2|              jpg->error = JPEG_EOB_RUN_TOO_LONG;
  667|      2|              return false;
  668|      2|            }
  669|  16.9k|            *eobrun += br->ReadBits(r);
  670|  16.9k|          }
  671|  40.5k|          break;
  672|  40.5k|        }
  673|    250|        in_zero_run = true;
  674|    250|      }
  675|  7.25M|      do {
  676|  7.25M|        coeff_t thiscoef = coeffs[kJPEGNaturalOrder[k]];
  677|  7.25M|        if (thiscoef != 0) {
  ------------------
  |  Branch (677:13): [True: 19.9k, False: 7.23M]
  ------------------
  678|  19.9k|          if (br->ReadBits(1)) {
  ------------------
  |  Branch (678:15): [True: 1.56k, False: 18.3k]
  ------------------
  679|  1.56k|            if ((thiscoef & p1) == 0) {
  ------------------
  |  Branch (679:17): [True: 1.56k, False: 0]
  ------------------
  680|  1.56k|              if (thiscoef >= 0) {
  ------------------
  |  Branch (680:19): [True: 538, False: 1.02k]
  ------------------
  681|    538|                thiscoef += p1;
  682|  1.02k|              } else {
  683|  1.02k|                thiscoef += m1;
  684|  1.02k|              }
  685|  1.56k|            }
  686|  1.56k|          }
  687|  19.9k|          coeffs[kJPEGNaturalOrder[k]] = thiscoef;
  688|  7.23M|        } else {
  689|  7.23M|          if (--r < 0) {
  ------------------
  |  Branch (689:15): [True: 6.76M, False: 468k]
  ------------------
  690|  6.76M|            break;
  691|  6.76M|          }
  692|  7.23M|        }
  693|   488k|        k++;
  694|   488k|      } while (k <= Se);
  ------------------
  |  Branch (694:16): [True: 488k, False: 23]
  ------------------
  695|  6.76M|      if (s) {
  ------------------
  |  Branch (695:11): [True: 6.76M, False: 250]
  ------------------
  696|  6.76M|        if (k > Se) {
  ------------------
  |  Branch (696:13): [True: 15, False: 6.76M]
  ------------------
  697|     15|          fprintf(stderr, "Out-of-band coefficient %d band was %d-%d\n",
  698|     15|                  k, Ss, Se);
  699|     15|          jpg->error = JPEG_OUT_OF_BAND_COEFF;
  700|     15|          return false;
  701|     15|        }
  702|  6.76M|        coeffs[kJPEGNaturalOrder[k]] = s;
  703|  6.76M|      }
  704|  6.76M|    }
  705|   221k|  }
  706|   281k|  if (in_zero_run) {
  ------------------
  |  Branch (706:7): [True: 9, False: 281k]
  ------------------
  707|      9|    fprintf(stderr, "Extra zero run before end-of-block.\n");
  708|      9|    jpg->error = JPEG_EXTRA_ZERO_RUN;
  709|      9|    return false;
  710|      9|  }
  711|   281k|  if (*eobrun > 0) {
  ------------------
  |  Branch (711:7): [True: 101k, False: 180k]
  ------------------
  712|  2.61M|    for (; k <= Se; k++) {
  ------------------
  |  Branch (712:12): [True: 2.51M, False: 101k]
  ------------------
  713|  2.51M|      coeff_t thiscoef = coeffs[kJPEGNaturalOrder[k]];
  714|  2.51M|      if (thiscoef != 0) {
  ------------------
  |  Branch (714:11): [True: 42.0k, False: 2.47M]
  ------------------
  715|  42.0k|        if (br->ReadBits(1)) {
  ------------------
  |  Branch (715:13): [True: 7.86k, False: 34.2k]
  ------------------
  716|  7.86k|          if ((thiscoef & p1) == 0) {
  ------------------
  |  Branch (716:15): [True: 7.86k, False: 0]
  ------------------
  717|  7.86k|            if (thiscoef >= 0) {
  ------------------
  |  Branch (717:17): [True: 560, False: 7.30k]
  ------------------
  718|    560|              thiscoef += p1;
  719|  7.30k|            } else {
  720|  7.30k|              thiscoef += m1;
  721|  7.30k|            }
  722|  7.86k|          }
  723|  7.86k|        }
  724|  42.0k|        coeffs[kJPEGNaturalOrder[k]] = thiscoef;
  725|  42.0k|      }
  726|  2.51M|    }
  727|   101k|  }
  728|   281k|  --(*eobrun);
  729|   281k|  return true;
  730|   281k|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_114BitReaderState12FinishStreamEPm:
  478|  7.80k|  bool FinishStream(size_t* pos) {
  479|       |    // Give back some bytes that we did not use.
  480|  7.80k|    int unused_bytes_left = bits_left_ >> 3;
  481|  52.0k|    while (unused_bytes_left-- > 0) {
  ------------------
  |  Branch (481:12): [True: 44.2k, False: 7.80k]
  ------------------
  482|  44.2k|      --pos_;
  483|       |      // If we give back a 0 byte, we need to check if it was a 0xff/0x00 escape
  484|       |      // sequence, and if yes, we need to give back one more byte.
  485|  44.2k|      if (pos_ < next_marker_pos_ &&
  ------------------
  |  Branch (485:11): [True: 11.9k, False: 32.2k]
  ------------------
  486|  44.2k|          data_[pos_] == 0 && data_[pos_ - 1] == 0xff) {
  ------------------
  |  Branch (486:11): [True: 4.89k, False: 7.10k]
  |  Branch (486:31): [True: 217, False: 4.67k]
  ------------------
  487|    217|        --pos_;
  488|    217|      }
  489|  44.2k|    }
  490|  7.80k|    if (pos_ > next_marker_pos_) {
  ------------------
  |  Branch (490:9): [True: 357, False: 7.44k]
  ------------------
  491|       |      // Data ran out before the scan was complete.
  492|    357|      fprintf(stderr, "Unexpected end of scan.\n");
  493|    357|      return false;
  494|    357|    }
  495|  7.44k|    *pos = pos_;
  496|  7.44k|    return true;
  497|  7.80k|  }
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_110ProcessDQTEPKhmPmPNS_8JPEGDataE:
  345|  8.51k|                JPEGData* jpg) {
  346|  8.51k|  const size_t start_pos = *pos;
  347|  8.51k|  VERIFY_LEN(2);
  ------------------
  |  |   32|  8.51k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 6, False: 8.50k]
  |  |  ------------------
  |  |   33|      6|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|      6|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|      6|            static_cast<int>(len));                                     \
  |  |   36|      6|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|      6|    return false;                                                       \
  |  |   38|      6|  }
  ------------------
  348|  8.50k|  size_t marker_len = ReadUint16(data, pos);
  349|  8.50k|  if (marker_len == 2) {
  ------------------
  |  Branch (349:7): [True: 1, False: 8.50k]
  ------------------
  350|      1|    fprintf(stderr, "DQT marker: no quantization table found\n");
  351|      1|    jpg->error = JPEG_EMPTY_DQT;
  352|      1|    return false;
  353|      1|  }
  354|  16.9k|  while (*pos < start_pos + marker_len && jpg->quant.size() < kMaxQuantTables) {
  ------------------
  |  Branch (354:10): [True: 8.58k, False: 8.39k]
  |  Branch (354:43): [True: 8.56k, False: 29]
  ------------------
  355|  8.56k|    VERIFY_LEN(1);
  ------------------
  |  |   32|  8.56k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 20, False: 8.54k]
  |  |  ------------------
  |  |   33|     20|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     20|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|     20|            static_cast<int>(len));                                     \
  |  |   36|     20|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     20|    return false;                                                       \
  |  |   38|     20|  }
  ------------------
  356|  8.54k|    int quant_table_index = ReadUint8(data, pos);
  357|  8.54k|    int quant_table_precision = quant_table_index >> 4;
  358|  8.54k|    quant_table_index &= 0xf;
  359|  8.54k|    VERIFY_INPUT(quant_table_index, 0, 3, QUANT_TBL_INDEX);
  ------------------
  |  |   41|  8.54k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 0, False: 8.54k]
  |  |  |  Branch (41:20): [True: 11, False: 8.52k]
  |  |  ------------------
  |  |   42|     11|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|     11|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|     11|        return false;                                                   \
  |  |   45|     11|  }
  ------------------
  360|  8.52k|    VERIFY_LEN((quant_table_precision ? 2 : 1) * kDCTBlockSize);
  ------------------
  |  |   32|  17.0k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 33, False: 8.49k]
  |  |  |  Branch (32:15): [True: 258, False: 8.27k]
  |  |  ------------------
  |  |   33|     33|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     66|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |  ------------------
  |  |  |  Branch (34:54): [True: 12, False: 21]
  |  |  ------------------
  |  |   35|     33|            static_cast<int>(len));                                     \
  |  |   36|     33|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     33|    return false;                                                       \
  |  |   38|     33|  }
  ------------------
  361|  8.49k|    JPEGQuantTable table;
  362|  8.49k|    table.index = quant_table_index;
  363|  8.49k|    table.precision = quant_table_precision;
  364|   551k|    for (int i = 0; i < kDCTBlockSize; ++i) {
  ------------------
  |  Branch (364:21): [True: 542k, False: 8.47k]
  ------------------
  365|   542k|      int quant_val = quant_table_precision ?
  ------------------
  |  Branch (365:23): [True: 15.3k, False: 527k]
  ------------------
  366|  15.3k|          ReadUint16(data, pos) :
  367|   542k|          ReadUint8(data, pos);
  368|   542k|      VERIFY_INPUT(quant_val, 1, 65535, QUANT_VAL);
  ------------------
  |  |   41|   542k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 19, False: 542k]
  |  |  |  Branch (41:20): [True: 0, False: 542k]
  |  |  ------------------
  |  |   42|     19|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|     19|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|     19|        return false;                                                   \
  |  |   45|     19|  }
  ------------------
  369|   542k|      table.values[kJPEGNaturalOrder[i]] = quant_val;
  370|   542k|    }
  371|  8.47k|    table.is_last = (*pos == start_pos + marker_len);
  372|  8.47k|    jpg->quant.push_back(table);
  373|  8.47k|  }
  374|  8.42k|  VERIFY_MARKER_END();
  ------------------
  |  |   48|  8.42k|  if (start_pos + marker_len != *pos) {                                 \
  |  |  ------------------
  |  |  |  Branch (48:7): [True: 47, False: 8.37k]
  |  |  ------------------
  |  |   49|     47|    fprintf(stderr, "Invalid marker length: declared=%d actual=%d\n",   \
  |  |   50|     47|            static_cast<int>(marker_len),                               \
  |  |   51|     47|            static_cast<int>(*pos - start_pos));                        \
  |  |   52|     47|    jpg->error = JPEG_WRONG_MARKER_SIZE;                                \
  |  |   53|     47|    return false;                                                       \
  |  |   54|     47|  }
  ------------------
  375|  8.37k|  return true;
  376|  8.42k|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_110ProcessDRIEPKhmPmPNS_8JPEGDataE:
  380|    600|                JPEGData* jpg) {
  381|    600|  if (jpg->restart_interval > 0) {
  ------------------
  |  Branch (381:7): [True: 18, False: 582]
  ------------------
  382|     18|    fprintf(stderr, "Duplicate DRI marker.\n");
  383|     18|    jpg->error = JPEG_DUPLICATE_DRI;
  384|     18|    return false;
  385|     18|  }
  386|    582|  const size_t start_pos = *pos;
  387|    582|  VERIFY_LEN(4);
  ------------------
  |  |   32|    582|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 10, False: 572]
  |  |  ------------------
  |  |   33|     10|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     10|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|     10|            static_cast<int>(len));                                     \
  |  |   36|     10|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     10|    return false;                                                       \
  |  |   38|     10|  }
  ------------------
  388|    572|  size_t marker_len = ReadUint16(data, pos);
  389|    572|  int restart_interval = ReadUint16(data, pos);
  390|    572|  jpg->restart_interval = restart_interval;
  391|    572|  VERIFY_MARKER_END();
  ------------------
  |  |   48|    572|  if (start_pos + marker_len != *pos) {                                 \
  |  |  ------------------
  |  |  |  Branch (48:7): [True: 5, False: 567]
  |  |  ------------------
  |  |   49|      5|    fprintf(stderr, "Invalid marker length: declared=%d actual=%d\n",   \
  |  |   50|      5|            static_cast<int>(marker_len),                               \
  |  |   51|      5|            static_cast<int>(*pos - start_pos));                        \
  |  |   52|      5|    jpg->error = JPEG_WRONG_MARKER_SIZE;                                \
  |  |   53|      5|    return false;                                                       \
  |  |   54|      5|  }
  ------------------
  392|    567|  return true;
  393|    572|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_110ProcessAPPEPKhmPmPNS_8JPEGDataE:
  397|  1.69M|                JPEGData* jpg) {
  398|  1.69M|  VERIFY_LEN(2);
  ------------------
  |  |   32|  1.69M|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 76, False: 1.69M]
  |  |  ------------------
  |  |   33|     76|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     76|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|     76|            static_cast<int>(len));                                     \
  |  |   36|     76|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     76|    return false;                                                       \
  |  |   38|     76|  }
  ------------------
  399|  1.69M|  size_t marker_len = ReadUint16(data, pos);
  400|  1.69M|  VERIFY_INPUT(marker_len, 2, 65535, MARKER_LEN);
  ------------------
  |  |   41|  1.69M|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 2, False: 1.69M]
  |  |  |  Branch (41:20): [True: 0, False: 1.69M]
  |  |  ------------------
  |  |   42|      2|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|      2|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|      2|        return false;                                                   \
  |  |   45|      2|  }
  ------------------
  401|  1.69M|  VERIFY_LEN(marker_len - 2);
  ------------------
  |  |   32|  1.69M|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 38, False: 1.69M]
  |  |  ------------------
  |  |   33|     38|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     38|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|     38|            static_cast<int>(len));                                     \
  |  |   36|     38|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     38|    return false;                                                       \
  |  |   38|     38|  }
  ------------------
  402|       |  // Save the marker type together with the app data.
  403|  1.69M|  std::string app_str(reinterpret_cast<const char*>(
  404|  1.69M|      &data[*pos - 3]), marker_len + 1);
  405|  1.69M|  *pos += marker_len - 2;
  406|  1.69M|  jpg->app_data.push_back(app_str);
  407|  1.69M|  return true;
  408|  1.69M|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_110ProcessCOMEPKhmPmPNS_8JPEGDataE:
  412|   400k|                JPEGData* jpg) {
  413|   400k|  VERIFY_LEN(2);
  ------------------
  |  |   32|   400k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 9, False: 400k]
  |  |  ------------------
  |  |   33|      9|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|      9|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|      9|            static_cast<int>(len));                                     \
  |  |   36|      9|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|      9|    return false;                                                       \
  |  |   38|      9|  }
  ------------------
  414|   400k|  size_t marker_len = ReadUint16(data, pos);
  415|   400k|  VERIFY_INPUT(marker_len, 2, 65535, MARKER_LEN);
  ------------------
  |  |   41|   400k|  if (var < low || var > high) {                                        \
  |  |  ------------------
  |  |  |  Branch (41:7): [True: 2, False: 400k]
  |  |  |  Branch (41:20): [True: 0, False: 400k]
  |  |  ------------------
  |  |   42|      2|    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
  |  |   43|      2|    jpg->error = JPEG_INVALID_ ## code;                                 \
  |  |   44|      2|        return false;                                                   \
  |  |   45|      2|  }
  ------------------
  416|   400k|  VERIFY_LEN(marker_len - 2);
  ------------------
  |  |   32|   400k|  if (*pos + (n) > len) {                                               \
  |  |  ------------------
  |  |  |  Branch (32:7): [True: 40, False: 400k]
  |  |  ------------------
  |  |   33|     40|    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
  |  |   34|     40|            static_cast<int>(*pos), static_cast<int>(n),                \
  |  |   35|     40|            static_cast<int>(len));                                     \
  |  |   36|     40|    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
  |  |   37|     40|    return false;                                                       \
  |  |   38|     40|  }
  ------------------
  417|   400k|  std::string com_str(reinterpret_cast<const char*>(
  418|   400k|      &data[*pos - 2]), marker_len);
  419|   400k|  *pos += marker_len - 2;
  420|   400k|  jpg->com_data.push_back(com_str);
  421|   400k|  return true;
  422|   400k|}
jpeg_data_reader.cc:_ZN7guetzli12_GLOBAL__N_112FixupIndexesEPNS_8JPEGDataE:
  890|  3.31k|bool FixupIndexes(JPEGData* jpg) {
  891|  13.0k|  for (size_t i = 0; i < jpg->components.size(); ++i) {
  ------------------
  |  Branch (891:22): [True: 9.72k, False: 3.28k]
  ------------------
  892|  9.72k|    JPEGComponent* c = &jpg->components[i];
  893|  9.72k|    bool found_index = false;
  894|  11.0k|    for (size_t j = 0; j < jpg->quant.size(); ++j) {
  ------------------
  |  Branch (894:24): [True: 10.9k, False: 30]
  ------------------
  895|  10.9k|      if (jpg->quant[j].index == c->quant_idx) {
  ------------------
  |  Branch (895:11): [True: 9.69k, False: 1.30k]
  ------------------
  896|  9.69k|        c->quant_idx = j;
  897|  9.69k|        found_index = true;
  898|  9.69k|        break;
  899|  9.69k|      }
  900|  10.9k|    }
  901|  9.72k|    if (!found_index) {
  ------------------
  |  Branch (901:9): [True: 30, False: 9.69k]
  ------------------
  902|     30|      fprintf(stderr, "Quantization table with index %zd not found\n",
  903|     30|              c->quant_idx);
  904|     30|      jpg->error = JPEG_QUANT_TABLE_NOT_FOUND;
  905|     30|      return false;
  906|     30|    }
  907|  9.72k|  }
  908|  3.28k|  return true;
  909|  3.31k|}

_ZN7guetzli28UpdateACHistogramForDCTBlockEPKsPNS_13JpegHistogramE:
  189|  17.6M|                                  JpegHistogram* ac_histogram) {
  190|  17.6M|  int r = 0;
  191|  1.13G|  for (int k = 1; k < 64; ++k) {
  ------------------
  |  Branch (191:19): [True: 1.11G, False: 17.6M]
  ------------------
  192|  1.11G|    coeff_t coeff = coeffs[kJPEGNaturalOrder[k]];
  193|  1.11G|    if (coeff == 0) {
  ------------------
  |  Branch (193:9): [True: 955M, False: 158M]
  ------------------
  194|   955M|      r++;
  195|   955M|      continue;
  196|   955M|    }
  197|   162M|    while (r > 15) {
  ------------------
  |  Branch (197:12): [True: 3.61M, False: 158M]
  ------------------
  198|  3.61M|      ac_histogram->Add(0xf0);
  199|  3.61M|      r -= 16;
  200|  3.61M|    }
  201|   158M|    int nbits = Log2FloorNonZero(std::abs(coeff)) + 1;
  202|   158M|    int symbol = (r << 4) + nbits;
  203|   158M|    ac_histogram->Add(symbol);
  204|   158M|    r = 0;
  205|   158M|  }
  206|  17.6M|  if (r > 0) {
  ------------------
  |  Branch (206:7): [True: 16.3M, False: 1.37M]
  ------------------
  207|  16.3M|    ac_histogram->Add(0);
  208|  16.3M|  }
  209|  17.6M|}
_ZN7guetzli19HistogramHeaderCostERKNS_13JpegHistogramE:
  211|  3.36M|size_t HistogramHeaderCost(const JpegHistogram& histo) {
  212|  3.36M|  size_t header_bits = 17 * 8;
  213|   864M|  for (int i = 0; i + 1 < JpegHistogram::kSize; ++i) {
  ------------------
  |  Branch (213:19): [True: 861M, False: 3.36M]
  ------------------
  214|   861M|    if (histo.counts[i] > 0) {
  ------------------
  |  Branch (214:9): [True: 46.8M, False: 814M]
  ------------------
  215|  46.8M|      header_bits += 8;
  216|  46.8M|    }
  217|   861M|  }
  218|  3.36M|  return header_bits;
  219|  3.36M|}
_ZN7guetzli20HistogramEntropyCostERKNS_13JpegHistogramEPKh:
  222|  10.1M|                            const uint8_t depths[256]) {
  223|  10.1M|  size_t bits = 0;
  224|  2.61G|  for (int i = 0; i + 1 < JpegHistogram::kSize; ++i) {
  ------------------
  |  Branch (224:19): [True: 2.60G, False: 10.1M]
  ------------------
  225|       |    // JpegHistogram::Add() counts every symbol twice, so we have to divide by
  226|       |    // two here.
  227|  2.60G|    bits += (histo.counts[i] / 2) * (depths[i] + (i & 0xf));
  228|  2.60G|  }
  229|       |  // Estimate escape byte rate to be 0.75/256.
  230|  10.1M|  bits += (bits * 3 + 512) >> 10;
  231|  10.1M|  return bits;
  232|  10.1M|}
_ZN7guetzli17BuildDCHistogramsERKNS_8JPEGDataEPNS_13JpegHistogramE:
  234|   168k|void BuildDCHistograms(const JPEGData& jpg, JpegHistogram* histo) {
  235|   618k|  for (size_t i = 0; i < jpg.components.size(); ++i) {
  ------------------
  |  Branch (235:22): [True: 449k, False: 168k]
  ------------------
  236|   449k|    const JPEGComponent& c = jpg.components[i];
  237|   449k|    JpegHistogram* dc_histogram = &histo[i];
  238|   449k|    coeff_t last_dc_coeff = 0;
  239|  2.48M|    for (int mcu_y = 0; mcu_y < jpg.MCU_rows; ++mcu_y) {
  ------------------
  |  Branch (239:25): [True: 2.03M, False: 449k]
  ------------------
  240|  14.2M|      for (int mcu_x = 0; mcu_x < jpg.MCU_cols; ++mcu_x) {
  ------------------
  |  Branch (240:27): [True: 12.2M, False: 2.03M]
  ------------------
  241|  26.2M|        for (int iy = 0; iy < c.v_samp_factor; ++iy) {
  ------------------
  |  Branch (241:26): [True: 14.0M, False: 12.2M]
  ------------------
  242|  31.7M|          for (int ix = 0; ix < c.h_samp_factor; ++ix) {
  ------------------
  |  Branch (242:28): [True: 17.6M, False: 14.0M]
  ------------------
  243|  17.6M|            int block_y = mcu_y * c.v_samp_factor + iy;
  244|  17.6M|            int block_x = mcu_x * c.h_samp_factor + ix;
  245|  17.6M|            int block_idx = block_y * c.width_in_blocks + block_x;
  246|  17.6M|            coeff_t dc_coeff = c.coeffs[block_idx << 6];
  247|  17.6M|            int diff = std::abs(dc_coeff - last_dc_coeff);
  248|  17.6M|            int nbits = Log2Floor(diff) + 1;
  249|  17.6M|            dc_histogram->Add(nbits);
  250|  17.6M|            last_dc_coeff = dc_coeff;
  251|  17.6M|          }
  252|  14.0M|        }
  253|  12.2M|      }
  254|  2.03M|    }
  255|   449k|  }
  256|   168k|}
_ZN7guetzli17BuildACHistogramsERKNS_8JPEGDataEPNS_13JpegHistogramE:
  258|   168k|void BuildACHistograms(const JPEGData& jpg, JpegHistogram* histo) {
  259|   618k|  for (size_t i = 0; i < jpg.components.size(); ++i) {
  ------------------
  |  Branch (259:22): [True: 449k, False: 168k]
  ------------------
  260|   449k|    const JPEGComponent& c = jpg.components[i];
  261|   449k|    JpegHistogram* ac_histogram = &histo[i];
  262|  18.1M|    for (size_t j = 0; j < c.coeffs.size(); j += kDCTBlockSize) {
  ------------------
  |  Branch (262:24): [True: 17.6M, False: 449k]
  ------------------
  263|  17.6M|      UpdateACHistogramForDCTBlock(&c.coeffs[j], ac_histogram);
  264|  17.6M|    }
  265|   449k|  }
  266|   168k|}
_ZN7guetzli14JpegHeaderSizeERKNS_8JPEGDataEb:
  269|  5.01k|size_t JpegHeaderSize(const JPEGData& jpg, bool strip_metadata) {
  270|  5.01k|  size_t num_bytes = 0;
  271|  5.01k|  num_bytes += 2;  // SOI
  272|  5.01k|  if (strip_metadata) {
  ------------------
  |  Branch (272:7): [True: 5.01k, False: 0]
  ------------------
  273|  5.01k|    num_bytes += 18;  // APP0
  274|  5.01k|  } else {
  275|      0|    for (size_t i = 0; i < jpg.app_data.size(); ++i) {
  ------------------
  |  Branch (275:24): [True: 0, False: 0]
  ------------------
  276|      0|      num_bytes += 1 + jpg.app_data[i].size();
  277|      0|    }
  278|      0|    for (size_t i = 0; i < jpg.com_data.size(); ++i) {
  ------------------
  |  Branch (278:24): [True: 0, False: 0]
  ------------------
  279|      0|      num_bytes += 2 + jpg.com_data[i].size();
  280|      0|    }
  281|      0|  }
  282|       |  // DQT
  283|  5.01k|  num_bytes += 4;
  284|  10.7k|  for (size_t i = 0; i < jpg.quant.size(); ++i) {
  ------------------
  |  Branch (284:22): [True: 5.70k, False: 5.01k]
  ------------------
  285|  5.70k|    num_bytes += 1 + (jpg.quant[i].precision ? 2 : 1) * kDCTBlockSize;
  ------------------
  |  Branch (285:23): [True: 12, False: 5.69k]
  ------------------
  286|  5.70k|  }
  287|  5.01k|  num_bytes += 10 + 3 * jpg.components.size();  // SOF
  288|  5.01k|  num_bytes += 4;  // DHT (w/o actual Huffman code data)
  289|  5.01k|  num_bytes += 8 + 2 * jpg.components.size();  // SOS
  290|  5.01k|  num_bytes += 2;  // EOI
  291|  5.01k|  num_bytes += jpg.tail_data.size();
  292|  5.01k|  return num_bytes;
  293|  5.01k|}
_ZN7guetzli17ClusterHistogramsEPNS_13JpegHistogramEPmPiPh:
  296|   652k|                         int* histo_indexes, uint8_t* depth) {
  297|   652k|  memset(depth, 0, *num * JpegHistogram::kSize);
  298|   652k|  size_t costs[kMaxComponents];
  299|  2.44M|  for (size_t i = 0; i < *num; ++i) {
  ------------------
  |  Branch (299:22): [True: 1.79M, False: 652k]
  ------------------
  300|  1.79M|    histo_indexes[i] = i;
  301|  1.79M|    std::vector<HuffmanTree> tree(2 * JpegHistogram::kSize + 1);
  302|  1.79M|    CreateHuffmanTree(histo[i].counts, JpegHistogram::kSize,
  303|  1.79M|                      kJpegHuffmanMaxBitLength, &tree[0],
  304|  1.79M|                      &depth[i * JpegHistogram::kSize]);
  305|  1.79M|    costs[i] = (HistogramHeaderCost(histo[i]) +
  306|  1.79M|                HistogramEntropyCost(histo[i],
  307|  1.79M|                                     &depth[i * JpegHistogram::kSize]));
  308|  1.79M|  }
  309|   652k|  const size_t orig_num = *num;
  310|  1.63M|  while (*num > 1) {
  ------------------
  |  Branch (310:10): [True: 1.12M, False: 504k]
  ------------------
  311|  1.12M|    size_t last = *num - 1;
  312|  1.12M|    size_t second_last = *num - 2;
  313|  1.12M|    JpegHistogram combined(histo[last]);
  314|  1.12M|    combined.AddHistogram(histo[second_last]);
  315|  1.12M|    std::vector<HuffmanTree> tree(2 * JpegHistogram::kSize + 1);
  316|  1.12M|    uint8_t depth_combined[JpegHistogram::kSize] = { 0 };
  317|  1.12M|    CreateHuffmanTree(combined.counts, JpegHistogram::kSize,
  318|  1.12M|                      kJpegHuffmanMaxBitLength, &tree[0], depth_combined);
  319|  1.12M|    size_t cost_combined = (HistogramHeaderCost(combined) +
  320|  1.12M|                            HistogramEntropyCost(combined, depth_combined));
  321|  1.12M|    if (cost_combined < costs[last] + costs[second_last]) {
  ------------------
  |  Branch (321:9): [True: 981k, False: 148k]
  ------------------
  322|   981k|      histo[second_last] = combined;
  323|   981k|      histo[last] = JpegHistogram();
  324|   981k|      costs[second_last] = cost_combined;
  325|   981k|      memcpy(&depth[second_last * JpegHistogram::kSize], depth_combined,
  326|   981k|             sizeof(depth_combined));
  327|  3.92M|      for (size_t i = 0; i < orig_num; ++i) {
  ------------------
  |  Branch (327:26): [True: 2.94M, False: 981k]
  ------------------
  328|  2.94M|        if (histo_indexes[i] == last) {
  ------------------
  |  Branch (328:13): [True: 1.40M, False: 1.53M]
  ------------------
  329|  1.40M|          histo_indexes[i] = second_last;
  330|  1.40M|        }
  331|  2.94M|      }
  332|   981k|      --(*num);
  333|   981k|    } else {
  334|   148k|      break;
  335|   148k|    }
  336|  1.12M|  }
  337|   652k|  size_t total_cost = 0;
  338|  1.46M|  for (size_t i = 0; i < *num; ++i) {
  ------------------
  |  Branch (338:22): [True: 813k, False: 652k]
  ------------------
  339|   813k|    total_cost += costs[i];
  340|   813k|  }
  341|   652k|  return (total_cost + 7) / 8;
  342|   652k|}
_ZN7guetzli9WriteJpegERKNS_8JPEGDataEbNS_10JPEGOutputE:
  540|   163k|bool WriteJpeg(const JPEGData& jpg, bool strip_metadata, JPEGOutput out) {
  541|   163k|  static const uint8_t kSOIMarker[2] = { 0xff, 0xd8 };
  542|   163k|  static const uint8_t kEOIMarker[2] = { 0xff, 0xd9 };
  543|   163k|  std::vector<HuffmanCodeTable> dc_codes;
  544|   163k|  std::vector<HuffmanCodeTable> ac_codes;
  545|   163k|  return (JPEGWrite(out, kSOIMarker, sizeof(kSOIMarker)) &&
  ------------------
  |  Branch (545:11): [True: 163k, False: 0]
  ------------------
  546|   163k|          EncodeMetadata(jpg, strip_metadata, out) &&
  ------------------
  |  Branch (546:11): [True: 163k, False: 0]
  ------------------
  547|   163k|          EncodeDQT(jpg.quant, out) &&
  ------------------
  |  Branch (547:11): [True: 163k, False: 0]
  ------------------
  548|   163k|          EncodeSOF(jpg, out) &&
  ------------------
  |  Branch (548:11): [True: 163k, False: 0]
  ------------------
  549|   163k|          BuildAndEncodeHuffmanCodes(jpg, out, &dc_codes, &ac_codes) &&
  ------------------
  |  Branch (549:11): [True: 163k, False: 0]
  ------------------
  550|   163k|          EncodeScan(jpg, dc_codes, ac_codes, out) &&
  ------------------
  |  Branch (550:11): [True: 163k, False: 0]
  ------------------
  551|   163k|          JPEGWrite(out, kEOIMarker, sizeof(kEOIMarker)) &&
  ------------------
  |  Branch (551:11): [True: 163k, False: 0]
  ------------------
  552|   163k|          (strip_metadata || JPEGWrite(out, jpg.tail_data)));
  ------------------
  |  Branch (552:12): [True: 163k, False: 0]
  |  Branch (552:30): [True: 0, False: 0]
  ------------------
  553|   163k|}
jpeg_data_writer.cc:_ZN7guetzli12_GLOBAL__N_19JPEGWriteENS_10JPEGOutputEPKhm:
   34|  1.14M|inline bool JPEGWrite(JPEGOutput out, const uint8_t* buf, size_t len) {
   35|  1.14M|  static const size_t kBlockSize = 1u << 30;
   36|  1.14M|  size_t pos = 0;
   37|  1.14M|  while (len - pos > kBlockSize) {
  ------------------
  |  Branch (37:10): [True: 0, False: 1.14M]
  ------------------
   38|      0|    if (!out.Write(buf + pos, kBlockSize)) {
  ------------------
  |  Branch (38:9): [True: 0, False: 0]
  ------------------
   39|      0|      return false;
   40|      0|    }
   41|      0|    pos += kBlockSize;
   42|      0|  }
   43|  1.14M|  return out.Write(buf + pos, len - pos);
   44|  1.14M|}
jpeg_data_writer.cc:_ZN7guetzli12_GLOBAL__N_114EncodeMetadataERKNS_8JPEGDataEbNS_10JPEGOutputE:
   52|   163k|bool EncodeMetadata(const JPEGData& jpg, bool strip_metadata, JPEGOutput out) {
   53|   163k|  if (strip_metadata) {
  ------------------
  |  Branch (53:7): [True: 163k, False: 0]
  ------------------
   54|   163k|    const uint8_t kApp0Data[] = {
   55|   163k|      0xff, 0xe0, 0x00, 0x10,        // APP0
   56|   163k|      0x4a, 0x46, 0x49, 0x46, 0x00,  // 'JFIF'
   57|   163k|      0x01, 0x01,                    // v1.01
   58|   163k|      0x00, 0x00, 0x01, 0x00, 0x01,  // aspect ratio = 1:1
   59|   163k|      0x00, 0x00                     // thumbnail width/height
   60|   163k|    };
   61|   163k|    return JPEGWrite(out, kApp0Data, sizeof(kApp0Data));
   62|   163k|  }
   63|      0|  bool ok = true;
   64|      0|  for (size_t i = 0; i < jpg.app_data.size(); ++i) {
  ------------------
  |  Branch (64:22): [True: 0, False: 0]
  ------------------
   65|      0|    uint8_t data[1] = { 0xff };
   66|      0|    ok = ok && JPEGWrite(out, data, sizeof(data));
  ------------------
  |  Branch (66:10): [True: 0, False: 0]
  |  Branch (66:16): [True: 0, False: 0]
  ------------------
   67|      0|    ok = ok && JPEGWrite(out, jpg.app_data[i]);
  ------------------
  |  Branch (67:10): [True: 0, False: 0]
  |  Branch (67:16): [True: 0, False: 0]
  ------------------
   68|      0|  }
   69|      0|  for (size_t i = 0; i < jpg.com_data.size(); ++i) {
  ------------------
  |  Branch (69:22): [True: 0, False: 0]
  ------------------
   70|      0|    uint8_t data[2] = { 0xff, 0xfe };
   71|      0|    ok = ok && JPEGWrite(out, data, sizeof(data));
  ------------------
  |  Branch (71:10): [True: 0, False: 0]
  |  Branch (71:16): [True: 0, False: 0]
  ------------------
   72|      0|    ok = ok && JPEGWrite(out, jpg.com_data[i]);
  ------------------
  |  Branch (72:10): [True: 0, False: 0]
  |  Branch (72:16): [True: 0, False: 0]
  ------------------
   73|      0|  }
   74|      0|  return ok;
   75|   163k|}
jpeg_data_writer.cc:_ZN7guetzli12_GLOBAL__N_19EncodeDQTERKNSt3__16vectorINS_14JPEGQuantTableENS1_9allocatorIS3_EEEENS_10JPEGOutputE:
   77|   163k|bool EncodeDQT(const std::vector<JPEGQuantTable>& quant, JPEGOutput out) {
   78|   163k|  int marker_len = 2;
   79|   360k|  for (size_t i = 0; i < quant.size(); ++i) {
  ------------------
  |  Branch (79:22): [True: 196k, False: 163k]
  ------------------
   80|   196k|    marker_len += 1 + (quant[i].precision ? 2 : 1) * kDCTBlockSize;
  ------------------
  |  Branch (80:24): [True: 83, False: 196k]
  ------------------
   81|   196k|  }
   82|   163k|  std::vector<uint8_t> data(marker_len + 2);
   83|   163k|  size_t pos = 0;
   84|   163k|  data[pos++] = 0xff;
   85|   163k|  data[pos++] = 0xdb;
   86|   163k|  data[pos++] = marker_len >> 8;
   87|   163k|  data[pos++] = marker_len & 0xff;
   88|   360k|  for (size_t i = 0; i < quant.size(); ++i) {
  ------------------
  |  Branch (88:22): [True: 196k, False: 163k]
  ------------------
   89|   196k|    const JPEGQuantTable& table = quant[i];
   90|   196k|    data[pos++] = (table.precision << 4) + table.index;
   91|  12.7M|    for (int k = 0; k < kDCTBlockSize; ++k) {
  ------------------
  |  Branch (91:21): [True: 12.5M, False: 196k]
  ------------------
   92|  12.5M|      int val = table.values[kJPEGNaturalOrder[k]];
   93|  12.5M|      if (table.precision) {
  ------------------
  |  Branch (93:11): [True: 5.31k, False: 12.5M]
  ------------------
   94|  5.31k|        data[pos++] = val >> 8;
   95|  5.31k|      }
   96|  12.5M|      data[pos++] = val & 0xff;
   97|  12.5M|    }
   98|   196k|  }
   99|   163k|  return JPEGWrite(out, &data[0], pos);
  100|   163k|}
jpeg_data_writer.cc:_ZN7guetzli12_GLOBAL__N_19EncodeSOFERKNS_8JPEGDataENS_10JPEGOutputE:
  102|   163k|bool EncodeSOF(const JPEGData& jpg, JPEGOutput out) {
  103|   163k|  const size_t ncomps = jpg.components.size();
  104|   163k|  const size_t marker_len = 8 + 3 * ncomps;
  105|   163k|  std::vector<uint8_t> data(marker_len + 2);
  106|   163k|  size_t pos = 0;
  107|   163k|  data[pos++] = 0xff;
  108|   163k|  data[pos++] = 0xc1;
  109|   163k|  data[pos++] = static_cast<uint8_t>(marker_len >> 8);
  110|   163k|  data[pos++] = marker_len & 0xff;
  111|   163k|  data[pos++] = kJpegPrecision;
  112|   163k|  data[pos++] = jpg.height >> 8;
  113|   163k|  data[pos++] = jpg.height & 0xff;
  114|   163k|  data[pos++] = jpg.width >> 8;
  115|   163k|  data[pos++] = jpg.width & 0xff;
  116|   163k|  data[pos++] = static_cast<uint8_t>(ncomps);
  117|   600k|  for (size_t i = 0; i < ncomps; ++i) {
  ------------------
  |  Branch (117:22): [True: 436k, False: 163k]
  ------------------
  118|   436k|    data[pos++] = jpg.components[i].id;
  119|   436k|    data[pos++] = ((jpg.components[i].h_samp_factor << 4) |
  120|   436k|                      (jpg.components[i].v_samp_factor));
  121|   436k|    const size_t quant_idx = jpg.components[i].quant_idx;
  122|   436k|    if (quant_idx >= jpg.quant.size()) {
  ------------------
  |  Branch (122:9): [True: 0, False: 436k]
  ------------------
  123|      0|      return false;
  124|      0|    }
  125|   436k|    data[pos++] = jpg.quant[quant_idx].index;
  126|   436k|  }
  127|   163k|  return JPEGWrite(out, &data[0], pos);
  128|   163k|}
jpeg_data_writer.cc:_ZN7guetzli12_GLOBAL__N_126BuildAndEncodeHuffmanCodesERKNS_8JPEGDataENS_10JPEGOutputEPNSt3__16vectorINS_16HuffmanCodeTableENS5_9allocatorIS7_EEEESB_:
  363|   163k|                                std::vector<HuffmanCodeTable>* ac_huff_tables) {
  364|   163k|  const int ncomps = jpg.components.size();
  365|   163k|  dc_huff_tables->resize(ncomps);
  366|   163k|  ac_huff_tables->resize(ncomps);
  367|       |
  368|       |  // Build separate DC histograms for each component.
  369|   163k|  std::vector<JpegHistogram> histograms(ncomps);
  370|   163k|  BuildDCHistograms(jpg, &histograms[0]);
  371|       |
  372|       |  // Cluster DC histograms.
  373|   163k|  size_t num_dc_histo = ncomps;
  374|   163k|  int dc_histo_indexes[kMaxComponents];
  375|   163k|  std::vector<uint8_t> depths(ncomps * JpegHistogram::kSize);
  376|   163k|  ClusterHistograms(&histograms[0], &num_dc_histo, dc_histo_indexes,
  377|   163k|                    &depths[0]);
  378|       |
  379|       |  // Build separate AC histograms for each component.
  380|   163k|  histograms.resize(num_dc_histo + ncomps);
  381|   163k|  depths.resize((num_dc_histo + ncomps) * JpegHistogram::kSize);
  382|   163k|  BuildACHistograms(jpg, &histograms[num_dc_histo]);
  383|       |
  384|       |  // Cluster AC histograms.
  385|   163k|  size_t num_ac_histo = ncomps;
  386|   163k|  int ac_histo_indexes[kMaxComponents];
  387|   163k|  ClusterHistograms(&histograms[num_dc_histo], &num_ac_histo, ac_histo_indexes,
  388|   163k|                    &depths[num_dc_histo * JpegHistogram::kSize]);
  389|       |
  390|       |  // Compute DHT and SOS marker data sizes and start emitting DHT marker.
  391|   163k|  int num_histo = num_dc_histo + num_ac_histo;
  392|   163k|  histograms.resize(num_histo);
  393|   163k|  int total_count = 0;
  394|   531k|  for (size_t i = 0; i < histograms.size(); ++i) {
  ------------------
  |  Branch (394:22): [True: 368k, False: 163k]
  ------------------
  395|   368k|    total_count += histograms[i].NumSymbols();
  396|   368k|  }
  397|   163k|  const size_t dht_marker_len =
  398|   163k|      2 + num_histo * (kJpegHuffmanMaxBitLength + 1) + total_count;
  399|   163k|  const size_t sos_marker_len = 6 + 2 * ncomps;
  400|   163k|  std::vector<uint8_t> data(dht_marker_len + sos_marker_len + 4);
  401|   163k|  size_t pos = 0;
  402|   163k|  data[pos++] = 0xff;
  403|   163k|  data[pos++] = 0xc4;
  404|   163k|  data[pos++] = static_cast<uint8_t>(dht_marker_len >> 8);
  405|   163k|  data[pos++] = dht_marker_len & 0xff;
  406|       |
  407|       |  // Compute Huffman codes for each histograms.
  408|   531k|  for (int i = 0; i < num_histo; ++i) {
  ------------------
  |  Branch (408:19): [True: 368k, False: 163k]
  ------------------
  409|   368k|    const bool is_dc = static_cast<size_t>(i) < num_dc_histo;
  410|   368k|    const int idx = is_dc ? i : i - num_dc_histo;
  ------------------
  |  Branch (410:21): [True: 164k, False: 204k]
  ------------------
  411|   368k|    int counts[kJpegHuffmanMaxBitLength + 1] = { 0 };
  412|   368k|    int values[JpegHistogram::kSize] = { 0 };
  413|   368k|    BuildHuffmanCode(&depths[i * JpegHistogram::kSize], counts, values);
  414|   368k|    HuffmanCodeTable table;
  415|  94.6M|    for (int j = 0; j < 256; ++j) table.depth[j] = 255;
  ------------------
  |  Branch (415:21): [True: 94.2M, False: 368k]
  ------------------
  416|   368k|    BuildHuffmanCodeTable(counts, values, &table);
  417|  1.36M|    for (int c = 0; c < ncomps; ++c) {
  ------------------
  |  Branch (417:21): [True: 995k, False: 368k]
  ------------------
  418|   995k|      if (is_dc) {
  ------------------
  |  Branch (418:11): [True: 437k, False: 557k]
  ------------------
  419|   437k|        if (dc_histo_indexes[c] == idx) (*dc_huff_tables)[c] = table;
  ------------------
  |  Branch (419:13): [True: 436k, False: 1.56k]
  ------------------
  420|   557k|      } else {
  421|   557k|        if (ac_histo_indexes[c] == idx) (*ac_huff_tables)[c] = table;
  ------------------
  |  Branch (421:13): [True: 436k, False: 121k]
  ------------------
  422|   557k|      }
  423|   995k|    }
  424|   368k|    int max_length = kJpegHuffmanMaxBitLength;
  425|  4.26M|    while (max_length > 0 && counts[max_length] == 0) --max_length;
  ------------------
  |  Branch (425:12): [True: 4.26M, False: 0]
  |  Branch (425:30): [True: 3.89M, False: 368k]
  ------------------
  426|   368k|    --counts[max_length];
  427|   368k|    int total_count = 0;
  428|  2.73M|    for (int j = 0; j <= max_length; ++j) total_count += counts[j];
  ------------------
  |  Branch (428:21): [True: 2.36M, False: 368k]
  ------------------
  429|   368k|    data[pos++] = is_dc ? i : static_cast<uint8_t>(i - num_dc_histo + 0x10);
  ------------------
  |  Branch (429:19): [True: 164k, False: 204k]
  ------------------
  430|  6.26M|    for (size_t j = 1; j <= kJpegHuffmanMaxBitLength; ++j) {
  ------------------
  |  Branch (430:24): [True: 5.89M, False: 368k]
  ------------------
  431|  5.89M|      data[pos++] = counts[j];
  432|  5.89M|    }
  433|  4.58M|    for (int j = 0; j < total_count; ++j) {
  ------------------
  |  Branch (433:21): [True: 4.21M, False: 368k]
  ------------------
  434|  4.21M|      data[pos++] = values[j];
  435|  4.21M|    }
  436|   368k|  }
  437|       |
  438|       |  // Emit SOS marker data.
  439|   163k|  data[pos++] = 0xff;
  440|   163k|  data[pos++] = 0xda;
  441|   163k|  data[pos++] = static_cast<uint8_t>(sos_marker_len >> 8);
  442|   163k|  data[pos++] = sos_marker_len & 0xff;
  443|   163k|  data[pos++] = ncomps;
  444|   600k|  for (int i = 0; i < ncomps; ++i) {
  ------------------
  |  Branch (444:19): [True: 436k, False: 163k]
  ------------------
  445|   436k|    data[pos++] = jpg.components[i].id;
  446|   436k|    data[pos++] = (dc_histo_indexes[i] << 4) | ac_histo_indexes[i];
  447|   436k|  }
  448|   163k|  data[pos++] = 0;
  449|   163k|  data[pos++] = 63;
  450|   163k|  data[pos++] = 0;
  451|   163k|  assert(pos == data.size());
  452|      0|  return JPEGWrite(out, &data[0], data.size());
  453|   163k|}
jpeg_data_writer.cc:_ZN7guetzli12_GLOBAL__N_116BuildHuffmanCodeEPhPiS2_:
  131|   368k|void BuildHuffmanCode(uint8_t* depth, int* counts, int* values) {
  132|  95.0M|  for (int i = 0; i < JpegHistogram::kSize; ++i) {
  ------------------
  |  Branch (132:19): [True: 94.6M, False: 368k]
  ------------------
  133|  94.6M|    if (depth[i] > 0) {
  ------------------
  |  Branch (133:9): [True: 4.58M, False: 90.0M]
  ------------------
  134|  4.58M|      ++counts[depth[i]];
  135|  4.58M|    }
  136|  94.6M|  }
  137|   368k|  int offset[kJpegHuffmanMaxBitLength + 1] = { 0 };
  138|  6.26M|  for (int i = 1; i <= kJpegHuffmanMaxBitLength; ++i) {
  ------------------
  |  Branch (138:19): [True: 5.89M, False: 368k]
  ------------------
  139|  5.89M|    offset[i] = offset[i - 1] + counts[i - 1];
  140|  5.89M|  }
  141|  95.0M|  for (int i = 0; i < JpegHistogram::kSize; ++i) {
  ------------------
  |  Branch (141:19): [True: 94.6M, False: 368k]
  ------------------
  142|  94.6M|    if (depth[i] > 0) {
  ------------------
  |  Branch (142:9): [True: 4.58M, False: 90.0M]
  ------------------
  143|  4.58M|      values[offset[depth[i]]++] = i;
  144|  4.58M|    }
  145|  94.6M|  }
  146|   368k|}
jpeg_data_writer.cc:_ZN7guetzli12_GLOBAL__N_121BuildHuffmanCodeTableEPKiS2_PNS_16HuffmanCodeTableE:
  149|   368k|                           HuffmanCodeTable* table) {
  150|   368k|  int huffcode[256];
  151|   368k|  int huffsize[256];
  152|   368k|  int p = 0;
  153|  6.26M|  for (int l = 1; l <= kJpegHuffmanMaxBitLength; ++l) {
  ------------------
  |  Branch (153:19): [True: 5.89M, False: 368k]
  ------------------
  154|  5.89M|    int i = counts[l];
  155|  10.4M|    while (i--) huffsize[p++] = l;
  ------------------
  |  Branch (155:12): [True: 4.58M, False: 5.89M]
  ------------------
  156|  5.89M|  }
  157|       |
  158|   368k|  if (p == 0)
  ------------------
  |  Branch (158:7): [True: 0, False: 368k]
  ------------------
  159|      0|    return;
  160|       |
  161|   368k|  huffsize[p - 1] = 0;
  162|   368k|  int lastp = p - 1;
  163|       |
  164|   368k|  int code = 0;
  165|   368k|  int si = huffsize[0];
  166|   368k|  p = 0;
  167|  2.30M|  while (huffsize[p]) {
  ------------------
  |  Branch (167:10): [True: 1.93M, False: 368k]
  ------------------
  168|  6.15M|    while ((huffsize[p]) == si) {
  ------------------
  |  Branch (168:12): [True: 4.21M, False: 1.93M]
  ------------------
  169|  4.21M|      huffcode[p++] = code;
  170|  4.21M|      code++;
  171|  4.21M|    }
  172|  1.93M|    code <<= 1;
  173|  1.93M|    si++;
  174|  1.93M|  }
  175|  4.58M|  for (p = 0; p < lastp; p++) {
  ------------------
  |  Branch (175:15): [True: 4.21M, False: 368k]
  ------------------
  176|  4.21M|    int i = values[p];
  177|  4.21M|    table->depth[i] = huffsize[p];
  178|  4.21M|    table->code[i] = huffcode[p];
  179|  4.21M|  }
  180|   368k|}
jpeg_data_writer.cc:_ZN7guetzli12_GLOBAL__N_110EncodeScanERKNS_8JPEGDataERKNSt3__16vectorINS_16HuffmanCodeTableENS4_9allocatorIS6_EEEESB_NS_10JPEGOutputE:
  505|   163k|                JPEGOutput out) {
  506|   163k|  coeff_t last_dc_coeff[kMaxComponents] = { 0 };
  507|   163k|  BitWriter bw(1 << 17);
  508|   948k|  for (int mcu_y = 0; mcu_y < jpg.MCU_rows; ++mcu_y) {
  ------------------
  |  Branch (508:23): [True: 785k, False: 163k]
  ------------------
  509|  5.46M|    for (int mcu_x = 0; mcu_x < jpg.MCU_cols; ++mcu_x) {
  ------------------
  |  Branch (509:25): [True: 4.67M, False: 785k]
  ------------------
  510|       |      // Encode one MCU
  511|  16.6M|      for (size_t i = 0; i < jpg.components.size(); ++i) {
  ------------------
  |  Branch (511:26): [True: 11.9M, False: 4.67M]
  ------------------
  512|  11.9M|        const JPEGComponent& c = jpg.components[i];
  513|  11.9M|        int nblocks_y = c.v_samp_factor;
  514|  11.9M|        int nblocks_x = c.h_samp_factor;
  515|  25.7M|        for (int iy = 0; iy < nblocks_y; ++iy) {
  ------------------
  |  Branch (515:26): [True: 13.7M, False: 11.9M]
  ------------------
  516|  31.0M|          for (int ix = 0; ix < nblocks_x; ++ix) {
  ------------------
  |  Branch (516:28): [True: 17.2M, False: 13.7M]
  ------------------
  517|  17.2M|            int block_y = mcu_y * nblocks_y + iy;
  518|  17.2M|            int block_x = mcu_x * nblocks_x + ix;
  519|  17.2M|            int block_idx = block_y * c.width_in_blocks + block_x;
  520|  17.2M|            const coeff_t* coeffs = &c.coeffs[block_idx << 6];
  521|  17.2M|            EncodeDCTBlockSequential(coeffs, dc_huff_table[i], ac_huff_table[i],
  522|  17.2M|                                     &last_dc_coeff[i], &bw);
  523|  17.2M|          }
  524|  13.7M|        }
  525|  11.9M|      }
  526|  4.67M|      if (bw.pos > (1 << 16)) {
  ------------------
  |  Branch (526:11): [True: 0, False: 4.67M]
  ------------------
  527|      0|        if (!JPEGWrite(out, bw.data.get(), bw.pos)) {
  ------------------
  |  Branch (527:13): [True: 0, False: 0]
  ------------------
  528|      0|          return false;
  529|      0|        }
  530|      0|        bw.pos = 0;
  531|      0|      }
  532|  4.67M|    }
  533|   785k|  }
  534|   163k|  bw.JumpToByteBoundary();
  535|   163k|  return !bw.overflow && JPEGWrite(out, bw.data.get(), bw.pos);
  ------------------
  |  Branch (535:10): [True: 163k, False: 0]
  |  Branch (535:26): [True: 163k, False: 0]
  ------------------
  536|   163k|}
jpeg_data_writer.cc:_ZN7guetzli12_GLOBAL__N_124EncodeDCTBlockSequentialEPKsRKNS_16HuffmanCodeTableES5_PsPNS_9BitWriterE:
  459|  17.2M|                              BitWriter* bw) {
  460|  17.2M|  coeff_t temp2;
  461|  17.2M|  coeff_t temp;
  462|  17.2M|  temp2 = coeffs[0];
  463|  17.2M|  temp = temp2 - *last_dc_coeff;
  464|  17.2M|  *last_dc_coeff = temp2;
  465|  17.2M|  temp2 = temp;
  466|  17.2M|  if (temp < 0) {
  ------------------
  |  Branch (466:7): [True: 1.75M, False: 15.5M]
  ------------------
  467|  1.75M|    temp = -temp;
  468|  1.75M|    temp2--;
  469|  1.75M|  }
  470|  17.2M|  int nbits = Log2Floor(temp) + 1;
  471|  17.2M|  bw->WriteBits(dc_huff.depth[nbits], dc_huff.code[nbits]);
  472|  17.2M|  if (nbits > 0) {
  ------------------
  |  Branch (472:7): [True: 2.95M, False: 14.3M]
  ------------------
  473|  2.95M|    bw->WriteBits(nbits, temp2 & ((1 << nbits) - 1));
  474|  2.95M|  }
  475|  17.2M|  int r = 0;
  476|  1.10G|  for (int k = 1; k < 64; ++k) {
  ------------------
  |  Branch (476:19): [True: 1.08G, False: 17.2M]
  ------------------
  477|  1.08G|    if ((temp = coeffs[kJPEGNaturalOrder[k]]) == 0) {
  ------------------
  |  Branch (477:9): [True: 931M, False: 155M]
  ------------------
  478|   931M|      r++;
  479|   931M|      continue;
  480|   931M|    }
  481|   155M|    if (temp < 0) {
  ------------------
  |  Branch (481:9): [True: 121M, False: 34.3M]
  ------------------
  482|   121M|      temp = -temp;
  483|   121M|      temp2 = ~temp;
  484|   121M|    } else {
  485|  34.3M|      temp2 = temp;
  486|  34.3M|    }
  487|   159M|    while (r > 15) {
  ------------------
  |  Branch (487:12): [True: 3.55M, False: 155M]
  ------------------
  488|  3.55M|      bw->WriteBits(ac_huff.depth[0xf0], ac_huff.code[0xf0]);
  489|  3.55M|      r -= 16;
  490|  3.55M|    }
  491|   155M|    int nbits = Log2FloorNonZero(temp) + 1;
  492|   155M|    int symbol = (r << 4) + nbits;
  493|   155M|    bw->WriteBits(ac_huff.depth[symbol], ac_huff.code[symbol]);
  494|   155M|    bw->WriteBits(nbits, temp2 & ((1 << nbits) - 1));
  495|   155M|    r = 0;
  496|   155M|  }
  497|  17.2M|  if (r > 0) {
  ------------------
  |  Branch (497:7): [True: 15.9M, False: 1.33M]
  ------------------
  498|  15.9M|    bw->WriteBits(ac_huff.depth[0], ac_huff.code[0]);
  499|  15.9M|  }
  500|  17.2M|}

_ZN7guetzli10JPEGOutputC2EPFiPvPKhmES1_:
   36|   163k|  JPEGOutput(JPEGOutputHook cb, void* data) : cb(cb), data(data) {}
_ZN7guetzli13JpegHistogramC2Ev:
   59|  1.60M|  JpegHistogram() { Clear(); }
_ZN7guetzli13JpegHistogram5ClearEv:
   60|  1.60M|  void Clear() {
   61|  1.60M|    memset(counts, 0, sizeof(counts));
   62|  1.60M|    counts[kSize - 1] = 1;
   63|  1.60M|  }
_ZN7guetzli13JpegHistogram3AddEii:
   67|   141M|  void Add(int symbol, int weight) {
   68|   141M|    counts[symbol] += 2 * weight;
   69|   141M|  }
_ZNK7guetzli10JPEGOutput5WriteEPKhm:
   37|  1.14M|  bool Write(const uint8_t* buf, size_t len) const {
   38|  1.14M|    return (len == 0) || (cb(data, buf, len) == len);
  ------------------
  |  Branch (38:12): [True: 0, False: 1.14M]
  |  Branch (38:26): [True: 1.14M, False: 0]
  ------------------
   39|  1.14M|  }
_ZN7guetzli13JpegHistogram3AddEi:
   64|   196M|  void Add(int symbol) {
   65|   196M|    counts[symbol] += 2;
   66|   196M|  }
_ZN7guetzli13JpegHistogram12AddHistogramERKS0_:
   70|  1.12M|  void AddHistogram(const JpegHistogram& other) {
   71|   290M|    for (int i = 0; i + 1 < kSize; ++i) {
  ------------------
  |  Branch (71:21): [True: 289M, False: 1.12M]
  ------------------
   72|   289M|      counts[i] += other.counts[i];
   73|   289M|    }
   74|  1.12M|    counts[kSize - 1] = 1;
   75|  1.12M|  }
_ZNK7guetzli13JpegHistogram10NumSymbolsEv:
   76|   368k|  int NumSymbols() const {
   77|   368k|    int n = 0;
   78|  94.6M|    for (int i = 0; i + 1 < kSize; ++i) {
  ------------------
  |  Branch (78:21): [True: 94.2M, False: 368k]
  ------------------
   79|  94.2M|      n += (counts[i] > 0 ? 1 : 0);
  ------------------
  |  Branch (79:13): [True: 4.21M, False: 90.0M]
  ------------------
   80|  94.2M|    }
   81|   368k|    return n;
   82|   368k|  }

_ZN7guetzli21BuildJpegHuffmanTableEPKiS1_PNS_17HuffmanTableEntryE:
   43|   256k|                          HuffmanTableEntry* lut) {
   44|   256k|  HuffmanTableEntry code;    // current table entry
   45|   256k|  HuffmanTableEntry* table;  // next available space in table
   46|   256k|  int len;         // current code length
   47|   256k|  int idx;         // symbol index
   48|   256k|  int key;         // prefix code
   49|   256k|  int reps;        // number of replicate key values in current table
   50|   256k|  int low;         // low bits for current root entry
   51|   256k|  int table_bits;  // key length of current table
   52|   256k|  int table_size;  // size of current table
   53|   256k|  int total_size;  // sum of root table size and 2nd level table sizes
   54|       |
   55|       |  // Make a local copy of the input bit length histogram.
   56|   256k|  int count[kJpegHuffmanMaxBitLength + 1] = { 0 };
   57|   256k|  int total_count = 0;
   58|  4.35M|  for (len = 1; len <= kJpegHuffmanMaxBitLength; ++len) {
  ------------------
  |  Branch (58:17): [True: 4.09M, False: 256k]
  ------------------
   59|  4.09M|    count[len] = count_in[len];
   60|  4.09M|    total_count += count[len];
   61|  4.09M|  }
   62|       |
   63|   256k|  table = lut;
   64|   256k|  table_bits = kJpegHuffmanRootTableBits;
   65|   256k|  table_size = 1 << table_bits;
   66|   256k|  total_size = table_size;
   67|       |
   68|       |  // Special case code with only one value.
   69|   256k|  if (total_count == 1) {
  ------------------
  |  Branch (69:7): [True: 208k, False: 47.2k]
  ------------------
   70|   208k|    code.bits = 0;
   71|   208k|    code.value = symbols[0];
   72|  53.6M|    for (key = 0; key < total_size; ++key) {
  ------------------
  |  Branch (72:19): [True: 53.4M, False: 208k]
  ------------------
   73|  53.4M|      table[key] = code;
   74|  53.4M|    }
   75|   208k|    return total_size;
   76|   208k|  }
   77|       |
   78|       |  // Fill in root table.
   79|  47.2k|  key = 0;
   80|  47.2k|  idx = 0;
   81|   425k|  for (len = 1; len <= kJpegHuffmanRootTableBits; ++len) {
  ------------------
  |  Branch (81:17): [True: 378k, False: 47.2k]
  ------------------
   82|   503k|    for (; count[len] > 0; --count[len]) {
  ------------------
  |  Branch (82:12): [True: 125k, False: 378k]
  ------------------
   83|   125k|      code.bits = len;
   84|   125k|      code.value = symbols[idx++];
   85|   125k|      reps = 1 << (kJpegHuffmanRootTableBits - len);
   86|  4.15M|      while (reps--) {
  ------------------
  |  Branch (86:14): [True: 4.02M, False: 125k]
  ------------------
   87|  4.02M|        table[key++] = code;
   88|  4.02M|      }
   89|   125k|    }
   90|   378k|  }
   91|       |
   92|       |  // Fill in 2nd level tables and add pointers to root table.
   93|  47.2k|  table += table_size;
   94|  47.2k|  table_size = 0;
   95|  47.2k|  low = 0;
   96|  47.2k|  for (len = kJpegHuffmanRootTableBits + 1;
   97|   425k|       len <= kJpegHuffmanMaxBitLength; ++len) {
  ------------------
  |  Branch (97:8): [True: 378k, False: 47.2k]
  ------------------
   98|   542k|    for (; count[len] > 0; --count[len]) {
  ------------------
  |  Branch (98:12): [True: 164k, False: 378k]
  ------------------
   99|       |      // Start a new sub-table if the previous one is full.
  100|   164k|      if (low >= table_size) {
  ------------------
  |  Branch (100:11): [True: 30.2k, False: 134k]
  ------------------
  101|  30.2k|        table += table_size;
  102|  30.2k|        table_bits = NextTableBitSize(count, len);
  103|  30.2k|        table_size = 1 << table_bits;
  104|  30.2k|        total_size += table_size;
  105|  30.2k|        low = 0;
  106|  30.2k|        lut[key].bits = table_bits + kJpegHuffmanRootTableBits;
  107|  30.2k|        lut[key].value = (table - lut) - key;
  108|  30.2k|        ++key;
  109|  30.2k|      }
  110|   164k|      code.bits = len - kJpegHuffmanRootTableBits;
  111|   164k|      code.value = symbols[idx++];
  112|   164k|      reps = 1 << (table_bits - code.bits);
  113|  1.48M|      while (reps--) {
  ------------------
  |  Branch (113:14): [True: 1.32M, False: 164k]
  ------------------
  114|  1.32M|        table[low++] = code;
  115|  1.32M|      }
  116|   164k|    }
  117|   378k|  }
  118|       |
  119|  47.2k|  return total_size;
  120|   256k|}
jpeg_huffman_decode.cc:_ZN7guetzliL16NextTableBitSizeEPKii:
   31|  30.2k|static inline int NextTableBitSize(const int* count, int len) {
   32|  30.2k|  int left = 1 << (len - kJpegHuffmanRootTableBits);
   33|   112k|  while (len < kJpegHuffmanMaxBitLength) {
  ------------------
  |  Branch (33:10): [True: 90.7k, False: 21.4k]
  ------------------
   34|  90.7k|    left -= count[len];
   35|  90.7k|    if (left <= 0) break;
  ------------------
  |  Branch (35:9): [True: 8.84k, False: 81.8k]
  ------------------
   36|  81.8k|    ++len;
   37|  81.8k|    left <<= 1;
   38|  81.8k|  }
   39|  30.2k|  return len - kJpegHuffmanRootTableBits;
   40|  30.2k|}

_ZN7guetzli17HuffmanTableEntryC2Ev:
   36|  68.6M|  HuffmanTableEntry() : bits(0), value(0xffff) {}

_ZN7guetzli20OutputImageComponentC2Eii:
   36|  9.32k|    : width_(w), height_(h) {
   37|  9.32k|  Reset(1, 1);
   38|  9.32k|}
_ZN7guetzli20OutputImageComponent5ResetEii:
   40|   160k|void OutputImageComponent::Reset(int factor_x, int factor_y) {
   41|   160k|  factor_x_ = factor_x;
   42|   160k|  factor_y_ = factor_y;
   43|   160k|  width_in_blocks_ = (width_ + 8 * factor_x_ - 1) / (8 * factor_x_);
   44|   160k|  height_in_blocks_ = (height_ + 8 * factor_y_ - 1) / (8 * factor_y_);
   45|   160k|  num_blocks_ = width_in_blocks_ * height_in_blocks_;
   46|   160k|  coeffs_ = std::vector<coeff_t>(num_blocks_ * kDCTBlockSize);
   47|   160k|  pixels_ = std::vector<uint16_t>(width_ * height_, 128 << 4);
   48|  10.4M|  for (int i = 0; i < kDCTBlockSize; ++i) quant_[i] = 1;
  ------------------
  |  Branch (48:19): [True: 10.2M, False: 160k]
  ------------------
   49|   160k|}
_ZNK7guetzli20OutputImageComponent9IsAllZeroEv:
   51|   201k|bool OutputImageComponent::IsAllZero() const {
   52|   201k|  int numcoeffs = num_blocks_ * kDCTBlockSize;
   53|  66.7M|  for (int i = 0; i < numcoeffs; ++i) {
  ------------------
  |  Branch (53:19): [True: 66.6M, False: 62.4k]
  ------------------
   54|  66.6M|    if (coeffs_[i] != 0) return false;
  ------------------
  |  Branch (54:9): [True: 139k, False: 66.5M]
  ------------------
   55|  66.6M|  }
   56|  62.4k|  return true;
   57|   201k|}
_ZNK7guetzli20OutputImageComponent13GetCoeffBlockEiiPs:
   60|  6.74M|                                         coeff_t block[kDCTBlockSize]) const {
   61|  6.74M|  assert(block_x < width_in_blocks_);
   62|      0|  assert(block_y < height_in_blocks_);
   63|      0|  int offset = (block_y * width_in_blocks_ + block_x) * kDCTBlockSize;
   64|  6.74M|  memcpy(block, &coeffs_[offset], kDCTBlockSize * sizeof(coeffs_[0]));
   65|  6.74M|}
_ZNK7guetzli20OutputImageComponent8ToPixelsEiiiiPhi:
   68|  22.7M|                                    uint8_t* out, int stride) const {
   69|  22.7M|  assert(xmin >= 0);
   70|      0|  assert(ymin >= 0);
   71|      0|  assert(xmin < width_);
   72|      0|  assert(ymin < height_);
   73|      0|  const int yend1 = ymin + ysize;
   74|  22.7M|  const int yend0 = std::min(yend1, height_);
   75|  22.7M|  int y = ymin;
   76|   217M|  for (; y < yend0; ++y) {
  ------------------
  |  Branch (76:10): [True: 194M, False: 22.7M]
  ------------------
   77|   194M|    const int xend1 = xmin + xsize;
   78|   194M|    const int xend0 = std::min(xend1, width_);
   79|   194M|    int x = xmin;
   80|   194M|    int px = y * width_ + xmin;
   81|  3.00G|    for (; x < xend0; ++x, ++px, out += stride) {
  ------------------
  |  Branch (81:12): [True: 2.80G, False: 194M]
  ------------------
   82|  2.80G|      *out = static_cast<uint8_t>((pixels_[px] + 8 - (x & 1)) >> 4);
   83|  2.80G|    }
   84|   194M|    const int offset = -stride;
   85|   267M|    for (; x < xend1; ++x) {
  ------------------
  |  Branch (85:12): [True: 72.5M, False: 194M]
  ------------------
   86|  72.5M|      *out = out[offset];
   87|  72.5M|      out += stride;
   88|  72.5M|    }
   89|   194M|  }
   90|  30.6M|  for (; y < yend1; ++y) {
  ------------------
  |  Branch (90:10): [True: 7.83M, False: 22.7M]
  ------------------
   91|  7.83M|    const int offset = -stride * xsize;
   92|  70.4M|    for (int x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (92:21): [True: 62.6M, False: 7.83M]
  ------------------
   93|  62.6M|      *out = out[offset];
   94|  62.6M|      out += stride;
   95|  62.6M|    }
   96|  7.83M|  }
   97|  22.7M|}
_ZN7guetzli20OutputImageComponent13SetCoeffBlockEiiPKs:
  124|  20.4M|                                         const coeff_t block[kDCTBlockSize]) {
  125|  20.4M|  assert(block_x < width_in_blocks_);
  126|      0|  assert(block_y < height_in_blocks_);
  127|      0|  int offset = (block_y * width_in_blocks_ + block_x) * kDCTBlockSize;
  128|  20.4M|  memcpy(&coeffs_[offset], block, kDCTBlockSize * sizeof(coeffs_[0]));
  129|  20.4M|  uint8_t idct[kDCTBlockSize];
  130|  20.4M|  ComputeBlockIDCT(&coeffs_[offset], idct);
  131|  20.4M|  UpdatePixelsForBlock(block_x, block_y, idct);
  132|  20.4M|}
_ZN7guetzli20OutputImageComponent20UpdatePixelsForBlockEiiPKh:
  135|  20.4M|    int block_x, int block_y, const uint8_t idct[kDCTBlockSize]) {
  136|  20.4M|  if (factor_x_ == 1 && factor_y_ == 1) {
  ------------------
  |  Branch (136:7): [True: 17.0M, False: 3.38M]
  |  Branch (136:25): [True: 17.0M, False: 0]
  ------------------
  137|   153M|    for (int iy = 0; iy < 8; ++iy) {
  ------------------
  |  Branch (137:22): [True: 136M, False: 17.0M]
  ------------------
  138|  1.22G|      for (int ix = 0; ix < 8; ++ix) {
  ------------------
  |  Branch (138:24): [True: 1.09G, False: 136M]
  ------------------
  139|  1.09G|        int x = 8 * block_x + ix;
  140|  1.09G|        int y = 8 * block_y + iy;
  141|  1.09G|        if (x >= width_ || y >= height_) continue;
  ------------------
  |  Branch (141:13): [True: 61.6M, False: 1.03G]
  |  Branch (141:28): [True: 45.0M, False: 985M]
  ------------------
  142|   985M|        int p = y * width_ + x;
  143|   985M|        pixels_[p] = idct[8 * iy + ix] << 4;
  144|   985M|      }
  145|   136M|    }
  146|  17.0M|  } else if (factor_x_ == 2 && factor_y_ == 2) {
  ------------------
  |  Branch (146:14): [True: 3.38M, False: 0]
  |  Branch (146:32): [True: 3.38M, False: 0]
  ------------------
  147|       |    // Fill in the 10x10 pixel area in the subsampled image that will be the
  148|       |    // basis of the upsampling. This area is enough to hold the 3x3 kernel of
  149|       |    // the fancy upsampler around each pixel.
  150|  3.38M|    static const int kSubsampledEdgeSize = 10;
  151|  3.38M|    uint16_t subsampled[kSubsampledEdgeSize * kSubsampledEdgeSize];
  152|  37.1M|    for (int j = 0; j < kSubsampledEdgeSize; ++j) {
  ------------------
  |  Branch (152:21): [True: 33.8M, False: 3.38M]
  ------------------
  153|       |      // The order we fill in the rows is:
  154|       |      //   8 rows intersecting the block, row below, row above
  155|  33.8M|      const int y0 = block_y * 16 + (j < 9 ? j * 2 : -2);
  ------------------
  |  Branch (155:38): [True: 30.4M, False: 3.38M]
  ------------------
  156|   371M|      for (int i = 0; i < kSubsampledEdgeSize; ++i) {
  ------------------
  |  Branch (156:23): [True: 338M, False: 33.8M]
  ------------------
  157|       |        // The order we fill in each row is:
  158|       |        //   8 pixels within the block, left edge, right edge
  159|   338M|        const int ix = ((j < 9 ? (j + 1) * kSubsampledEdgeSize : 0) +
  ------------------
  |  Branch (159:26): [True: 304M, False: 33.8M]
  ------------------
  160|   338M|                        (i < 9 ? i + 1 : 0));
  ------------------
  |  Branch (160:26): [True: 304M, False: 33.8M]
  ------------------
  161|   338M|        const int x0 = block_x * 16 + (i < 9 ? i * 2 : -2);
  ------------------
  |  Branch (161:40): [True: 304M, False: 33.8M]
  ------------------
  162|   338M|        if (x0 < 0) {
  ------------------
  |  Branch (162:13): [True: 8.03M, False: 330M]
  ------------------
  163|  8.03M|          subsampled[ix] = subsampled[ix + 1];
  164|   330M|        } else if (y0 < 0) {
  ------------------
  |  Branch (164:20): [True: 9.79M, False: 320M]
  ------------------
  165|  9.79M|          subsampled[ix] = subsampled[ix + kSubsampledEdgeSize];
  166|   320M|        } else if (x0 >= width_) {
  ------------------
  |  Branch (166:20): [True: 37.5M, False: 282M]
  ------------------
  167|  37.5M|          subsampled[ix] = subsampled[ix - 1];
  168|   282M|        } else if (y0 >= height_) {
  ------------------
  |  Branch (168:20): [True: 40.5M, False: 242M]
  ------------------
  169|  40.5M|          subsampled[ix] = subsampled[ix - kSubsampledEdgeSize];
  170|   242M|        } else if (i < 8 && j < 8) {
  ------------------
  |  Branch (170:20): [True: 199M, False: 42.7M]
  |  Branch (170:29): [True: 164M, False: 34.8M]
  ------------------
  171|   164M|          subsampled[ix] = idct[j * 8 + i] << 4;
  172|   164M|        } else {
  173|       |          // Reconstruct the subsampled pixels around the edge of the current
  174|       |          // block by computing the inverse of the fancy upsampler.
  175|  77.5M|          const int y1 = std::max(y0 - 1, 0);
  176|  77.5M|          const int x1 = std::max(x0 - 1, 0);
  177|  77.5M|          subsampled[ix] = (pixels_[y0 * width_ + x0] * 9 +
  178|  77.5M|                            pixels_[y1 * width_ + x1] +
  179|  77.5M|                            pixels_[y0 * width_ + x1] * -3 +
  180|  77.5M|                            pixels_[y1 * width_ + x0] * -3) >> 2;
  181|  77.5M|        }
  182|   338M|      }
  183|  33.8M|    }
  184|       |
  185|       |    // Determine area to update.
  186|  3.38M|    int xmin = std::max(block_x * 16 - 1, 0);
  187|  3.38M|    int xmax = std::min(block_x * 16 + 16, width_ - 1);
  188|  3.38M|    int ymin = std::max(block_y * 16 - 1, 0);
  189|  3.38M|    int ymax = std::min(block_y * 16 + 16, height_ - 1);
  190|       |
  191|       |    // Apply the fancy upsampler on the subsampled block.
  192|  54.2M|    for (int y = ymin; y <= ymax; ++y) {
  ------------------
  |  Branch (192:24): [True: 50.8M, False: 3.38M]
  ------------------
  193|  50.8M|      const int y0 = ((y & ~1) / 2 - block_y * 8 + 1) * kSubsampledEdgeSize;
  194|  50.8M|      const int dy = ((y & 1) * 2 - 1) * kSubsampledEdgeSize;
  195|  50.8M|      uint16_t* rowptr = &pixels_[y * width_];
  196|   845M|      for (int x = xmin; x <= xmax; ++x) {
  ------------------
  |  Branch (196:26): [True: 794M, False: 50.8M]
  ------------------
  197|   794M|        const int x0 = (x & ~1) / 2 - block_x * 8 + 1;
  198|   794M|        const int dx = (x & 1) * 2 - 1;
  199|   794M|        const int ix = x0 + y0;
  200|   794M|        rowptr[x] = (subsampled[ix] * 9 + subsampled[ix + dy] * 3 +
  201|   794M|                     subsampled[ix + dx] * 3 + subsampled[ix + dx + dy]) >> 4;
  202|   794M|      }
  203|  50.8M|    }
  204|  3.38M|  } else {
  205|      0|    printf("Sampling ratio not supported: factor_x = %d factor_y = %d\n",
  206|      0|           factor_x_, factor_y_);
  207|      0|    exit(1);
  208|      0|  }
  209|  20.4M|}
_ZN7guetzli20OutputImageComponent21CopyFromJpegComponentERKNS_13JPEGComponentEiiPKi:
  213|   151k|                                                 const int* quant) {
  214|   151k|  Reset(factor_x, factor_y);
  215|   151k|  assert(width_in_blocks_ <= comp.width_in_blocks);
  216|      0|  assert(height_in_blocks_ <= comp.height_in_blocks);
  217|      0|  const size_t src_row_size = comp.width_in_blocks * kDCTBlockSize;
  218|   941k|  for (int block_y = 0; block_y < height_in_blocks_; ++block_y) {
  ------------------
  |  Branch (218:25): [True: 790k, False: 151k]
  ------------------
  219|   790k|    const coeff_t* src_coeffs = &comp.coeffs[block_y * src_row_size];
  220|  5.34M|    for (int block_x = 0; block_x < width_in_blocks_; ++block_x) {
  ------------------
  |  Branch (220:27): [True: 4.55M, False: 790k]
  ------------------
  221|  4.55M|      coeff_t block[kDCTBlockSize];
  222|   295M|      for (int i = 0; i < kDCTBlockSize; ++i) {
  ------------------
  |  Branch (222:23): [True: 291M, False: 4.55M]
  ------------------
  223|   291M|        block[i] = src_coeffs[i] * quant[i];
  224|   291M|      }
  225|  4.55M|      SetCoeffBlock(block_x, block_y, block);
  226|  4.55M|      src_coeffs += kDCTBlockSize;
  227|  4.55M|    }
  228|   790k|  }
  229|   151k|  memcpy(quant_, quant, sizeof(quant_));
  230|   151k|}
_ZN7guetzli20OutputImageComponent23ApplyGlobalQuantizationEPKi:
  232|   144k|void OutputImageComponent::ApplyGlobalQuantization(const int q[kDCTBlockSize]) {
  233|   867k|  for (int block_y = 0; block_y < height_in_blocks_; ++block_y) {
  ------------------
  |  Branch (233:25): [True: 723k, False: 144k]
  ------------------
  234|  4.69M|    for (int block_x = 0; block_x < width_in_blocks_; ++block_x) {
  ------------------
  |  Branch (234:27): [True: 3.97M, False: 723k]
  ------------------
  235|  3.97M|      coeff_t block[kDCTBlockSize];
  236|  3.97M|      GetCoeffBlock(block_x, block_y, block);
  237|  3.97M|      if (QuantizeBlock(block, q)) {
  ------------------
  |  Branch (237:11): [True: 1.37M, False: 2.60M]
  ------------------
  238|  1.37M|        SetCoeffBlock(block_x, block_y, block);
  239|  1.37M|      }
  240|  3.97M|    }
  241|   723k|  }
  242|   144k|  memcpy(quant_, q, sizeof(quant_));
  243|   144k|}
_ZN7guetzli11OutputImageC2Eii:
  248|  9.32k|      components_(3, OutputImageComponent(w, h)) {}
_ZN7guetzli11OutputImage16CopyFromJpegDataERKNS_8JPEGDataE:
  250|  57.4k|void OutputImage::CopyFromJpegData(const JPEGData& jpg) {
  251|   208k|  for (size_t i = 0; i < jpg.components.size(); ++i) {
  ------------------
  |  Branch (251:22): [True: 151k, False: 57.4k]
  ------------------
  252|   151k|    const JPEGComponent& comp = jpg.components[i];
  253|   151k|    assert(jpg.max_h_samp_factor % comp.h_samp_factor == 0);
  254|      0|    assert(jpg.max_v_samp_factor % comp.v_samp_factor == 0);
  255|      0|    int factor_x = jpg.max_h_samp_factor / comp.h_samp_factor;
  256|   151k|    int factor_y = jpg.max_v_samp_factor / comp.v_samp_factor;
  257|   151k|    assert(comp.quant_idx < jpg.quant.size());
  258|      0|    components_[i].CopyFromJpegComponent(comp, factor_x, factor_y,
  259|   151k|                                         &jpg.quant[comp.quant_idx].values[0]);
  260|   151k|  }
  261|  57.4k|}
_ZN7guetzli11OutputImage23ApplyGlobalQuantizationEPA64_Ki:
  342|  48.0k|void OutputImage::ApplyGlobalQuantization(const int q[3][kDCTBlockSize]) {
  343|   192k|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (343:19): [True: 144k, False: 48.0k]
  ------------------
  344|   144k|    components_[c].ApplyGlobalQuantization(&q[c][0]);
  345|   144k|  }
  346|  48.0k|}
_ZNK7guetzli11OutputImage14SaveToJpegDataEPNS_8JPEGDataE:
  348|   168k|void OutputImage::SaveToJpegData(JPEGData* jpg) const {
  349|   168k|  assert(components_[0].factor_x() == 1);
  350|      0|  assert(components_[0].factor_y() == 1);
  351|      0|  jpg->width = width_;
  352|   168k|  jpg->height = height_;
  353|   168k|  jpg->max_h_samp_factor = 1;
  354|   168k|  jpg->max_v_samp_factor = 1;
  355|   168k|  jpg->MCU_cols = components_[0].width_in_blocks();
  356|   168k|  jpg->MCU_rows = components_[0].height_in_blocks();
  357|   168k|  int ncomp = components_[1].IsAllZero() && components_[2].IsAllZero() ? 1 : 3;
  ------------------
  |  Branch (357:15): [True: 33.8k, False: 134k]
  |  Branch (357:45): [True: 28.6k, False: 5.19k]
  ------------------
  358|   446k|  for (int i = 1; i < ncomp; ++i) {
  ------------------
  |  Branch (358:19): [True: 278k, False: 168k]
  ------------------
  359|   278k|    jpg->max_h_samp_factor = std::max(jpg->max_h_samp_factor,
  360|   278k|                                      components_[i].factor_x());
  361|   278k|    jpg->max_v_samp_factor = std::max(jpg->max_h_samp_factor,
  362|   278k|                                      components_[i].factor_y());
  363|   278k|    jpg->MCU_cols = std::min(jpg->MCU_cols, components_[i].width_in_blocks());
  364|   278k|    jpg->MCU_rows = std::min(jpg->MCU_rows, components_[i].height_in_blocks());
  365|   278k|  }
  366|   168k|  jpg->components.resize(ncomp);
  367|   168k|  int q[3][kDCTBlockSize];
  368|   672k|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (368:19): [True: 504k, False: 168k]
  ------------------
  369|   504k|    memcpy(&q[c][0], components_[c].quant(), kDCTBlockSize * sizeof(q[0][0]));
  370|   504k|  }
  371|   615k|  for (int c = 0; c < ncomp; ++c) {
  ------------------
  |  Branch (371:19): [True: 446k, False: 168k]
  ------------------
  372|   446k|    JPEGComponent* comp = &jpg->components[c];
  373|   446k|    assert(jpg->max_h_samp_factor % components_[c].factor_x() == 0);
  374|      0|    assert(jpg->max_v_samp_factor % components_[c].factor_y() == 0);
  375|      0|    comp->id = c;
  376|   446k|    comp->h_samp_factor = jpg->max_h_samp_factor / components_[c].factor_x();
  377|   446k|    comp->v_samp_factor = jpg->max_v_samp_factor / components_[c].factor_y();
  378|   446k|    comp->width_in_blocks = jpg->MCU_cols * comp->h_samp_factor;
  379|   446k|    comp->height_in_blocks = jpg->MCU_rows * comp->v_samp_factor;
  380|   446k|    comp->num_blocks = comp->width_in_blocks * comp->height_in_blocks;
  381|   446k|    comp->coeffs.resize(kDCTBlockSize * comp->num_blocks);
  382|       |
  383|   446k|    int last_dc = 0;
  384|   446k|    const coeff_t* src_coeffs = components_[c].coeffs();
  385|   446k|    coeff_t* dest_coeffs = &comp->coeffs[0];
  386|  2.78M|    for (int block_y = 0; block_y < comp->height_in_blocks; ++block_y) {
  ------------------
  |  Branch (386:27): [True: 2.33M, False: 446k]
  ------------------
  387|  19.9M|      for (int block_x = 0; block_x < comp->width_in_blocks; ++block_x) {
  ------------------
  |  Branch (387:29): [True: 17.5M, False: 2.33M]
  ------------------
  388|  17.5M|        if (block_y >= components_[c].height_in_blocks() ||
  ------------------
  |  Branch (388:13): [True: 828k, False: 16.7M]
  ------------------
  389|  17.5M|            block_x >= components_[c].width_in_blocks()) {
  ------------------
  |  Branch (389:13): [True: 371k, False: 16.3M]
  ------------------
  390|  1.19M|          dest_coeffs[0] = last_dc;
  391|  76.7M|          for (int k = 1; k < kDCTBlockSize; ++k) {
  ------------------
  |  Branch (391:27): [True: 75.5M, False: 1.19M]
  ------------------
  392|  75.5M|            dest_coeffs[k] = 0;
  393|  75.5M|          }
  394|  16.3M|        } else {
  395|  1.06G|          for (int k = 0; k < kDCTBlockSize; ++k) {
  ------------------
  |  Branch (395:27): [True: 1.04G, False: 16.3M]
  ------------------
  396|  1.04G|            const int quant = q[c][k];
  397|  1.04G|            int coeff = src_coeffs[k];
  398|  1.04G|            assert(coeff % quant == 0);
  399|      0|            dest_coeffs[k] = coeff / quant;
  400|  1.04G|          }
  401|  16.3M|          src_coeffs += kDCTBlockSize;
  402|  16.3M|        }
  403|  17.5M|        last_dc = dest_coeffs[0];
  404|  17.5M|        dest_coeffs += kDCTBlockSize;
  405|  17.5M|      }
  406|  2.33M|    }
  407|   446k|  }
  408|   168k|  SaveQuantTables(q, jpg);
  409|   168k|}
_ZNK7guetzli11OutputImage6ToSRGBEiiii:
  412|  7.59M|                                         int xsize, int ysize) const {
  413|  7.59M|  std::vector<uint8_t> rgb(xsize * ysize * 3);
  414|  30.3M|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (414:19): [True: 22.7M, False: 7.59M]
  ------------------
  415|  22.7M|    components_[c].ToPixels(xmin, ymin, xsize, ysize, &rgb[c], 3);
  416|  22.7M|  }
  417|   989M|  for (size_t p = 0; p < rgb.size(); p += 3) {
  ------------------
  |  Branch (417:22): [True: 981M, False: 7.59M]
  ------------------
  418|   981M|    ColorTransformYCbCrToRGB(&rgb[p]);
  419|   981M|  }
  420|  7.59M|  return rgb;
  421|  7.59M|}
_ZNK7guetzli11OutputImage6ToSRGBEv:
  423|  3.23k|std::vector<uint8_t> OutputImage::ToSRGB() const {
  424|  3.23k|  return ToSRGB(0, 0, width_, height_);
  425|  3.23k|}
_ZNK7guetzli11OutputImage11ToLinearRGBEiiiiPNSt3__16vectorINS2_IfNS1_9allocatorIfEEEENS3_IS5_EEEE:
  428|  7.59M|                              std::vector<std::vector<float> >* rgb) const {
  429|  7.59M|  const double* lut = Srgb8ToLinearTable();
  430|  7.59M|  std::vector<uint8_t> rgb_pixels = ToSRGB(xmin, ymin, xsize, ysize);
  431|   980M|  for (int p = 0; p < xsize * ysize; ++p) {
  ------------------
  |  Branch (431:19): [True: 972M, False: 7.59M]
  ------------------
  432|  3.88G|    for (int i = 0; i < 3; ++i) {
  ------------------
  |  Branch (432:21): [True: 2.91G, False: 972M]
  ------------------
  433|  2.91G|      (*rgb)[i][p] = static_cast<float>(lut[rgb_pixels[3 * p + i]]);
  434|  2.91G|    }
  435|   972M|  }
  436|  7.59M|}
_ZNK7guetzli11OutputImage11ToLinearRGBEPNSt3__16vectorINS2_IfNS1_9allocatorIfEEEENS3_IS5_EEEE:
  438|   163k|void OutputImage::ToLinearRGB(std::vector<std::vector<float> >* rgb) const {
  439|   163k|  ToLinearRGB(0, 0, width_, height_, rgb);
  440|   163k|}
_ZNK7guetzli11OutputImage12FrameTypeStrEv:
  442|   205k|std::string OutputImage::FrameTypeStr() const {
  443|   205k|  char buf[128];
  444|   205k|  int len = snprintf(buf, sizeof(buf), "f%d%d%d%d%d%d",
  445|   205k|                     component(0).factor_x(), component(0).factor_y(),
  446|   205k|                     component(1).factor_x(), component(1).factor_y(),
  447|   205k|                     component(2).factor_x(), component(2).factor_y());
  448|   205k|  return std::string(buf, len);
  449|   205k|}

_ZNK7guetzli20OutputImageComponent8factor_xEv:
   35|  2.21M|  int factor_x() const { return factor_x_; }
_ZNK7guetzli20OutputImageComponent8factor_yEv:
   36|  2.21M|  int factor_y() const { return factor_y_; }
_ZNK7guetzli20OutputImageComponent15width_in_blocksEv:
   37|  17.1M|  int width_in_blocks() const { return width_in_blocks_; }
_ZNK7guetzli20OutputImageComponent16height_in_blocksEv:
   38|  18.0M|  int height_in_blocks() const { return height_in_blocks_; }
_ZNK7guetzli20OutputImageComponent6coeffsEv:
   39|   446k|  const coeff_t* coeffs() const { return &coeffs_[0]; }
_ZNK7guetzli20OutputImageComponent5quantEv:
   40|  3.02M|  const int* quant() const { return &quant_[0]; }
_ZNK7guetzli11OutputImage5widthEv:
   98|  7.78M|  int width() const { return width_; }
_ZNK7guetzli11OutputImage6heightEv:
   99|  7.63M|  int height() const { return height_; }
_ZN7guetzli11OutputImage9componentEi:
  101|  20.3M|  OutputImageComponent& component(int c) { return components_[c]; }
_ZNK7guetzli11OutputImage9componentEi:
  102|  1.23M|  const OutputImageComponent& component(int c) const { return components_[c]; }

_ZN7guetzli16GuetzliStringOutEPvPKhm:
  123|  1.14M|int GuetzliStringOut(void* data, const uint8_t* buf, size_t count) {
  124|  1.14M|  std::string* sink =
  125|  1.14M|      reinterpret_cast<std::string*>(data);
  126|  1.14M|  sink->append(reinterpret_cast<const char*>(buf), count);
  127|  1.14M|  return count;
  128|  1.14M|}
_ZN7guetzli20CompareQuantMatricesEPKiS1_:
  161|   344k|int CompareQuantMatrices(const int* a, const int* b) {
  162|   344k|  int i = 0;
  163|  1.53M|  while (i < kBlockSize && a[i] == b[i]) ++i;
  ------------------
  |  Branch (163:10): [True: 1.53M, False: 2.74k]
  |  Branch (163:28): [True: 1.19M, False: 341k]
  ------------------
  164|   344k|  if (i == kBlockSize) {
  ------------------
  |  Branch (164:7): [True: 2.74k, False: 341k]
  ------------------
  165|  2.74k|    return 0;
  166|  2.74k|  }
  167|   341k|  if (a[i] < b[i]) {
  ------------------
  |  Branch (167:7): [True: 85.3k, False: 256k]
  ------------------
  168|  15.9M|    for (++i; i < kBlockSize; ++i) {
  ------------------
  |  Branch (168:15): [True: 15.8M, False: 85.3k]
  ------------------
  169|  15.8M|      if (a[i] > b[i]) return 2;
  ------------------
  |  Branch (169:11): [True: 0, False: 15.8M]
  ------------------
  170|  15.8M|    }
  171|  85.3k|    return -1;
  172|   256k|  } else {
  173|  48.9M|    for (++i; i < kBlockSize; ++i) {
  ------------------
  |  Branch (173:15): [True: 48.7M, False: 256k]
  ------------------
  174|  48.7M|      if (a[i] < b[i]) return 2;
  ------------------
  |  Branch (174:11): [True: 0, False: 48.7M]
  ------------------
  175|  48.7M|    }
  176|   256k|    return 1;
  177|   256k|  }
  178|   341k|}
_ZN7guetzli19ContrastSensitivityEi:
  180|  22.1M|double ContrastSensitivity(int k) {
  181|  22.1M|  return 1.0 / (1.0 + kJPEGZigZagOrder[k] / 2.0);
  182|  22.1M|}
_ZN7guetzli25QuantMatrixHeuristicScoreEPA64_Ki:
  184|  87.0k|double QuantMatrixHeuristicScore(const int q[3][kDCTBlockSize]) {
  185|  87.0k|  double score = 0.0;
  186|   348k|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (186:19): [True: 261k, False: 87.0k]
  ------------------
  187|  16.9M|    for (int k = 0; k < kDCTBlockSize; ++k) {
  ------------------
  |  Branch (187:21): [True: 16.7M, False: 261k]
  ------------------
  188|  16.7M|      score += 0.5 * (q[c][k] - 1.0) * ContrastSensitivity(k);
  189|  16.7M|    }
  190|   261k|  }
  191|  87.0k|  return score;
  192|  87.0k|}
_ZN7guetzli15ProcessJpegDataERKNS_6ParamsERKNS_8JPEGDataEPNS_10ComparatorEPNS_13GuetzliOutputEPNS_12ProcessStatsE:
  885|  3.23k|                     ProcessStats* stats) {
  886|  3.23k|  Processor processor;
  887|  3.23k|  return processor.ProcessJpegData(params, jpg_in, comparator, out, stats);
  888|  3.23k|}
_ZN7guetzli7ProcessERKNS_6ParamsEPNS_12ProcessStatsERKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEPSB_:
  892|  5.22k|             std::string* jpg_out) {
  893|  5.22k|  JPEGData jpg;
  894|  5.22k|  if (!ReadJpeg(data, JPEG_READ_ALL, &jpg)) {
  ------------------
  |  Branch (894:7): [True: 1.94k, False: 3.27k]
  ------------------
  895|  1.94k|    fprintf(stderr, "Can't read jpg data from input file\n");
  896|  1.94k|    return false;
  897|  1.94k|  }
  898|  3.27k|  if (!CheckJpegSanity(jpg)) {
  ------------------
  |  Branch (898:7): [True: 12, False: 3.26k]
  ------------------
  899|     12|    fprintf(stderr, "Unsupported input JPEG (unexpectedly large coefficient "
  900|     12|            "values).\n");
  901|     12|    return false;
  902|     12|  }
  903|  3.26k|  std::vector<uint8_t> rgb = DecodeJpegToRGB(jpg);
  904|  3.26k|  if (rgb.empty()) {
  ------------------
  |  Branch (904:7): [True: 29, False: 3.23k]
  ------------------
  905|     29|    fprintf(stderr, "Unsupported input JPEG file (e.g. unsupported "
  906|     29|            "downsampling mode).\nPlease provide the input image as "
  907|     29|            "a PNG file.\n");
  908|     29|    return false;
  909|     29|  }
  910|  3.23k|  GuetzliOutput out;
  911|  3.23k|  ProcessStats dummy_stats;
  912|  3.23k|  if (stats == nullptr) {
  ------------------
  |  Branch (912:7): [True: 3.23k, False: 0]
  ------------------
  913|  3.23k|    stats = &dummy_stats;
  914|  3.23k|  }
  915|  3.23k|  std::unique_ptr<ButteraugliComparator> comparator;
  916|  3.23k|  if (jpg.width >= 32 && jpg.height >= 32) {
  ------------------
  |  Branch (916:7): [True: 3.15k, False: 84]
  |  Branch (916:26): [True: 3.10k, False: 49]
  ------------------
  917|  3.10k|    comparator.reset(
  918|  3.10k|        new ButteraugliComparator(jpg.width, jpg.height, &rgb,
  919|  3.10k|                                  params.butteraugli_target, stats));
  920|  3.10k|  }
  921|  3.23k|  bool ok = ProcessJpegData(params, jpg, comparator.get(), &out, stats);
  922|  3.23k|  *jpg_out = out.jpeg_data;
  923|  3.23k|  return ok;
  924|  3.26k|}
processor.cc:_ZN7guetzli12_GLOBAL__N_19Processor15ProcessJpegDataERKNS_6ParamsERKNS_8JPEGDataEPNS_10ComparatorEPNS_13GuetzliOutputEPNS_12ProcessStatsE:
  794|  3.23k|                                ProcessStats* stats) {
  795|  3.23k|  params_ = params;
  796|  3.23k|  comparator_ = comparator;
  797|  3.23k|  final_output_ = out;
  798|  3.23k|  stats_ = stats;
  799|       |
  800|  3.23k|  if (params.butteraugli_target > 2.0f) {
  ------------------
  |  Branch (800:7): [True: 0, False: 3.23k]
  ------------------
  801|      0|    fprintf(stderr,
  802|      0|            "Guetzli should be called with quality >= 84, otherwise the\n"
  803|      0|            "output will have noticeable artifacts. If you want to\n"
  804|      0|            "proceed anyway, please edit the source code.\n");
  805|      0|    return false;
  806|      0|  }
  807|  3.23k|  if (jpg_in.components.size() != 3 || !HasYCbCrColorSpace(jpg_in)) {
  ------------------
  |  Branch (807:7): [True: 86, False: 3.14k]
  |  Branch (807:40): [True: 0, False: 3.14k]
  ------------------
  808|     86|    fprintf(stderr, "Only YUV color space input jpeg is supported\n");
  809|     86|    return false;
  810|     86|  }
  811|  3.14k|  bool input_is_420;
  812|  3.14k|  if (jpg_in.Is444()) {
  ------------------
  |  Branch (812:7): [True: 480, False: 2.66k]
  ------------------
  813|    480|    input_is_420 = false;
  814|  2.66k|  } else if (jpg_in.Is420()) {
  ------------------
  |  Branch (814:14): [True: 2.66k, False: 0]
  ------------------
  815|  2.66k|    input_is_420 = true;
  816|  2.66k|  } else {
  817|      0|    fprintf(stderr, "Unsupported sampling factors:");
  818|      0|    for (size_t i = 0; i < jpg_in.components.size(); ++i) {
  ------------------
  |  Branch (818:24): [True: 0, False: 0]
  ------------------
  819|      0|      fprintf(stderr, " %dx%d", jpg_in.components[i].h_samp_factor,
  820|      0|              jpg_in.components[i].v_samp_factor);
  821|      0|    }
  822|      0|    fprintf(stderr, "\n");
  823|      0|    return false;
  824|      0|  }
  825|  3.14k|  int q_in[3][kDCTBlockSize];
  826|       |  // Output the original image, in case we do not manage to create anything
  827|       |  // with a good enough quality.
  828|  3.14k|  std::string encoded_jpg;
  829|  3.14k|  OutputJpeg(jpg_in, &encoded_jpg);
  830|  3.14k|  final_output_->score = -1;
  831|  3.14k|  GUETZLI_LOG(stats, "Original Out[%7zd]", encoded_jpg.size());
  ------------------
  |  |   29|  3.14k|  do {                                                             \
  |  |   30|  3.14k|    char debug_string[1024];                                       \
  |  |   31|  3.14k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |   32|  3.14k|                       __VA_ARGS__);                               \
  |  |   33|  3.14k|    assert(res > 0 && "expected successful printing");             \
  |  |   34|  3.14k|    (void)res;                                                     \
  |  |   35|  3.14k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |   36|  3.14k|    ::guetzli::PrintDebug(                      \
  |  |   37|  3.14k|         stats, std::string(debug_string));        \
  |  |   38|  3.14k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  832|  3.14k|  if (comparator_ == nullptr) {
  ------------------
  |  Branch (832:7): [True: 105, False: 3.04k]
  ------------------
  833|    105|    GUETZLI_LOG(stats, " <image too small for Butteraugli>\n");
  ------------------
  |  |   29|    105|  do {                                                             \
  |  |   30|    105|    char debug_string[1024];                                       \
  |  |   31|    105|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |   32|    105|                       __VA_ARGS__);                               \
  |  |   33|    105|    assert(res > 0 && "expected successful printing");             \
  |  |   34|    105|    (void)res;                                                     \
  |  |   35|    105|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |   36|    105|    ::guetzli::PrintDebug(                      \
  |  |   37|    105|         stats, std::string(debug_string));        \
  |  |   38|    105|  } while (0)
  |  |  ------------------
  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  834|      0|    final_output_->jpeg_data = encoded_jpg;
  835|    105|    final_output_->score = encoded_jpg.size();
  836|       |    // Butteraugli doesn't work with images this small.
  837|    105|    return true;
  838|    105|  }
  839|  3.04k|  {
  840|  3.04k|    JPEGData jpg = jpg_in;
  841|  3.04k|    RemoveOriginalQuantization(&jpg, q_in);
  842|  3.04k|    OutputImage img(jpg.width, jpg.height);
  843|  3.04k|    img.CopyFromJpegData(jpg);
  844|  3.04k|    comparator_->Compare(img);
  845|  3.04k|  }
  846|  3.04k|  MaybeOutput(encoded_jpg);
  847|  3.04k|  int try_420 = (input_is_420 || params_.force_420 ||
  ------------------
  |  Branch (847:18): [True: 2.57k, False: 469]
  |  Branch (847:34): [True: 0, False: 469]
  ------------------
  848|  3.04k|                 (params_.try_420 && !IsGrayscale(jpg_in))) ? 1 : 0;
  ------------------
  |  Branch (848:19): [True: 0, False: 469]
  |  Branch (848:38): [True: 0, False: 0]
  ------------------
  849|  3.04k|  int force_420 = (input_is_420 || params_.force_420) ? 1 : 0;
  ------------------
  |  Branch (849:20): [True: 2.57k, False: 469]
  |  Branch (849:36): [True: 0, False: 469]
  ------------------
  850|  6.08k|  for (int downsample = force_420; downsample <= try_420; ++downsample) {
  ------------------
  |  Branch (850:36): [True: 3.04k, False: 3.04k]
  ------------------
  851|  3.04k|    JPEGData jpg = jpg_in;
  852|  3.04k|    RemoveOriginalQuantization(&jpg, q_in);
  853|  3.04k|    OutputImage img(jpg.width, jpg.height);
  854|  3.04k|    img.CopyFromJpegData(jpg);
  855|  3.04k|    if (downsample) {
  ------------------
  |  Branch (855:9): [True: 2.57k, False: 469]
  ------------------
  856|  2.57k|      DownsampleImage(&img);
  857|  2.57k|      img.SaveToJpegData(&jpg);
  858|  2.57k|    }
  859|  3.04k|    int best_q[3][kDCTBlockSize];
  860|  3.04k|    memcpy(best_q, q_in, sizeof(best_q));
  861|  3.04k|    if (!SelectQuantMatrix(jpg, downsample != 0, best_q, &img)) {
  ------------------
  |  Branch (861:9): [True: 0, False: 3.04k]
  ------------------
  862|      0|      for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (862:23): [True: 0, False: 0]
  ------------------
  863|      0|        for (int i = 0; i < kDCTBlockSize; ++i) {
  ------------------
  |  Branch (863:25): [True: 0, False: 0]
  ------------------
  864|      0|          best_q[c][i] = 1;
  865|      0|        }
  866|      0|      }
  867|      0|    }
  868|  3.04k|    img.CopyFromJpegData(jpg);
  869|  3.04k|    img.ApplyGlobalQuantization(best_q);
  870|       |
  871|  3.04k|    if (!downsample) {
  ------------------
  |  Branch (871:9): [True: 469, False: 2.57k]
  ------------------
  872|    469|      SelectFrequencyMasking(jpg, &img, 7, 1.0, false);
  873|  2.57k|    } else {
  874|  2.57k|      const float ymul = jpg.components.size() == 1 ? 1.0f : 0.97f;
  ------------------
  |  Branch (874:26): [True: 607, False: 1.96k]
  ------------------
  875|  2.57k|      SelectFrequencyMasking(jpg, &img, 1, ymul, false);
  876|  2.57k|      SelectFrequencyMasking(jpg, &img, 6, 1.0, true);
  877|  2.57k|    }
  878|  3.04k|  }
  879|       |
  880|  3.04k|  return true;
  881|  3.14k|}
processor.cc:_ZN7guetzli12_GLOBAL__N_19Processor10OutputJpegERKNS_8JPEGDataEPNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEE:
  131|   163k|                           std::string* out) {
  132|   163k|  out->clear();
  133|   163k|  JPEGOutput output(GuetzliStringOut, out);
  134|   163k|  if (!WriteJpeg(jpg, params_.clear_metadata, output)) {
  ------------------
  |  Branch (134:7): [True: 0, False: 163k]
  ------------------
  135|      0|    assert(0);
  136|      0|  }
  137|   163k|}
processor.cc:_ZN7guetzli12_GLOBAL__N_126RemoveOriginalQuantizationEPNS_8JPEGDataEPA64_i:
   82|  6.08k|void RemoveOriginalQuantization(JPEGData* jpg, int q_in[3][kDCTBlockSize]) {
   83|  24.3k|  for (int i = 0; i < 3; ++i) {
  ------------------
  |  Branch (83:19): [True: 18.2k, False: 6.08k]
  ------------------
   84|  18.2k|    JPEGComponent& c = jpg->components[i];
   85|  18.2k|    const int* q = &jpg->quant[c.quant_idx].values[0];
   86|  18.2k|    memcpy(&q_in[i][0], q, kDCTBlockSize * sizeof(q[0]));
   87|  37.2M|    for (size_t j = 0; j < c.coeffs.size(); ++j) {
  ------------------
  |  Branch (87:24): [True: 37.1M, False: 18.2k]
  ------------------
   88|  37.1M|      c.coeffs[j] *= q[j % kDCTBlockSize];
   89|  37.1M|    }
   90|  18.2k|  }
   91|  6.08k|  int q[3][kDCTBlockSize];
   92|  24.3k|  for (int i = 0; i < 3; ++i)
  ------------------
  |  Branch (92:19): [True: 18.2k, False: 6.08k]
  ------------------
   93|  1.18M|    for (int j = 0; j < kDCTBlockSize; ++j) q[i][j] = 1;
  ------------------
  |  Branch (93:21): [True: 1.16M, False: 18.2k]
  ------------------
   94|  6.08k|  SaveQuantTables(q, jpg);
   95|  6.08k|}
processor.cc:_ZN7guetzli12_GLOBAL__N_19Processor11MaybeOutputERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  139|   163k|void Processor::MaybeOutput(const std::string& encoded_jpg) {
  140|   163k|  double score = comparator_->ScoreOutputSize(encoded_jpg.size());
  141|   163k|  GUETZLI_LOG(stats_, " Score[%.4f]", score);
  ------------------
  |  |   29|   163k|  do {                                                             \
  |  |   30|   163k|    char debug_string[1024];                                       \
  |  |   31|   163k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |   32|   163k|                       __VA_ARGS__);                               \
  |  |   33|   163k|    assert(res > 0 && "expected successful printing");             \
  |  |   34|   163k|    (void)res;                                                     \
  |  |   35|   163k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |   36|   163k|    ::guetzli::PrintDebug(                      \
  |  |   37|   163k|         stats, std::string(debug_string));        \
  |  |   38|   163k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  142|   163k|  if (score < final_output_->score || final_output_->score < 0) {
  ------------------
  |  Branch (142:7): [True: 5.60k, False: 157k]
  |  Branch (142:39): [True: 3.04k, False: 154k]
  ------------------
  143|  8.64k|    final_output_->jpeg_data = encoded_jpg;
  144|  8.64k|    final_output_->score = score;
  145|  8.64k|    GUETZLI_LOG(stats_, " (*)");
  ------------------
  |  |   29|  8.64k|  do {                                                             \
  |  |   30|  8.64k|    char debug_string[1024];                                       \
  |  |   31|  8.64k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |   32|  8.64k|                       __VA_ARGS__);                               \
  |  |   33|  8.64k|    assert(res > 0 && "expected successful printing");             \
  |  |   34|  8.64k|    (void)res;                                                     \
  |  |   35|  8.64k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |   36|  8.64k|    ::guetzli::PrintDebug(                      \
  |  |   37|  8.64k|         stats, std::string(debug_string));        \
  |  |   38|  8.64k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  146|  8.64k|  }
  147|   163k|  GUETZLI_LOG(stats_, "\n");
  ------------------
  |  |   29|   163k|  do {                                                             \
  |  |   30|   163k|    char debug_string[1024];                                       \
  |  |   31|   163k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |   32|   163k|                       __VA_ARGS__);                               \
  |  |   33|   163k|    assert(res > 0 && "expected successful printing");             \
  |  |   34|   163k|    (void)res;                                                     \
  |  |   35|   163k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |   36|   163k|    ::guetzli::PrintDebug(                      \
  |  |   37|   163k|         stats, std::string(debug_string));        \
  |  |   38|   163k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  148|   163k|}
processor.cc:_ZN7guetzli12_GLOBAL__N_19Processor15DownsampleImageEPNS_11OutputImageE:
   97|  2.57k|void Processor::DownsampleImage(OutputImage* img) {
   98|  2.57k|  if (img->component(1).factor_x() > 1 || img->component(1).factor_y() > 1) {
  ------------------
  |  Branch (98:7): [True: 2.57k, False: 0]
  |  Branch (98:43): [True: 0, False: 0]
  ------------------
   99|  2.57k|    return;
  100|  2.57k|  }
  101|      0|  OutputImage::DownsampleConfig cfg;
  102|      0|  cfg.use_silver_screen = params_.use_silver_screen;
  103|      0|  img->Downsample(cfg);
  104|      0|}
processor.cc:_ZN7guetzli12_GLOBAL__N_19Processor17SelectQuantMatrixERKNS_8JPEGDataEbPA64_iPNS_11OutputImageE:
  330|  3.04k|                                  OutputImage* img) {
  331|  3.04k|  QuantMatrixGenerator qgen(downsample, stats_);
  332|       |  // Don't try to go up to exactly the target distance when selecting a
  333|       |  // quantization matrix, since we will need some slack to do the frequency
  334|       |  // masking later.
  335|  3.04k|  const float target_mul_high = 0.97f;
  336|  3.04k|  const float target_mul_low = 0.95f;
  337|       |
  338|  3.04k|  QuantData best = TryQuantMatrix(jpg_in, target_mul_high, best_q, img);
  339|  44.8k|  for (;;) {
  340|  44.8k|    int q_next[3][kDCTBlockSize];
  341|  44.8k|    if (!qgen.GetNext(q_next)) {
  ------------------
  |  Branch (341:9): [True: 2.84k, False: 42.0k]
  ------------------
  342|  2.84k|      break;
  343|  2.84k|    }
  344|       |
  345|  42.0k|    QuantData data = TryQuantMatrix(jpg_in, target_mul_high, q_next, img);
  346|  42.0k|    qgen.Add(data);
  347|  42.0k|    if (CompareQuantData(data, best)) {
  ------------------
  |  Branch (347:9): [True: 2.67k, False: 39.3k]
  ------------------
  348|  2.67k|      best = data;
  349|  2.67k|      if (data.dist_ok && !comparator_->DistanceOK(target_mul_low)) {
  ------------------
  |  Branch (349:11): [True: 2.67k, False: 0]
  |  Branch (349:27): [True: 201, False: 2.47k]
  ------------------
  350|    201|        break;
  351|    201|      }
  352|  2.67k|    }
  353|  42.0k|  }
  354|       |
  355|  3.04k|  memcpy(&best_q[0][0], &best.q[0][0], kBlockSize * sizeof(best_q[0][0]));
  356|  3.04k|  GUETZLI_LOG(stats_, "\n%s selected quantization matrix:\n",
  ------------------
  |  |   29|  3.04k|  do {                                                             \
  |  |   30|  3.04k|    char debug_string[1024];                                       \
  |  |   31|  3.04k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |   32|  6.08k|                       __VA_ARGS__);                               \
  |  |  ------------------
  |  |  |  Branch (32:24): [True: 2.57k, False: 469]
  |  |  ------------------
  |  |   33|  3.04k|    assert(res > 0 && "expected successful printing");             \
  |  |   34|  3.04k|    (void)res;                                                     \
  |  |   35|  3.04k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |   36|  3.04k|    ::guetzli::PrintDebug(                      \
  |  |   37|  3.04k|         stats, std::string(debug_string));        \
  |  |   38|  3.04k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  357|  3.04k|              downsample ? "YUV420" : "YUV444");
  358|  3.04k|  GUETZLI_LOG_QUANT(stats_, best_q);
  ------------------
  |  |   40|  27.3k|  for (int y = 0; y < 8; ++y) {                        \
  |  |  ------------------
  |  |  |  Branch (40:19): [True: 24.3k, False: 3.04k]
  |  |  ------------------
  |  |   41|  97.3k|    for (int c = 0; c < 3; ++c) {                      \
  |  |  ------------------
  |  |  |  Branch (41:21): [True: 73.0k, False: 24.3k]
  |  |  ------------------
  |  |   42|   657k|      for (int x = 0; x < 8; ++x)                      \
  |  |  ------------------
  |  |  |  Branch (42:23): [True: 584k, False: 73.0k]
  |  |  ------------------
  |  |   43|   584k|        GUETZLI_LOG(stats, " %2d", (q)[c][8 * y + x]); \
  |  |  ------------------
  |  |  |  |   29|   584k|  do {                                                             \
  |  |  |  |   30|   584k|    char debug_string[1024];                                       \
  |  |  |  |   31|   584k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |  |  |   32|   584k|                       __VA_ARGS__);                               \
  |  |  |  |   33|   584k|    assert(res > 0 && "expected successful printing");             \
  |  |  |  |   34|   584k|    (void)res;                                                     \
  |  |  |  |   35|   584k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |  |  |   36|   584k|    ::guetzli::PrintDebug(                      \
  |  |  |  |   37|   584k|         stats, std::string(debug_string));        \
  |  |  |  |   38|   584k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   44|  73.0k|      GUETZLI_LOG(stats, "   ");                       \
  |  |  ------------------
  |  |  |  |   29|  73.0k|  do {                                                             \
  |  |  |  |   30|  73.0k|    char debug_string[1024];                                       \
  |  |  |  |   31|  73.0k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |  |  |   32|  73.0k|                       __VA_ARGS__);                               \
  |  |  |  |   33|  73.0k|    assert(res > 0 && "expected successful printing");             \
  |  |  |  |   34|  73.0k|    (void)res;                                                     \
  |  |  |  |   35|  73.0k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |  |  |   36|  73.0k|    ::guetzli::PrintDebug(                      \
  |  |  |  |   37|  73.0k|         stats, std::string(debug_string));        \
  |  |  |  |   38|  73.0k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   45|  73.0k|    }                                                  \
  |  |   46|  24.3k|    GUETZLI_LOG(stats, "\n");                          \
  |  |  ------------------
  |  |  |  |   29|  24.3k|  do {                                                             \
  |  |  |  |   30|  24.3k|    char debug_string[1024];                                       \
  |  |  |  |   31|  24.3k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |  |  |   32|  24.3k|                       __VA_ARGS__);                               \
  |  |  |  |   33|  24.3k|    assert(res > 0 && "expected successful printing");             \
  |  |  |  |   34|  24.3k|    (void)res;                                                     \
  |  |  |  |   35|  24.3k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |  |  |   36|  24.3k|    ::guetzli::PrintDebug(                      \
  |  |  |  |   37|  24.3k|         stats, std::string(debug_string));        \
  |  |  |  |   38|  24.3k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   47|  24.3k|  }
  ------------------
  359|  3.04k|  return best.dist_ok;
  360|  3.04k|}
_ZN7guetzli20QuantMatrixGeneratorC2EbPNS_12ProcessStatsE:
  198|  3.04k|        total_csf_(0.0), stats_(stats) {
  199|   197k|    for (int k = 0; k < kDCTBlockSize; ++k) {
  ------------------
  |  Branch (199:21): [True: 194k, False: 3.04k]
  ------------------
  200|   194k|      total_csf_ += 3.0 * ContrastSensitivity(k);
  201|   194k|    }
  202|  3.04k|  }
processor.cc:_ZN7guetzli12_GLOBAL__N_19Processor14TryQuantMatrixERKNS_8JPEGDataEfPA64_iPNS_11OutputImageE:
  301|  45.0k|                                    OutputImage* img) {
  302|  45.0k|  QuantData data;
  303|  45.0k|  memcpy(data.q, q, sizeof(data.q));
  304|  45.0k|  img->CopyFromJpegData(jpg_in);
  305|  45.0k|  img->ApplyGlobalQuantization(data.q);
  306|  45.0k|  std::string encoded_jpg;
  307|  45.0k|  {
  308|  45.0k|    JPEGData jpg_out = jpg_in;
  309|  45.0k|    img->SaveToJpegData(&jpg_out);
  310|  45.0k|    OutputJpeg(jpg_out, &encoded_jpg);
  311|  45.0k|  }
  312|  45.0k|  GUETZLI_LOG(stats_, "Iter %2d: %s quantization matrix:\n",
  ------------------
  |  |   29|  45.0k|  do {                                                             \
  |  |   30|  45.0k|    char debug_string[1024];                                       \
  |  |   31|  45.0k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |   32|  45.0k|                       __VA_ARGS__);                               \
  |  |   33|  45.0k|    assert(res > 0 && "expected successful printing");             \
  |  |   34|  45.0k|    (void)res;                                                     \
  |  |   35|  45.0k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |   36|  45.0k|    ::guetzli::PrintDebug(                      \
  |  |   37|  45.0k|         stats, std::string(debug_string));        \
  |  |   38|  45.0k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  313|  45.0k|              stats_->counters[kNumItersCnt] + 1,
  314|  45.0k|              img->FrameTypeStr().c_str());
  315|  45.0k|  GUETZLI_LOG_QUANT(stats_, q);
  ------------------
  |  |   40|   405k|  for (int y = 0; y < 8; ++y) {                        \
  |  |  ------------------
  |  |  |  Branch (40:19): [True: 360k, False: 45.0k]
  |  |  ------------------
  |  |   41|  1.44M|    for (int c = 0; c < 3; ++c) {                      \
  |  |  ------------------
  |  |  |  Branch (41:21): [True: 1.08M, False: 360k]
  |  |  ------------------
  |  |   42|  9.73M|      for (int x = 0; x < 8; ++x)                      \
  |  |  ------------------
  |  |  |  Branch (42:23): [True: 8.64M, False: 1.08M]
  |  |  ------------------
  |  |   43|  8.64M|        GUETZLI_LOG(stats, " %2d", (q)[c][8 * y + x]); \
  |  |  ------------------
  |  |  |  |   29|  8.64M|  do {                                                             \
  |  |  |  |   30|  8.64M|    char debug_string[1024];                                       \
  |  |  |  |   31|  8.64M|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |  |  |   32|  8.64M|                       __VA_ARGS__);                               \
  |  |  |  |   33|  8.64M|    assert(res > 0 && "expected successful printing");             \
  |  |  |  |   34|  8.64M|    (void)res;                                                     \
  |  |  |  |   35|  8.64M|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |  |  |   36|  8.64M|    ::guetzli::PrintDebug(                      \
  |  |  |  |   37|  8.64M|         stats, std::string(debug_string));        \
  |  |  |  |   38|  8.64M|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   44|  1.08M|      GUETZLI_LOG(stats, "   ");                       \
  |  |  ------------------
  |  |  |  |   29|  1.08M|  do {                                                             \
  |  |  |  |   30|  1.08M|    char debug_string[1024];                                       \
  |  |  |  |   31|  1.08M|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |  |  |   32|  1.08M|                       __VA_ARGS__);                               \
  |  |  |  |   33|  1.08M|    assert(res > 0 && "expected successful printing");             \
  |  |  |  |   34|  1.08M|    (void)res;                                                     \
  |  |  |  |   35|  1.08M|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |  |  |   36|  1.08M|    ::guetzli::PrintDebug(                      \
  |  |  |  |   37|  1.08M|         stats, std::string(debug_string));        \
  |  |  |  |   38|  1.08M|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   45|  1.08M|    }                                                  \
  |  |   46|   360k|    GUETZLI_LOG(stats, "\n");                          \
  |  |  ------------------
  |  |  |  |   29|   360k|  do {                                                             \
  |  |  |  |   30|   360k|    char debug_string[1024];                                       \
  |  |  |  |   31|   360k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |  |  |   32|   360k|                       __VA_ARGS__);                               \
  |  |  |  |   33|   360k|    assert(res > 0 && "expected successful printing");             \
  |  |  |  |   34|   360k|    (void)res;                                                     \
  |  |  |  |   35|   360k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |  |  |   36|   360k|    ::guetzli::PrintDebug(                      \
  |  |  |  |   37|   360k|         stats, std::string(debug_string));        \
  |  |  |  |   38|   360k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   47|   360k|  }
  ------------------
  316|  45.0k|  GUETZLI_LOG(stats_, "Iter %2d: %s GQ[%5.2f] Out[%7zd]",
  ------------------
  |  |   29|  45.0k|  do {                                                             \
  |  |   30|  45.0k|    char debug_string[1024];                                       \
  |  |   31|  45.0k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |   32|  45.0k|                       __VA_ARGS__);                               \
  |  |   33|  45.0k|    assert(res > 0 && "expected successful printing");             \
  |  |   34|  45.0k|    (void)res;                                                     \
  |  |   35|  45.0k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |   36|  45.0k|    ::guetzli::PrintDebug(                      \
  |  |   37|  45.0k|         stats, std::string(debug_string));        \
  |  |   38|  45.0k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  317|  45.0k|              stats_->counters[kNumItersCnt] + 1,
  318|  45.0k|              img->FrameTypeStr().c_str(),
  319|  45.0k|              QuantMatrixHeuristicScore(q), encoded_jpg.size());
  320|      0|  ++stats_->counters[kNumItersCnt];
  321|  45.0k|  comparator_->Compare(*img);
  322|  45.0k|  data.dist_ok = comparator_->DistanceOK(target_mul);
  323|  45.0k|  data.jpg_size = encoded_jpg.size();
  324|  45.0k|  MaybeOutput(encoded_jpg);
  325|  45.0k|  return data;
  326|  45.0k|}
_ZN7guetzli20QuantMatrixGenerator7GetNextEPA64_i:
  204|  44.8k|  bool GetNext(int q[3][kDCTBlockSize]) {
  205|       |    // This loop should terminate by return. This 1000 iteration limit is just a
  206|       |    // precaution.
  207|  45.9k|    for (int iter = 0; iter < 1000; iter++) {
  ------------------
  |  Branch (207:24): [True: 45.9k, False: 0]
  ------------------
  208|  45.9k|      double hscore;
  209|  45.9k|      if (hscore_b_ == -1.0) {
  ------------------
  |  Branch (209:11): [True: 26.3k, False: 19.5k]
  ------------------
  210|  26.3k|        if (hscore_a_ == -1.0) {
  ------------------
  |  Branch (210:13): [True: 3.04k, False: 23.2k]
  ------------------
  211|  3.04k|          hscore = downsample_ ? 0.0 : total_csf_;
  ------------------
  |  Branch (211:20): [True: 2.57k, False: 469]
  ------------------
  212|  23.2k|        } else {
  213|  23.2k|          if (hscore_a_ < 5.0 * total_csf_) {
  ------------------
  |  Branch (213:15): [True: 14.4k, False: 8.81k]
  ------------------
  214|  14.4k|            hscore = hscore_a_ + total_csf_;
  215|  14.4k|          } else {
  216|  8.81k|            hscore = 2 * (hscore_a_ + total_csf_);
  217|  8.81k|          }
  218|  23.2k|        }
  219|  26.3k|        if (hscore > 100 * total_csf_) {
  ------------------
  |  Branch (219:13): [True: 1.17k, False: 25.1k]
  ------------------
  220|       |          // We could not find a quantization matrix that creates enough
  221|       |          // butteraugli error. This can happen if all dct coefficients are
  222|       |          // close to zero in the original image.
  223|  1.17k|          return false;
  224|  1.17k|        }
  225|  26.3k|      } else if (hscore_b_ == 0.0) {
  ------------------
  |  Branch (225:18): [True: 0, False: 19.5k]
  ------------------
  226|      0|        return false;
  227|  19.5k|      } else if (hscore_a_ == -1.0) {
  ------------------
  |  Branch (227:18): [True: 17, False: 19.5k]
  ------------------
  228|     17|        hscore = 0.0;
  229|  19.5k|      } else {
  230|  19.5k|        int lower_q[3][kDCTBlockSize];
  231|  19.5k|        int upper_q[3][kDCTBlockSize];
  232|  19.5k|        constexpr double kEps = 0.05;
  233|  19.5k|        GetQuantMatrixWithHeuristicScore(
  234|  19.5k|            (1 - kEps) * hscore_a_ + kEps * 0.5 * (hscore_a_ + hscore_b_),
  235|  19.5k|            lower_q);
  236|  19.5k|        GetQuantMatrixWithHeuristicScore(
  237|  19.5k|            (1 - kEps) * hscore_b_ + kEps * 0.5 * (hscore_a_ + hscore_b_),
  238|  19.5k|            upper_q);
  239|  19.5k|        if (CompareQuantMatrices(&lower_q[0][0], &upper_q[0][0]) == 0)
  ------------------
  |  Branch (239:13): [True: 1.66k, False: 17.9k]
  ------------------
  240|  1.66k|          return false;
  241|  17.9k|        hscore = (hscore_a_ + hscore_b_) * 0.5;
  242|  17.9k|      }
  243|  43.0k|      GetQuantMatrixWithHeuristicScore(hscore, q);
  244|  43.0k|      bool retry = false;
  245|   366k|      for (size_t i = 0; i < quants_.size(); ++i) {
  ------------------
  |  Branch (245:26): [True: 324k, False: 42.0k]
  ------------------
  246|   324k|        if (CompareQuantMatrices(&q[0][0], &quants_[i].q[0][0]) == 0) {
  ------------------
  |  Branch (246:13): [True: 1.07k, False: 323k]
  ------------------
  247|  1.07k|          if (quants_[i].dist_ok) {
  ------------------
  |  Branch (247:15): [True: 0, False: 1.07k]
  ------------------
  248|      0|            hscore_a_ = hscore;
  249|  1.07k|          } else {
  250|  1.07k|            hscore_b_ = hscore;
  251|  1.07k|          }
  252|  1.07k|          retry = true;
  253|  1.07k|          break;
  254|  1.07k|        }
  255|   324k|      }
  256|  43.0k|      if (!retry) return true;
  ------------------
  |  Branch (256:11): [True: 42.0k, False: 1.07k]
  ------------------
  257|  43.0k|    }
  258|      0|    return false;
  259|  44.8k|  }
_ZNK7guetzli20QuantMatrixGenerator32GetQuantMatrixWithHeuristicScoreEdPA64_i:
  273|  82.2k|                                        int q[3][kDCTBlockSize]) const {
  274|  82.2k|    int level = static_cast<int>(score / total_csf_);
  275|  82.2k|    score -= level * total_csf_;
  276|  5.34M|    for (int k = kDCTBlockSize - 1; k >= 0; --k) {
  ------------------
  |  Branch (276:37): [True: 5.26M, False: 82.2k]
  ------------------
  277|  21.0M|      for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (277:23): [True: 15.7M, False: 5.26M]
  ------------------
  278|  15.7M|        q[c][kJPEGNaturalOrder[k]] = 2 * level + (score > 0.0 ? 3 : 1);
  ------------------
  |  Branch (278:51): [True: 7.83M, False: 7.95M]
  ------------------
  279|  15.7M|      }
  280|  5.26M|      score -= 3.0 * ContrastSensitivity(kJPEGNaturalOrder[k]);
  281|  5.26M|    }
  282|  82.2k|  }
processor.cc:_ZN7guetzli20QuantMatrixGenerator3AddERKNS_12_GLOBAL__N_19QuantDataE:
  261|  42.0k|  void Add(const QuantData& data) {
  262|  42.0k|    quants_.push_back(data);
  263|  42.0k|    double hscore = QuantMatrixHeuristicScore(data.q);
  264|  42.0k|    if (data.dist_ok) {
  ------------------
  |  Branch (264:9): [True: 30.5k, False: 11.4k]
  ------------------
  265|  30.5k|      hscore_a_ = std::max(hscore_a_, hscore);
  266|  30.5k|    } else {
  267|  11.4k|      hscore_b_ = hscore_b_ == -1.0 ? hscore : std::min(hscore_b_, hscore);
  ------------------
  |  Branch (267:19): [True: 1.83k, False: 9.63k]
  ------------------
  268|  11.4k|    }
  269|  42.0k|  }
processor.cc:_ZN7guetzli16CompareQuantDataERKNS_12_GLOBAL__N_19QuantDataES3_:
  150|  42.0k|bool CompareQuantData(const QuantData& a, const QuantData& b) {
  151|  42.0k|  if (a.dist_ok && !b.dist_ok) return true;
  ------------------
  |  Branch (151:7): [True: 30.5k, False: 11.4k]
  |  Branch (151:20): [True: 0, False: 30.5k]
  ------------------
  152|  42.0k|  if (!a.dist_ok && b.dist_ok) return false;
  ------------------
  |  Branch (152:7): [True: 11.4k, False: 30.5k]
  |  Branch (152:21): [True: 11.4k, False: 0]
  ------------------
  153|  30.5k|  return a.jpg_size < b.jpg_size;
  154|  42.0k|}
processor.cc:_ZN7guetzli12_GLOBAL__N_19Processor22SelectFrequencyMaskingERKNS_8JPEGDataEPNS_11OutputImageEhdb:
  542|  5.61k|                                       bool stop_early) {
  543|  5.61k|  const int width = img->width();
  544|  5.61k|  const int height = img->height();
  545|  5.61k|  const int ncomp = jpg.components.size();
  546|  5.61k|  const int last_c = Log2FloorNonZero(comp_mask);
  547|  5.61k|  if (static_cast<size_t>(last_c) >= jpg.components.size()) return;
  ------------------
  |  Branch (547:7): [True: 607, False: 5.01k]
  ------------------
  548|  5.01k|  const int factor_x = img->component(last_c).factor_x();
  549|  5.01k|  const int factor_y = img->component(last_c).factor_y();
  550|  5.01k|  const int block_width = (width + 8 * factor_x - 1) / (8 * factor_x);
  551|  5.01k|  const int block_height = (height + 8 * factor_y - 1) / (8 * factor_y);
  552|  5.01k|  const int num_blocks = block_width * block_height;
  553|       |
  554|  5.01k|  std::vector<int> candidate_coeff_offsets(num_blocks + 1);
  555|  5.01k|  std::vector<uint8_t> candidate_coeffs;
  556|  5.01k|  std::vector<float> candidate_coeff_errors;
  557|  5.01k|  candidate_coeffs.reserve(60 * num_blocks);
  558|  5.01k|  candidate_coeff_errors.reserve(60 * num_blocks);
  559|  5.01k|  std::vector<CoeffData> block_order;
  560|  5.01k|  block_order.reserve(3 * kDCTBlockSize);
  561|  5.01k|  comparator_->StartBlockComparisons();
  562|  33.2k|  for (int block_y = 0, block_ix = 0; block_y < block_height; ++block_y) {
  ------------------
  |  Branch (562:39): [True: 28.2k, False: 5.01k]
  ------------------
  563|   205k|    for (int block_x = 0; block_x < block_width; ++block_x, ++block_ix) {
  ------------------
  |  Branch (563:27): [True: 177k, False: 28.2k]
  ------------------
  564|   177k|      coeff_t block[kBlockSize] = { 0 };
  565|   177k|      coeff_t orig_block[kBlockSize] = { 0 };
  566|   710k|      for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (566:23): [True: 532k, False: 177k]
  ------------------
  567|   532k|        if (comp_mask & (1 << c)) {
  ------------------
  |  Branch (567:13): [True: 249k, False: 282k]
  ------------------
  568|   249k|          assert(img->component(c).factor_x() == factor_x);
  569|      0|          assert(img->component(c).factor_y() == factor_y);
  570|      0|          img->component(c).GetCoeffBlock(block_x, block_y,
  571|   249k|                                          &block[c * kDCTBlockSize]);
  572|   249k|          const JPEGComponent& comp = jpg.components[c];
  573|   249k|          int jpg_block_ix = block_y * comp.width_in_blocks + block_x;
  574|   249k|          memcpy(&orig_block[c * kDCTBlockSize],
  575|   249k|                 &comp.coeffs[jpg_block_ix * kDCTBlockSize],
  576|   249k|                 kDCTBlockSize * sizeof(orig_block[0]));
  577|   249k|        }
  578|   532k|      }
  579|   177k|      block_order.clear();
  580|   177k|      ComputeBlockZeroingOrder(block, orig_block, block_x, block_y, factor_x,
  581|   177k|                               factor_y, comp_mask, img, &block_order);
  582|   177k|      candidate_coeff_offsets[block_ix] = candidate_coeffs.size();
  583|  1.99M|      for (size_t i = 0; i < block_order.size(); ++i) {
  ------------------
  |  Branch (583:26): [True: 1.82M, False: 177k]
  ------------------
  584|  1.82M|        candidate_coeffs.push_back(block_order[i].idx);
  585|  1.82M|        candidate_coeff_errors.push_back(block_order[i].block_err);
  586|  1.82M|      }
  587|   177k|    }
  588|  28.2k|  }
  589|  5.01k|  comparator_->FinishBlockComparisons();
  590|  5.01k|  candidate_coeff_offsets[num_blocks] = candidate_coeffs.size();
  591|       |
  592|  5.01k|  std::vector<JpegHistogram> ac_histograms(ncomp);
  593|  5.01k|  int jpg_header_size, dc_size;
  594|  5.01k|  {
  595|  5.01k|    JPEGData jpg_out = jpg;
  596|  5.01k|    img->SaveToJpegData(&jpg_out);
  597|  5.01k|    jpg_header_size = JpegHeaderSize(jpg_out, params_.clear_metadata);
  598|  5.01k|    dc_size = EstimateDCSize(jpg_out);
  599|  5.01k|    BuildACHistograms(jpg_out, &ac_histograms[0]);
  600|  5.01k|  }
  601|  5.01k|  std::vector<uint8_t> ac_depths;
  602|  5.01k|  int ac_histogram_size = ComputeEntropyCodes(ac_histograms, &ac_depths);
  603|  5.01k|  int base_size = jpg_header_size + dc_size + ac_histogram_size +
  604|  5.01k|      EntropyCodedDataSize(ac_histograms, ac_depths);
  605|  5.01k|  int prev_size = base_size;
  606|       |
  607|  5.01k|  std::vector<float> max_block_error(num_blocks);
  608|  5.01k|  std::vector<int> last_indexes(num_blocks);
  609|       |
  610|  5.01k|  bool first_up_iter = true;
  611|  10.0k|  for (int direction : {1, -1}) {
  ------------------
  |  Branch (611:22): [True: 10.0k, False: 5.01k]
  ------------------
  612|   125k|    for (;;) {
  613|   125k|      if (stop_early && direction == -1) {
  ------------------
  |  Branch (613:11): [True: 19.2k, False: 106k]
  |  Branch (613:25): [True: 15.4k, False: 3.86k]
  ------------------
  614|  15.4k|        if (prev_size > 1.01 * final_output_->jpeg_data.size()) {
  ------------------
  |  Branch (614:13): [True: 510, False: 14.9k]
  ------------------
  615|       |          // If we are down-adjusting the error, the output size will only keep
  616|       |          // increasing.
  617|       |          // TODO(user): Do this check always by comparing only the size
  618|       |          // of the currently processed components.
  619|    510|          break;
  620|    510|        }
  621|  15.4k|      }
  622|   124k|      std::vector<std::pair<int, float> > global_order;
  623|   124k|      int blocks_to_change;
  624|   124k|      std::vector<float> block_weight;
  625|   164k|      for (int rblock = 1; rblock <= 4; ++rblock) {
  ------------------
  |  Branch (625:28): [True: 154k, False: 9.51k]
  ------------------
  626|   154k|        block_weight = std::vector<float>(num_blocks);
  627|   154k|        std::vector<float> distmap(width * height);
  628|   154k|        if (!first_up_iter) {
  ------------------
  |  Branch (628:13): [True: 138k, False: 16.3k]
  ------------------
  629|   138k|          distmap = comparator_->distmap();
  630|   138k|        }
  631|   154k|        comparator_->ComputeBlockErrorAdjustmentWeights(
  632|   154k|            direction, rblock, target_mul, factor_x, factor_y, distmap,
  633|   154k|            &block_weight);
  634|   154k|        global_order.clear();
  635|   154k|        blocks_to_change = 0;
  636|  1.04M|        for (int block_y = 0, block_ix = 0; block_y < block_height; ++block_y) {
  ------------------
  |  Branch (636:45): [True: 885k, False: 154k]
  ------------------
  637|  8.37M|          for (int block_x = 0; block_x < block_width; ++block_x, ++block_ix) {
  ------------------
  |  Branch (637:33): [True: 7.49M, False: 885k]
  ------------------
  638|  7.49M|            const int last_index = last_indexes[block_ix];
  639|  7.49M|            const int offset = candidate_coeff_offsets[block_ix];
  640|  7.49M|            const int num_candidates =
  641|  7.49M|                candidate_coeff_offsets[block_ix + 1] - offset;
  642|  7.49M|            const float* candidate_errors = &candidate_coeff_errors[offset];
  643|  7.49M|            const float max_err = max_block_error[block_ix];
  644|  7.49M|            if (block_weight[block_ix] == 0) {
  ------------------
  |  Branch (644:17): [True: 2.64M, False: 4.84M]
  ------------------
  645|  2.64M|              continue;
  646|  2.64M|            }
  647|  4.84M|            if (direction > 0) {
  ------------------
  |  Branch (647:17): [True: 436k, False: 4.40M]
  ------------------
  648|  2.25M|              for (size_t i = last_index; i < num_candidates; ++i) {
  ------------------
  |  Branch (648:43): [True: 1.82M, False: 436k]
  ------------------
  649|  1.82M|                float val = ((candidate_errors[i] - max_err) /
  650|  1.82M|                             block_weight[block_ix]);
  651|  1.82M|                global_order.push_back(std::make_pair(block_ix, val));
  652|  1.82M|              }
  653|   436k|              blocks_to_change += (last_index < num_candidates ? 1 : 0);
  ------------------
  |  Branch (653:36): [True: 72.8k, False: 364k]
  ------------------
  654|  4.40M|            } else {
  655|  97.5M|              for (int i = last_index - 1; i >= 0; --i) {
  ------------------
  |  Branch (655:44): [True: 93.1M, False: 4.40M]
  ------------------
  656|  93.1M|                float val = ((max_err - candidate_errors[i]) /
  657|  93.1M|                             block_weight[block_ix]);
  658|  93.1M|                global_order.push_back(std::make_pair(block_ix, val));
  659|  93.1M|              }
  660|  4.40M|              blocks_to_change += (last_index > 0 ? 1 : 0);
  ------------------
  |  Branch (660:36): [True: 3.52M, False: 878k]
  ------------------
  661|  4.40M|            }
  662|  4.84M|          }
  663|   885k|        }
  664|   154k|        if (!global_order.empty()) {
  ------------------
  |  Branch (664:13): [True: 115k, False: 39.4k]
  ------------------
  665|       |          // If we found something to adjust with the current block adjustment
  666|       |          // radius, we can stop and adjust the blocks we have.
  667|   115k|          break;
  668|   115k|        }
  669|   154k|      }
  670|       |
  671|   124k|      if (global_order.empty()) {
  ------------------
  |  Branch (671:11): [True: 9.51k, False: 115k]
  ------------------
  672|  9.51k|        break;
  673|  9.51k|      }
  674|       |
  675|   115k|      std::sort(global_order.begin(), global_order.end(),
  676|   115k|                [](const std::pair<int, float>& a,
  677|   115k|                   const std::pair<int, float>& b) {
  678|   115k|                  return a.second < b.second; });
  679|       |
  680|   115k|      double rel_size_delta = direction > 0 ? 0.01 : 0.0005;
  ------------------
  |  Branch (680:31): [True: 3.45k, False: 111k]
  ------------------
  681|   115k|      if (direction > 0 && comparator_->DistanceOK(1.0)) {
  ------------------
  |  Branch (681:11): [True: 3.45k, False: 111k]
  |  Branch (681:28): [True: 2.99k, False: 457]
  ------------------
  682|  2.99k|        rel_size_delta = 0.05;
  683|  2.99k|      }
  684|   115k|      double min_size_delta = base_size * rel_size_delta;
  685|       |
  686|   115k|      float coeffs_to_change_per_block =
  687|   115k|          direction > 0 ? 2.0f : factor_x * factor_y * 0.2f;
  ------------------
  |  Branch (687:11): [True: 3.45k, False: 111k]
  ------------------
  688|   115k|      int min_coeffs_to_change = coeffs_to_change_per_block * blocks_to_change;
  689|       |
  690|   115k|      if (first_up_iter) {
  ------------------
  |  Branch (690:11): [True: 3.37k, False: 112k]
  ------------------
  691|  3.37k|        const float limit = 0.75f * comparator_->BlockErrorLimit();
  692|  3.37k|        auto it = std::partition_point(global_order.begin(), global_order.end(),
  693|  3.37k|                                       [=](const std::pair<int, float>& a) {
  694|  3.37k|                                         return a.second < limit; });
  695|  3.37k|        min_coeffs_to_change = std::max<int>(min_coeffs_to_change,
  696|  3.37k|                                             it - global_order.begin());
  697|  3.37k|        first_up_iter = false;
  698|  3.37k|      }
  699|       |
  700|   115k|      std::set<int> changed_blocks;
  701|   115k|      float val_threshold = 0.0;
  702|   115k|      int changed_coeffs = 0;
  703|   115k|      int est_jpg_size = prev_size;
  704|  2.52M|      for (size_t i = 0; i < global_order.size(); ++i) {
  ------------------
  |  Branch (704:26): [True: 2.52M, False: 1.72k]
  ------------------
  705|  2.52M|        const int block_ix = global_order[i].first;
  706|  2.52M|        const int block_x = block_ix % block_width;
  707|  2.52M|        const int block_y = block_ix / block_width;
  708|  2.52M|        const int last_idx = last_indexes[block_ix];
  709|  2.52M|        const int offset = candidate_coeff_offsets[block_ix];
  710|  2.52M|        const uint8_t* candidates = &candidate_coeffs[offset];
  711|  2.52M|        const int idx = candidates[last_idx + std::min(direction, 0)];
  712|  2.52M|        const int c = idx / kDCTBlockSize;
  713|  2.52M|        const int k = idx % kDCTBlockSize;
  714|  2.52M|        const int* quant = img->component(c).quant();
  715|  2.52M|        const JPEGComponent& comp = jpg.components[c];
  716|  2.52M|        const int jpg_block_ix = block_y * comp.width_in_blocks + block_x;
  717|  2.52M|        const int newval = direction > 0 ? 0 : Quantize(
  ------------------
  |  Branch (717:28): [True: 1.63M, False: 886k]
  ------------------
  718|   886k|            comp.coeffs[jpg_block_ix * kDCTBlockSize + k], quant[k]);
  719|  2.52M|        coeff_t block[kDCTBlockSize] = { 0 };
  720|  2.52M|        img->component(c).GetCoeffBlock(block_x, block_y, block);
  721|  2.52M|        UpdateACHistogram(-1, block, quant, &ac_histograms[c]);
  722|  2.52M|        double sum_of_hf = 0;
  723|   156M|        for (int ii = 3; ii < 64; ++ii) {
  ------------------
  |  Branch (723:26): [True: 154M, False: 2.52M]
  ------------------
  724|   154M|          if ((ii & 7) < 3 && ii < 3 * 8) continue;
  ------------------
  |  Branch (724:15): [True: 53.0M, False: 100M]
  |  Branch (724:31): [True: 15.1M, False: 37.8M]
  ------------------
  725|   138M|          sum_of_hf += std::abs(comp.coeffs[jpg_block_ix * kDCTBlockSize + ii]);
  726|   138M|        }
  727|  2.52M|        int limit = sum_of_hf < 60 ? 4 : 8;
  ------------------
  |  Branch (727:21): [True: 39.1k, False: 2.48M]
  ------------------
  728|  2.52M|        bool precious =
  729|  2.52M|            (k == 1 || k == 8) &&
  ------------------
  |  Branch (729:14): [True: 35.5k, False: 2.48M]
  |  Branch (729:24): [True: 34.2k, False: 2.45M]
  ------------------
  730|  2.52M|            std::abs(comp.coeffs[jpg_block_ix * kDCTBlockSize + k]) >= limit;
  ------------------
  |  Branch (730:13): [True: 38.5k, False: 31.2k]
  ------------------
  731|  2.52M|        if (!precious || newval != 0) {
  ------------------
  |  Branch (731:13): [True: 2.48M, False: 38.5k]
  |  Branch (731:26): [True: 11.7k, False: 26.8k]
  ------------------
  732|  2.49M|          block[k] = newval;
  733|  2.49M|        }
  734|  2.52M|        UpdateACHistogram(1, block, quant, &ac_histograms[c]);
  735|  2.52M|        img->component(c).SetCoeffBlock(block_x, block_y, block);
  736|  2.52M|        last_indexes[block_ix] += direction;
  737|  2.52M|        changed_blocks.insert(block_ix);
  738|  2.52M|        val_threshold = global_order[i].second;
  739|  2.52M|        ++changed_coeffs;
  740|  2.52M|        static const int kEntropyCodeUpdateFreq = 10;
  741|  2.52M|        if (i % kEntropyCodeUpdateFreq == 0) {
  ------------------
  |  Branch (741:13): [True: 315k, False: 2.20M]
  ------------------
  742|   315k|          ac_histogram_size = ComputeEntropyCodes(ac_histograms, &ac_depths);
  743|   315k|        }
  744|  2.52M|        est_jpg_size = jpg_header_size + dc_size + ac_histogram_size +
  745|  2.52M|            EntropyCodedDataSize(ac_histograms, ac_depths);
  746|  2.52M|        if (changed_coeffs > min_coeffs_to_change &&
  ------------------
  |  Branch (746:13): [True: 178k, False: 2.34M]
  ------------------
  747|  2.52M|            std::abs(est_jpg_size - prev_size) > min_size_delta) {
  ------------------
  |  Branch (747:13): [True: 113k, False: 64.5k]
  ------------------
  748|   113k|          break;
  749|   113k|        }
  750|  2.52M|      }
  751|   115k|      size_t global_order_size = global_order.size();
  752|   115k|      std::vector<std::pair<int, float>>().swap(global_order);
  753|       |
  754|  6.06M|      for (int i = 0; i < num_blocks; ++i) {
  ------------------
  |  Branch (754:23): [True: 5.94M, False: 115k]
  ------------------
  755|  5.94M|        max_block_error[i] += block_weight[i] * val_threshold * direction;
  756|  5.94M|      }
  757|       |
  758|   115k|      ++stats_->counters[kNumItersCnt];
  759|   115k|      ++stats_->counters[direction > 0 ? kNumItersUpCnt : kNumItersDownCnt];
  ------------------
  |  Branch (759:26): [True: 3.45k, False: 111k]
  ------------------
  760|   115k|      std::string encoded_jpg;
  761|   115k|      {
  762|   115k|        JPEGData jpg_out = jpg;
  763|   115k|        img->SaveToJpegData(&jpg_out);
  764|   115k|        OutputJpeg(jpg_out, &encoded_jpg);
  765|   115k|      }
  766|   115k|      GUETZLI_LOG(stats_,
  ------------------
  |  |   29|   115k|  do {                                                             \
  |  |   30|   115k|    char debug_string[1024];                                       \
  |  |   31|   115k|    int res = snprintf(debug_string, sizeof(debug_string),         \
  |  |   32|   230k|                       __VA_ARGS__);                               \
  |  |  ------------------
  |  |  |  Branch (32:24): [True: 3.45k, False: 111k]
  |  |  ------------------
  |  |   33|   115k|    assert(res > 0 && "expected successful printing");             \
  |  |   34|   115k|    (void)res;                                                     \
  |  |   35|   115k|    debug_string[sizeof(debug_string) - 1] = '\0';                 \
  |  |   36|   115k|    ::guetzli::PrintDebug(                      \
  |  |   37|   115k|         stats, std::string(debug_string));        \
  |  |   38|   115k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (38:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  767|   115k|                  "Iter %2d: %s(%d) %s Coeffs[%d/%zd] "
  768|   115k|                  "Blocks[%zd/%d/%d] ValThres[%.4f] Out[%7zd] EstErr[%.2f%%]",
  769|   115k|                  stats_->counters[kNumItersCnt], img->FrameTypeStr().c_str(),
  770|   115k|                  comp_mask, direction > 0 ? "up" : "down", changed_coeffs,
  771|   115k|                  global_order_size, changed_blocks.size(),
  772|   115k|                  blocks_to_change, num_blocks, val_threshold,
  773|   115k|                  encoded_jpg.size(),
  774|   115k|                  100.0 - (100.0 * est_jpg_size) / encoded_jpg.size());
  775|      0|      comparator_->Compare(*img);
  776|   115k|      MaybeOutput(encoded_jpg);
  777|   115k|      prev_size = est_jpg_size;
  778|   115k|    }
  779|  10.0k|  }
  780|  5.01k|}
processor.cc:_ZN7guetzli12_GLOBAL__N_19Processor24ComputeBlockZeroingOrderEPKsS3_iiiihPNS_11OutputImageEPNSt3__16vectorINS0_9CoeffDataENS6_9allocatorIS8_EEEE:
  368|   177k|    std::vector<CoeffData>* output_order) {
  369|   177k|  static const uint8_t oldCsf[kDCTBlockSize] = {
  370|   177k|      10, 10, 20, 40, 60, 70, 80, 90,
  371|   177k|      10, 20, 30, 60, 70, 80, 90, 90,
  372|   177k|      20, 30, 60, 70, 80, 90, 90, 90,
  373|   177k|      40, 60, 70, 80, 90, 90, 90, 90,
  374|   177k|      60, 70, 80, 90, 90, 90, 90, 90,
  375|   177k|      70, 80, 90, 90, 90, 90, 90, 90,
  376|   177k|      80, 90, 90, 90, 90, 90, 90, 90,
  377|   177k|      90, 90, 90, 90, 90, 90, 90, 90,
  378|   177k|  };
  379|   177k|  static const double kWeight[3] = { 1.0, 0.22, 0.20 };
  380|   177k|#include "guetzli/order.inc"
  ------------------
  |  |    1|       |// Automatically generated by guetzli/order:update_c_code
  |  |    2|       |
  |  |    3|   177k|static const float csf[192] = {
  |  |    4|   177k|  0.0f,
  |  |    5|   177k|  1.71014f,
  |  |    6|   177k|  0.298711f,
  |  |    7|   177k|  0.233709f,
  |  |    8|   177k|  0.223126f,
  |  |    9|   177k|  0.207072f,
  |  |   10|   177k|  0.192775f,
  |  |   11|   177k|  0.161201f,
  |  |   12|   177k|  2.05807f,
  |  |   13|   177k|  0.222927f,
  |  |   14|   177k|  0.203406f,
  |  |   15|   177k|  0.188465f,
  |  |   16|   177k|  0.184668f,
  |  |   17|   177k|  0.169993f,
  |  |   18|   177k|  0.159142f,
  |  |   19|   177k|  0.130155f,
  |  |   20|   177k|  0.430518f,
  |  |   21|   177k|  0.204939f,
  |  |   22|   177k|  0.206655f,
  |  |   23|   177k|  0.192231f,
  |  |   24|   177k|  0.182941f,
  |  |   25|   177k|  0.169455f,
  |  |   26|   177k|  0.157599f,
  |  |   27|   177k|  0.127153f,
  |  |   28|   177k|  0.234757f,
  |  |   29|   177k|  0.191098f,
  |  |   30|   177k|  0.192698f,
  |  |   31|   177k|  0.17425f,
  |  |   32|   177k|  0.166503f,
  |  |   33|   177k|  0.142154f,
  |  |   34|   177k|  0.126182f,
  |  |   35|   177k|  0.104196f,
  |  |   36|   177k|  0.226117f,
  |  |   37|   177k|  0.185373f,
  |  |   38|   177k|  0.183825f,
  |  |   39|   177k|  0.166643f,
  |  |   40|   177k|  0.159414f,
  |  |   41|   177k|  0.12636f,
  |  |   42|   177k|  0.108696f,
  |  |   43|   177k|  0.0911974f,
  |  |   44|   177k|  0.207463f,
  |  |   45|   177k|  0.171517f,
  |  |   46|   177k|  0.170124f,
  |  |   47|   177k|  0.141582f,
  |  |   48|   177k|  0.126213f,
  |  |   49|   177k|  0.103627f,
  |  |   50|   177k|  0.0882436f,
  |  |   51|   177k|  0.0751848f,
  |  |   52|   177k|  0.196436f,
  |  |   53|   177k|  0.161947f,
  |  |   54|   177k|  0.159271f,
  |  |   55|   177k|  0.126938f,
  |  |   56|   177k|  0.109125f,
  |  |   57|   177k|  0.0878027f,
  |  |   58|   177k|  0.0749842f,
  |  |   59|   177k|  0.0633859f,
  |  |   60|   177k|  0.165232f,
  |  |   61|   177k|  0.132905f,
  |  |   62|   177k|  0.128679f,
  |  |   63|   177k|  0.105766f,
  |  |   64|   177k|  0.0906087f,
  |  |   65|   177k|  0.0751544f,
  |  |   66|   177k|  0.0641187f,
  |  |   67|   177k|  0.0529921f,
  |  |   68|   177k|  0.0f,
  |  |   69|   177k|  0.147235f,
  |  |   70|   177k|  0.11264f,
  |  |   71|   177k|  0.0757892f,
  |  |   72|   177k|  0.0493929f,
  |  |   73|   177k|  0.0280663f,
  |  |   74|   177k|  0.0075012f,
  |  |   75|   177k|  -0.000945567f,
  |  |   76|   177k|  0.149251f,
  |  |   77|   177k|  0.0964806f,
  |  |   78|   177k|  0.0786224f,
  |  |   79|   177k|  0.05206f,
  |  |   80|   177k|  0.0292758f,
  |  |   81|   177k|  0.00353094f,
  |  |   82|   177k|  -0.00277912f,
  |  |   83|   177k|  -0.00404481f,
  |  |   84|   177k|  0.115551f,
  |  |   85|   177k|  0.0793142f,
  |  |   86|   177k|  0.0623735f,
  |  |   87|   177k|  0.0405019f,
  |  |   88|   177k|  0.0152656f,
  |  |   89|   177k|  -0.00145742f,
  |  |   90|   177k|  -0.00370369f,
  |  |   91|   177k|  -0.00375106f,
  |  |   92|   177k|  0.0791547f,
  |  |   93|   177k|  0.0537506f,
  |  |   94|   177k|  0.0413634f,
  |  |   95|   177k|  0.0193486f,
  |  |   96|   177k|  0.000609066f,
  |  |   97|   177k|  -0.00510923f,
  |  |   98|   177k|  -0.0046452f,
  |  |   99|   177k|  -0.00385187f,
  |  |  100|   177k|  0.0544534f,
  |  |  101|   177k|  0.0334066f,
  |  |  102|   177k|  0.0153899f,
  |  |  103|   177k|  0.000539088f,
  |  |  104|   177k|  -0.00356085f,
  |  |  105|   177k|  -0.00535661f,
  |  |  106|   177k|  -0.00429145f,
  |  |  107|   177k|  -0.00343131f,
  |  |  108|   177k|  0.0356439f,
  |  |  109|   177k|  0.00865645f,
  |  |  110|   177k|  0.00165229f,
  |  |  111|   177k|  -0.00425931f,
  |  |  112|   177k|  -0.00507324f,
  |  |  113|   177k|  -0.00459083f,
  |  |  114|   177k|  -0.003703f,
  |  |  115|   177k|  -0.00310327f,
  |  |  116|   177k|  0.0121926f,
  |  |  117|   177k|  -0.0009259f,
  |  |  118|   177k|  -0.00330991f,
  |  |  119|   177k|  -0.00499378f,
  |  |  120|   177k|  -0.00437381f,
  |  |  121|   177k|  -0.00377427f,
  |  |  122|   177k|  -0.00311731f,
  |  |  123|   177k|  -0.00255125f,
  |  |  124|   177k|  -0.000320593f,
  |  |  125|   177k|  -0.00426043f,
  |  |  126|   177k|  -0.00416549f,
  |  |  127|   177k|  -0.00419364f,
  |  |  128|   177k|  -0.00365418f,
  |  |  129|   177k|  -0.00317499f,
  |  |  130|   177k|  -0.00255932f,
  |  |  131|   177k|  -0.00217917f,
  |  |  132|   177k|  0.0f,
  |  |  133|   177k|  0.143471f,
  |  |  134|   177k|  0.124336f,
  |  |  135|   177k|  0.0947465f,
  |  |  136|   177k|  0.0814066f,
  |  |  137|   177k|  0.0686776f,
  |  |  138|   177k|  0.0588122f,
  |  |  139|   177k|  0.0374415f,
  |  |  140|   177k|  0.146315f,
  |  |  141|   177k|  0.105334f,
  |  |  142|   177k|  0.0949415f,
  |  |  143|   177k|  0.0784241f,
  |  |  144|   177k|  0.0689064f,
  |  |  145|   177k|  0.0588304f,
  |  |  146|   177k|  0.0495961f,
  |  |  147|   177k|  0.0202342f,
  |  |  148|   177k|  0.123818f,
  |  |  149|   177k|  0.0952654f,
  |  |  150|   177k|  0.0860556f,
  |  |  151|   177k|  0.0724158f,
  |  |  152|   177k|  0.0628307f,
  |  |  153|   177k|  0.0529965f,
  |  |  154|   177k|  0.0353941f,
  |  |  155|   177k|  0.00815821f,
  |  |  156|   177k|  0.097054f,
  |  |  157|   177k|  0.080422f,
  |  |  158|   177k|  0.0731085f,
  |  |  159|   177k|  0.0636154f,
  |  |  160|   177k|  0.055606f,
  |  |  161|   177k|  0.0384127f,
  |  |  162|   177k|  0.0142879f,
  |  |  163|   177k|  0.00105195f,
  |  |  164|   177k|  0.0849312f,
  |  |  165|   177k|  0.071115f,
  |  |  166|   177k|  0.0631183f,
  |  |  167|   177k|  0.0552972f,
  |  |  168|   177k|  0.0369221f,
  |  |  169|   177k|  0.00798314f,
  |  |  170|   177k|  0.000716374f,
  |  |  171|   177k|  -0.00200948f,
  |  |  172|   177k|  0.0722298f,
  |  |  173|   177k|  0.0599559f,
  |  |  174|   177k|  0.054841f,
  |  |  175|   177k|  0.0387529f,
  |  |  176|   177k|  0.0107262f,
  |  |  177|   177k|  0.000355315f,
  |  |  178|   177k|  -0.00244803f,
  |  |  179|   177k|  -0.00335222f,
  |  |  180|   177k|  0.0635335f,
  |  |  181|   177k|  0.0514196f,
  |  |  182|   177k|  0.0406309f,
  |  |  183|   177k|  0.0125833f,
  |  |  184|   177k|  0.00151305f,
  |  |  185|   177k|  -0.00140269f,
  |  |  186|   177k|  -0.00362547f,
  |  |  187|   177k|  -0.00337649f,
  |  |  188|   177k|  0.0472024f,
  |  |  189|   177k|  0.0198725f,
  |  |  190|   177k|  0.0113437f,
  |  |  191|   177k|  0.00266305f,
  |  |  192|   177k|  -0.00137183f,
  |  |  193|   177k|  -0.00354158f,
  |  |  194|   177k|  -0.00341292f,
  |  |  195|   177k|  -0.00290074f
  |  |  196|   177k|};
  |  |  197|       |
  |  |  198|   177k|static const float bias[192] = {
  |  |  199|   177k|  0.0f,
  |  |  200|   177k|  0.0f,
  |  |  201|   177k|  0.0f,
  |  |  202|   177k|  0.0f,
  |  |  203|   177k|  0.0f,
  |  |  204|   177k|  0.0f,
  |  |  205|   177k|  0.0f,
  |  |  206|   177k|  0.0f,
  |  |  207|   177k|  0.0f,
  |  |  208|   177k|  0.0f,
  |  |  209|   177k|  0.0f,
  |  |  210|   177k|  0.0f,
  |  |  211|   177k|  0.0f,
  |  |  212|   177k|  0.0f,
  |  |  213|   177k|  0.0f,
  |  |  214|   177k|  0.0f,
  |  |  215|   177k|  0.0f,
  |  |  216|   177k|  0.0f,
  |  |  217|   177k|  0.0f,
  |  |  218|   177k|  0.0f,
  |  |  219|   177k|  0.0f,
  |  |  220|   177k|  0.0f,
  |  |  221|   177k|  0.0f,
  |  |  222|   177k|  0.0f,
  |  |  223|   177k|  0.0f,
  |  |  224|   177k|  0.0f,
  |  |  225|   177k|  0.0f,
  |  |  226|   177k|  0.0f,
  |  |  227|   177k|  0.0f,
  |  |  228|   177k|  0.0f,
  |  |  229|   177k|  0.0f,
  |  |  230|   177k|  0.0f,
  |  |  231|   177k|  0.0f,
  |  |  232|   177k|  0.0f,
  |  |  233|   177k|  0.0f,
  |  |  234|   177k|  0.0f,
  |  |  235|   177k|  0.0f,
  |  |  236|   177k|  0.0f,
  |  |  237|   177k|  0.0f,
  |  |  238|   177k|  0.0f,
  |  |  239|   177k|  0.0f,
  |  |  240|   177k|  0.0f,
  |  |  241|   177k|  0.0f,
  |  |  242|   177k|  0.0f,
  |  |  243|   177k|  0.0f,
  |  |  244|   177k|  0.0f,
  |  |  245|   177k|  0.0f,
  |  |  246|   177k|  0.0f,
  |  |  247|   177k|  0.0f,
  |  |  248|   177k|  0.0f,
  |  |  249|   177k|  0.0f,
  |  |  250|   177k|  0.0f,
  |  |  251|   177k|  0.0f,
  |  |  252|   177k|  0.0f,
  |  |  253|   177k|  0.0f,
  |  |  254|   177k|  0.0f,
  |  |  255|   177k|  0.0f,
  |  |  256|   177k|  0.0f,
  |  |  257|   177k|  0.0f,
  |  |  258|   177k|  0.0f,
  |  |  259|   177k|  0.0f,
  |  |  260|   177k|  0.0f,
  |  |  261|   177k|  0.0f,
  |  |  262|   177k|  0.0f,
  |  |  263|   177k|  0.0f,
  |  |  264|   177k|  0.0f,
  |  |  265|   177k|  0.0f,
  |  |  266|   177k|  0.0f,
  |  |  267|   177k|  0.0f,
  |  |  268|   177k|  0.0f,
  |  |  269|   177k|  0.0f,
  |  |  270|   177k|  0.0f,
  |  |  271|   177k|  0.0f,
  |  |  272|   177k|  0.0f,
  |  |  273|   177k|  0.0f,
  |  |  274|   177k|  0.0f,
  |  |  275|   177k|  0.0f,
  |  |  276|   177k|  0.0f,
  |  |  277|   177k|  0.0f,
  |  |  278|   177k|  0.0f,
  |  |  279|   177k|  0.0f,
  |  |  280|   177k|  0.0f,
  |  |  281|   177k|  0.0f,
  |  |  282|   177k|  0.0f,
  |  |  283|   177k|  0.0f,
  |  |  284|   177k|  0.0f,
  |  |  285|   177k|  0.0f,
  |  |  286|   177k|  0.0f,
  |  |  287|   177k|  0.0f,
  |  |  288|   177k|  0.0f,
  |  |  289|   177k|  0.0f,
  |  |  290|   177k|  0.0f,
  |  |  291|   177k|  0.0f,
  |  |  292|   177k|  0.0f,
  |  |  293|   177k|  0.0f,
  |  |  294|   177k|  0.0f,
  |  |  295|   177k|  0.0f,
  |  |  296|   177k|  0.0f,
  |  |  297|   177k|  0.0f,
  |  |  298|   177k|  0.0f,
  |  |  299|   177k|  0.0f,
  |  |  300|   177k|  0.0f,
  |  |  301|   177k|  0.0f,
  |  |  302|   177k|  0.0f,
  |  |  303|   177k|  0.0f,
  |  |  304|   177k|  0.0f,
  |  |  305|   177k|  0.0f,
  |  |  306|   177k|  0.0f,
  |  |  307|   177k|  0.0f,
  |  |  308|   177k|  0.0f,
  |  |  309|   177k|  0.0f,
  |  |  310|   177k|  0.0f,
  |  |  311|   177k|  0.0f,
  |  |  312|   177k|  0.0f,
  |  |  313|   177k|  0.0f,
  |  |  314|   177k|  0.0f,
  |  |  315|   177k|  0.0f,
  |  |  316|   177k|  0.0f,
  |  |  317|   177k|  0.0f,
  |  |  318|   177k|  0.0f,
  |  |  319|   177k|  0.0f,
  |  |  320|   177k|  0.0f,
  |  |  321|   177k|  0.0f,
  |  |  322|   177k|  0.0f,
  |  |  323|   177k|  0.0f,
  |  |  324|   177k|  0.0f,
  |  |  325|   177k|  0.0f,
  |  |  326|   177k|  0.0f,
  |  |  327|   177k|  0.0f,
  |  |  328|   177k|  0.0f,
  |  |  329|   177k|  0.0f,
  |  |  330|   177k|  0.0f,
  |  |  331|   177k|  0.0f,
  |  |  332|   177k|  0.0f,
  |  |  333|   177k|  0.0f,
  |  |  334|   177k|  0.0f,
  |  |  335|   177k|  0.0f,
  |  |  336|   177k|  0.0f,
  |  |  337|   177k|  0.0f,
  |  |  338|   177k|  0.0f,
  |  |  339|   177k|  0.0f,
  |  |  340|   177k|  0.0f,
  |  |  341|   177k|  0.0f,
  |  |  342|   177k|  0.0f,
  |  |  343|   177k|  0.0f,
  |  |  344|   177k|  0.0f,
  |  |  345|   177k|  0.0f,
  |  |  346|   177k|  0.0f,
  |  |  347|   177k|  0.0f,
  |  |  348|   177k|  0.0f,
  |  |  349|   177k|  0.0f,
  |  |  350|   177k|  0.0f,
  |  |  351|   177k|  0.0f,
  |  |  352|   177k|  0.0f,
  |  |  353|   177k|  0.0f,
  |  |  354|   177k|  0.0f,
  |  |  355|   177k|  0.0f,
  |  |  356|   177k|  0.0f,
  |  |  357|   177k|  0.0f,
  |  |  358|   177k|  0.0f,
  |  |  359|   177k|  0.0f,
  |  |  360|   177k|  0.0f,
  |  |  361|   177k|  0.0f,
  |  |  362|   177k|  0.0f,
  |  |  363|   177k|  0.0f,
  |  |  364|   177k|  0.0f,
  |  |  365|   177k|  0.0f,
  |  |  366|   177k|  0.0f,
  |  |  367|   177k|  0.0f,
  |  |  368|   177k|  0.0f,
  |  |  369|   177k|  0.0f,
  |  |  370|   177k|  0.0f,
  |  |  371|   177k|  0.0f,
  |  |  372|   177k|  0.0f,
  |  |  373|   177k|  0.0f,
  |  |  374|   177k|  0.0f,
  |  |  375|   177k|  0.0f,
  |  |  376|   177k|  0.0f,
  |  |  377|   177k|  0.0f,
  |  |  378|   177k|  0.0f,
  |  |  379|   177k|  0.0f,
  |  |  380|   177k|  0.0f,
  |  |  381|   177k|  0.0f,
  |  |  382|   177k|  0.0f,
  |  |  383|   177k|  0.0f,
  |  |  384|   177k|  0.0f,
  |  |  385|   177k|  0.0f,
  |  |  386|   177k|  0.0f,
  |  |  387|   177k|  0.0f,
  |  |  388|   177k|  0.0f,
  |  |  389|   177k|  0.0f,
  |  |  390|   177k|  0.0
  |  |  391|   177k|};
  ------------------
  381|   177k|  std::vector<std::pair<int, float> > input_order;
  382|   710k|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (382:19): [True: 532k, False: 177k]
  ------------------
  383|   532k|    if (!(comp_mask & (1 << c))) continue;
  ------------------
  |  Branch (383:9): [True: 282k, False: 249k]
  ------------------
  384|  15.9M|    for (int k = 1; k < kDCTBlockSize; ++k) {
  ------------------
  |  Branch (384:21): [True: 15.7M, False: 249k]
  ------------------
  385|  15.7M|      int idx = c * kDCTBlockSize + k;
  386|  15.7M|      if (block[idx] != 0) {
  ------------------
  |  Branch (386:11): [True: 2.10M, False: 13.6M]
  ------------------
  387|  2.10M|        float score;
  388|  2.10M|        if (params_.new_zeroing_model) {
  ------------------
  |  Branch (388:13): [True: 2.10M, False: 0]
  ------------------
  389|  2.10M|          score = std::abs(orig_block[idx]) * csf[idx] + bias[idx];
  390|  2.10M|        } else {
  391|      0|          score = static_cast<float>((std::abs(orig_block[idx]) - kJPEGZigZagOrder[k] / 64.0) *
  392|      0|                  kWeight[c] / oldCsf[k]);
  393|      0|        }
  394|  2.10M|        input_order.push_back(std::make_pair(idx, score));
  395|  2.10M|      }
  396|  15.7M|    }
  397|   249k|  }
  398|   177k|  std::sort(input_order.begin(), input_order.end(),
  399|   177k|            [](const std::pair<int, float>& a, const std::pair<int, float>& b) {
  400|   177k|              return a.second < b.second; });
  401|   177k|  coeff_t processed_block[kBlockSize];
  402|   177k|  memcpy(processed_block, block, sizeof(processed_block));
  403|   177k|  comparator_->SwitchBlock(block_x, block_y, factor_x, factor_y);
  404|  2.28M|  while (!input_order.empty()) {
  ------------------
  |  Branch (404:10): [True: 2.10M, False: 177k]
  ------------------
  405|  2.10M|    float best_err = 1e17f;
  406|  2.10M|    int best_i = 0;
  407|  8.18M|    for (size_t i = 0; i < std::min<size_t>(params_.zeroing_greedy_lookahead,
  ------------------
  |  Branch (407:24): [True: 6.08M, False: 2.10M]
  ------------------
  408|  8.18M|                                         input_order.size());
  409|  6.08M|         ++i) {
  410|  6.08M|      coeff_t candidate_block[kBlockSize];
  411|  6.08M|      memcpy(candidate_block, processed_block, sizeof(candidate_block));
  412|  6.08M|      const int idx = input_order[i].first;
  413|  6.08M|      candidate_block[idx] = 0;
  414|  24.3M|      for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (414:23): [True: 18.2M, False: 6.08M]
  ------------------
  415|  18.2M|        if (comp_mask & (1 << c)) {
  ------------------
  |  Branch (415:13): [True: 8.72M, False: 9.52M]
  ------------------
  416|  8.72M|          img->component(c).SetCoeffBlock(
  417|  8.72M|              block_x, block_y, &candidate_block[c * kDCTBlockSize]);
  418|  8.72M|        }
  419|  18.2M|      }
  420|  6.08M|      float max_err = 0;
  421|  12.7M|      for (int iy = 0; iy < factor_y; ++iy) {
  ------------------
  |  Branch (421:24): [True: 6.64M, False: 6.08M]
  ------------------
  422|  14.4M|        for (int ix = 0; ix < factor_x; ++ix) {
  ------------------
  |  Branch (422:26): [True: 7.77M, False: 6.64M]
  ------------------
  423|  7.77M|          int block_xx = block_x * factor_x + ix;
  424|  7.77M|          int block_yy = block_y * factor_y + iy;
  425|  7.77M|          if (8 * block_xx < img->width() && 8 * block_yy < img->height()) {
  ------------------
  |  Branch (425:15): [True: 7.62M, False: 145k]
  |  Branch (425:46): [True: 7.43M, False: 197k]
  ------------------
  426|  7.43M|            float err = static_cast<float>(comparator_->CompareBlock(*img, ix, iy));
  427|  7.43M|            max_err = std::max(max_err, err);
  428|  7.43M|          }
  429|  7.77M|        }
  430|  6.64M|      }
  431|  6.08M|      if (max_err < best_err) {
  ------------------
  |  Branch (431:11): [True: 4.06M, False: 2.01M]
  ------------------
  432|  4.06M|        best_err = max_err;
  433|  4.06M|        best_i = i;
  434|  4.06M|      }
  435|  6.08M|    }
  436|  2.10M|    int idx = input_order[best_i].first;
  437|  2.10M|    processed_block[idx] = 0;
  438|  2.10M|    input_order.erase(input_order.begin() + best_i);
  439|  2.10M|    output_order->push_back({idx, best_err});
  440|  8.41M|    for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (440:21): [True: 6.30M, False: 2.10M]
  ------------------
  441|  6.30M|      if (comp_mask & (1 << c)) {
  ------------------
  |  Branch (441:11): [True: 3.02M, False: 3.28M]
  ------------------
  442|  3.02M|        img->component(c).SetCoeffBlock(
  443|  3.02M|            block_x, block_y, &processed_block[c * kDCTBlockSize]);
  444|  3.02M|      }
  445|  6.30M|    }
  446|  2.10M|  }
  447|       |  // Make the block error values monotonic.
  448|   177k|  float min_err = 1e10;
  449|  2.28M|  for (int i = output_order->size() - 1; i >= 0; --i) {
  ------------------
  |  Branch (449:42): [True: 2.10M, False: 177k]
  ------------------
  450|  2.10M|    min_err = std::min(min_err, (*output_order)[i].block_err);
  451|  2.10M|    (*output_order)[i].block_err = min_err;
  452|  2.10M|  }
  453|       |  // Cut off at the block error limit.
  454|   177k|  size_t num = 0;
  455|  1.99M|  while (num < output_order->size() &&
  ------------------
  |  Branch (455:10): [True: 1.86M, False: 129k]
  ------------------
  456|  1.99M|         (*output_order)[num].block_err <= comparator_->BlockErrorLimit()) {
  ------------------
  |  Branch (456:10): [True: 1.82M, False: 47.6k]
  ------------------
  457|  1.82M|    ++num;
  458|  1.82M|  }
  459|   177k|  output_order->resize(num);
  460|       |  // Restore *img to the same state as it was at the start of this function.
  461|   710k|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (461:19): [True: 532k, False: 177k]
  ------------------
  462|   532k|    if (comp_mask & (1 << c)) {
  ------------------
  |  Branch (462:9): [True: 249k, False: 282k]
  ------------------
  463|   249k|      img->component(c).SetCoeffBlock(
  464|   249k|          block_x, block_y, &block[c * kDCTBlockSize]);
  465|   249k|    }
  466|   532k|  }
  467|   177k|}
processor.cc:_ZZN7guetzli12_GLOBAL__N_19Processor24ComputeBlockZeroingOrderEPKsS3_iiiihPNS_11OutputImageEPNSt3__16vectorINS0_9CoeffDataENS6_9allocatorIS8_EEEEENK3$_0clERKNS6_4pairIifEESH_:
  399|  11.5M|            [](const std::pair<int, float>& a, const std::pair<int, float>& b) {
  400|  11.5M|              return a.second < b.second; });
processor.cc:_ZN7guetzli12_GLOBAL__N_114EstimateDCSizeERKNS_8JPEGDataE:
  528|  5.01k|size_t EstimateDCSize(const JPEGData& jpg) {
  529|  5.01k|  std::vector<JpegHistogram> histograms(jpg.components.size());
  530|  5.01k|  BuildDCHistograms(jpg, &histograms[0]);
  531|  5.01k|  size_t num = histograms.size();
  532|  5.01k|  std::vector<int> indexes(num);
  533|  5.01k|  std::vector<uint8_t> depths(num * JpegHistogram::kSize);
  534|  5.01k|  return ClusterHistograms(&histograms[0], &num, &indexes[0], &depths[0]);
  535|  5.01k|}
processor.cc:_ZN7guetzli12_GLOBAL__N_119ComputeEntropyCodesERKNSt3__16vectorINS_13JpegHistogramENS1_9allocatorIS3_EEEEPNS2_IhNS4_IhEEEE:
  498|   320k|                           std::vector<uint8_t>* depths) {
  499|   320k|  std::vector<JpegHistogram> clustered = histograms;
  500|   320k|  size_t num = histograms.size();
  501|   320k|  std::vector<int> indexes(histograms.size());
  502|   320k|  std::vector<uint8_t> clustered_depths(
  503|   320k|      histograms.size() * JpegHistogram::kSize);
  504|   320k|  ClusterHistograms(&clustered[0], &num, &indexes[0], &clustered_depths[0]);
  505|   320k|  depths->resize(clustered_depths.size());
  506|  1.22M|  for (size_t i = 0; i < histograms.size(); ++i) {
  ------------------
  |  Branch (506:22): [True: 908k, False: 320k]
  ------------------
  507|   908k|    memcpy(&(*depths)[i * JpegHistogram::kSize],
  508|   908k|           &clustered_depths[indexes[i] * JpegHistogram::kSize],
  509|   908k|           JpegHistogram::kSize);
  510|   908k|  }
  511|   320k|  size_t histogram_size = 0;
  512|   760k|  for (size_t i = 0; i < num; ++i) {
  ------------------
  |  Branch (512:22): [True: 440k, False: 320k]
  ------------------
  513|   440k|    histogram_size += HistogramHeaderCost(clustered[i]) / 8;
  514|   440k|  }
  515|   320k|  return histogram_size;
  516|   320k|}
processor.cc:_ZN7guetzli12_GLOBAL__N_120EntropyCodedDataSizeERKNSt3__16vectorINS_13JpegHistogramENS1_9allocatorIS3_EEEERKNS2_IhNS4_IhEEEE:
  519|  2.52M|                            const std::vector<uint8_t>& depths) {
  520|  2.52M|  size_t numbits = 0;
  521|  9.78M|  for (size_t i = 0; i < histograms.size(); ++i) {
  ------------------
  |  Branch (521:22): [True: 7.25M, False: 2.52M]
  ------------------
  522|  7.25M|    numbits += HistogramEntropyCost(
  523|  7.25M|        histograms[i], &depths[i * JpegHistogram::kSize]);
  524|  7.25M|  }
  525|  2.52M|  return (numbits + 7) / 8;
  526|  2.52M|}
processor.cc:_ZZN7guetzli12_GLOBAL__N_19Processor22SelectFrequencyMaskingERKNS_8JPEGDataEPNS_11OutputImageEhdbENK3$_1clERKNSt3__14pairIifEESC_:
  677|  1.04G|                   const std::pair<int, float>& b) {
  678|  1.04G|                  return a.second < b.second; });
processor.cc:_ZZN7guetzli12_GLOBAL__N_19Processor22SelectFrequencyMaskingERKNS_8JPEGDataEPNS_11OutputImageEhdbENK3$_2clERKNSt3__14pairIifEE:
  693|  21.7k|                                       [=](const std::pair<int, float>& a) {
  694|  21.7k|                                         return a.second < limit; });
processor.cc:_ZN7guetzli12_GLOBAL__N_117UpdateACHistogramEiPKsPKiPNS_13JpegHistogramE:
  474|  5.04M|                       JpegHistogram* ac_histogram) {
  475|  5.04M|  int r = 0;
  476|   323M|  for (int k = 1; k < 64; ++k) {
  ------------------
  |  Branch (476:19): [True: 318M, False: 5.04M]
  ------------------
  477|   318M|    const int k_nat = kJPEGNaturalOrder[k];
  478|   318M|    coeff_t coeff = coeffs[k_nat];
  479|   318M|    if (coeff == 0) {
  ------------------
  |  Branch (479:9): [True: 182M, False: 135M]
  ------------------
  480|   182M|      r++;
  481|   182M|      continue;
  482|   182M|    }
  483|   138M|    while (r > 15) {
  ------------------
  |  Branch (483:12): [True: 2.50M, False: 135M]
  ------------------
  484|  2.50M|      ac_histogram->Add(0xf0, weight);
  485|  2.50M|      r -= 16;
  486|  2.50M|    }
  487|   135M|    int nbits = Log2FloorNonZero(std::abs(coeff / q[k_nat])) + 1;
  488|   135M|    int symbol = (r << 4) + nbits;
  489|   135M|    ac_histogram->Add(symbol, weight);
  490|   135M|    r = 0;
  491|   135M|  }
  492|  5.04M|  if (r > 0) {
  ------------------
  |  Branch (492:7): [True: 3.85M, False: 1.19M]
  ------------------
  493|  3.85M|    ac_histogram->Add(0, weight);
  494|  3.85M|  }
  495|  5.04M|}
processor.cc:_ZN7guetzli12_GLOBAL__N_115CheckJpegSanityERKNS_8JPEGDataE:
  106|  3.27k|bool CheckJpegSanity(const JPEGData& jpg) {
  107|  3.27k|  const int kMaxComponent = 1 << 12;
  108|  9.63k|  for (const JPEGComponent& comp : jpg.components) {
  ------------------
  |  Branch (108:34): [True: 9.63k, False: 3.26k]
  ------------------
  109|  9.63k|    const JPEGQuantTable& quant_table = jpg.quant[comp.quant_idx];
  110|  34.0M|    for (int i = 0; i < comp.coeffs.size(); i++) {
  ------------------
  |  Branch (110:21): [True: 33.9M, False: 9.62k]
  ------------------
  111|  33.9M|      coeff_t coeff = comp.coeffs[i];
  112|  33.9M|      int quant = quant_table.values[i % kDCTBlockSize];
  113|  33.9M|      if (std::abs(static_cast<int64_t>(coeff) * quant) > kMaxComponent) {
  ------------------
  |  Branch (113:11): [True: 12, False: 33.9M]
  ------------------
  114|     12|        return false;
  115|     12|      }
  116|  33.9M|    }
  117|  9.63k|  }
  118|  3.26k|  return true;
  119|  3.27k|}

_ZN7guetzli13QuantizeBlockEPsPKi:
   22|  3.97M|                   const int q[kDCTBlockSize]) {
   23|  3.97M|  bool changed = false;
   24|   258M|  for (int k = 0; k < kDCTBlockSize; ++k) {
  ------------------
  |  Branch (24:19): [True: 254M, False: 3.97M]
  ------------------
   25|   254M|    coeff_t coeff = Quantize(block[k], q[k]);
   26|   254M|    changed = changed || (coeff != block[k]);
  ------------------
  |  Branch (26:15): [True: 77.6M, False: 176M]
  |  Branch (26:26): [True: 1.37M, False: 175M]
  ------------------
   27|   254M|    block[k] = coeff;
   28|   254M|  }
   29|  3.97M|  return changed;
   30|  3.97M|}

_ZN7guetzli8QuantizeEsi:
   24|   255M|inline coeff_t Quantize(coeff_t raw_coeff, int quant) {
   25|   255M|  const int r = raw_coeff % quant;
   26|   255M|  const coeff_t delta =
   27|   255M|      2 * r > quant ? quant - r : (-2) * r > quant ? -quant - r : -r;
  ------------------
  |  Branch (27:7): [True: 3.24M, False: 252M]
  |  Branch (27:35): [True: 11.2M, False: 240M]
  ------------------
   28|   255M|  return raw_coeff + delta;
   29|   255M|}

_ZN7guetzli9ScoreJPEGEdid:
   24|   163k|                 double butteraugli_target) {
   25|   163k|  constexpr double kScale = 50;
   26|   163k|  constexpr double kMaxExponent = 10;
   27|   163k|  constexpr double kLargeSize = 1e30;
   28|       |  // TODO(user): The score should also depend on distance below target (and be
   29|       |  // smooth).
   30|   163k|  double diff = butteraugli_distance - butteraugli_target;
   31|   163k|  if (diff <= 0.0) {
  ------------------
  |  Branch (31:7): [True: 43.7k, False: 119k]
  ------------------
   32|  43.7k|    return size;
   33|   119k|  } else {
   34|   119k|    double exponent = kScale * diff;
   35|   119k|    if (exponent > kMaxExponent) {
  ------------------
  |  Branch (35:9): [True: 102k, False: 17.6k]
  ------------------
   36|   102k|      return kLargeSize * std::exp(kMaxExponent) * diff + size;
   37|   102k|    } else {
   38|  17.6k|      return std::exp(exponent) * size;
   39|  17.6k|    }
   40|   119k|  }
   41|   163k|}

_ZN7guetzli12ProcessStatsC2Ev:
   34|  3.23k|  ProcessStats() {}

_ZN11butteraugli12CacheAligned8AllocateEm:
   60|   106M|void *CacheAligned::Allocate(const size_t bytes) {
   61|   106M|  char *const allocated = static_cast<char *>(malloc(bytes + kCacheLineSize));
   62|   106M|  if (allocated == nullptr) {
  ------------------
  |  Branch (62:7): [True: 0, False: 106M]
  ------------------
   63|      0|    return nullptr;
   64|      0|  }
   65|   106M|  const uintptr_t misalignment =
   66|   106M|      reinterpret_cast<uintptr_t>(allocated) & (kCacheLineSize - 1);
   67|       |  // malloc is at least kPointerSize aligned, so we can store the "allocated"
   68|       |  // pointer immediately before the aligned memory.
   69|   106M|  assert(misalignment % kPointerSize == 0);
   70|      0|  char *const aligned = allocated + kCacheLineSize - misalignment;
   71|   106M|  memcpy(aligned - kPointerSize, &allocated, kPointerSize);
   72|   106M|  return BUTTERAUGLI_ASSUME_ALIGNED(aligned, 64);
  ------------------
  |  |  137|   106M|#define BUTTERAUGLI_ASSUME_ALIGNED(ptr, align) __builtin_assume_aligned((ptr), (align))
  ------------------
   73|   106M|}
_ZN11butteraugli12CacheAligned4FreeEPv:
   75|   106M|void CacheAligned::Free(void *aligned_pointer) {
   76|   106M|  if (aligned_pointer == nullptr) {
  ------------------
  |  Branch (76:7): [True: 0, False: 106M]
  ------------------
   77|      0|    return;
   78|      0|  }
   79|   106M|  char *const aligned = static_cast<char *>(aligned_pointer);
   80|   106M|  assert(reinterpret_cast<uintptr_t>(aligned) % kCacheLineSize == 0);
   81|      0|  char *allocated;
   82|   106M|  memcpy(&allocated, aligned - kPointerSize, kPointerSize);
   83|   106M|  assert(allocated <= aligned - kPointerSize);
   84|      0|  assert(allocated >= aligned - kCacheLineSize);
   85|      0|  free(allocated);
   86|   106M|}
_ZN11butteraugli13ComputeKernelEf:
  145|  26.2M|std::vector<float> ComputeKernel(float sigma) {
  146|  26.2M|  const float m = 2.25;  // Accuracy increases when m is increased.
  147|  26.2M|  const float scaler = -1.0 / (2 * sigma * sigma);
  148|  26.2M|  const int diff = std::max<int>(1, m * fabs(sigma));
  149|  26.2M|  std::vector<float> kernel(2 * diff + 1);
  150|   199M|  for (int i = -diff; i <= diff; ++i) {
  ------------------
  |  Branch (150:23): [True: 172M, False: 26.2M]
  ------------------
  151|   172M|    kernel[i + diff] = exp(scaler * i * i);
  152|   172M|  }
  153|  26.2M|  return kernel;
  154|  26.2M|}
_ZN11butteraugli20ConvolveBorderColumnERKNS_5ImageIfEERKNSt3__16vectorIfNS4_9allocatorIfEEEEffmPf:
  162|   293M|    float* const BUTTERAUGLI_RESTRICT row_out) {
  163|   293M|  const int offset = kernel.size() / 2;
  164|   293M|  int minx = x < offset ? 0 : x - offset;
  ------------------
  |  Branch (164:14): [True: 149M, False: 143M]
  ------------------
  165|   293M|  int maxx = std::min<int>(in.xsize() - 1, x + offset);
  166|   293M|  float weight = 0.0f;
  167|  3.33G|  for (int j = minx; j <= maxx; ++j) {
  ------------------
  |  Branch (167:22): [True: 3.04G, False: 293M]
  ------------------
  168|  3.04G|    weight += kernel[j - x + offset];
  169|  3.04G|  }
  170|       |  // Interpolate linearly between the no-border scaling and border scaling.
  171|   293M|  weight = (1.0f - border_ratio) * weight + border_ratio * weight_no_border;
  172|   293M|  float scale = 1.0f / weight;
  173|  7.74G|  for (size_t y = 0; y < in.ysize(); ++y) {
  ------------------
  |  Branch (173:22): [True: 7.45G, False: 293M]
  ------------------
  174|  7.45G|    const float* const BUTTERAUGLI_RESTRICT row_in = in.Row(y);
  175|  7.45G|    float sum = 0.0f;
  176|   144G|    for (int j = minx; j <= maxx; ++j) {
  ------------------
  |  Branch (176:24): [True: 137G, False: 7.45G]
  ------------------
  177|   137G|      sum += row_in[j] * kernel[j - x + offset];
  178|   137G|    }
  179|  7.45G|    row_out[y] = sum * scale;
  180|  7.45G|  }
  181|   293M|}
_ZN11butteraugli11ConvolutionERKNS_5ImageIfEERKNSt3__16vectorIfNS4_9allocatorIfEEEEf:
  186|  52.5M|                   const float border_ratio) {
  187|  52.5M|  ImageF out(in.ysize(), in.xsize());
  188|  52.5M|  const int len = kernel.size();
  189|  52.5M|  const int offset = kernel.size() / 2;
  190|  52.5M|  float weight_no_border = 0.0f;
  191|   398M|  for (int j = 0; j < len; ++j) {
  ------------------
  |  Branch (191:19): [True: 345M, False: 52.5M]
  ------------------
  192|   345M|    weight_no_border += kernel[j];
  193|   345M|  }
  194|  52.5M|  float scale_no_border = 1.0f / weight_no_border;
  195|  52.5M|  const int border1 = in.xsize() <= offset ? in.xsize() : offset;
  ------------------
  |  Branch (195:23): [True: 0, False: 52.5M]
  ------------------
  196|  52.5M|  const int border2 = in.xsize() - offset;
  197|  52.5M|  std::vector<float> scaled_kernel = kernel;
  198|   398M|  for (int i = 0; i < scaled_kernel.size(); ++i) {
  ------------------
  |  Branch (198:19): [True: 345M, False: 52.5M]
  ------------------
  199|   345M|    scaled_kernel[i] *= scale_no_border;
  200|   345M|  }
  201|       |  // left border
  202|   199M|  for (int x = 0; x < border1; ++x) {
  ------------------
  |  Branch (202:19): [True: 146M, False: 52.5M]
  ------------------
  203|   146M|    ConvolveBorderColumn(in, kernel, weight_no_border, border_ratio, x,
  204|   146M|                         out.Row(x));
  205|   146M|  }
  206|       |  // middle
  207|   770M|  for (size_t y = 0; y < in.ysize(); ++y) {
  ------------------
  |  Branch (207:22): [True: 718M, False: 52.5M]
  ------------------
  208|   718M|    const float* const BUTTERAUGLI_RESTRICT row_in = in.Row(y);
  209|  15.5G|    for (int x = border1; x < border2; ++x) {
  ------------------
  |  Branch (209:27): [True: 14.8G, False: 718M]
  ------------------
  210|  14.8G|      const int d = x - offset;
  211|  14.8G|      float* const BUTTERAUGLI_RESTRICT row_out = out.Row(x);
  212|  14.8G|      float sum = 0.0f;
  213|   197G|      for (int j = 0; j < len; ++j) {
  ------------------
  |  Branch (213:23): [True: 182G, False: 14.8G]
  ------------------
  214|   182G|        sum += row_in[d + j] * scaled_kernel[j];
  215|   182G|      }
  216|  14.8G|      row_out[y] = sum;
  217|  14.8G|    }
  218|   718M|  }
  219|       |  // right border
  220|   199M|  for (int x = border2; x < in.xsize(); ++x) {
  ------------------
  |  Branch (220:25): [True: 146M, False: 52.5M]
  ------------------
  221|   146M|    ConvolveBorderColumn(in, kernel, weight_no_border, border_ratio, x,
  222|   146M|                         out.Row(x));
  223|   146M|  }
  224|  52.5M|  return out;
  225|  52.5M|}
_ZN11butteraugli4BlurERKNS_5ImageIfEEff:
  229|  26.2M|ImageF Blur(const ImageF& in, float sigma, float border_ratio) {
  230|  26.2M|  std::vector<float> kernel = ComputeKernel(sigma);
  231|  26.2M|  return Convolution(Convolution(in, kernel, border_ratio),
  232|  26.2M|                     kernel, border_ratio);
  233|  26.2M|}
_ZN11butteraugli18OpsinDynamicsImageERKNSt3__16vectorINS_5ImageIfEENS0_9allocatorIS3_EEEE:
  324|  8.03M|std::vector<ImageF> OpsinDynamicsImage(const std::vector<ImageF>& rgb) {
  325|  8.03M|  PROFILER_FUNC;
  326|  8.03M|  std::vector<ImageF> xyb(3);
  327|  8.03M|  std::vector<ImageF> blurred(3);
  328|  8.03M|  const double kSigma = 1.2;
  329|  32.1M|  for (int i = 0; i < 3; ++i) {
  ------------------
  |  Branch (329:19): [True: 24.0M, False: 8.03M]
  ------------------
  330|  24.0M|    xyb[i] = ImageF(rgb[i].xsize(), rgb[i].ysize());
  331|  24.0M|    blurred[i] = Blur(rgb[i], kSigma, 0.0f);
  332|  24.0M|  }
  333|  85.5M|  for (size_t y = 0; y < rgb[0].ysize(); ++y) {
  ------------------
  |  Branch (333:22): [True: 77.5M, False: 8.03M]
  ------------------
  334|  77.5M|    const float* const BUTTERAUGLI_RESTRICT row_r = rgb[0].Row(y);
  335|  77.5M|    const float* const BUTTERAUGLI_RESTRICT row_g = rgb[1].Row(y);
  336|  77.5M|    const float* const BUTTERAUGLI_RESTRICT row_b = rgb[2].Row(y);
  337|  77.5M|    const float* const BUTTERAUGLI_RESTRICT row_blurred_r = blurred[0].Row(y);
  338|  77.5M|    const float* const BUTTERAUGLI_RESTRICT row_blurred_g = blurred[1].Row(y);
  339|  77.5M|    const float* const BUTTERAUGLI_RESTRICT row_blurred_b = blurred[2].Row(y);
  340|  77.5M|    float* const BUTTERAUGLI_RESTRICT row_out_x = xyb[0].Row(y);
  341|  77.5M|    float* const BUTTERAUGLI_RESTRICT row_out_y = xyb[1].Row(y);
  342|  77.5M|    float* const BUTTERAUGLI_RESTRICT row_out_b = xyb[2].Row(y);
  343|  1.58G|    for (size_t x = 0; x < rgb[0].xsize(); ++x) {
  ------------------
  |  Branch (343:24): [True: 1.50G, False: 77.5M]
  ------------------
  344|  1.50G|      float sensitivity[3];
  345|  1.50G|      {
  346|       |        // Calculate sensitivity based on the smoothed image gamma derivative.
  347|  1.50G|        float pre_mixed0, pre_mixed1, pre_mixed2;
  348|  1.50G|        OpsinAbsorbance(row_blurred_r[x], row_blurred_g[x], row_blurred_b[x],
  349|  1.50G|                        &pre_mixed0, &pre_mixed1, &pre_mixed2);
  350|       |        // TODO: use new polynomial to compute Gamma(x)/x derivative.
  351|  1.50G|        sensitivity[0] = Gamma(pre_mixed0) / pre_mixed0;
  352|  1.50G|        sensitivity[1] = Gamma(pre_mixed1) / pre_mixed1;
  353|  1.50G|        sensitivity[2] = Gamma(pre_mixed2) / pre_mixed2;
  354|  1.50G|      }
  355|  1.50G|      float cur_mixed0, cur_mixed1, cur_mixed2;
  356|  1.50G|      OpsinAbsorbance(row_r[x], row_g[x], row_b[x],
  357|  1.50G|                      &cur_mixed0, &cur_mixed1, &cur_mixed2);
  358|  1.50G|      cur_mixed0 *= sensitivity[0];
  359|  1.50G|      cur_mixed1 *= sensitivity[1];
  360|  1.50G|      cur_mixed2 *= sensitivity[2];
  361|  1.50G|      RgbToXyb(cur_mixed0, cur_mixed1, cur_mixed2,
  362|  1.50G|               &row_out_x[x], &row_out_y[x], &row_out_b[x]);
  363|  1.50G|    }
  364|  77.5M|  }
  365|  8.03M|  return xyb;
  366|  8.03M|}
_ZN11butteraugli16CalculateDiffmapERKNS_5ImageIfEE:
  718|   163k|ImageF CalculateDiffmap(const ImageF& diffmap_in) {
  719|   163k|  PROFILER_FUNC;
  720|       |  // Take square root.
  721|   163k|  ImageF diffmap(diffmap_in.xsize(), diffmap_in.ysize());
  722|   163k|  static const float kInitialSlope = 100.0f;
  723|  7.92M|  for (size_t y = 0; y < diffmap.ysize(); ++y) {
  ------------------
  |  Branch (723:22): [True: 7.76M, False: 163k]
  ------------------
  724|  7.76M|    const float* const BUTTERAUGLI_RESTRICT row_in = diffmap_in.Row(y);
  725|  7.76M|    float* const BUTTERAUGLI_RESTRICT row_out = diffmap.Row(y);
  726|   504M|    for (size_t x = 0; x < diffmap.xsize(); ++x) {
  ------------------
  |  Branch (726:24): [True: 496M, False: 7.76M]
  ------------------
  727|   496M|      const float orig_val = row_in[x];
  728|       |      // TODO(b/29974893): Until that is fixed do not call sqrt on very small
  729|       |      // numbers.
  730|   496M|      row_out[x] = (orig_val < (1.0f / (kInitialSlope * kInitialSlope))
  ------------------
  |  Branch (730:21): [True: 48.7M, False: 448M]
  ------------------
  731|   496M|                    ? kInitialSlope * orig_val
  732|   496M|                    : std::sqrt(orig_val));
  733|   496M|    }
  734|  7.76M|  }
  735|   163k|  {
  736|   163k|    static const double kSigma = 1.72547472444;
  737|   163k|    static const double mul1 = 0.458794906198;
  738|   163k|    static const float scale = 1.0f / (1.0f + mul1);
  739|   163k|    static const double border_ratio = 1.0; // 2.01209066992;
  740|   163k|    ImageF blurred = Blur(diffmap, kSigma, border_ratio);
  741|  7.92M|    for (int y = 0; y < diffmap.ysize(); ++y) {
  ------------------
  |  Branch (741:21): [True: 7.76M, False: 163k]
  ------------------
  742|  7.76M|      const float* const BUTTERAUGLI_RESTRICT row_blurred = blurred.Row(y);
  743|  7.76M|      float* const BUTTERAUGLI_RESTRICT row = diffmap.Row(y);
  744|   504M|      for (int x = 0; x < diffmap.xsize(); ++x) {
  ------------------
  |  Branch (744:23): [True: 496M, False: 7.76M]
  ------------------
  745|   496M|        row[x] += mul1 * row_blurred[x];
  746|   496M|        row[x] *= scale;
  747|   496M|      }
  748|  7.76M|    }
  749|   163k|  }
  750|   163k|  return diffmap;
  751|   163k|}
_ZN11butteraugli15MaskPsychoImageERKNS_11PsychoImageES2_mmPNSt3__16vectorINS_5ImageIfEENS3_9allocatorIS6_EEEESA_:
  756|   163k|                     std::vector<ImageF>* BUTTERAUGLI_RESTRICT mask_dc) {
  757|   163k|  std::vector<ImageF> mask_xyb0 = CreatePlanes<float>(xsize, ysize, 3);
  758|   163k|  std::vector<ImageF> mask_xyb1 = CreatePlanes<float>(xsize, ysize, 3);
  759|   163k|  static const double muls[4] = {
  760|   163k|    0,
  761|   163k|    1.64178305129,
  762|   163k|    0.831081703362,
  763|   163k|    3.23680933546,
  764|   163k|  };
  765|   490k|  for (int i = 0; i < 2; ++i) {
  ------------------
  |  Branch (765:19): [True: 327k, False: 163k]
  ------------------
  766|   327k|    double a = muls[2 * i];
  767|   327k|    double b = muls[2 * i + 1];
  768|  15.8M|    for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (768:24): [True: 15.5M, False: 327k]
  ------------------
  769|  15.5M|      const float* const BUTTERAUGLI_RESTRICT row_hf0 = pi0.hf[i].Row(y);
  770|  15.5M|      const float* const BUTTERAUGLI_RESTRICT row_hf1 = pi1.hf[i].Row(y);
  771|  15.5M|      const float* const BUTTERAUGLI_RESTRICT row_uhf0 = pi0.uhf[i].Row(y);
  772|  15.5M|      const float* const BUTTERAUGLI_RESTRICT row_uhf1 = pi1.uhf[i].Row(y);
  773|  15.5M|      float* const BUTTERAUGLI_RESTRICT row0 = mask_xyb0[i].Row(y);
  774|  15.5M|      float* const BUTTERAUGLI_RESTRICT row1 = mask_xyb1[i].Row(y);
  775|  1.00G|      for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (775:26): [True: 993M, False: 15.5M]
  ------------------
  776|   993M|        row0[x] = a * row_uhf0[x] + b * row_hf0[x];
  777|   993M|        row1[x] = a * row_uhf1[x] + b * row_hf1[x];
  778|   993M|      }
  779|  15.5M|    }
  780|   327k|  }
  781|   163k|  Mask(mask_xyb0, mask_xyb1, mask, mask_dc);
  782|   163k|}
_ZN11butteraugli21ButteraugliComparatorC2ERKNSt3__16vectorINS_5ImageIfEENS1_9allocatorIS4_EEEE:
  787|  3.10k|      num_pixels_(xsize_ * ysize_) {
  788|  3.10k|  if (xsize_ < 8 || ysize_ < 8) return;
  ------------------
  |  Branch (788:7): [True: 0, False: 3.10k]
  |  Branch (788:21): [True: 0, False: 3.10k]
  ------------------
  789|  3.10k|  std::vector<ImageF> xyb0 = OpsinDynamicsImage(rgb0);
  790|  3.10k|  SeparateFrequencies(xsize_, ysize_, xyb0, pi0_);
  791|  3.10k|}
_ZNK11butteraugli21ButteraugliComparator7DiffmapERKNSt3__16vectorINS_5ImageIfEENS1_9allocatorIS4_EEEERS4_:
  800|   163k|                                    ImageF &result) const {
  801|   163k|  PROFILER_FUNC;
  802|   163k|  if (xsize_ < 8 || ysize_ < 8) return;
  ------------------
  |  Branch (802:7): [True: 0, False: 163k]
  |  Branch (802:21): [True: 0, False: 163k]
  ------------------
  803|   163k|  DiffmapOpsinDynamicsImage(OpsinDynamicsImage(rgb1), result);
  804|   163k|}
_ZNK11butteraugli21ButteraugliComparator25DiffmapOpsinDynamicsImageERKNSt3__16vectorINS_5ImageIfEENS1_9allocatorIS4_EEEERS4_:
  808|   163k|    ImageF &result) const {
  809|   163k|  PROFILER_FUNC;
  810|   163k|  if (xsize_ < 8 || ysize_ < 8) return;
  ------------------
  |  Branch (810:7): [True: 0, False: 163k]
  |  Branch (810:21): [True: 0, False: 163k]
  ------------------
  811|   163k|  PsychoImage pi1;
  812|   163k|  SeparateFrequencies(xsize_, ysize_, xyb1, pi1);
  813|   163k|  result = ImageF(xsize_, ysize_);
  814|   163k|  DiffmapPsychoImage(pi1, result);
  815|   163k|}
_ZNK11butteraugli21ButteraugliComparator18DiffmapPsychoImageERKNS_11PsychoImageERNS_5ImageIfEE:
  818|   163k|                                               ImageF& result) const {
  819|   163k|  PROFILER_FUNC;
  820|   163k|  const float hf_asymmetry_ = 0.8f;
  821|   163k|  if (xsize_ < 8 || ysize_ < 8) {
  ------------------
  |  Branch (821:7): [True: 0, False: 163k]
  |  Branch (821:21): [True: 0, False: 163k]
  ------------------
  822|      0|    return;
  823|      0|  }
  824|   163k|  std::vector<ImageF> block_diff_dc(3);
  825|   163k|  std::vector<ImageF> block_diff_ac(3);
  826|   654k|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (826:19): [True: 490k, False: 163k]
  ------------------
  827|   490k|    block_diff_dc[c] = ImageF(xsize_, ysize_, 0.0);
  828|   490k|    block_diff_ac[c] = ImageF(xsize_, ysize_, 0.0);
  829|   490k|  }
  830|       |
  831|   163k|  static const double wUhfMalta = 5.1409625726;
  832|   163k|  static const double norm1Uhf = 58.5001247061;
  833|   163k|  MaltaDiffMap(pi0_.uhf[1], pi1.uhf[1],
  834|   163k|               wUhfMalta * hf_asymmetry_,
  835|   163k|               wUhfMalta / hf_asymmetry_,
  836|   163k|               norm1Uhf,
  837|   163k|               &block_diff_ac[1]);
  838|       |
  839|   163k|  static const double wUhfMaltaX = 4.91743441556;
  840|   163k|  static const double norm1UhfX = 687196.39002;
  841|   163k|  MaltaDiffMap(pi0_.uhf[0], pi1.uhf[0],
  842|   163k|               wUhfMaltaX * hf_asymmetry_,
  843|   163k|               wUhfMaltaX / hf_asymmetry_,
  844|   163k|               norm1UhfX,
  845|   163k|               &block_diff_ac[0]);
  846|       |
  847|   163k|  static const double wHfMalta = 153.671655716;
  848|   163k|  static const double norm1Hf = 83150785.9592;
  849|   163k|  MaltaDiffMapLF(pi0_.hf[1], pi1.hf[1],
  850|   163k|                 wHfMalta * sqrt(hf_asymmetry_),
  851|   163k|                 wHfMalta / sqrt(hf_asymmetry_),
  852|   163k|                 norm1Hf,
  853|   163k|                 &block_diff_ac[1]);
  854|       |
  855|   163k|  static const double wHfMaltaX = 668.358918152;
  856|   163k|  static const double norm1HfX = 0.882954368025;
  857|   163k|  MaltaDiffMapLF(pi0_.hf[0], pi1.hf[0],
  858|   163k|                 wHfMaltaX * sqrt(hf_asymmetry_),
  859|   163k|                 wHfMaltaX / sqrt(hf_asymmetry_),
  860|   163k|                 norm1HfX,
  861|   163k|                 &block_diff_ac[0]);
  862|       |
  863|   163k|  static const double wMfMalta = 6841.81248144;
  864|   163k|  static const double norm1Mf = 0.0135134962487;
  865|   163k|  MaltaDiffMapLF(pi0_.mf[1], pi1.mf[1], wMfMalta, wMfMalta, norm1Mf,
  866|   163k|                 &block_diff_ac[1]);
  867|       |
  868|   163k|  static const double wMfMaltaX = 813.901703816;
  869|   163k|  static const double norm1MfX = 16792.9322251;
  870|   163k|  MaltaDiffMapLF(pi0_.mf[0], pi1.mf[0], wMfMaltaX, wMfMaltaX, norm1MfX,
  871|   163k|                 &block_diff_ac[0]);
  872|       |
  873|   163k|  static const double wmul[9] = {
  874|   163k|    0,
  875|   163k|    32.4449876135,
  876|   163k|    0,
  877|   163k|    0,
  878|   163k|    0,
  879|   163k|    0,
  880|   163k|    1.01370836411,
  881|   163k|    0,
  882|   163k|    1.74566011615,
  883|   163k|  };
  884|       |
  885|   163k|  static const double maxclamp = 85.7047444518;
  886|   163k|  static const double kSigmaHfX = 10.6666499623;
  887|   163k|  static const double w = 884.809801415;
  888|   163k|  SameNoiseLevels(pi0_.hf[1], pi1.hf[1], kSigmaHfX, w, maxclamp,
  889|   163k|                  &block_diff_ac[1]);
  890|       |
  891|   654k|  for (int c = 0; c < 3; ++c) {
  ------------------
  |  Branch (891:19): [True: 490k, False: 163k]
  ------------------
  892|   490k|    if (c < 2) {
  ------------------
  |  Branch (892:9): [True: 327k, False: 163k]
  ------------------
  893|   327k|      L2DiffAsymmetric(pi0_.hf[c], pi1.hf[c],
  894|   327k|                       wmul[c] * hf_asymmetry_,
  895|   327k|                       wmul[c] / hf_asymmetry_,
  896|   327k|                       &block_diff_ac[c]);
  897|   327k|    }
  898|   490k|    L2Diff(pi0_.mf[c], pi1.mf[c], wmul[3 + c], &block_diff_ac[c]);
  899|   490k|    L2Diff(pi0_.lf[c], pi1.lf[c], wmul[6 + c], &block_diff_dc[c]);
  900|   490k|  }
  901|       |
  902|   163k|  std::vector<ImageF> mask_xyb;
  903|   163k|  std::vector<ImageF> mask_xyb_dc;
  904|   163k|  MaskPsychoImage(pi0_, pi1, xsize_, ysize_, &mask_xyb, &mask_xyb_dc);
  905|       |
  906|   163k|  result = CalculateDiffmap(
  907|   163k|      CombineChannels(mask_xyb, mask_xyb_dc, block_diff_dc, block_diff_ac));
  908|   163k|}
_ZNK11butteraugli21ButteraugliComparator12MaltaDiffMapERKNS_5ImageIfEES4_dddPS2_:
 1574|   327k|    const double norm1, ImageF* BUTTERAUGLI_RESTRICT block_diff_ac) const {
 1575|   327k|  PROFILER_FUNC;
 1576|   327k|  const double len = 3.75;
 1577|   327k|  static const double mulli = 0.354191303559;
 1578|   327k|  MaltaDiffMapImpl<MaltaTag>(lum0, lum1, xsize_, ysize_, w_0gt1, w_0lt1,
 1579|   327k|                             norm1, len,
 1580|   327k|                             mulli, block_diff_ac);
 1581|   327k|}
_ZNK11butteraugli21ButteraugliComparator14MaltaDiffMapLFERKNS_5ImageIfEES4_dddPS2_:
 1587|   654k|    const double norm1, ImageF* BUTTERAUGLI_RESTRICT block_diff_ac) const {
 1588|   654k|  PROFILER_FUNC;
 1589|   654k|  const double len = 3.75;
 1590|   654k|  static const double mulli = 0.405371989604;
 1591|   654k|  MaltaDiffMapImpl<MaltaTagLF>(lum0, lum1, xsize_, ysize_,
 1592|   654k|                               w_0gt1, w_0lt1,
 1593|   654k|                               norm1, len,
 1594|   654k|                               mulli, block_diff_ac);
 1595|   654k|}
_ZNK11butteraugli21ButteraugliComparator15CombineChannelsERKNSt3__16vectorINS_5ImageIfEENS1_9allocatorIS4_EEEES9_S9_S9_:
 1601|   163k|    const std::vector<ImageF>& block_diff_ac) const {
 1602|   163k|  PROFILER_FUNC;
 1603|   163k|  ImageF result(xsize_, ysize_);
 1604|  7.92M|  for (size_t y = 0; y < ysize_; ++y) {
  ------------------
  |  Branch (1604:22): [True: 7.76M, False: 163k]
  ------------------
 1605|  7.76M|    float* const BUTTERAUGLI_RESTRICT row_out = result.Row(y);
 1606|   504M|    for (size_t x = 0; x < xsize_; ++x) {
  ------------------
  |  Branch (1606:24): [True: 496M, False: 7.76M]
  ------------------
 1607|   496M|      float mask[3];
 1608|   496M|      float dc_mask[3];
 1609|   496M|      float diff_dc[3];
 1610|   496M|      float diff_ac[3];
 1611|  1.98G|      for (int i = 0; i < 3; ++i) {
  ------------------
  |  Branch (1611:23): [True: 1.49G, False: 496M]
  ------------------
 1612|  1.49G|        mask[i] = mask_xyb[i].Row(y)[x];
 1613|  1.49G|        dc_mask[i] = mask_xyb_dc[i].Row(y)[x];
 1614|  1.49G|        diff_dc[i] = block_diff_dc[i].Row(y)[x];
 1615|  1.49G|        diff_ac[i] = block_diff_ac[i].Row(y)[x];
 1616|  1.49G|      }
 1617|   496M|      row_out[x] = (DotProduct(diff_dc, dc_mask) + DotProduct(diff_ac, mask));
 1618|   496M|    }
 1619|  7.76M|  }
 1620|   163k|  return result;
 1621|   163k|}
_ZN11butteraugli27ButteraugliScoreFromDiffmapERKNS_5ImageIfEE:
 1623|   163k|double ButteraugliScoreFromDiffmap(const ImageF& diffmap) {
 1624|   163k|  PROFILER_FUNC;
 1625|   163k|  float retval = 0.0f;
 1626|  7.92M|  for (size_t y = 0; y < diffmap.ysize(); ++y) {
  ------------------
  |  Branch (1626:22): [True: 7.76M, False: 163k]
  ------------------
 1627|  7.76M|    const float * const BUTTERAUGLI_RESTRICT row = diffmap.Row(y);
 1628|   504M|    for (size_t x = 0; x < diffmap.xsize(); ++x) {
  ------------------
  |  Branch (1628:24): [True: 496M, False: 7.76M]
  ------------------
 1629|   496M|      retval = std::max(retval, row[x]);
 1630|   496M|    }
 1631|  7.76M|  }
 1632|   163k|  return retval;
 1633|   163k|}
_ZN11butteraugli5MaskXEd:
 1655|   510M|double MaskX(double delta) {
 1656|   510M|  static const double extmul = 2.59885507073;
 1657|   510M|  static const double extoff = 3.08805636789;
 1658|   510M|  static const double offset = 0.315424196682;
 1659|   510M|  static const double scaler = 16.2770141832;
 1660|   510M|  static const double mul = 5.62939030582;
 1661|   510M|  static const std::array<double, 512> lut =
 1662|   510M|                MakeMask(extmul, extoff, mul, offset, scaler);
 1663|   510M|  return InterpolateClampNegative(lut.data(), lut.size(), delta);
 1664|   510M|}
_ZN11butteraugli5MaskYEd:
 1666|  1.02G|double MaskY(double delta) {
 1667|  1.02G|  static const double extmul = 0.9613705131;
 1668|  1.02G|  static const double extoff = -0.581933100068;
 1669|  1.02G|  static const double offset = 1.00846207765;
 1670|  1.02G|  static const double scaler = 2.2342321176;
 1671|  1.02G|  static const double mul = 6.64307621174;
 1672|  1.02G|  static const std::array<double, 512> lut =
 1673|  1.02G|      MakeMask(extmul, extoff, mul, offset, scaler);
 1674|  1.02G|  return InterpolateClampNegative(lut.data(), lut.size(), delta);
 1675|  1.02G|}
_ZN11butteraugli7MaskDcXEd:
 1677|   510M|double MaskDcX(double delta) {
 1678|   510M|  static const double extmul = 10.0470705878;
 1679|   510M|  static const double extoff = 3.18472654033;
 1680|   510M|  static const double offset = 0.0551512255218;
 1681|   510M|  static const double scaler = 70.0;
 1682|   510M|  static const double mul = 0.373092999662;
 1683|   510M|  static const std::array<double, 512> lut =
 1684|   510M|      MakeMask(extmul, extoff, mul, offset, scaler);
 1685|   510M|  return InterpolateClampNegative(lut.data(), lut.size(), delta);
 1686|   510M|}
_ZN11butteraugli7MaskDcYEd:
 1688|  1.02G|double MaskDcY(double delta) {
 1689|  1.02G|  static const double extmul = 0.0115640939227;
 1690|  1.02G|  static const double extoff = 45.9483175519;
 1691|  1.02G|  static const double offset = 0.0142290066313;
 1692|  1.02G|  static const double scaler = 5.0;
 1693|  1.02G|  static const double mul = 2.52611324247;
 1694|  1.02G|  static const std::array<double, 512> lut =
 1695|  1.02G|      MakeMask(extmul, extoff, mul, offset, scaler);
 1696|  1.02G|  return InterpolateClampNegative(lut.data(), lut.size(), delta);
 1697|  1.02G|}
_ZN11butteraugli14DiffPrecomputeERKNS_5ImageIfEES3_:
 1699|   337k|ImageF DiffPrecompute(const ImageF& xyb0, const ImageF& xyb1) {
 1700|   337k|  PROFILER_FUNC;
 1701|   337k|  const size_t xsize = xyb0.xsize();
 1702|   337k|  const size_t ysize = xyb0.ysize();
 1703|   337k|  ImageF result(xsize, ysize);
 1704|   337k|  size_t x2, y2;
 1705|  16.3M|  for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (1705:22): [True: 16.0M, False: 337k]
  ------------------
 1706|  16.0M|    if (y + 1 < ysize) {
  ------------------
  |  Branch (1706:9): [True: 15.7M, False: 337k]
  ------------------
 1707|  15.7M|      y2 = y + 1;
 1708|  15.7M|    } else if (y > 0) {
  ------------------
  |  Branch (1708:16): [True: 337k, False: 0]
  ------------------
 1709|   337k|      y2 = y - 1;
 1710|   337k|    } else {
 1711|      0|      y2 = y;
 1712|      0|    }
 1713|  16.0M|    const float* const BUTTERAUGLI_RESTRICT row0_in = xyb0.Row(y);
 1714|  16.0M|    const float* const BUTTERAUGLI_RESTRICT row1_in = xyb1.Row(y);
 1715|  16.0M|    const float* const BUTTERAUGLI_RESTRICT row0_in2 = xyb0.Row(y2);
 1716|  16.0M|    const float* const BUTTERAUGLI_RESTRICT row1_in2 = xyb1.Row(y2);
 1717|  16.0M|    float* const BUTTERAUGLI_RESTRICT row_out = result.Row(y);
 1718|  1.03G|    for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (1718:24): [True: 1.02G, False: 16.0M]
  ------------------
 1719|  1.02G|      if (x + 1 < xsize) {
  ------------------
  |  Branch (1719:11): [True: 1.00G, False: 16.0M]
  ------------------
 1720|  1.00G|        x2 = x + 1;
 1721|  1.00G|      } else if (x > 0) {
  ------------------
  |  Branch (1721:18): [True: 16.0M, False: 0]
  ------------------
 1722|  16.0M|        x2 = x - 1;
 1723|  16.0M|      } else {
 1724|      0|        x2 = x;
 1725|      0|      }
 1726|  1.02G|      double sup0 = (fabs(row0_in[x] - row0_in[x2]) +
 1727|  1.02G|                     fabs(row0_in[x] - row0_in2[x]));
 1728|  1.02G|      double sup1 = (fabs(row1_in[x] - row1_in[x2]) +
 1729|  1.02G|                     fabs(row1_in[x] - row1_in2[x]));
 1730|  1.02G|      static const double mul0 = 0.918416534734;
 1731|  1.02G|      row_out[x] = mul0 * std::min(sup0, sup1);
 1732|  1.02G|      static const double cutoff = 55.0184555849;
 1733|  1.02G|      if (row_out[x] >= cutoff) {
  ------------------
  |  Branch (1733:11): [True: 126M, False: 894M]
  ------------------
 1734|   126M|        row_out[x] = cutoff;
 1735|   126M|      }
 1736|  1.02G|    }
 1737|  16.0M|  }
 1738|   337k|  return result;
 1739|   337k|}
_ZN11butteraugli4MaskERKNSt3__16vectorINS_5ImageIfEENS0_9allocatorIS3_EEEES8_PS6_S9_:
 1744|   168k|          std::vector<ImageF>* BUTTERAUGLI_RESTRICT mask_dc) {
 1745|   168k|  PROFILER_FUNC;
 1746|   168k|  const size_t xsize = xyb0[0].xsize();
 1747|   168k|  const size_t ysize = xyb0[0].ysize();
 1748|   168k|  mask->resize(3);
 1749|   168k|  *mask_dc = CreatePlanes<float>(xsize, ysize, 3);
 1750|   168k|  double muls[2] = {
 1751|   168k|    0.207017089891,
 1752|   168k|    0.267138152891,
 1753|   168k|  };
 1754|   168k|  double normalizer = {
 1755|   168k|    1.0 / (muls[0] + muls[1]),
 1756|   168k|  };
 1757|   168k|  static const double r0 = 2.3770330432;
 1758|   168k|  static const double r1 = 9.04353323561;
 1759|   168k|  static const double r2 = 9.24456601467;
 1760|   168k|  static const double border_ratio = -0.0724948220913;
 1761|       |
 1762|   168k|  {
 1763|       |    // X component
 1764|   168k|    ImageF diff = DiffPrecompute(xyb0[0], xyb1[0]);
 1765|   168k|    ImageF blurred = Blur(diff, r2, border_ratio);
 1766|   168k|    (*mask)[0] = ImageF(xsize, ysize);
 1767|  8.18M|    for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (1767:24): [True: 8.02M, False: 168k]
  ------------------
 1768|   518M|      for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (1768:26): [True: 510M, False: 8.02M]
  ------------------
 1769|   510M|        (*mask)[0].Row(y)[x] = blurred.Row(y)[x];
 1770|   510M|      }
 1771|  8.02M|    }
 1772|   168k|  }
 1773|   168k|  {
 1774|       |    // Y component
 1775|   168k|    (*mask)[1] = ImageF(xsize, ysize);
 1776|   168k|    ImageF diff = DiffPrecompute(xyb0[1], xyb1[1]);
 1777|   168k|    ImageF blurred1 = Blur(diff, r0, border_ratio);
 1778|   168k|    ImageF blurred2 = Blur(diff, r1, border_ratio);
 1779|  8.18M|    for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (1779:24): [True: 8.02M, False: 168k]
  ------------------
 1780|   518M|      for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (1780:26): [True: 510M, False: 8.02M]
  ------------------
 1781|   510M|        const double val = normalizer * (
 1782|   510M|            muls[0] * blurred1.Row(y)[x] +
 1783|   510M|            muls[1] * blurred2.Row(y)[x]);
 1784|   510M|        (*mask)[1].Row(y)[x] = val;
 1785|   510M|      }
 1786|  8.02M|    }
 1787|   168k|  }
 1788|       |  // B component
 1789|   168k|  (*mask)[2] = ImageF(xsize, ysize);
 1790|   168k|  static const double mul[2] = {
 1791|   168k|    16.6963293877,
 1792|   168k|    2.1364621982,
 1793|   168k|  };
 1794|   168k|  static const double w00 = 36.4671237619;
 1795|   168k|  static const double w11 = 2.1887170895;
 1796|   168k|  static const double w_ytob_hf = std::max<double>(
 1797|   168k|      0.086624184478,
 1798|   168k|      0.0);
 1799|   168k|  static const double w_ytob_lf = 21.6804277046;
 1800|   168k|  static const double p1_to_p0 = 0.0513061271723;
 1801|       |
 1802|  8.18M|  for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (1802:22): [True: 8.02M, False: 168k]
  ------------------
 1803|   518M|    for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (1803:24): [True: 510M, False: 8.02M]
  ------------------
 1804|   510M|      const double s0 = (*mask)[0].Row(y)[x];
 1805|   510M|      const double s1 = (*mask)[1].Row(y)[x];
 1806|   510M|      const double p1 = mul[1] * w11 * s1;
 1807|   510M|      const double p0 = mul[0] * w00 * s0 + p1_to_p0 * p1;
 1808|       |
 1809|   510M|      (*mask)[0].Row(y)[x] = MaskX(p0);
 1810|   510M|      (*mask)[1].Row(y)[x] = MaskY(p1);
 1811|   510M|      (*mask)[2].Row(y)[x] = w_ytob_hf * MaskY(p1);
 1812|   510M|      (*mask_dc)[0].Row(y)[x] = MaskDcX(p0);
 1813|   510M|      (*mask_dc)[1].Row(y)[x] = MaskDcY(p1);
 1814|   510M|      (*mask_dc)[2].Row(y)[x] = w_ytob_lf * MaskDcY(p1);
 1815|   510M|    }
 1816|  8.02M|  }
 1817|   168k|}
butteraugli.cc:_ZN11butteraugliL5GammaEd:
  319|  4.52G|static inline double Gamma(double v) {
  320|       |  //return SimpleGamma(v);
  321|  4.52G|  return GammaPolynomial(v);
  322|  4.52G|}
butteraugli.cc:_ZN11butteraugliL19SeparateFrequenciesEmmRKNSt3__16vectorINS_5ImageIfEENS0_9allocatorIS3_EEEERNS_11PsychoImageE:
  492|   166k|    PsychoImage &ps) {
  493|   166k|  PROFILER_FUNC;
  494|   166k|  ps.lf.resize(3);   // XYB
  495|   166k|  ps.mf.resize(3);   // XYB
  496|   166k|  ps.hf.resize(2);   // XY
  497|   166k|  ps.uhf.resize(2);  // XY
  498|       |  // Extract lf ...
  499|   166k|  static const double kSigmaLf = 7.46953768697;
  500|   166k|  static const double kSigmaHf = 3.734768843485;
  501|   166k|  static const double kSigmaUhf = 1.8673844217425;
  502|       |  // At borders we move some more of the energy to the high frequency
  503|       |  // parts, because there can be unfortunate continuations in tiling
  504|       |  // background color etc. So we want to represent the borders with
  505|       |  // some more accuracy.
  506|   166k|  static double border_lf = -0.00457628248637;
  507|   166k|  static double border_mf = -0.271277366628;
  508|   166k|  static double border_hf = 0.147068973249;
  509|   499k|  for (int i = 0; i < 3; ++i) {
  ------------------
  |  Branch (509:19): [True: 499k, False: 0]
  ------------------
  510|   499k|    ps.lf[i] = Blur(xyb[i], kSigmaLf, border_lf);
  511|       |    // ... and keep everything else in mf.
  512|   499k|    ps.mf[i] = ImageF(xsize, ysize);
  513|  24.2M|    for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (513:24): [True: 23.7M, False: 499k]
  ------------------
  514|  1.54G|      for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (514:26): [True: 1.51G, False: 23.7M]
  ------------------
  515|  1.51G|        ps.mf[i].Row(y)[x] = xyb[i].Row(y)[x] - ps.lf[i].Row(y)[x];
  516|  1.51G|      }
  517|  23.7M|    }
  518|   499k|    if (i == 2) {
  ------------------
  |  Branch (518:9): [True: 166k, False: 333k]
  ------------------
  519|   166k|      ps.mf[i] = Blur(ps.mf[i], kSigmaHf, border_mf);
  520|   166k|      break;
  521|   166k|    }
  522|       |    // Divide mf into mf and hf.
  523|   333k|    ps.hf[i] = ImageF(xsize, ysize);
  524|  16.1M|    for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (524:24): [True: 15.8M, False: 333k]
  ------------------
  525|  15.8M|      float* BUTTERAUGLI_RESTRICT const row_mf = ps.mf[i].Row(y);
  526|  15.8M|      float* BUTTERAUGLI_RESTRICT const row_hf = ps.hf[i].Row(y);
  527|  1.02G|      for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (527:26): [True: 1.01G, False: 15.8M]
  ------------------
  528|  1.01G|        row_hf[x] = row_mf[x];
  529|  1.01G|      }
  530|  15.8M|    }
  531|   333k|    ps.mf[i] = Blur(ps.mf[i], kSigmaHf, border_mf);
  532|   333k|    static const double w0 = 0.120079806822;
  533|   333k|    static const double w1 = 0.03430529365;
  534|   333k|    if (i == 0) {
  ------------------
  |  Branch (534:9): [True: 166k, False: 166k]
  ------------------
  535|  8.09M|      for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (535:26): [True: 7.93M, False: 166k]
  ------------------
  536|  7.93M|        float* BUTTERAUGLI_RESTRICT const row_mf = ps.mf[0].Row(y);
  537|  7.93M|        float* BUTTERAUGLI_RESTRICT const row_hf = ps.hf[0].Row(y);
  538|   513M|        for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (538:28): [True: 505M, False: 7.93M]
  ------------------
  539|   505M|          row_hf[x] -= row_mf[x];
  540|   505M|          row_mf[x] = RemoveRangeAroundZero(w0, row_mf[x]);
  541|   505M|        }
  542|  7.93M|      }
  543|   166k|    } else {
  544|  8.09M|      for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (544:26): [True: 7.93M, False: 166k]
  ------------------
  545|  7.93M|        float* BUTTERAUGLI_RESTRICT const row_mf = ps.mf[1].Row(y);
  546|  7.93M|        float* BUTTERAUGLI_RESTRICT const row_hf = ps.hf[1].Row(y);
  547|   513M|        for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (547:28): [True: 505M, False: 7.93M]
  ------------------
  548|   505M|          row_hf[x] -= row_mf[x];
  549|   505M|          row_mf[x] = AmplifyRangeAroundZero(w1, row_mf[x]);
  550|   505M|        }
  551|  7.93M|      }
  552|   166k|    }
  553|   333k|  }
  554|       |  // Suppress red-green by intensity change in the high freq channels.
  555|   166k|  static const double suppress = 2.96534974403;
  556|   166k|  ps.hf[0] = SuppressXByY(xsize, ysize, ps.hf[0], ps.hf[1], suppress);
  557|       |
  558|   499k|  for (int i = 0; i < 2; ++i) {
  ------------------
  |  Branch (558:19): [True: 333k, False: 166k]
  ------------------
  559|       |    // Divide hf into hf and uhf.
  560|   333k|    ps.uhf[i] = ImageF(xsize, ysize);
  561|  16.1M|    for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (561:24): [True: 15.8M, False: 333k]
  ------------------
  562|  15.8M|      float* BUTTERAUGLI_RESTRICT const row_uhf = ps.uhf[i].Row(y);
  563|  15.8M|      float* BUTTERAUGLI_RESTRICT const row_hf = ps.hf[i].Row(y);
  564|  1.02G|      for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (564:26): [True: 1.01G, False: 15.8M]
  ------------------
  565|  1.01G|        row_uhf[x] = row_hf[x];
  566|  1.01G|      }
  567|  15.8M|    }
  568|   333k|    ps.hf[i] = Blur(ps.hf[i], kSigmaUhf, border_hf);
  569|   333k|    static const double kRemoveHfRange = 0.0287615200377;
  570|   333k|    static const double kMaxclampHf = 78.8223237675;
  571|   333k|    static const double kMaxclampUhf = 5.8907152736;
  572|   333k|    static const float kMulSuppressHf = 1.10684769012;
  573|   333k|    static const float kMulRegHf = 0.478741530298;
  574|   333k|    static const float kRegHf = 2000 * kMulRegHf;
  575|   333k|    static const float kMulSuppressUhf = 1.76905001176;
  576|   333k|    static const float kMulRegUhf = 0.310148420674;
  577|   333k|    static const float kRegUhf = 2000 * kMulRegUhf;
  578|       |
  579|   333k|    if (i == 0) {
  ------------------
  |  Branch (579:9): [True: 166k, False: 166k]
  ------------------
  580|  8.09M|      for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (580:26): [True: 7.93M, False: 166k]
  ------------------
  581|  7.93M|        float* BUTTERAUGLI_RESTRICT const row_uhf = ps.uhf[0].Row(y);
  582|  7.93M|        float* BUTTERAUGLI_RESTRICT const row_hf = ps.hf[0].Row(y);
  583|   513M|        for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (583:28): [True: 505M, False: 7.93M]
  ------------------
  584|   505M|          row_uhf[x] -= row_hf[x];
  585|   505M|          row_hf[x] = RemoveRangeAroundZero(kRemoveHfRange, row_hf[x]);
  586|   505M|        }
  587|  7.93M|      }
  588|   166k|    } else {
  589|  8.09M|      for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (589:26): [True: 7.93M, False: 166k]
  ------------------
  590|  7.93M|        float* BUTTERAUGLI_RESTRICT const row_uhf = ps.uhf[1].Row(y);
  591|  7.93M|        float* BUTTERAUGLI_RESTRICT const row_hf = ps.hf[1].Row(y);
  592|  7.93M|        float* BUTTERAUGLI_RESTRICT const row_lf = ps.lf[1].Row(y);
  593|   513M|        for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (593:28): [True: 505M, False: 7.93M]
  ------------------
  594|   505M|          row_uhf[x] -= row_hf[x];
  595|   505M|          row_hf[x] = MaximumClamp(row_hf[x], kMaxclampHf);
  596|   505M|          row_uhf[x] = MaximumClamp(row_uhf[x], kMaxclampUhf);
  597|   505M|          row_uhf[x] = SuppressUhfInBrightAreas(row_uhf[x], row_lf[x],
  598|   505M|                                                kMulSuppressUhf, kRegUhf);
  599|   505M|          row_hf[x] = SuppressHfInBrightAreas(row_hf[x], row_lf[x],
  600|   505M|                                              kMulSuppressHf, kRegHf);
  601|       |
  602|   505M|        }
  603|  7.93M|      }
  604|   166k|    }
  605|   333k|  }
  606|       |  // Modify range around zero code only concerns the high frequency
  607|       |  // planes and only the X and Y channels.
  608|       |  // Convert low freq xyb to vals space so that we can do a simple squared sum
  609|       |  // diff on the low frequencies later.
  610|  8.09M|  for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (610:22): [True: 7.93M, False: 166k]
  ------------------
  611|  7.93M|    float* BUTTERAUGLI_RESTRICT const row_x = ps.lf[0].Row(y);
  612|  7.93M|    float* BUTTERAUGLI_RESTRICT const row_y = ps.lf[1].Row(y);
  613|  7.93M|    float* BUTTERAUGLI_RESTRICT const row_b = ps.lf[2].Row(y);
  614|   513M|    for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (614:24): [True: 505M, False: 7.93M]
  ------------------
  615|   505M|      float valx, valy, valb;
  616|   505M|      XybLowFreqToVals(row_x[x], row_y[x], row_b[x], &valx, &valy, &valb);
  617|   505M|      row_x[x] = valx;
  618|   505M|      row_y[x] = valy;
  619|   505M|      row_b[x] = valb;
  620|   505M|    }
  621|  7.93M|  }
  622|   166k|}
butteraugli.cc:_ZN11butteraugliL21RemoveRangeAroundZeroEff:
  369|  1.01G|static BUTTERAUGLI_INLINE float RemoveRangeAroundZero(float w, float x) {
  370|  1.01G|  return x > w ? x - w : x < -w ? x + w : 0.0f;
  ------------------
  |  Branch (370:10): [True: 191M, False: 820M]
  |  Branch (370:26): [True: 191M, False: 628M]
  ------------------
  371|  1.01G|}
butteraugli.cc:_ZN11butteraugliL22AmplifyRangeAroundZeroEff:
  374|   505M|static BUTTERAUGLI_INLINE float AmplifyRangeAroundZero(float w, float x) {
  375|   505M|  return x > w ? x + w : x < -w ? x - w : 2.0f * x;
  ------------------
  |  Branch (375:10): [True: 201M, False: 303M]
  |  Branch (375:26): [True: 278M, False: 25.2M]
  ------------------
  376|   505M|}
butteraugli.cc:_ZN11butteraugliL12SuppressXByYEmmRKNS_5ImageIfEES3_d:
  472|   166k|                           const double yw) {
  473|   166k|  static const double s = 0.745954517135;
  474|   166k|  ImageF inew(xsize, ysize);
  475|  8.09M|  for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (475:22): [True: 7.93M, False: 166k]
  ------------------
  476|  7.93M|    const float* const rowx = ix.Row(y);
  477|  7.93M|    const float* const rowy = iy.Row(y);
  478|  7.93M|    float* const rownew = inew.Row(y);
  479|   513M|    for (size_t x = 0; x < xsize; ++x) {
  ------------------
  |  Branch (479:24): [True: 505M, False: 7.93M]
  ------------------
  480|   505M|      const double xval = rowx[x];
  481|   505M|      const double yval = rowy[x];
  482|   505M|      const double scaler = s + (yw * (1.0 - s)) / (yw + yval * yval);
  483|   505M|      rownew[x] = scaler * xval;
  484|   505M|    }
  485|  7.93M|  }
  486|   166k|  return inew;
  487|   166k|}
butteraugli.cc:_ZN11butteraugliL12MaximumClampEff:
  432|  1.01G|static float MaximumClamp(float v, float maxval) {
  433|  1.01G|  static const double kMul = 0.688059627878;
  434|  1.01G|  if (v >= maxval) {
  ------------------
  |  Branch (434:7): [True: 125M, False: 885M]
  ------------------
  435|   125M|    v -= maxval;
  436|   125M|    v *= kMul;
  437|   125M|    v += maxval;
  438|   885M|  } else if (v < -maxval) {
  ------------------
  |  Branch (438:14): [True: 152M, False: 733M]
  ------------------
  439|   152M|    v += maxval;
  440|   152M|    v *= kMul;
  441|   152M|    v -= maxval;
  442|   152M|  }
  443|  1.01G|  return v;
  444|  1.01G|}
butteraugli.cc:_ZN11butteraugliL24SuppressUhfInBrightAreasEffff:
  427|   505M|                                      float mul, float reg) {
  428|   505M|  float scaler = mul * reg / (reg + brightness);
  429|   505M|  return scaler * hf;
  430|   505M|}
butteraugli.cc:_ZN11butteraugliL23SuppressHfInBrightAreasEffff:
  421|   505M|                                     float mul, float reg) {
  422|   505M|  float scaler = mul * reg / (reg + brightness);
  423|   505M|  return scaler * hf;
  424|   505M|}
_ZN11butteraugli16XybLowFreqToValsIfEEvRKT_S3_S3_PS1_S4_S4_:
  385|   505M|                                         V *BUTTERAUGLI_RESTRICT valb) {
  386|   505M|  static const double xmuli = 5.57547552483;
  387|   505M|  static const double ymuli = 1.20828034498;
  388|   505M|  static const double bmuli = 6.08319517575;
  389|   505M|  static const double y_to_b_muli = -0.628811683685;
  390|       |
  391|   505M|  const V xmul(xmuli);
  392|   505M|  const V ymul(ymuli);
  393|   505M|  const V bmul(bmuli);
  394|   505M|  const V y_to_b_mul(y_to_b_muli);
  395|   505M|  const V b = b_arg + y_to_b_mul * y;
  396|   505M|  *valb = b * bmul;
  397|   505M|  *valx = x * xmul;
  398|   505M|  *valy = y * ymul;
  399|   505M|}
butteraugli.cc:_ZN11butteraugliL15SameNoiseLevelsERKNS_5ImageIfEES3_dddPS1_:
  628|   163k|                            ImageF* BUTTERAUGLI_RESTRICT diffmap) {
  629|   163k|  ImageF blurred(i0.xsize(), i0.ysize());
  630|  7.92M|  for (size_t y = 0; y < i0.ysize(); ++y) {
  ------------------
  |  Branch (630:22): [True: 7.76M, False: 163k]
  ------------------
  631|  7.76M|    const float* BUTTERAUGLI_RESTRICT const row0 = i0.Row(y);
  632|  7.76M|    const float* BUTTERAUGLI_RESTRICT const row1 = i1.Row(y);
  633|  7.76M|    float* BUTTERAUGLI_RESTRICT const to = blurred.Row(y);
  634|   504M|    for (size_t x = 0; x < i0.xsize(); ++x) {
  ------------------
  |  Branch (634:24): [True: 496M, False: 7.76M]
  ------------------
  635|   496M|      double v0 = fabs(row0[x]);
  636|   496M|      double v1 = fabs(row1[x]);
  637|   496M|      if (v0 > maxclamp) v0 = maxclamp;
  ------------------
  |  Branch (637:11): [True: 0, False: 496M]
  ------------------
  638|   496M|      if (v1 > maxclamp) v1 = maxclamp;
  ------------------
  |  Branch (638:11): [True: 0, False: 496M]
  ------------------
  639|   496M|      to[x] = v0 - v1;
  640|   496M|    }
  641|       |
  642|  7.76M|  }
  643|   163k|  blurred = Blur(blurred, kSigma, 0.0);
  644|  7.92M|  for (size_t y = 0; y < i0.ysize(); ++y) {
  ------------------
  |  Branch (644:22): [True: 7.76M, False: 163k]
  ------------------
  645|  7.76M|    const float* BUTTERAUGLI_RESTRICT const row = blurred.Row(y);
  646|  7.76M|    float* BUTTERAUGLI_RESTRICT const row_diff = diffmap->Row(y);
  647|   504M|    for (size_t x = 0; x < i0.xsize(); ++x) {
  ------------------
  |  Branch (647:24): [True: 496M, False: 7.76M]
  ------------------
  648|   496M|      double diff = row[x];
  649|   496M|      row_diff[x] += w * diff * diff;
  650|   496M|    }
  651|  7.76M|  }
  652|   163k|}
butteraugli.cc:_ZN11butteraugliL16L2DiffAsymmetricERKNS_5ImageIfEES3_ddPS1_:
  675|   327k|                             ImageF* BUTTERAUGLI_RESTRICT diffmap) {
  676|   327k|  if (w_0gt1 == 0 && w_0lt1 == 0) {
  ------------------
  |  Branch (676:7): [True: 163k, False: 163k]
  |  Branch (676:22): [True: 163k, False: 0]
  ------------------
  677|   163k|    return;
  678|   163k|  }
  679|   163k|  w_0gt1 *= 0.8;
  680|   163k|  w_0lt1 *= 0.8;
  681|  7.92M|  for (size_t y = 0; y < i0.ysize(); ++y) {
  ------------------
  |  Branch (681:22): [True: 7.76M, False: 163k]
  ------------------
  682|  7.76M|    const float* BUTTERAUGLI_RESTRICT const row0 = i0.Row(y);
  683|  7.76M|    const float* BUTTERAUGLI_RESTRICT const row1 = i1.Row(y);
  684|  7.76M|    float* BUTTERAUGLI_RESTRICT const row_diff = diffmap->Row(y);
  685|   504M|    for (size_t x = 0; x < i0.xsize(); ++x) {
  ------------------
  |  Branch (685:24): [True: 496M, False: 7.76M]
  ------------------
  686|       |      // Primary symmetric quadratic objective.
  687|   496M|      double diff = row0[x] - row1[x];
  688|   496M|      row_diff[x] += w_0gt1 * diff * diff;
  689|       |
  690|       |      // Secondary half-open quadratic objectives.
  691|   496M|      const double fabs0 = fabs(row0[x]);
  692|   496M|      const double too_small = 0.4 * fabs0;
  693|   496M|      const double too_big = 1.0 * fabs0;
  694|       |
  695|   496M|      if (row0[x] < 0) {
  ------------------
  |  Branch (695:11): [True: 246M, False: 249M]
  ------------------
  696|   246M|        if (row1[x] > -too_small) {
  ------------------
  |  Branch (696:13): [True: 21.9M, False: 224M]
  ------------------
  697|  21.9M|          double v = row1[x] + too_small;
  698|  21.9M|          row_diff[x] += w_0lt1 * v * v;
  699|   224M|        } else if (row1[x] < -too_big) {
  ------------------
  |  Branch (699:20): [True: 103M, False: 121M]
  ------------------
  700|   103M|          double v = -row1[x] - too_big;
  701|   103M|          row_diff[x] += w_0lt1 * v * v;
  702|   103M|        }
  703|   249M|      } else {
  704|   249M|        if (row1[x] < too_small) {
  ------------------
  |  Branch (704:13): [True: 20.5M, False: 229M]
  ------------------
  705|  20.5M|          double v = too_small - row1[x];
  706|  20.5M|          row_diff[x] += w_0lt1 * v * v;
  707|   229M|        } else if (row1[x] > too_big) {
  ------------------
  |  Branch (707:20): [True: 103M, False: 125M]
  ------------------
  708|   103M|          double v = row1[x] - too_big;
  709|   103M|          row_diff[x] += w_0lt1 * v * v;
  710|   103M|        }
  711|   249M|      }
  712|   496M|    }
  713|  7.76M|  }
  714|   163k|}
butteraugli.cc:_ZN11butteraugliL6L2DiffERKNS_5ImageIfEES3_dPS1_:
  655|   981k|                   ImageF* BUTTERAUGLI_RESTRICT diffmap) {
  656|   981k|  if (w == 0) {
  ------------------
  |  Branch (656:7): [True: 654k, False: 327k]
  ------------------
  657|   654k|    return;
  658|   654k|  }
  659|  15.8M|  for (size_t y = 0; y < i0.ysize(); ++y) {
  ------------------
  |  Branch (659:22): [True: 15.5M, False: 327k]
  ------------------
  660|  15.5M|    const float* BUTTERAUGLI_RESTRICT const row0 = i0.Row(y);
  661|  15.5M|    const float* BUTTERAUGLI_RESTRICT const row1 = i1.Row(y);
  662|  15.5M|    float* BUTTERAUGLI_RESTRICT const row_diff = diffmap->Row(y);
  663|  1.00G|    for (size_t x = 0; x < i0.xsize(); ++x) {
  ------------------
  |  Branch (663:24): [True: 993M, False: 15.5M]
  ------------------
  664|   993M|      double diff = row0[x] - row1[x];
  665|   993M|      row_diff[x] += w * diff * diff;
  666|   993M|    }
  667|  15.5M|  }
  668|   327k|}
_ZN11butteraugli10DotProductEPKfS1_:
  141|   993M|inline float DotProduct(const float u[3], const float v[3]) {
  142|   993M|  return u[0] * v[0] + u[1] * v[1] + u[2] * v[2];
  143|   993M|}
butteraugli.cc:_ZN11butteraugliL8MakeMaskEddddd:
 1641|      4|    double scaler) {
 1642|      4|  std::array<double, 512> lut;
 1643|  2.05k|  for (int i = 0; i < lut.size(); ++i) {
  ------------------
  |  Branch (1643:19): [True: 2.04k, False: 4]
  ------------------
 1644|  2.04k|    const double c = mul / ((0.01 * scaler * i) + offset);
 1645|  2.04k|    lut[i] = kGlobalScale * (1.0 + extmul * (c + extoff));
 1646|  2.04k|    if (lut[i] < 1e-5) {
  ------------------
  |  Branch (1646:9): [True: 0, False: 2.04k]
  ------------------
 1647|      0|      lut[i] = 1e-5;
 1648|      0|    }
 1649|  2.04k|    assert(lut[i] >= 0.0);
 1650|      0|    lut[i] *= lut[i];
 1651|  2.04k|  }
 1652|      4|  return lut;
 1653|      4|}
_ZN11butteraugli24InterpolateClampNegativeEPKdid:
  237|  3.06G|                                       int size, double ix) {
  238|  3.06G|  if (ix < 0) {
  ------------------
  |  Branch (238:7): [True: 0, False: 3.06G]
  ------------------
  239|      0|    ix = 0;
  240|      0|  }
  241|  3.06G|  int baseix = static_cast<int>(ix);
  242|  3.06G|  double res;
  243|  3.06G|  if (baseix >= size - 1) {
  ------------------
  |  Branch (243:7): [True: 11.4M, False: 3.05G]
  ------------------
  244|  11.4M|    res = array[size - 1];
  245|  3.05G|  } else {
  246|  3.05G|    double mix = ix - baseix;
  247|  3.05G|    int nextix = baseix + 1;
  248|  3.05G|    res = array[baseix] + mix * (array[nextix] - array[baseix]);
  249|  3.05G|  }
  250|  3.06G|  return res;
  251|  3.06G|}
butteraugli.cc:_ZN11butteraugliL16MaltaDiffMapImplINS_8MaltaTagEEEvRKNS_5ImageIfEES5_mmdddddPS3_:
 1467|   327k|                             ImageF* block_diff_ac) {
 1468|   327k|  const float kWeight0 = 0.5;
 1469|   327k|  const float kWeight1 = 0.33;
 1470|       |
 1471|   327k|  const double w_pre0gt1 = mulli * sqrt(kWeight0 * w_0gt1) / (len * 2 + 1);
 1472|   327k|  const double w_pre0lt1 = mulli * sqrt(kWeight1 * w_0lt1) / (len * 2 + 1);
 1473|   327k|  const float norm2_0gt1 = w_pre0gt1 * norm1;
 1474|   327k|  const float norm2_0lt1 = w_pre0lt1 * norm1;
 1475|       |
 1476|   327k|  std::vector<float> diffs(ysize_ * xsize_);
 1477|  15.8M|  for (size_t y = 0, ix = 0; y < ysize_; ++y) {
  ------------------
  |  Branch (1477:30): [True: 15.5M, False: 327k]
  ------------------
 1478|  15.5M|    const float* BUTTERAUGLI_RESTRICT const row0 = lum0.Row(y);
 1479|  15.5M|    const float* BUTTERAUGLI_RESTRICT const row1 = lum1.Row(y);
 1480|  1.00G|    for (size_t x = 0; x < xsize_; ++x, ++ix) {
  ------------------
  |  Branch (1480:24): [True: 993M, False: 15.5M]
  ------------------
 1481|   993M|      const float absval = 0.5 * std::abs(row0[x]) + 0.5 * std::abs(row1[x]);
 1482|   993M|      const float diff = row0[x] - row1[x];
 1483|   993M|      const float scaler = norm2_0gt1 / (static_cast<float>(norm1) + absval);
 1484|       |
 1485|       |      // Primary symmetric quadratic objective.
 1486|   993M|      diffs[ix] = scaler * diff;
 1487|       |
 1488|   993M|      const float scaler2 = norm2_0lt1 / (static_cast<float>(norm1) + absval);
 1489|   993M|      const double fabs0 = fabs(row0[x]);
 1490|       |
 1491|       |      // Secondary half-open quadratic objectives.
 1492|   993M|      const double too_small = 0.55 * fabs0;
 1493|   993M|      const double too_big = 1.05 * fabs0;
 1494|       |
 1495|   993M|      if (row0[x] < 0) {
  ------------------
  |  Branch (1495:11): [True: 527M, False: 465M]
  ------------------
 1496|   527M|        if (row1[x] > -too_small) {
  ------------------
  |  Branch (1496:13): [True: 72.0M, False: 455M]
  ------------------
 1497|  72.0M|          double impact = scaler2 * (row1[x] + too_small);
 1498|  72.0M|          if (diff < 0) {
  ------------------
  |  Branch (1498:15): [True: 72.0M, False: 0]
  ------------------
 1499|  72.0M|            diffs[ix] -= impact;
 1500|  72.0M|          } else {
 1501|      0|            diffs[ix] += impact;
 1502|      0|          }
 1503|   455M|        } else if (row1[x] < -too_big) {
  ------------------
  |  Branch (1503:20): [True: 125M, False: 330M]
  ------------------
 1504|   125M|          double impact = scaler2 * (-row1[x] - too_big);
 1505|   125M|          if (diff < 0) {
  ------------------
  |  Branch (1505:15): [True: 0, False: 125M]
  ------------------
 1506|      0|            diffs[ix] -= impact;
 1507|   125M|          } else {
 1508|   125M|            diffs[ix] += impact;
 1509|   125M|          }
 1510|   125M|        }
 1511|   527M|      } else {
 1512|   465M|        if (row1[x] < too_small) {
  ------------------
  |  Branch (1512:13): [True: 65.0M, False: 400M]
  ------------------
 1513|  65.0M|          double impact = scaler2 * (too_small - row1[x]);
 1514|  65.0M|          if (diff < 0) {
  ------------------
  |  Branch (1514:15): [True: 0, False: 65.0M]
  ------------------
 1515|      0|            diffs[ix] -= impact;
 1516|  65.0M|          } else {
 1517|  65.0M|            diffs[ix] += impact;
 1518|  65.0M|          }
 1519|   400M|        } else if (row1[x] > too_big) {
  ------------------
  |  Branch (1519:20): [True: 111M, False: 288M]
  ------------------
 1520|   111M|          double impact = scaler2 * (row1[x] - too_big);
 1521|   111M|          if (diff < 0) {
  ------------------
  |  Branch (1521:15): [True: 111M, False: 0]
  ------------------
 1522|   111M|            diffs[ix] -= impact;
 1523|   111M|          } else {
 1524|      0|            diffs[ix] += impact;
 1525|      0|          }
 1526|   111M|        }
 1527|   465M|      }
 1528|   993M|    }
 1529|  15.5M|  }
 1530|       |
 1531|   327k|  size_t y0 = 0;
 1532|       |  // Top
 1533|  1.63M|  for (; y0 < 4; ++y0) {
  ------------------
  |  Branch (1533:10): [True: 1.30M, False: 327k]
  ------------------
 1534|  1.30M|    float* const BUTTERAUGLI_RESTRICT row_diff = block_diff_ac->Row(y0);
 1535|  83.0M|    for (size_t x0 = 0; x0 < xsize_; ++x0) {
  ------------------
  |  Branch (1535:25): [True: 81.7M, False: 1.30M]
  ------------------
 1536|  81.7M|      row_diff[x0] +=
 1537|  81.7M|          PaddedMaltaUnit<false, Tag>(&diffs[0], x0, y0, xsize_, ysize_);
 1538|  81.7M|    }
 1539|  1.30M|  }
 1540|       |
 1541|       |  // Middle
 1542|  13.2M|  for (; y0 < ysize_ - 4; ++y0) {
  ------------------
  |  Branch (1542:10): [True: 12.9M, False: 327k]
  ------------------
 1543|  12.9M|    float* const BUTTERAUGLI_RESTRICT row_diff = block_diff_ac->Row(y0);
 1544|  12.9M|    size_t x0 = 0;
 1545|  64.5M|    for (; x0 < 4; ++x0) {
  ------------------
  |  Branch (1545:12): [True: 51.6M, False: 12.9M]
  ------------------
 1546|  51.6M|      row_diff[x0] +=
 1547|  51.6M|          PaddedMaltaUnit<false, Tag>(&diffs[0], x0, y0, xsize_, ysize_);
 1548|  51.6M|    }
 1549|   739M|    for (; x0 < xsize_ - 4; ++x0) {
  ------------------
  |  Branch (1549:12): [True: 726M, False: 12.9M]
  ------------------
 1550|   726M|      row_diff[x0] +=
 1551|   726M|          PaddedMaltaUnit<true, Tag>(&diffs[0], x0, y0, xsize_, ysize_);
 1552|   726M|    }
 1553|       |
 1554|  64.5M|    for (; x0 < xsize_; ++x0) {
  ------------------
  |  Branch (1554:12): [True: 51.6M, False: 12.9M]
  ------------------
 1555|  51.6M|      row_diff[x0] +=
 1556|  51.6M|          PaddedMaltaUnit<false, Tag>(&diffs[0], x0, y0, xsize_, ysize_);
 1557|  51.6M|    }
 1558|  12.9M|  }
 1559|       |
 1560|       |  // Bottom
 1561|  1.63M|  for (; y0 < ysize_; ++y0) {
  ------------------
  |  Branch (1561:10): [True: 1.30M, False: 327k]
  ------------------
 1562|  1.30M|    float* const BUTTERAUGLI_RESTRICT row_diff = block_diff_ac->Row(y0);
 1563|  83.0M|    for (size_t x0 = 0; x0 < xsize_; ++x0) {
  ------------------
  |  Branch (1563:25): [True: 81.7M, False: 1.30M]
  ------------------
 1564|  81.7M|      row_diff[x0] +=
 1565|  81.7M|          PaddedMaltaUnit<false, Tag>(&diffs[0], x0, y0, xsize_, ysize_);
 1566|  81.7M|    }
 1567|  1.30M|  }
 1568|   327k|}
butteraugli.cc:_ZN11butteraugliL15PaddedMaltaUnitILb0ENS_8MaltaTagEEEfPfmmmm:
 1431|   266M|    const size_t xsize_, const size_t ysize_) {
 1432|   266M|  int ix0 = y0 * xsize_ + x0;
 1433|   266M|  const float* BUTTERAUGLI_RESTRICT d = &diffs[ix0];
 1434|   266M|  if (fastMode ||
  ------------------
  |  Branch (1434:7): [Folded - Ignored]
  ------------------
 1435|   266M|      (x0 >= 4 && y0 >= 4 && x0 < (xsize_ - 4) && y0 < (ysize_ - 4))) {
  ------------------
  |  Branch (1435:8): [True: 204M, False: 62.1M]
  |  Branch (1435:19): [True: 128M, False: 76.5M]
  |  Branch (1435:30): [True: 71.3M, False: 56.8M]
  |  Branch (1435:51): [True: 0, False: 71.3M]
  ------------------
 1436|      0|    return MaltaUnit(Tag(), d, xsize_);
 1437|      0|  }
 1438|       |
 1439|   266M|  float borderimage[9 * 9];
 1440|  2.66G|  for (int dy = 0; dy < 9; ++dy) {
  ------------------
  |  Branch (1440:20): [True: 2.40G, False: 266M]
  ------------------
 1441|  2.40G|    int y = y0 + dy - 4;
 1442|  2.40G|    if (y < 0 || y >= ysize_) {
  ------------------
  |  Branch (1442:9): [True: 204M, False: 2.19G]
  |  Branch (1442:18): [True: 204M, False: 1.99G]
  ------------------
 1443|  4.08G|      for (int dx = 0; dx < 9; ++dx) {
  ------------------
  |  Branch (1443:24): [True: 3.67G, False: 408M]
  ------------------
 1444|  3.67G|        borderimage[dy * 9 + dx] = 0.0f;
 1445|  3.67G|      }
 1446|  1.99G|    } else {
 1447|  19.9G|      for (int dx = 0; dx < 9; ++dx) {
  ------------------
  |  Branch (1447:24): [True: 17.9G, False: 1.99G]
  ------------------
 1448|  17.9G|        int x = x0 + dx - 4;
 1449|  17.9G|        if (x < 0 || x >= xsize_) {
  ------------------
  |  Branch (1449:13): [True: 1.33G, False: 16.6G]
  |  Branch (1449:22): [True: 1.33G, False: 15.2G]
  ------------------
 1450|  2.66G|          borderimage[dy * 9 + dx] = 0.0f;
 1451|  15.2G|        } else {
 1452|  15.2G|          borderimage[dy * 9 + dx] = diffs[y * xsize_ + x];
 1453|  15.2G|        }
 1454|  17.9G|      }
 1455|  1.99G|    }
 1456|  2.40G|  }
 1457|   266M|  return MaltaUnit(Tag(), &borderimage[4 * 9 + 4], 9);
 1458|   266M|}
butteraugli.cc:_ZN11butteraugliL9MaltaUnitENS_8MaltaTagEPKfi:
 1147|   993M|                       const int xs) {
 1148|   993M|  const int xs3 = 3 * xs;
 1149|   993M|  float retval = 0;
 1150|   993M|  {
 1151|       |    // x grows, y constant
 1152|   993M|    float sum =
 1153|   993M|        d[-4] +
 1154|   993M|        d[-3] +
 1155|   993M|        d[-2] +
 1156|   993M|        d[-1] +
 1157|   993M|        d[0] +
 1158|   993M|        d[1] +
 1159|   993M|        d[2] +
 1160|   993M|        d[3] +
 1161|   993M|        d[4];
 1162|   993M|    retval += sum * sum;
 1163|   993M|  }
 1164|   993M|  {
 1165|       |    // y grows, x constant
 1166|   993M|    float sum =
 1167|   993M|        d[-xs3 - xs] +
 1168|   993M|        d[-xs3] +
 1169|   993M|        d[-xs - xs] +
 1170|   993M|        d[-xs] +
 1171|   993M|        d[0] +
 1172|   993M|        d[xs] +
 1173|   993M|        d[xs + xs] +
 1174|   993M|        d[xs3] +
 1175|   993M|        d[xs3 + xs];
 1176|   993M|    retval += sum * sum;
 1177|   993M|  }
 1178|   993M|  {
 1179|       |    // both grow
 1180|   993M|    float sum =
 1181|   993M|        d[-xs3 - 3] +
 1182|   993M|        d[-xs - xs - 2] +
 1183|   993M|        d[-xs - 1] +
 1184|   993M|        d[0] +
 1185|   993M|        d[xs + 1] +
 1186|   993M|        d[xs + xs + 2] +
 1187|   993M|        d[xs3 + 3];
 1188|   993M|    retval += sum * sum;
 1189|   993M|  }
 1190|   993M|  {
 1191|       |    // y grows, x shrinks
 1192|   993M|    float sum =
 1193|   993M|        d[-xs3 + 3] +
 1194|   993M|        d[-xs - xs + 2] +
 1195|   993M|        d[-xs + 1] +
 1196|   993M|        d[0] +
 1197|   993M|        d[xs - 1] +
 1198|   993M|        d[xs + xs - 2] +
 1199|   993M|        d[xs3 - 3];
 1200|   993M|    retval += sum * sum;
 1201|   993M|  }
 1202|   993M|  {
 1203|       |    // y grows -4 to 4, x shrinks 1 -> -1
 1204|   993M|    float sum =
 1205|   993M|        d[-xs3 - xs + 1] +
 1206|   993M|        d[-xs3 + 1] +
 1207|   993M|        d[-xs - xs + 1] +
 1208|   993M|        d[-xs] +
 1209|   993M|        d[0] +
 1210|   993M|        d[xs] +
 1211|   993M|        d[xs + xs - 1] +
 1212|   993M|        d[xs3 - 1] +
 1213|   993M|        d[xs3 + xs - 1];
 1214|   993M|    retval += sum * sum;
 1215|   993M|  }
 1216|   993M|  {
 1217|       |    //  y grows -4 to 4, x grows -1 -> 1
 1218|   993M|    float sum =
 1219|   993M|        d[-xs3 - xs - 1] +
 1220|   993M|        d[-xs3 - 1] +
 1221|   993M|        d[-xs - xs - 1] +
 1222|   993M|        d[-xs] +
 1223|   993M|        d[0] +
 1224|   993M|        d[xs] +
 1225|   993M|        d[xs + xs + 1] +
 1226|   993M|        d[xs3 + 1] +
 1227|   993M|        d[xs3 + xs + 1];
 1228|   993M|    retval += sum * sum;
 1229|   993M|  }
 1230|   993M|  {
 1231|       |    // x grows -4 to 4, y grows -1 to 1
 1232|   993M|    float sum =
 1233|   993M|        d[-4 - xs] +
 1234|   993M|        d[-3 - xs] +
 1235|   993M|        d[-2 - xs] +
 1236|   993M|        d[-1] +
 1237|   993M|        d[0] +
 1238|   993M|        d[1] +
 1239|   993M|        d[2 + xs] +
 1240|   993M|        d[3 + xs] +
 1241|   993M|        d[4 + xs];
 1242|   993M|    retval += sum * sum;
 1243|   993M|  }
 1244|   993M|  {
 1245|       |    // x grows -4 to 4, y shrinks 1 to -1
 1246|   993M|    float sum =
 1247|   993M|        d[-4 + xs] +
 1248|   993M|        d[-3 + xs] +
 1249|   993M|        d[-2 + xs] +
 1250|   993M|        d[-1] +
 1251|   993M|        d[0] +
 1252|   993M|        d[1] +
 1253|   993M|        d[2 - xs] +
 1254|   993M|        d[3 - xs] +
 1255|   993M|        d[4 - xs];
 1256|   993M|    retval += sum * sum;
 1257|   993M|  }
 1258|   993M|  {
 1259|       |    /* 0_________
 1260|       |       1__*______
 1261|       |       2___*_____
 1262|       |       3___*_____
 1263|       |       4____0____
 1264|       |       5_____*___
 1265|       |       6_____*___
 1266|       |       7______*__
 1267|       |       8_________ */
 1268|   993M|    float sum =
 1269|   993M|        d[-xs3 - 2] +
 1270|   993M|        d[-xs - xs - 1] +
 1271|   993M|        d[-xs - 1] +
 1272|   993M|        d[0] +
 1273|   993M|        d[xs + 1] +
 1274|   993M|        d[xs + xs + 1] +
 1275|   993M|        d[xs3 + 2];
 1276|   993M|    retval += sum * sum;
 1277|   993M|  }
 1278|   993M|  {
 1279|       |    /* 0_________
 1280|       |       1______*__
 1281|       |       2_____*___
 1282|       |       3_____*___
 1283|       |       4____0____
 1284|       |       5___*_____
 1285|       |       6___*_____
 1286|       |       7__*______
 1287|       |       8_________ */
 1288|   993M|    float sum =
 1289|   993M|        d[-xs3 + 2] +
 1290|   993M|        d[-xs - xs + 1] +
 1291|   993M|        d[-xs + 1] +
 1292|   993M|        d[0] +
 1293|   993M|        d[xs - 1] +
 1294|   993M|        d[xs + xs - 1] +
 1295|   993M|        d[xs3 - 2];
 1296|   993M|    retval += sum * sum;
 1297|   993M|  }
 1298|   993M|  {
 1299|       |    /* 0_________
 1300|       |       1_________
 1301|       |       2_*_______
 1302|       |       3__**_____
 1303|       |       4____0____
 1304|       |       5_____**__
 1305|       |       6_______*_
 1306|       |       7_________
 1307|       |       8_________ */
 1308|   993M|    float sum =
 1309|   993M|        d[-xs - xs - 3] +
 1310|   993M|        d[-xs - 2] +
 1311|   993M|        d[-xs - 1] +
 1312|   993M|        d[0] +
 1313|   993M|        d[xs + 1] +
 1314|   993M|        d[xs + 2] +
 1315|   993M|        d[xs + xs + 3];
 1316|   993M|    retval += sum * sum;
 1317|   993M|  }
 1318|   993M|  {
 1319|       |    /* 0_________
 1320|       |       1_________
 1321|       |       2_______*_
 1322|       |       3_____**__
 1323|       |       4____0____
 1324|       |       5__**_____
 1325|       |       6_*_______
 1326|       |       7_________
 1327|       |       8_________ */
 1328|   993M|    float sum =
 1329|   993M|        d[-xs - xs + 3] +
 1330|   993M|        d[-xs + 2] +
 1331|   993M|        d[-xs + 1] +
 1332|   993M|        d[0] +
 1333|   993M|        d[xs - 1] +
 1334|   993M|        d[xs - 2] +
 1335|   993M|        d[xs + xs - 3];
 1336|   993M|    retval += sum * sum;
 1337|   993M|  }
 1338|   993M|  {
 1339|       |    /* 0_________
 1340|       |       1_________
 1341|       |       2_________
 1342|       |       3______**_
 1343|       |       4____0*___
 1344|       |       5__**_____
 1345|       |       6**_______
 1346|       |       7_________
 1347|       |       8_________ */
 1348|       |
 1349|   993M|    float sum =
 1350|   993M|        d[xs + xs - 4] +
 1351|   993M|        d[xs + xs - 3] +
 1352|   993M|        d[xs - 2] +
 1353|   993M|        d[xs - 1] +
 1354|   993M|        d[0] +
 1355|   993M|        d[1] +
 1356|   993M|        d[-xs + 2] +
 1357|   993M|        d[-xs + 3];
 1358|   993M|    retval += sum * sum;
 1359|   993M|  }
 1360|   993M|  {
 1361|       |    /* 0_________
 1362|       |       1_________
 1363|       |       2**_______
 1364|       |       3__**_____
 1365|       |       4____0*___
 1366|       |       5______**_
 1367|       |       6_________
 1368|       |       7_________
 1369|       |       8_________ */
 1370|   993M|    float sum =
 1371|   993M|        d[-xs - xs - 4] +
 1372|   993M|        d[-xs - xs - 3] +
 1373|   993M|        d[-xs - 2] +
 1374|   993M|        d[-xs - 1] +
 1375|   993M|        d[0] +
 1376|   993M|        d[1] +
 1377|   993M|        d[xs + 2] +
 1378|   993M|        d[xs + 3];
 1379|   993M|    retval += sum * sum;
 1380|   993M|  }
 1381|   993M|  {
 1382|       |    /* 0__*______
 1383|       |       1__*______
 1384|       |       2___*_____
 1385|       |       3___*_____
 1386|       |       4____0____
 1387|       |       5____*____
 1388|       |       6_____*___
 1389|       |       7_____*___
 1390|       |       8_________ */
 1391|   993M|    float sum =
 1392|   993M|        d[-xs3 - xs - 2] +
 1393|   993M|        d[-xs3 - 2] +
 1394|   993M|        d[-xs - xs - 1] +
 1395|   993M|        d[-xs - 1] +
 1396|   993M|        d[0] +
 1397|   993M|        d[xs] +
 1398|   993M|        d[xs + xs + 1] +
 1399|   993M|        d[xs3 + 1];
 1400|   993M|    retval += sum * sum;
 1401|   993M|  }
 1402|   993M|  {
 1403|       |    /* 0______*__
 1404|       |       1______*__
 1405|       |       2_____*___
 1406|       |       3_____*___
 1407|       |       4____0____
 1408|       |       5____*____
 1409|       |       6___*_____
 1410|       |       7___*_____
 1411|       |       8_________ */
 1412|   993M|    float sum =
 1413|   993M|        d[-xs3 - xs + 2] +
 1414|   993M|        d[-xs3 + 2] +
 1415|   993M|        d[-xs - xs + 1] +
 1416|   993M|        d[-xs + 1] +
 1417|   993M|        d[0] +
 1418|   993M|        d[xs] +
 1419|   993M|        d[xs + xs - 1] +
 1420|   993M|        d[xs3 - 1];
 1421|   993M|    retval += sum * sum;
 1422|   993M|  }
 1423|   993M|  return retval;
 1424|   993M|}
butteraugli.cc:_ZN11butteraugliL15PaddedMaltaUnitILb1ENS_8MaltaTagEEEfPfmmmm:
 1431|   726M|    const size_t xsize_, const size_t ysize_) {
 1432|   726M|  int ix0 = y0 * xsize_ + x0;
 1433|   726M|  const float* BUTTERAUGLI_RESTRICT d = &diffs[ix0];
 1434|   726M|  if (fastMode ||
  ------------------
  |  Branch (1434:7): [Folded - Ignored]
  ------------------
 1435|   726M|      (x0 >= 4 && y0 >= 4 && x0 < (xsize_ - 4) && y0 < (ysize_ - 4))) {
  ------------------
  |  Branch (1435:8): [True: 0, False: 0]
  |  Branch (1435:19): [True: 0, False: 0]
  |  Branch (1435:30): [True: 0, False: 0]
  |  Branch (1435:51): [True: 0, False: 0]
  ------------------
 1436|   726M|    return MaltaUnit(Tag(), d, xsize_);
 1437|   726M|  }
 1438|       |
 1439|      0|  float borderimage[9 * 9];
 1440|      0|  for (int dy = 0; dy < 9; ++dy) {
  ------------------
  |  Branch (1440:20): [True: 0, False: 0]
  ------------------
 1441|      0|    int y = y0 + dy - 4;
 1442|      0|    if (y < 0 || y >= ysize_) {
  ------------------
  |  Branch (1442:9): [True: 0, False: 0]
  |  Branch (1442:18): [True: 0, False: 0]
  ------------------
 1443|      0|      for (int dx = 0; dx < 9; ++dx) {
  ------------------
  |  Branch (1443:24): [True: 0, False: 0]
  ------------------
 1444|      0|        borderimage[dy * 9 + dx] = 0.0f;
 1445|      0|      }
 1446|      0|    } else {
 1447|      0|      for (int dx = 0; dx < 9; ++dx) {
  ------------------
  |  Branch (1447:24): [True: 0, False: 0]
  ------------------
 1448|      0|        int x = x0 + dx - 4;
 1449|      0|        if (x < 0 || x >= xsize_) {
  ------------------
  |  Branch (1449:13): [True: 0, False: 0]
  |  Branch (1449:22): [True: 0, False: 0]
  ------------------
 1450|      0|          borderimage[dy * 9 + dx] = 0.0f;
 1451|      0|        } else {
 1452|      0|          borderimage[dy * 9 + dx] = diffs[y * xsize_ + x];
 1453|      0|        }
 1454|      0|      }
 1455|      0|    }
 1456|      0|  }
 1457|      0|  return MaltaUnit(Tag(), &borderimage[4 * 9 + 4], 9);
 1458|   726M|}
butteraugli.cc:_ZN11butteraugliL16MaltaDiffMapImplINS_10MaltaTagLFEEEvRKNS_5ImageIfEES5_mmdddddPS3_:
 1467|   654k|                             ImageF* block_diff_ac) {
 1468|   654k|  const float kWeight0 = 0.5;
 1469|   654k|  const float kWeight1 = 0.33;
 1470|       |
 1471|   654k|  const double w_pre0gt1 = mulli * sqrt(kWeight0 * w_0gt1) / (len * 2 + 1);
 1472|   654k|  const double w_pre0lt1 = mulli * sqrt(kWeight1 * w_0lt1) / (len * 2 + 1);
 1473|   654k|  const float norm2_0gt1 = w_pre0gt1 * norm1;
 1474|   654k|  const float norm2_0lt1 = w_pre0lt1 * norm1;
 1475|       |
 1476|   654k|  std::vector<float> diffs(ysize_ * xsize_);
 1477|  31.7M|  for (size_t y = 0, ix = 0; y < ysize_; ++y) {
  ------------------
  |  Branch (1477:30): [True: 31.0M, False: 654k]
  ------------------
 1478|  31.0M|    const float* BUTTERAUGLI_RESTRICT const row0 = lum0.Row(y);
 1479|  31.0M|    const float* BUTTERAUGLI_RESTRICT const row1 = lum1.Row(y);
 1480|  2.01G|    for (size_t x = 0; x < xsize_; ++x, ++ix) {
  ------------------
  |  Branch (1480:24): [True: 1.98G, False: 31.0M]
  ------------------
 1481|  1.98G|      const float absval = 0.5 * std::abs(row0[x]) + 0.5 * std::abs(row1[x]);
 1482|  1.98G|      const float diff = row0[x] - row1[x];
 1483|  1.98G|      const float scaler = norm2_0gt1 / (static_cast<float>(norm1) + absval);
 1484|       |
 1485|       |      // Primary symmetric quadratic objective.
 1486|  1.98G|      diffs[ix] = scaler * diff;
 1487|       |
 1488|  1.98G|      const float scaler2 = norm2_0lt1 / (static_cast<float>(norm1) + absval);
 1489|  1.98G|      const double fabs0 = fabs(row0[x]);
 1490|       |
 1491|       |      // Secondary half-open quadratic objectives.
 1492|  1.98G|      const double too_small = 0.55 * fabs0;
 1493|  1.98G|      const double too_big = 1.05 * fabs0;
 1494|       |
 1495|  1.98G|      if (row0[x] < 0) {
  ------------------
  |  Branch (1495:11): [True: 725M, False: 1.26G]
  ------------------
 1496|   725M|        if (row1[x] > -too_small) {
  ------------------
  |  Branch (1496:13): [True: 62.7M, False: 663M]
  ------------------
 1497|  62.7M|          double impact = scaler2 * (row1[x] + too_small);
 1498|  62.7M|          if (diff < 0) {
  ------------------
  |  Branch (1498:15): [True: 62.7M, False: 0]
  ------------------
 1499|  62.7M|            diffs[ix] -= impact;
 1500|  62.7M|          } else {
 1501|      0|            diffs[ix] += impact;
 1502|      0|          }
 1503|   663M|        } else if (row1[x] < -too_big) {
  ------------------
  |  Branch (1503:20): [True: 163M, False: 499M]
  ------------------
 1504|   163M|          double impact = scaler2 * (-row1[x] - too_big);
 1505|   163M|          if (diff < 0) {
  ------------------
  |  Branch (1505:15): [True: 0, False: 163M]
  ------------------
 1506|      0|            diffs[ix] -= impact;
 1507|   163M|          } else {
 1508|   163M|            diffs[ix] += impact;
 1509|   163M|          }
 1510|   163M|        }
 1511|  1.26G|      } else {
 1512|  1.26G|        if (row1[x] < too_small) {
  ------------------
  |  Branch (1512:13): [True: 69.3M, False: 1.19G]
  ------------------
 1513|  69.3M|          double impact = scaler2 * (too_small - row1[x]);
 1514|  69.3M|          if (diff < 0) {
  ------------------
  |  Branch (1514:15): [True: 0, False: 69.3M]
  ------------------
 1515|      0|            diffs[ix] -= impact;
 1516|  69.3M|          } else {
 1517|  69.3M|            diffs[ix] += impact;
 1518|  69.3M|          }
 1519|  1.19G|        } else if (row1[x] > too_big) {
  ------------------
  |  Branch (1519:20): [True: 163M, False: 1.02G]
  ------------------
 1520|   163M|          double impact = scaler2 * (row1[x] - too_big);
 1521|   163M|          if (diff < 0) {
  ------------------
  |  Branch (1521:15): [True: 163M, False: 0]
  ------------------
 1522|   163M|            diffs[ix] -= impact;
 1523|   163M|          } else {
 1524|      0|            diffs[ix] += impact;
 1525|      0|          }
 1526|   163M|        }
 1527|  1.26G|      }
 1528|  1.98G|    }
 1529|  31.0M|  }
 1530|       |
 1531|   654k|  size_t y0 = 0;
 1532|       |  // Top
 1533|  3.27M|  for (; y0 < 4; ++y0) {
  ------------------
  |  Branch (1533:10): [True: 2.61M, False: 654k]
  ------------------
 1534|  2.61M|    float* const BUTTERAUGLI_RESTRICT row_diff = block_diff_ac->Row(y0);
 1535|   166M|    for (size_t x0 = 0; x0 < xsize_; ++x0) {
  ------------------
  |  Branch (1535:25): [True: 163M, False: 2.61M]
  ------------------
 1536|   163M|      row_diff[x0] +=
 1537|   163M|          PaddedMaltaUnit<false, Tag>(&diffs[0], x0, y0, xsize_, ysize_);
 1538|   163M|    }
 1539|  2.61M|  }
 1540|       |
 1541|       |  // Middle
 1542|  26.4M|  for (; y0 < ysize_ - 4; ++y0) {
  ------------------
  |  Branch (1542:10): [True: 25.8M, False: 654k]
  ------------------
 1543|  25.8M|    float* const BUTTERAUGLI_RESTRICT row_diff = block_diff_ac->Row(y0);
 1544|  25.8M|    size_t x0 = 0;
 1545|   129M|    for (; x0 < 4; ++x0) {
  ------------------
  |  Branch (1545:12): [True: 103M, False: 25.8M]
  ------------------
 1546|   103M|      row_diff[x0] +=
 1547|   103M|          PaddedMaltaUnit<false, Tag>(&diffs[0], x0, y0, xsize_, ysize_);
 1548|   103M|    }
 1549|  1.47G|    for (; x0 < xsize_ - 4; ++x0) {
  ------------------
  |  Branch (1549:12): [True: 1.45G, False: 25.8M]
  ------------------
 1550|  1.45G|      row_diff[x0] +=
 1551|  1.45G|          PaddedMaltaUnit<true, Tag>(&diffs[0], x0, y0, xsize_, ysize_);
 1552|  1.45G|    }
 1553|       |
 1554|   129M|    for (; x0 < xsize_; ++x0) {
  ------------------
  |  Branch (1554:12): [True: 103M, False: 25.8M]
  ------------------
 1555|   103M|      row_diff[x0] +=
 1556|   103M|          PaddedMaltaUnit<false, Tag>(&diffs[0], x0, y0, xsize_, ysize_);
 1557|   103M|    }
 1558|  25.8M|  }
 1559|       |
 1560|       |  // Bottom
 1561|  3.27M|  for (; y0 < ysize_; ++y0) {
  ------------------
  |  Branch (1561:10): [True: 2.61M, False: 654k]
  ------------------
 1562|  2.61M|    float* const BUTTERAUGLI_RESTRICT row_diff = block_diff_ac->Row(y0);
 1563|   166M|    for (size_t x0 = 0; x0 < xsize_; ++x0) {
  ------------------
  |  Branch (1563:25): [True: 163M, False: 2.61M]
  ------------------
 1564|   163M|      row_diff[x0] +=
 1565|   163M|          PaddedMaltaUnit<false, Tag>(&diffs[0], x0, y0, xsize_, ysize_);
 1566|   163M|    }
 1567|  2.61M|  }
 1568|   654k|}
butteraugli.cc:_ZN11butteraugliL15PaddedMaltaUnitILb0ENS_10MaltaTagLFEEEfPfmmmm:
 1431|   533M|    const size_t xsize_, const size_t ysize_) {
 1432|   533M|  int ix0 = y0 * xsize_ + x0;
 1433|   533M|  const float* BUTTERAUGLI_RESTRICT d = &diffs[ix0];
 1434|   533M|  if (fastMode ||
  ------------------
  |  Branch (1434:7): [Folded - Ignored]
  ------------------
 1435|   533M|      (x0 >= 4 && y0 >= 4 && x0 < (xsize_ - 4) && y0 < (ysize_ - 4))) {
  ------------------
  |  Branch (1435:8): [True: 409M, False: 124M]
  |  Branch (1435:19): [True: 256M, False: 153M]
  |  Branch (1435:30): [True: 142M, False: 113M]
  |  Branch (1435:51): [True: 0, False: 142M]
  ------------------
 1436|      0|    return MaltaUnit(Tag(), d, xsize_);
 1437|      0|  }
 1438|       |
 1439|   533M|  float borderimage[9 * 9];
 1440|  5.33G|  for (int dy = 0; dy < 9; ++dy) {
  ------------------
  |  Branch (1440:20): [True: 4.80G, False: 533M]
  ------------------
 1441|  4.80G|    int y = y0 + dy - 4;
 1442|  4.80G|    if (y < 0 || y >= ysize_) {
  ------------------
  |  Branch (1442:9): [True: 408M, False: 4.39G]
  |  Branch (1442:18): [True: 408M, False: 3.98G]
  ------------------
 1443|  8.17G|      for (int dx = 0; dx < 9; ++dx) {
  ------------------
  |  Branch (1443:24): [True: 7.35G, False: 817M]
  ------------------
 1444|  7.35G|        borderimage[dy * 9 + dx] = 0.0f;
 1445|  7.35G|      }
 1446|  3.98G|    } else {
 1447|  39.8G|      for (int dx = 0; dx < 9; ++dx) {
  ------------------
  |  Branch (1447:24): [True: 35.8G, False: 3.98G]
  ------------------
 1448|  35.8G|        int x = x0 + dx - 4;
 1449|  35.8G|        if (x < 0 || x >= xsize_) {
  ------------------
  |  Branch (1449:13): [True: 2.66G, False: 33.2G]
  |  Branch (1449:22): [True: 2.66G, False: 30.5G]
  ------------------
 1450|  5.32G|          borderimage[dy * 9 + dx] = 0.0f;
 1451|  30.5G|        } else {
 1452|  30.5G|          borderimage[dy * 9 + dx] = diffs[y * xsize_ + x];
 1453|  30.5G|        }
 1454|  35.8G|      }
 1455|  3.98G|    }
 1456|  4.80G|  }
 1457|   533M|  return MaltaUnit(Tag(), &borderimage[4 * 9 + 4], 9);
 1458|   533M|}
butteraugli.cc:_ZN11butteraugliL9MaltaUnitENS_10MaltaTagLFEPKfi:
  915|  1.98G|                       const int xs) {
  916|  1.98G|  const int xs3 = 3 * xs;
  917|  1.98G|  float retval = 0;
  918|  1.98G|  {
  919|       |    // x grows, y constant
  920|  1.98G|    float sum =
  921|  1.98G|        d[-4] +
  922|  1.98G|        d[-2] +
  923|  1.98G|        d[0] +
  924|  1.98G|        d[2] +
  925|  1.98G|        d[4];
  926|  1.98G|    retval += sum * sum;
  927|  1.98G|  }
  928|  1.98G|  {
  929|       |    // y grows, x constant
  930|  1.98G|    float sum =
  931|  1.98G|        d[-xs3 - xs] +
  932|  1.98G|        d[-xs - xs] +
  933|  1.98G|        d[0] +
  934|  1.98G|        d[xs + xs] +
  935|  1.98G|        d[xs3 + xs];
  936|  1.98G|    retval += sum * sum;
  937|  1.98G|  }
  938|  1.98G|  {
  939|       |    // both grow
  940|  1.98G|    float sum =
  941|  1.98G|        d[-xs3 - 3] +
  942|  1.98G|        d[-xs - xs - 2] +
  943|  1.98G|        d[0] +
  944|  1.98G|        d[xs + xs + 2] +
  945|  1.98G|        d[xs3 + 3];
  946|  1.98G|    retval += sum * sum;
  947|  1.98G|  }
  948|  1.98G|  {
  949|       |    // y grows, x shrinks
  950|  1.98G|    float sum =
  951|  1.98G|        d[-xs3 + 3] +
  952|  1.98G|        d[-xs - xs + 2] +
  953|  1.98G|        d[0] +
  954|  1.98G|        d[xs + xs - 2] +
  955|  1.98G|        d[xs3 - 3];
  956|  1.98G|    retval += sum * sum;
  957|  1.98G|  }
  958|  1.98G|  {
  959|       |    // y grows -4 to 4, x shrinks 1 -> -1
  960|  1.98G|    float sum =
  961|  1.98G|        d[-xs3 - xs + 1] +
  962|  1.98G|        d[-xs - xs + 1] +
  963|  1.98G|        d[0] +
  964|  1.98G|        d[xs + xs - 1] +
  965|  1.98G|        d[xs3 + xs - 1];
  966|  1.98G|    retval += sum * sum;
  967|  1.98G|  }
  968|  1.98G|  {
  969|       |    //  y grows -4 to 4, x grows -1 -> 1
  970|  1.98G|    float sum =
  971|  1.98G|        d[-xs3 - xs - 1] +
  972|  1.98G|        d[-xs - xs - 1] +
  973|  1.98G|        d[0] +
  974|  1.98G|        d[xs + xs + 1] +
  975|  1.98G|        d[xs3 + xs + 1];
  976|  1.98G|    retval += sum * sum;
  977|  1.98G|  }
  978|  1.98G|  {
  979|       |    // x grows -4 to 4, y grows -1 to 1
  980|  1.98G|    float sum =
  981|  1.98G|        d[-4 - xs] +
  982|  1.98G|        d[-2 - xs] +
  983|  1.98G|        d[0] +
  984|  1.98G|        d[2 + xs] +
  985|  1.98G|        d[4 + xs];
  986|  1.98G|    retval += sum * sum;
  987|  1.98G|  }
  988|  1.98G|  {
  989|       |    // x grows -4 to 4, y shrinks 1 to -1
  990|  1.98G|    float sum =
  991|  1.98G|        d[-4 + xs] +
  992|  1.98G|        d[-2 + xs] +
  993|  1.98G|        d[0] +
  994|  1.98G|        d[2 - xs] +
  995|  1.98G|        d[4 - xs];
  996|  1.98G|    retval += sum * sum;
  997|  1.98G|  }
  998|  1.98G|  {
  999|       |    /* 0_________
 1000|       |       1__*______
 1001|       |       2___*_____
 1002|       |       3_________
 1003|       |       4____0____
 1004|       |       5_________
 1005|       |       6_____*___
 1006|       |       7______*__
 1007|       |       8_________ */
 1008|  1.98G|    float sum =
 1009|  1.98G|        d[-xs3 - 2] +
 1010|  1.98G|        d[-xs - xs - 1] +
 1011|  1.98G|        d[0] +
 1012|  1.98G|        d[xs + xs + 1] +
 1013|  1.98G|        d[xs3 + 2];
 1014|  1.98G|    retval += sum * sum;
 1015|  1.98G|  }
 1016|  1.98G|  {
 1017|       |    /* 0_________
 1018|       |       1______*__
 1019|       |       2_____*___
 1020|       |       3_________
 1021|       |       4____0____
 1022|       |       5_________
 1023|       |       6___*_____
 1024|       |       7__*______
 1025|       |       8_________ */
 1026|  1.98G|    float sum =
 1027|  1.98G|        d[-xs3 + 2] +
 1028|  1.98G|        d[-xs - xs + 1] +
 1029|  1.98G|        d[0] +
 1030|  1.98G|        d[xs + xs - 1] +
 1031|  1.98G|        d[xs3 - 2];
 1032|  1.98G|    retval += sum * sum;
 1033|  1.98G|  }
 1034|  1.98G|  {
 1035|       |    /* 0_________
 1036|       |       1_________
 1037|       |       2_*_______
 1038|       |       3__*______
 1039|       |       4____0____
 1040|       |       5______*__
 1041|       |       6_______*_
 1042|       |       7_________
 1043|       |       8_________ */
 1044|  1.98G|    float sum =
 1045|  1.98G|        d[-xs - xs - 3] +
 1046|  1.98G|        d[-xs - 2] +
 1047|  1.98G|        d[0] +
 1048|  1.98G|        d[xs + 2] +
 1049|  1.98G|        d[xs + xs + 3];
 1050|  1.98G|    retval += sum * sum;
 1051|  1.98G|  }
 1052|  1.98G|  {
 1053|       |    /* 0_________
 1054|       |       1_________
 1055|       |       2_______*_
 1056|       |       3______*__
 1057|       |       4____0____
 1058|       |       5__*______
 1059|       |       6_*_______
 1060|       |       7_________
 1061|       |       8_________ */
 1062|  1.98G|    float sum =
 1063|  1.98G|        d[-xs - xs + 3] +
 1064|  1.98G|        d[-xs + 2] +
 1065|  1.98G|        d[0] +
 1066|  1.98G|        d[xs - 2] +
 1067|  1.98G|        d[xs + xs - 3];
 1068|  1.98G|    retval += sum * sum;
 1069|  1.98G|  }
 1070|  1.98G|  {
 1071|       |    /* 0_________
 1072|       |       1_________
 1073|       |       2________*
 1074|       |       3______*__
 1075|       |       4____0____
 1076|       |       5__*______
 1077|       |       6*________
 1078|       |       7_________
 1079|       |       8_________ */
 1080|       |
 1081|  1.98G|    float sum =
 1082|  1.98G|        d[xs + xs - 4] +
 1083|  1.98G|        d[xs - 2] +
 1084|  1.98G|        d[0] +
 1085|  1.98G|        d[-xs + 2] +
 1086|  1.98G|        d[-xs - xs + 4];
 1087|  1.98G|    retval += sum * sum;
 1088|  1.98G|  }
 1089|  1.98G|  {
 1090|       |    /* 0_________
 1091|       |       1_________
 1092|       |       2*________
 1093|       |       3__*______
 1094|       |       4____0____
 1095|       |       5______*__
 1096|       |       6________*
 1097|       |       7_________
 1098|       |       8_________ */
 1099|  1.98G|    float sum =
 1100|  1.98G|        d[-xs - xs - 4] +
 1101|  1.98G|        d[-xs - 2] +
 1102|  1.98G|        d[0] +
 1103|  1.98G|        d[xs + 2] +
 1104|  1.98G|        d[xs + xs + 4];
 1105|  1.98G|    retval += sum * sum;
 1106|  1.98G|  }
 1107|  1.98G|  {
 1108|       |    /* 0__*______
 1109|       |       1_________
 1110|       |       2___*_____
 1111|       |       3_________
 1112|       |       4____0____
 1113|       |       5_________
 1114|       |       6_____*___
 1115|       |       7_________
 1116|       |       8______*__ */
 1117|  1.98G|    float sum =
 1118|  1.98G|        d[-xs3 - xs - 2] +
 1119|  1.98G|        d[-xs - xs - 1] +
 1120|  1.98G|        d[0] +
 1121|  1.98G|        d[xs + xs + 1] +
 1122|  1.98G|        d[xs3 + xs + 2];
 1123|  1.98G|    retval += sum * sum;
 1124|  1.98G|  }
 1125|  1.98G|  {
 1126|       |    /* 0______*__
 1127|       |       1_________
 1128|       |       2_____*___
 1129|       |       3_________
 1130|       |       4____0____
 1131|       |       5_________
 1132|       |       6___*_____
 1133|       |       7_________
 1134|       |       8__*______ */
 1135|  1.98G|    float sum =
 1136|  1.98G|        d[-xs3 - xs + 2] +
 1137|  1.98G|        d[-xs - xs + 1] +
 1138|  1.98G|        d[0] +
 1139|  1.98G|        d[xs + xs - 1] +
 1140|  1.98G|        d[xs3 + xs - 2];
 1141|  1.98G|    retval += sum * sum;
 1142|  1.98G|  }
 1143|  1.98G|  return retval;
 1144|  1.98G|}
butteraugli.cc:_ZN11butteraugliL15PaddedMaltaUnitILb1ENS_10MaltaTagLFEEEfPfmmmm:
 1431|  1.45G|    const size_t xsize_, const size_t ysize_) {
 1432|  1.45G|  int ix0 = y0 * xsize_ + x0;
 1433|  1.45G|  const float* BUTTERAUGLI_RESTRICT d = &diffs[ix0];
 1434|  1.45G|  if (fastMode ||
  ------------------
  |  Branch (1434:7): [Folded - Ignored]
  ------------------
 1435|  1.45G|      (x0 >= 4 && y0 >= 4 && x0 < (xsize_ - 4) && y0 < (ysize_ - 4))) {
  ------------------
  |  Branch (1435:8): [True: 0, False: 0]
  |  Branch (1435:19): [True: 0, False: 0]
  |  Branch (1435:30): [True: 0, False: 0]
  |  Branch (1435:51): [True: 0, False: 0]
  ------------------
 1436|  1.45G|    return MaltaUnit(Tag(), d, xsize_);
 1437|  1.45G|  }
 1438|       |
 1439|      0|  float borderimage[9 * 9];
 1440|      0|  for (int dy = 0; dy < 9; ++dy) {
  ------------------
  |  Branch (1440:20): [True: 0, False: 0]
  ------------------
 1441|      0|    int y = y0 + dy - 4;
 1442|      0|    if (y < 0 || y >= ysize_) {
  ------------------
  |  Branch (1442:9): [True: 0, False: 0]
  |  Branch (1442:18): [True: 0, False: 0]
  ------------------
 1443|      0|      for (int dx = 0; dx < 9; ++dx) {
  ------------------
  |  Branch (1443:24): [True: 0, False: 0]
  ------------------
 1444|      0|        borderimage[dy * 9 + dx] = 0.0f;
 1445|      0|      }
 1446|      0|    } else {
 1447|      0|      for (int dx = 0; dx < 9; ++dx) {
  ------------------
  |  Branch (1447:24): [True: 0, False: 0]
  ------------------
 1448|      0|        int x = x0 + dx - 4;
 1449|      0|        if (x < 0 || x >= xsize_) {
  ------------------
  |  Branch (1449:13): [True: 0, False: 0]
  |  Branch (1449:22): [True: 0, False: 0]
  ------------------
 1450|      0|          borderimage[dy * 9 + dx] = 0.0f;
 1451|      0|        } else {
 1452|      0|          borderimage[dy * 9 + dx] = diffs[y * xsize_ + x];
 1453|      0|        }
 1454|      0|      }
 1455|      0|    }
 1456|      0|  }
 1457|      0|  return MaltaUnit(Tag(), &borderimage[4 * 9 + 4], 9);
 1458|  1.45G|}

_ZNK11butteraugli18RationalPolynomialclEd:
  581|  4.52G|  inline double operator()(const double x) const {
  582|       |    // First normalize to [0, 1].
  583|  4.52G|    const double x01 = (x - min_value) / (max_value - min_value);
  584|       |    // And then to [-1, 1] domain of Chebyshev polynomials.
  585|  4.52G|    const double xc = 2.0 * x01 - 1.0;
  586|       |
  587|  4.52G|    const double yp = EvaluatePolynomial(xc, p);
  588|  4.52G|    const double yq = EvaluatePolynomial(xc, q);
  589|  4.52G|    if (yq == 0.0) return 0.0;
  ------------------
  |  Branch (589:9): [True: 0, False: 4.52G]
  ------------------
  590|  4.52G|    return static_cast<float>(yp / yq);
  591|  4.52G|  }
_ZN11butteraugli18RationalPolynomial18EvaluatePolynomialILi6EEEddRAT__Kd:
  573|  9.05G|                                   const double (&coefficients)[N]) {
  574|  9.05G|    double b1 = 0.0;
  575|  9.05G|    double b2 = 0.0;
  576|  9.05G|    ClenshawRecursion<N - 1>(x, coefficients, &b1, &b2);
  577|  9.05G|    return b1;
  578|  9.05G|  }
butteraugli_comparator.cc:_ZN11butteraugliL12CreatePlanesIfEENSt3__16vectorINS_5ImageIT_EENS1_9allocatorIS5_EEEEmmm:
  328|   171k|                                                 const size_t num_planes) {
  329|   171k|  std::vector<Image<T>> planes;
  330|   171k|  planes.reserve(num_planes);
  331|   686k|  for (size_t i = 0; i < num_planes; ++i) {
  ------------------
  |  Branch (331:22): [True: 514k, False: 171k]
  ------------------
  332|   514k|    planes.emplace_back(xsize, ysize);
  333|   514k|  }
  334|   171k|  return planes;
  335|   171k|}
_ZN11butteraugli5ImageIfEC2EOS1_:
  253|  23.5M|        bytes_(std::move(other.bytes_)) {}
_ZN11butteraugli5ImageIfEC2Emm:
  225|   105M|        bytes_(Allocate(bytes_per_row_ * ysize)) {}
_ZN11butteraugli5ImageIfE11BytesPerRowEm:
  200|   106M|  static size_t BytesPerRow(const size_t xsize) {
  201|       |    // Allow reading one extra AVX-2 vector on the right margin.
  202|   106M|    const size_t row_size = xsize * sizeof(T) + 32;
  203|   106M|    const size_t align = CacheAligned::kCacheLineSize;
  204|   106M|    size_t bytes_per_row = (row_size + align - 1) & ~(align - 1);
  205|       |    // During the lengthy window before writes are committed to memory, CPUs
  206|       |    // guard against read after write hazards by checking the address, but
  207|       |    // only the lower 11 bits. We avoid a false dependency between writes to
  208|       |    // consecutive rows by ensuring their sizes are not multiples of 2 KiB.
  209|   106M|    if (bytes_per_row % 2048 == 0) {
  ------------------
  |  Branch (209:9): [True: 0, False: 106M]
  ------------------
  210|      0|      bytes_per_row += align;
  211|      0|    }
  212|   106M|    return bytes_per_row;
  213|   106M|  }
butteraugli_comparator.cc:_ZN11butteraugliL8AllocateIhEENSt3__110unique_ptrIA_T_PFvPvEEEm:
  159|  25.5M|static inline CacheAlignedUniquePtrT<T> Allocate(const size_t entries) {
  160|  25.5M|  return CacheAlignedUniquePtrT<T>(
  161|  25.5M|      static_cast<T * const BUTTERAUGLI_RESTRICT>(
  162|  25.5M|          CacheAligned::Allocate(entries * sizeof(T))),
  163|  25.5M|      CacheAligned::Free);
  164|  25.5M|}
_ZN11butteraugli5ImageIfE3RowEm:
  275|  25.9G|  T *const BUTTERAUGLI_RESTRICT Row(const size_t y) {
  276|  25.9G|#ifdef BUTTERAUGLI_ENABLE_CHECKS
  277|  25.9G|    if (y >= ysize_) {
  ------------------
  |  Branch (277:9): [True: 0, False: 25.9G]
  ------------------
  278|      0|      printf("Row %zu out of bounds (ysize=%zu)\n", y, ysize_);
  279|      0|      abort();
  280|      0|    }
  281|  25.9G|#endif
  282|  25.9G|    void *row = bytes_.get() + y * bytes_per_row_;
  283|  25.9G|    return reinterpret_cast<T *>(BUTTERAUGLI_ASSUME_ALIGNED(row, 64));
  ------------------
  |  |  137|  25.9G|#define BUTTERAUGLI_ASSUME_ALIGNED(ptr, align) __builtin_assume_aligned((ptr), (align))
  ------------------
  284|  25.9G|  }
butteraugli_comparator.cc:_ZN11butteraugliL16PlanesFromPackedIfEENSt3__16vectorINS_5ImageIT_EENS1_9allocatorIS5_EEEEmmRKNS2_INS2_IS4_NS6_IS4_EEEENS6_ISA_EEEE:
  394|  7.85M|    const std::vector<std::vector<T>> &packed) {
  395|  7.85M|  std::vector<Image<T>> planes;
  396|  7.85M|  planes.reserve(packed.size());
  397|  23.5M|  for (const std::vector<T> &p : packed) {
  ------------------
  |  Branch (397:32): [True: 23.5M, False: 7.85M]
  ------------------
  398|  23.5M|    planes.push_back(Image<T>(xsize, ysize));
  399|  23.5M|    CopyFromPacked(p, &planes.back());
  400|  23.5M|  }
  401|  7.85M|  return planes;
  402|  7.85M|}
butteraugli_comparator.cc:_ZN11butteraugliL14CopyFromPackedIfEEvRKNSt3__16vectorIT_NS1_9allocatorIS3_EEEEPNS_5ImageIS3_EE:
  379|  23.5M|static inline void CopyFromPacked(const std::vector<T> &from, Image<T> *to) {
  380|  23.5M|  const size_t xsize = to->xsize();
  381|  23.5M|  const size_t ysize = to->ysize();
  382|  23.5M|  assert(from.size() == xsize * ysize);
  383|   231M|  for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (383:22): [True: 207M, False: 23.5M]
  ------------------
  384|   207M|    const float* const BUTTERAUGLI_RESTRICT row_from =
  385|   207M|        from.data() + y * xsize;
  386|   207M|    float* const BUTTERAUGLI_RESTRICT row_to = to->Row(y);
  387|   207M|    memcpy(row_to, row_from, xsize * sizeof(T));
  388|   207M|  }
  389|  23.5M|}
_ZNK11butteraugli5ImageIfE5xsizeEv:
  272|  6.35G|  size_t xsize() const { return xsize_; }
_ZNK11butteraugli5ImageIfE5ysizeEv:
  273|  8.79G|  size_t ysize() const { return ysize_; }
_ZN11butteraugli5ImageIfEC2Ev:
  219|  51.5M|            bytes_(static_cast<uint8_t*>(nullptr), Ignore) {}
butteraugli_comparator.cc:_ZN11butteraugliL12CopyToPackedIfEEvRKNS_5ImageIT_EEPNSt3__16vectorIS2_NS6_9allocatorIS2_EEEE:
  361|  23.2M|static inline void CopyToPacked(const Image<T> &from, std::vector<T> *to) {
  362|  23.2M|  const size_t xsize = from.xsize();
  363|  23.2M|  const size_t ysize = from.ysize();
  364|       |#if BUTTERAUGLI_ENABLE_CHECKS
  365|       |  if (to->size() < xsize * ysize) {
  366|       |    printf("%zu x %zu exceeds %zu capacity\n", xsize, ysize, to->size());
  367|       |    abort();
  368|       |  }
  369|       |#endif
  370|   215M|  for (size_t y = 0; y < ysize; ++y) {
  ------------------
  |  Branch (370:22): [True: 192M, False: 23.2M]
  ------------------
  371|   192M|    const float* const BUTTERAUGLI_RESTRICT row_from = from.Row(y);
  372|   192M|    float* const BUTTERAUGLI_RESTRICT row_to = to->data() + y * xsize;
  373|   192M|    memcpy(row_to, row_from, xsize * sizeof(T));
  374|   192M|  }
  375|  23.2M|}
butteraugli_comparator.cc:_ZN11butteraugliL16PackedFromPlanesIfEENSt3__16vectorINS2_IT_NS1_9allocatorIS3_EEEENS4_IS6_EEEERKNS2_INS_5ImageIS3_EENS4_ISA_EEEE:
  406|  7.69M|    const std::vector<Image<T>> &planes) {
  407|  7.69M|  assert(!planes.empty());
  408|      0|  const size_t num_pixels = planes[0].xsize() * planes[0].ysize();
  409|  7.69M|  std::vector<std::vector<T>> packed;
  410|  7.69M|  packed.reserve(planes.size());
  411|  23.0M|  for (const Image<T> &image : planes) {
  ------------------
  |  Branch (411:30): [True: 23.0M, False: 7.69M]
  ------------------
  412|  23.0M|    packed.push_back(std::vector<T>(num_pixels));
  413|  23.0M|    CopyToPacked(image, &packed.back());
  414|  23.0M|  }
  415|  7.69M|  return packed;
  416|  7.69M|}
_ZNK11butteraugli5ImageIfE3RowEm:
  286|  16.4G|  const T *const BUTTERAUGLI_RESTRICT Row(const size_t y) const {
  287|  16.4G|#ifdef BUTTERAUGLI_ENABLE_CHECKS
  288|  16.4G|    if (y >= ysize_) {
  ------------------
  |  Branch (288:9): [True: 0, False: 16.4G]
  ------------------
  289|      0|      printf("Const row %zu out of bounds (ysize=%zu)\n", y, ysize_);
  290|      0|      abort();
  291|      0|    }
  292|  16.4G|#endif
  293|  16.4G|    void *row = bytes_.get() + y * bytes_per_row_;
  294|  16.4G|    return reinterpret_cast<const T *>(BUTTERAUGLI_ASSUME_ALIGNED(row, 64));
  ------------------
  |  |  137|  16.4G|#define BUTTERAUGLI_ASSUME_ALIGNED(ptr, align) __builtin_assume_aligned((ptr), (align))
  ------------------
  295|  16.4G|  }
butteraugli.cc:_ZN11butteraugliL15GammaPolynomialEd:
  603|  4.52G|static inline double GammaPolynomial(double value) {
  604|  4.52G|  static const RationalPolynomial r = {
  605|  4.52G|    0.971783, 590.188894,
  606|  4.52G|    {
  607|  4.52G|      98.7821300963361, 164.273222212631, 92.948112871376,
  608|  4.52G|      33.8165311212688, 6.91626704983562, 0.556380877028234
  609|  4.52G|    },
  610|  4.52G|    {
  611|  4.52G|      1, 1.64339473427892, 0.89392405219969, 0.298947051776379,
  612|  4.52G|      0.0507146002577288, 0.00226495093949756
  613|  4.52G|    }};
  614|  4.52G|  return r(value);
  615|  4.52G|}
butteraugli.cc:_ZN11butteraugliL17ClenshawRecursionILi5EEEvdPKdPdS3_:
  550|  9.05G|                                     double *b1, double *b2) {
  551|  9.05G|  const double x_b1 = x * (*b1);
  552|  9.05G|  const double t = (x_b1 + x_b1) - (*b2) + coefficients[INDEX];
  553|  9.05G|  *b2 = *b1;
  554|  9.05G|  *b1 = t;
  555|       |
  556|  9.05G|  ClenshawRecursion<INDEX - 1>(x, coefficients, b1, b2);
  557|  9.05G|}
butteraugli.cc:_ZN11butteraugliL17ClenshawRecursionILi4EEEvdPKdPdS3_:
  550|  9.05G|                                     double *b1, double *b2) {
  551|  9.05G|  const double x_b1 = x * (*b1);
  552|  9.05G|  const double t = (x_b1 + x_b1) - (*b2) + coefficients[INDEX];
  553|  9.05G|  *b2 = *b1;
  554|  9.05G|  *b1 = t;
  555|       |
  556|  9.05G|  ClenshawRecursion<INDEX - 1>(x, coefficients, b1, b2);
  557|  9.05G|}
butteraugli.cc:_ZN11butteraugliL17ClenshawRecursionILi3EEEvdPKdPdS3_:
  550|  9.05G|                                     double *b1, double *b2) {
  551|  9.05G|  const double x_b1 = x * (*b1);
  552|  9.05G|  const double t = (x_b1 + x_b1) - (*b2) + coefficients[INDEX];
  553|  9.05G|  *b2 = *b1;
  554|  9.05G|  *b1 = t;
  555|       |
  556|  9.05G|  ClenshawRecursion<INDEX - 1>(x, coefficients, b1, b2);
  557|  9.05G|}
butteraugli.cc:_ZN11butteraugliL17ClenshawRecursionILi2EEEvdPKdPdS3_:
  550|  9.05G|                                     double *b1, double *b2) {
  551|  9.05G|  const double x_b1 = x * (*b1);
  552|  9.05G|  const double t = (x_b1 + x_b1) - (*b2) + coefficients[INDEX];
  553|  9.05G|  *b2 = *b1;
  554|  9.05G|  *b1 = t;
  555|       |
  556|  9.05G|  ClenshawRecursion<INDEX - 1>(x, coefficients, b1, b2);
  557|  9.05G|}
butteraugli.cc:_ZN11butteraugliL17ClenshawRecursionILi1EEEvdPKdPdS3_:
  550|  9.05G|                                     double *b1, double *b2) {
  551|  9.05G|  const double x_b1 = x * (*b1);
  552|  9.05G|  const double t = (x_b1 + x_b1) - (*b2) + coefficients[INDEX];
  553|  9.05G|  *b2 = *b1;
  554|  9.05G|  *b1 = t;
  555|       |
  556|  9.05G|  ClenshawRecursion<INDEX - 1>(x, coefficients, b1, b2);
  557|  9.05G|}
butteraugli.cc:_ZN11butteraugliL17ClenshawRecursionILi0EEEvdPKdPdS3_:
  562|  9.05G|                                 double *b1, double *b2) {
  563|  9.05G|  const double x_b1 = x * (*b1);
  564|       |  // The final iteration differs - no 2 * x_b1 here.
  565|  9.05G|  *b1 = x_b1 - (*b2) + coefficients[0];
  566|  9.05G|}
butteraugli.cc:_ZN11butteraugliL8AllocateIhEENSt3__110unique_ptrIA_T_PFvPvEEEm:
  159|  80.4M|static inline CacheAlignedUniquePtrT<T> Allocate(const size_t entries) {
  160|  80.4M|  return CacheAlignedUniquePtrT<T>(
  161|  80.4M|      static_cast<T * const BUTTERAUGLI_RESTRICT>(
  162|  80.4M|          CacheAligned::Allocate(entries * sizeof(T))),
  163|  80.4M|      CacheAligned::Free);
  164|  80.4M|}
_ZN11butteraugli5ImageIfEaSEOS1_:
  256|  52.8M|  Image &operator=(Image &&other) {
  257|  52.8M|    xsize_ = other.xsize_;
  258|  52.8M|    ysize_ = other.ysize_;
  259|  52.8M|    bytes_per_row_ = other.bytes_per_row_;
  260|  52.8M|    bytes_ = std::move(other.bytes_);
  261|  52.8M|    return *this;
  262|  52.8M|  }
_ZN11butteraugli15OpsinAbsorbanceIfEEvRKT_S3_S3_PS1_S4_S4_:
  503|  3.01G|                                        V *BUTTERAUGLI_RESTRICT out2) {
  504|       |  // https://en.wikipedia.org/wiki/Photopsin absorbance modeling.
  505|  3.01G|  static const double mixi0 = 0.254462330846;
  506|  3.01G|  static const double mixi1 = 0.488238255095;
  507|  3.01G|  static const double mixi2 = 0.0635278003854;
  508|  3.01G|  static const double mixi3 = 1.01681026909;
  509|  3.01G|  static const double mixi4 = 0.195214015766;
  510|  3.01G|  static const double mixi5 = 0.568019861857;
  511|  3.01G|  static const double mixi6 = 0.0860755536007;
  512|  3.01G|  static const double mixi7 = 1.1510118369;
  513|  3.01G|  static const double mixi8 = 0.07374607900105684;
  514|  3.01G|  static const double mixi9 = 0.06142425304154509;
  515|  3.01G|  static const double mixi10 = 0.24416850520714256;
  516|  3.01G|  static const double mixi11 = 1.20481945273;
  517|       |
  518|  3.01G|  const V mix0(mixi0);
  519|  3.01G|  const V mix1(mixi1);
  520|  3.01G|  const V mix2(mixi2);
  521|  3.01G|  const V mix3(mixi3);
  522|  3.01G|  const V mix4(mixi4);
  523|  3.01G|  const V mix5(mixi5);
  524|  3.01G|  const V mix6(mixi6);
  525|  3.01G|  const V mix7(mixi7);
  526|  3.01G|  const V mix8(mixi8);
  527|  3.01G|  const V mix9(mixi9);
  528|  3.01G|  const V mix10(mixi10);
  529|  3.01G|  const V mix11(mixi11);
  530|       |
  531|  3.01G|  *out0 = mix0 * in0 + mix1 * in1 + mix2 * in2 + mix3;
  532|  3.01G|  *out1 = mix4 * in0 + mix5 * in1 + mix6 * in2 + mix7;
  533|  3.01G|  *out2 = mix8 * in0 + mix9 * in1 + mix10 * in2 + mix11;
  534|  3.01G|}
_ZN11butteraugli8RgbToXybIfEEvRKT_S3_S3_PS1_S4_S4_:
  492|  1.50G|                                 V *BUTTERAUGLI_RESTRICT valb) {
  493|  1.50G|  *valx = r - g;
  494|  1.50G|  *valy = r + g;
  495|  1.50G|  *valb = b;
  496|  1.50G|}
butteraugli.cc:_ZN11butteraugliL12CreatePlanesIfEENSt3__16vectorINS_5ImageIT_EENS1_9allocatorIS5_EEEEmmm:
  328|   495k|                                                 const size_t num_planes) {
  329|   495k|  std::vector<Image<T>> planes;
  330|   495k|  planes.reserve(num_planes);
  331|  1.98M|  for (size_t i = 0; i < num_planes; ++i) {
  ------------------
  |  Branch (331:22): [True: 1.48M, False: 495k]
  ------------------
  332|  1.48M|    planes.emplace_back(xsize, ysize);
  333|  1.48M|  }
  334|   495k|  return planes;
  335|   495k|}
_ZN11butteraugli5ImageIfEC2Emmf:
  231|   981k|        bytes_(Allocate(bytes_per_row_ * ysize)) {
  232|  47.5M|    for (size_t y = 0; y < ysize_; ++y) {
  ------------------
  |  Branch (232:24): [True: 46.5M, False: 981k]
  ------------------
  233|  46.5M|      T* const BUTTERAUGLI_RESTRICT row = Row(y);
  234|  3.02G|      for (int x = 0; x < xsize_; ++x) {
  ------------------
  |  Branch (234:23): [True: 2.98G, False: 46.5M]
  ------------------
  235|  2.98G|        row[x] = val;
  236|  2.98G|      }
  237|  46.5M|    }
  238|   981k|  }

