ColorHistogram ColorHistogram::ScaleHistogram(const vector<float>& gain) const { const ColorHistogramIndexLUT& lut = ColorHistogramIndexLUTFactory::Instance().GetLUT( lum_bins_, color_bins_, color_bins_); ColorHistogram result = EmptyCopy(); if (!IsSparse()) { for (int i = 0; i < total_bins_; ++i) { const float value = bins_[i]; if (value) { const std::tuple<int, int, int>& idx_3d = lut.Ind2Sub(i); const float bin_lum = std::min(lum_bins_ - 1.f, std::get<0>(idx_3d) * gain[0]); const float bin_col1 = std::min(color_bins_ - 1.f, std::get<1>(idx_3d) * gain[1]); const float bin_col2 = std::min(color_bins_ - 1.f, std::get<2>(idx_3d) * gain[2]); result.AddValueInterpolated(bin_lum, bin_col1, bin_col2, value); } } } else { for (const auto& bin : sparse_bins_) { const std::tuple<int, int, int>& idx_3d = lut.Ind2Sub(bin.first); const float bin_lum = std::min(lum_bins_ - 1.f, std::get<0>(idx_3d) * gain[0]); const float bin_col1 = std::min(color_bins_ - 1.f, std::get<1>(idx_3d) * gain[1]); const float bin_col2 = std::min(color_bins_ - 1.f, std::get<2>(idx_3d) * gain[2]); result.AddValueInterpolated(bin_lum, bin_col1, bin_col2, bin.second); } } DCHECK_LT(fabs(WeightSum() - result.WeightSum()), 1e-3f); return result; }
HuffmanCode::WeightSum HuffmanCode::build(const std::vector<HuffmanCode::WeightTp>& W) { if (W.empty()) { output_code.clear(); return WeightSum(); } unsigned int n = W.size(); typedef std::pair<WeightTp, unsigned int> PP; std::priority_queue<PP, std::vector<PP>, std::greater<PP> > pq; unsigned int i = 0; for (std::vector<WeightTp>::const_iterator it = W.begin(); it != W.end(); ++it) pq.push(std::make_pair(*it, i++)); std::vector<unsigned int> parent(W.size()); parent.reserve(W.size()*2 - 1); assert(!pq.empty()); while (true) { PP t1 = pq.top(); pq.pop(); if (pq.empty()) break; PP t2 = pq.top(); pq.pop(); parent.push_back(0); unsigned int newid = parent.size() - 1; parent[t1.second] = newid; parent[t2.second] = newid; pq.push(std::make_pair(t1.first + t2.first, newid)); } assert(pq.empty()); // compute code length std::vector<uint16_t> L(parent.size()); L[L.size() - 1] = 0; WeightSum total = 0; for (int i = (int)L.size()-2; i >= 0; i--) { L[i] = 1 + L[parent[i]]; if ((unsigned int) i < n) total += ((WeightSum)W[i]) * L[i]; } loadCode(W.size(), L); return total; }