xref: /aosp_15_r20/external/zucchini/encoded_view.h (revision a03ca8b91e029cd15055c20c78c2e087c84792e4)
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 #ifndef COMPONENTS_ZUCCHINI_ENCODED_VIEW_H_
6*a03ca8b9SKrzysztof Kosiński #define COMPONENTS_ZUCCHINI_ENCODED_VIEW_H_
7*a03ca8b9SKrzysztof Kosiński 
8*a03ca8b9SKrzysztof Kosiński #include <stddef.h>
9*a03ca8b9SKrzysztof Kosiński #include <stdint.h>
10*a03ca8b9SKrzysztof Kosiński 
11*a03ca8b9SKrzysztof Kosiński #include <iterator>
12*a03ca8b9SKrzysztof Kosiński #include <vector>
13*a03ca8b9SKrzysztof Kosiński 
14*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/image_index.h"
15*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/image_utils.h"
16*a03ca8b9SKrzysztof Kosiński 
17*a03ca8b9SKrzysztof Kosiński namespace zucchini {
18*a03ca8b9SKrzysztof Kosiński 
19*a03ca8b9SKrzysztof Kosiński // Zucchini-gen performs semantics-aware matching:
20*a03ca8b9SKrzysztof Kosiński // - Same-typed reference target in "old" and "new" can be associated.
21*a03ca8b9SKrzysztof Kosiński //   Associated targets are assigned an identifier called "label" (and for
22*a03ca8b9SKrzysztof Kosiński //   unassociated targets, label = 0).
23*a03ca8b9SKrzysztof Kosiński // - EncodedView maps each offset in "old" and "new" images to a "projected
24*a03ca8b9SKrzysztof Kosiński //   value", which can be:
25*a03ca8b9SKrzysztof Kosiński //   - Raw byte value (0-255) for non-references.
26*a03ca8b9SKrzysztof Kosiński //   - Reference "projected value" (> 256) that depends on target {type, label}
27*a03ca8b9SKrzysztof Kosiński //     at each reference's location (byte 0).
28*a03ca8b9SKrzysztof Kosiński //   - Reference padding value (256) at the body of each reference (bytes 1+).
29*a03ca8b9SKrzysztof Kosiński // - The projected values for "old" and "new" are used to build the equivalence
30*a03ca8b9SKrzysztof Kosiński //   map.
31*a03ca8b9SKrzysztof Kosiński 
32*a03ca8b9SKrzysztof Kosiński constexpr size_t kReferencePaddingProjection = 256;
33*a03ca8b9SKrzysztof Kosiński constexpr size_t kBaseReferenceProjection = 257;
34*a03ca8b9SKrzysztof Kosiński 
35*a03ca8b9SKrzysztof Kosiński // A Range (providing begin and end iterators) that adapts ImageIndex to make
36*a03ca8b9SKrzysztof Kosiński // image data appear as an Encoded Image, that is encoded data under a higher
37*a03ca8b9SKrzysztof Kosiński // level of abstraction than raw bytes. In particular:
38*a03ca8b9SKrzysztof Kosiński // - First byte of each reference become a projection of its type and label.
39*a03ca8b9SKrzysztof Kosiński // - Subsequent bytes of each reference becomes |kReferencePaddingProjection|.
40*a03ca8b9SKrzysztof Kosiński // - Non-reference raw bytes remain as raw bytes.
41*a03ca8b9SKrzysztof Kosiński class EncodedView {
42*a03ca8b9SKrzysztof Kosiński  public:
43*a03ca8b9SKrzysztof Kosiński   // RandomAccessIterator whose values are the results of Projection().
44*a03ca8b9SKrzysztof Kosiński   class Iterator {
45*a03ca8b9SKrzysztof Kosiński    public:
46*a03ca8b9SKrzysztof Kosiński     using iterator_category = std::random_access_iterator_tag;
47*a03ca8b9SKrzysztof Kosiński     using value_type = size_t;
48*a03ca8b9SKrzysztof Kosiński     using difference_type = ptrdiff_t;
49*a03ca8b9SKrzysztof Kosiński     using reference = size_t;
50*a03ca8b9SKrzysztof Kosiński     using pointer = size_t*;
51*a03ca8b9SKrzysztof Kosiński 
Iterator(const EncodedView * encoded_view,difference_type pos)52*a03ca8b9SKrzysztof Kosiński     Iterator(const EncodedView* encoded_view, difference_type pos)
53*a03ca8b9SKrzysztof Kosiński         : encoded_view_(encoded_view), pos_(pos) {}
54*a03ca8b9SKrzysztof Kosiński 
55*a03ca8b9SKrzysztof Kosiński     Iterator(const Iterator&) = default;
56*a03ca8b9SKrzysztof Kosiński 
57*a03ca8b9SKrzysztof Kosiński     Iterator& operator=(const Iterator&) = default;
58*a03ca8b9SKrzysztof Kosiński 
59*a03ca8b9SKrzysztof Kosiński     value_type operator*() const {
60*a03ca8b9SKrzysztof Kosiński       return encoded_view_->Projection(static_cast<offset_t>(pos_));
61*a03ca8b9SKrzysztof Kosiński     }
62*a03ca8b9SKrzysztof Kosiński 
63*a03ca8b9SKrzysztof Kosiński     value_type operator[](difference_type n) const {
64*a03ca8b9SKrzysztof Kosiński       return encoded_view_->Projection(static_cast<offset_t>(pos_ + n));
65*a03ca8b9SKrzysztof Kosiński     }
66*a03ca8b9SKrzysztof Kosiński 
67*a03ca8b9SKrzysztof Kosiński     Iterator& operator++() {
68*a03ca8b9SKrzysztof Kosiński       ++pos_;
69*a03ca8b9SKrzysztof Kosiński       return *this;
70*a03ca8b9SKrzysztof Kosiński     }
71*a03ca8b9SKrzysztof Kosiński 
72*a03ca8b9SKrzysztof Kosiński     Iterator operator++(int) {
73*a03ca8b9SKrzysztof Kosiński       Iterator tmp = *this;
74*a03ca8b9SKrzysztof Kosiński       ++pos_;
75*a03ca8b9SKrzysztof Kosiński       return tmp;
76*a03ca8b9SKrzysztof Kosiński     }
77*a03ca8b9SKrzysztof Kosiński 
78*a03ca8b9SKrzysztof Kosiński     Iterator& operator--() {
79*a03ca8b9SKrzysztof Kosiński       --pos_;
80*a03ca8b9SKrzysztof Kosiński       return *this;
81*a03ca8b9SKrzysztof Kosiński     }
82*a03ca8b9SKrzysztof Kosiński 
83*a03ca8b9SKrzysztof Kosiński     Iterator operator--(int) {
84*a03ca8b9SKrzysztof Kosiński       Iterator tmp = *this;
85*a03ca8b9SKrzysztof Kosiński       --pos_;
86*a03ca8b9SKrzysztof Kosiński       return tmp;
87*a03ca8b9SKrzysztof Kosiński     }
88*a03ca8b9SKrzysztof Kosiński 
89*a03ca8b9SKrzysztof Kosiński     Iterator& operator+=(difference_type n) {
90*a03ca8b9SKrzysztof Kosiński       pos_ += n;
91*a03ca8b9SKrzysztof Kosiński       return *this;
92*a03ca8b9SKrzysztof Kosiński     }
93*a03ca8b9SKrzysztof Kosiński 
94*a03ca8b9SKrzysztof Kosiński     Iterator& operator-=(difference_type n) {
95*a03ca8b9SKrzysztof Kosiński       pos_ -= n;
96*a03ca8b9SKrzysztof Kosiński       return *this;
97*a03ca8b9SKrzysztof Kosiński     }
98*a03ca8b9SKrzysztof Kosiński 
99*a03ca8b9SKrzysztof Kosiński     friend bool operator==(Iterator a, Iterator b) { return a.pos_ == b.pos_; }
100*a03ca8b9SKrzysztof Kosiński 
101*a03ca8b9SKrzysztof Kosiński     friend bool operator!=(Iterator a, Iterator b) { return !(a == b); }
102*a03ca8b9SKrzysztof Kosiński 
103*a03ca8b9SKrzysztof Kosiński     friend bool operator<(Iterator a, Iterator b) { return a.pos_ < b.pos_; }
104*a03ca8b9SKrzysztof Kosiński 
105*a03ca8b9SKrzysztof Kosiński     friend bool operator>(Iterator a, Iterator b) { return b < a; }
106*a03ca8b9SKrzysztof Kosiński 
107*a03ca8b9SKrzysztof Kosiński     friend bool operator<=(Iterator a, Iterator b) { return !(b < a); }
108*a03ca8b9SKrzysztof Kosiński 
109*a03ca8b9SKrzysztof Kosiński     friend bool operator>=(Iterator a, Iterator b) { return !(a < b); }
110*a03ca8b9SKrzysztof Kosiński 
111*a03ca8b9SKrzysztof Kosiński     friend difference_type operator-(Iterator a, Iterator b) {
112*a03ca8b9SKrzysztof Kosiński       return a.pos_ - b.pos_;
113*a03ca8b9SKrzysztof Kosiński     }
114*a03ca8b9SKrzysztof Kosiński 
115*a03ca8b9SKrzysztof Kosiński     friend Iterator operator+(Iterator it, difference_type n) {
116*a03ca8b9SKrzysztof Kosiński       it += n;
117*a03ca8b9SKrzysztof Kosiński       return it;
118*a03ca8b9SKrzysztof Kosiński     }
119*a03ca8b9SKrzysztof Kosiński 
120*a03ca8b9SKrzysztof Kosiński     friend Iterator operator-(Iterator it, difference_type n) {
121*a03ca8b9SKrzysztof Kosiński       it -= n;
122*a03ca8b9SKrzysztof Kosiński       return it;
123*a03ca8b9SKrzysztof Kosiński     }
124*a03ca8b9SKrzysztof Kosiński 
125*a03ca8b9SKrzysztof Kosiński    private:
126*a03ca8b9SKrzysztof Kosiński     const EncodedView* encoded_view_;
127*a03ca8b9SKrzysztof Kosiński     difference_type pos_;
128*a03ca8b9SKrzysztof Kosiński   };
129*a03ca8b9SKrzysztof Kosiński 
130*a03ca8b9SKrzysztof Kosiński   using value_type = size_t;
131*a03ca8b9SKrzysztof Kosiński   using size_type = offset_t;
132*a03ca8b9SKrzysztof Kosiński   using difference_type = ptrdiff_t;
133*a03ca8b9SKrzysztof Kosiński   using const_iterator = Iterator;
134*a03ca8b9SKrzysztof Kosiński 
135*a03ca8b9SKrzysztof Kosiński   // |image_index| is the annotated image being adapted, and is required to
136*a03ca8b9SKrzysztof Kosiński   // remain valid for the lifetime of the object.
137*a03ca8b9SKrzysztof Kosiński   explicit EncodedView(const ImageIndex& image_index);
138*a03ca8b9SKrzysztof Kosiński   EncodedView(const EncodedView&) = delete;
139*a03ca8b9SKrzysztof Kosiński   const EncodedView& operator=(const EncodedView&) = delete;
140*a03ca8b9SKrzysztof Kosiński   ~EncodedView();
141*a03ca8b9SKrzysztof Kosiński 
142*a03ca8b9SKrzysztof Kosiński   // Projects |location| to a scalar value that describes the content at a
143*a03ca8b9SKrzysztof Kosiński   // higher level of abstraction.
144*a03ca8b9SKrzysztof Kosiński   value_type Projection(offset_t location) const;
145*a03ca8b9SKrzysztof Kosiński 
IsToken(offset_t location)146*a03ca8b9SKrzysztof Kosiński   bool IsToken(offset_t location) const {
147*a03ca8b9SKrzysztof Kosiński     return image_index_.IsToken(location);
148*a03ca8b9SKrzysztof Kosiński   }
149*a03ca8b9SKrzysztof Kosiński 
150*a03ca8b9SKrzysztof Kosiński   // Returns the cardinality of the projection, i.e., the upper bound on
151*a03ca8b9SKrzysztof Kosiński   // values returned by Projection().
152*a03ca8b9SKrzysztof Kosiński   value_type Cardinality() const;
153*a03ca8b9SKrzysztof Kosiński 
154*a03ca8b9SKrzysztof Kosiński   // Associates |labels| to targets for a given |pool|, replacing previous
155*a03ca8b9SKrzysztof Kosiński   // association. Values in |labels| must be smaller than |bound|.
156*a03ca8b9SKrzysztof Kosiński   void SetLabels(PoolTag pool, std::vector<uint32_t>&& labels, size_t bound);
image_index()157*a03ca8b9SKrzysztof Kosiński   const ImageIndex& image_index() const { return image_index_; }
158*a03ca8b9SKrzysztof Kosiński 
159*a03ca8b9SKrzysztof Kosiński   // Range functions.
size()160*a03ca8b9SKrzysztof Kosiński   size_type size() const { return size_type(image_index_.size()); }
begin()161*a03ca8b9SKrzysztof Kosiński   const_iterator begin() const {
162*a03ca8b9SKrzysztof Kosiński     return const_iterator{this, difference_type(0)};
163*a03ca8b9SKrzysztof Kosiński   }
end()164*a03ca8b9SKrzysztof Kosiński   const_iterator end() const {
165*a03ca8b9SKrzysztof Kosiński     return const_iterator{this, difference_type(size())};
166*a03ca8b9SKrzysztof Kosiński   }
167*a03ca8b9SKrzysztof Kosiński 
168*a03ca8b9SKrzysztof Kosiński  private:
169*a03ca8b9SKrzysztof Kosiński   struct PoolInfo {
170*a03ca8b9SKrzysztof Kosiński     PoolInfo();
171*a03ca8b9SKrzysztof Kosiński     PoolInfo(PoolInfo&&);
172*a03ca8b9SKrzysztof Kosiński     ~PoolInfo();
173*a03ca8b9SKrzysztof Kosiński 
174*a03ca8b9SKrzysztof Kosiński     // |labels| translates IndirectReference target_key to label.
175*a03ca8b9SKrzysztof Kosiński     std::vector<uint32_t> labels;
176*a03ca8b9SKrzysztof Kosiński     size_t bound = 0;
177*a03ca8b9SKrzysztof Kosiński   };
178*a03ca8b9SKrzysztof Kosiński 
179*a03ca8b9SKrzysztof Kosiński   const ImageIndex& image_index_;
180*a03ca8b9SKrzysztof Kosiński   std::vector<PoolInfo> pool_infos_;
181*a03ca8b9SKrzysztof Kosiński };
182*a03ca8b9SKrzysztof Kosiński 
183*a03ca8b9SKrzysztof Kosiński }  // namespace zucchini
184*a03ca8b9SKrzysztof Kosiński 
185*a03ca8b9SKrzysztof Kosiński #endif  // COMPONENTS_ZUCCHINI_ENCODED_VIEW_H_
186