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