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