79 lines
2.7 KiB
C++
79 lines
2.7 KiB
C++
// Copyright 2017 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "components/zucchini/encoded_view.h"
|
|
|
|
#include <algorithm>
|
|
#include <utility>
|
|
|
|
#include "base/check_op.h"
|
|
|
|
namespace zucchini {
|
|
|
|
EncodedView::EncodedView(const ImageIndex& image_index)
|
|
: image_index_(image_index), pool_infos_(image_index.PoolCount()) {}
|
|
EncodedView::~EncodedView() = default;
|
|
|
|
EncodedView::value_type EncodedView::Projection(offset_t location) const {
|
|
DCHECK_LT(location, image_index_.size());
|
|
|
|
// Find out what lies at |location|.
|
|
TypeTag type = image_index_.LookupType(location);
|
|
|
|
// |location| points into raw data.
|
|
if (type == kNoTypeTag) {
|
|
// The projection is the identity function on raw content.
|
|
return image_index_.GetRawValue(location);
|
|
}
|
|
|
|
// |location| points into a Reference.
|
|
const ReferenceSet& ref_set = image_index_.refs(type);
|
|
Reference ref = ref_set.at(location);
|
|
DCHECK_GE(location, ref.location);
|
|
DCHECK_LT(location, ref.location + ref_set.width());
|
|
|
|
// |location| is not the first byte of the reference.
|
|
if (location != ref.location) {
|
|
// Trailing bytes of a reference are all projected to the same value.
|
|
return kReferencePaddingProjection;
|
|
}
|
|
|
|
PoolTag pool_tag = ref_set.pool_tag();
|
|
const auto& target_pool = ref_set.target_pool();
|
|
|
|
// Targets with an associated Label will use its Label index in projection.
|
|
DCHECK_EQ(target_pool.size(), pool_infos_[pool_tag.value()].labels.size());
|
|
uint32_t label = pool_infos_[pool_tag.value()]
|
|
.labels[target_pool.KeyForOffset(ref.target)];
|
|
|
|
// Projection is done on (|target|, |type|), shifted by
|
|
// kBaseReferenceProjection to avoid collisions with raw content.
|
|
value_type projection = label;
|
|
projection *= image_index_.TypeCount();
|
|
projection += type.value();
|
|
return projection + kBaseReferenceProjection;
|
|
}
|
|
|
|
size_t EncodedView::Cardinality() const {
|
|
size_t max_width = 0;
|
|
for (const auto& pool_info : pool_infos_)
|
|
max_width = std::max(max_width, pool_info.bound);
|
|
return max_width * image_index_.TypeCount() + kBaseReferenceProjection;
|
|
}
|
|
|
|
void EncodedView::SetLabels(PoolTag pool,
|
|
std::vector<uint32_t>&& labels,
|
|
size_t bound) {
|
|
DCHECK_EQ(labels.size(), image_index_.pool(pool).size());
|
|
DCHECK(labels.empty() || *max_element(labels.begin(), labels.end()) < bound);
|
|
pool_infos_[pool.value()].labels = std::move(labels);
|
|
pool_infos_[pool.value()].bound = bound;
|
|
}
|
|
|
|
EncodedView::PoolInfo::PoolInfo() = default;
|
|
EncodedView::PoolInfo::PoolInfo(PoolInfo&&) = default;
|
|
EncodedView::PoolInfo::~PoolInfo() = default;
|
|
|
|
} // namespace zucchini
|