• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The libgav1 Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef LIBGAV1_SRC_UTILS_ARRAY_2D_H_
18 #define LIBGAV1_SRC_UTILS_ARRAY_2D_H_
19 
20 #include <cassert>
21 #include <cstddef>
22 #include <cstring>
23 #include <memory>
24 #include <new>
25 #include <type_traits>
26 
27 #include "src/utils/compiler_attributes.h"
28 
29 namespace libgav1 {
30 
31 // Exposes a 1D allocated memory buffer as a 2D array.
32 template <typename T>
33 class Array2DView {
34  public:
35   Array2DView() = default;
Array2DView(int rows,int columns,T * const data)36   Array2DView(int rows, int columns, T* const data) {
37     Reset(rows, columns, data);
38   }
39 
40   // Copyable and Movable.
41   Array2DView(const Array2DView& rhs) = default;
42   Array2DView& operator=(const Array2DView& rhs) = default;
43 
Reset(int rows,int columns,T * const data)44   void Reset(int rows, int columns, T* const data) {
45     rows_ = rows;
46     columns_ = columns;
47     data_ = data;
48   }
49 
rows()50   int rows() const { return rows_; }
columns()51   int columns() const { return columns_; }
52 
53   T* operator[](int row) { return const_cast<T*>(GetRow(row)); }
54 
55   const T* operator[](int row) const { return GetRow(row); }
56 
57  private:
GetRow(int row)58   const T* GetRow(int row) const {
59     assert(row < rows_);
60     const ptrdiff_t offset = static_cast<ptrdiff_t>(row) * columns_;
61     return data_ + offset;
62   }
63 
64   int rows_ = 0;
65   int columns_ = 0;
66   T* data_ = nullptr;
67 };
68 
69 // Allocates and owns the contiguous memory and exposes an Array2DView of
70 // dimension |rows| x |columns|.
71 template <typename T>
72 class Array2D {
73  public:
74   Array2D() = default;
75 
76   // Copyable and Movable.
77   Array2D(const Array2D& rhs) = default;
78   Array2D& operator=(const Array2D& rhs) = default;
79 
80   LIBGAV1_MUST_USE_RESULT bool Reset(int rows, int columns,
81                                      bool zero_initialize = true) {
82     size_ = rows * columns;
83     // If T is not a trivial type, we should always reallocate the data_
84     // buffer, so that the destructors of any existing objects are invoked.
85     if (!std::is_trivial<T>::value || allocated_size_ < size_) {
86       // Note: This invokes the global operator new if T is a non-class type,
87       // such as integer or enum types, or a class type that is not derived
88       // from libgav1::Allocable, such as std::unique_ptr. If we enforce a
89       // maximum allocation size or keep track of our own heap memory
90       // consumption, we will need to handle the allocations here that use the
91       // global operator new.
92       if (zero_initialize) {
93         data_.reset(new (std::nothrow) T[size_]());
94       } else {
95         data_.reset(new (std::nothrow) T[size_]);
96       }
97       if (data_ == nullptr) {
98         allocated_size_ = 0;
99         return false;
100       }
101       allocated_size_ = size_;
102     } else if (zero_initialize) {
103       // Cast the data_ pointer to void* to avoid the GCC -Wclass-memaccess
104       // warning. The memset is safe because T is a trivial type.
105       void* dest = data_.get();
106       memset(dest, 0, sizeof(T) * size_);
107     }
108     data_view_.Reset(rows, columns, data_.get());
109     return true;
110   }
111 
rows()112   int rows() const { return data_view_.rows(); }
columns()113   int columns() const { return data_view_.columns(); }
size()114   size_t size() const { return size_; }
data()115   T* data() { return data_.get(); }
data()116   const T* data() const { return data_.get(); }
117 
118   T* operator[](int row) { return data_view_[row]; }
119 
120   const T* operator[](int row) const { return data_view_[row]; }
121 
122  private:
123   std::unique_ptr<T[]> data_;
124   size_t allocated_size_ = 0;
125   size_t size_ = 0;
126   Array2DView<T> data_view_;
127 };
128 
129 }  // namespace libgav1
130 
131 #endif  // LIBGAV1_SRC_UTILS_ARRAY_2D_H_
132