2222#pragma once
2323
2424#include " adt/Array1DRef.h"
25+ #include " adt/CroppedArray1DRef.h" // IWYU pragma: keep
2526#include " adt/Invariant.h"
2627#include " adt/Optional.h"
2728#include < cstddef>
3132namespace rawspeed {
3233
3334template <class T > class Array2DRef final {
34- T* _data ;
35+ Array1DRef<T> data ;
3536 int _pitch;
3637
3738 friend Array2DRef<const T>; // We need to be able to convert to const version.
@@ -40,6 +41,8 @@ template <class T> class Array2DRef final {
4041 friend Array2DRef<std::byte>;
4142 friend Array2DRef<const std::byte>;
4243
44+ Array2DRef (Array1DRef<T> data, int width, int height, int pitch);
45+
4346public:
4447 void establishClassInvariants () const noexcept ;
4548
@@ -51,7 +54,9 @@ template <class T> class Array2DRef final {
5154
5255 Array2DRef () = delete ;
5356
54- Array2DRef (T* data, int width, int height, int pitch = 0 );
57+ Array2DRef (T* data, int width, int height, int pitch);
58+
59+ Array2DRef (T* data, int width, int height);
5560
5661 // Can not cast away constness.
5762 template <typename T2>
@@ -70,7 +75,7 @@ template <class T> class Array2DRef final {
7075 requires (!std::is_const_v<T2> && std::is_const_v<T> &&
7176 std::is_same_v<std::remove_const_t <T>, std::remove_const_t <T2>>)
7277 Array2DRef (Array2DRef<T2> RHS) // NOLINT google-explicit-constructor
73- : _data (RHS._data ), _pitch(RHS._pitch), width(RHS.width),
78+ : data (RHS.data ), _pitch(RHS._pitch), width(RHS.width),
7479 height (RHS.height) {}
7580
7681 // Const-preserving conversion from Array2DRef<T> to Array2DRef<std::byte>.
@@ -80,7 +85,7 @@ template <class T> class Array2DRef final {
8085 std::remove_const_t <T2>>) &&
8186 std::is_same_v<std::remove_const_t<T>, std::byte>)
8287 Array2DRef(Array2DRef<T2> RHS) // NOLINT google-explicit-constructor
83- : _data( reinterpret_cast <T*>( RHS._data) ), _pitch(sizeof (T2) * RHS._pitch),
88+ : data( RHS.data ), _pitch(sizeof (T2) * RHS._pitch),
8489 width(sizeof (T2) * RHS.width), height(RHS.height) {}
8590
8691 template <typename AllocatorType =
@@ -102,26 +107,47 @@ template <class T> class Array2DRef final {
102107
103108// CTAD deduction guide
104109template <typename T>
105- explicit Array2DRef (T* data, int width, int height, int pitch = 0 )
110+ explicit Array2DRef (Array1DRef<T> data, int width, int height, int pitch)
106111 -> Array2DRef<T>;
107112
113+ // CTAD deduction guide
114+ template <typename T>
115+ explicit Array2DRef (T* data, int width, int height, int pitch) -> Array2DRef<T>;
116+
117+ // CTAD deduction guide
118+ template <typename T>
119+ explicit Array2DRef (T* data, int width, int height) -> Array2DRef<T>;
120+
108121template <class T >
109122inline void Array2DRef<T>::establishClassInvariants() const noexcept {
110- invariant (_data );
123+ data. establishClassInvariants ( );
111124 invariant (width >= 0 );
112125 invariant (height >= 0 );
113126 invariant (_pitch >= 0 );
114127 invariant (_pitch >= width);
115128 invariant ((width == 0 ) == (height == 0 ));
116129 invariant ((_pitch == 0 ) == (width == 0 ));
117130 invariant ((_pitch == 0 ) == (height == 0 ));
131+ invariant (data.size () == _pitch * height);
132+ }
133+
134+ template <class T >
135+ Array2DRef<T>::Array2DRef(Array1DRef<T> data_, const int width_,
136+ const int height_, const int pitch_)
137+ : data(data_), _pitch(pitch_), width(width_), height(height_) {
138+ establishClassInvariants ();
139+ }
140+
141+ template <class T >
142+ Array2DRef<T>::Array2DRef(T* data_, const int width_, const int height_,
143+ const int pitch_)
144+ : Array2DRef({data_, pitch_ * height_}, width_, height_, pitch_) {
145+ establishClassInvariants ();
118146}
119147
120148template <class T >
121- Array2DRef<T>::Array2DRef(T* data, const int width_, const int height_,
122- const int pitch_ /* = 0 */ )
123- : _data(data), _pitch(pitch_ == 0 ? width_ : pitch_), width(width_),
124- height (height_) {
149+ Array2DRef<T>::Array2DRef(T* data_, const int width_, const int height_)
150+ : Array2DRef(data_, width_, height_, /* pitch=*/ width_) {
125151 establishClassInvariants ();
126152}
127153
@@ -130,7 +156,7 @@ template <class T>
130156Array2DRef<T>::getAsArray1DRef() const {
131157 establishClassInvariants ();
132158 if (height == 1 || _pitch == width)
133- return {{_data , width * height}} ;
159+ return data. getCrop ( /* offset= */ 0 , width * height). getAsArray1DRef () ;
134160 return std::nullopt ;
135161}
136162
@@ -139,12 +165,7 @@ inline Array1DRef<T> Array2DRef<T>::operator[](const int row) const {
139165 establishClassInvariants ();
140166 invariant (row >= 0 );
141167 invariant (row < height);
142- #pragma GCC diagnostic push
143- #pragma GCC diagnostic ignored "-Wpragmas"
144- #pragma GCC diagnostic ignored "-Wunknown-warning-option"
145- #pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
146- return Array1DRef<T>(&_data[row * _pitch], width);
147- #pragma GCC diagnostic pop
168+ return data.getCrop (row * _pitch, width).getAsArray1DRef ();
148169}
149170
150171template <class T >
0 commit comments