1*a03ca8b9SKrzysztof Kosiński // Copyright 2017 The Chromium Authors. All rights reserved.
2*a03ca8b9SKrzysztof Kosiński // Use of this source code is governed by a BSD-style license that can be
3*a03ca8b9SKrzysztof Kosiński // found in the LICENSE file.
4*a03ca8b9SKrzysztof Kosiński
5*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/encoded_view.h"
6*a03ca8b9SKrzysztof Kosiński
7*a03ca8b9SKrzysztof Kosiński #include <algorithm>
8*a03ca8b9SKrzysztof Kosiński #include <utility>
9*a03ca8b9SKrzysztof Kosiński
10*a03ca8b9SKrzysztof Kosiński #include "base/check_op.h"
11*a03ca8b9SKrzysztof Kosiński
12*a03ca8b9SKrzysztof Kosiński namespace zucchini {
13*a03ca8b9SKrzysztof Kosiński
EncodedView(const ImageIndex & image_index)14*a03ca8b9SKrzysztof Kosiński EncodedView::EncodedView(const ImageIndex& image_index)
15*a03ca8b9SKrzysztof Kosiński : image_index_(image_index), pool_infos_(image_index.PoolCount()) {}
16*a03ca8b9SKrzysztof Kosiński EncodedView::~EncodedView() = default;
17*a03ca8b9SKrzysztof Kosiński
Projection(offset_t location) const18*a03ca8b9SKrzysztof Kosiński EncodedView::value_type EncodedView::Projection(offset_t location) const {
19*a03ca8b9SKrzysztof Kosiński DCHECK_LT(location, image_index_.size());
20*a03ca8b9SKrzysztof Kosiński
21*a03ca8b9SKrzysztof Kosiński // Find out what lies at |location|.
22*a03ca8b9SKrzysztof Kosiński TypeTag type = image_index_.LookupType(location);
23*a03ca8b9SKrzysztof Kosiński
24*a03ca8b9SKrzysztof Kosiński // |location| points into raw data.
25*a03ca8b9SKrzysztof Kosiński if (type == kNoTypeTag) {
26*a03ca8b9SKrzysztof Kosiński // The projection is the identity function on raw content.
27*a03ca8b9SKrzysztof Kosiński return image_index_.GetRawValue(location);
28*a03ca8b9SKrzysztof Kosiński }
29*a03ca8b9SKrzysztof Kosiński
30*a03ca8b9SKrzysztof Kosiński // |location| points into a Reference.
31*a03ca8b9SKrzysztof Kosiński const ReferenceSet& ref_set = image_index_.refs(type);
32*a03ca8b9SKrzysztof Kosiński Reference ref = ref_set.at(location);
33*a03ca8b9SKrzysztof Kosiński DCHECK_GE(location, ref.location);
34*a03ca8b9SKrzysztof Kosiński DCHECK_LT(location, ref.location + ref_set.width());
35*a03ca8b9SKrzysztof Kosiński
36*a03ca8b9SKrzysztof Kosiński // |location| is not the first byte of the reference.
37*a03ca8b9SKrzysztof Kosiński if (location != ref.location) {
38*a03ca8b9SKrzysztof Kosiński // Trailing bytes of a reference are all projected to the same value.
39*a03ca8b9SKrzysztof Kosiński return kReferencePaddingProjection;
40*a03ca8b9SKrzysztof Kosiński }
41*a03ca8b9SKrzysztof Kosiński
42*a03ca8b9SKrzysztof Kosiński PoolTag pool_tag = ref_set.pool_tag();
43*a03ca8b9SKrzysztof Kosiński const auto& target_pool = ref_set.target_pool();
44*a03ca8b9SKrzysztof Kosiński
45*a03ca8b9SKrzysztof Kosiński // Targets with an associated Label will use its Label index in projection.
46*a03ca8b9SKrzysztof Kosiński DCHECK_EQ(target_pool.size(), pool_infos_[pool_tag.value()].labels.size());
47*a03ca8b9SKrzysztof Kosiński uint32_t label = pool_infos_[pool_tag.value()]
48*a03ca8b9SKrzysztof Kosiński .labels[target_pool.KeyForOffset(ref.target)];
49*a03ca8b9SKrzysztof Kosiński
50*a03ca8b9SKrzysztof Kosiński // Projection is done on (|target|, |type|), shifted by
51*a03ca8b9SKrzysztof Kosiński // kBaseReferenceProjection to avoid collisions with raw content.
52*a03ca8b9SKrzysztof Kosiński value_type projection = label;
53*a03ca8b9SKrzysztof Kosiński projection *= image_index_.TypeCount();
54*a03ca8b9SKrzysztof Kosiński projection += type.value();
55*a03ca8b9SKrzysztof Kosiński return projection + kBaseReferenceProjection;
56*a03ca8b9SKrzysztof Kosiński }
57*a03ca8b9SKrzysztof Kosiński
Cardinality() const58*a03ca8b9SKrzysztof Kosiński size_t EncodedView::Cardinality() const {
59*a03ca8b9SKrzysztof Kosiński size_t max_width = 0;
60*a03ca8b9SKrzysztof Kosiński for (const auto& pool_info : pool_infos_)
61*a03ca8b9SKrzysztof Kosiński max_width = std::max(max_width, pool_info.bound);
62*a03ca8b9SKrzysztof Kosiński return max_width * image_index_.TypeCount() + kBaseReferenceProjection;
63*a03ca8b9SKrzysztof Kosiński }
64*a03ca8b9SKrzysztof Kosiński
SetLabels(PoolTag pool,std::vector<uint32_t> && labels,size_t bound)65*a03ca8b9SKrzysztof Kosiński void EncodedView::SetLabels(PoolTag pool,
66*a03ca8b9SKrzysztof Kosiński std::vector<uint32_t>&& labels,
67*a03ca8b9SKrzysztof Kosiński size_t bound) {
68*a03ca8b9SKrzysztof Kosiński DCHECK_EQ(labels.size(), image_index_.pool(pool).size());
69*a03ca8b9SKrzysztof Kosiński DCHECK(labels.empty() || *max_element(labels.begin(), labels.end()) < bound);
70*a03ca8b9SKrzysztof Kosiński pool_infos_[pool.value()].labels = std::move(labels);
71*a03ca8b9SKrzysztof Kosiński pool_infos_[pool.value()].bound = bound;
72*a03ca8b9SKrzysztof Kosiński }
73*a03ca8b9SKrzysztof Kosiński
74*a03ca8b9SKrzysztof Kosiński EncodedView::PoolInfo::PoolInfo() = default;
75*a03ca8b9SKrzysztof Kosiński EncodedView::PoolInfo::PoolInfo(PoolInfo&&) = default;
76*a03ca8b9SKrzysztof Kosiński EncodedView::PoolInfo::~PoolInfo() = default;
77*a03ca8b9SKrzysztof Kosiński
78*a03ca8b9SKrzysztof Kosiński } // namespace zucchini
79