• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef TEST_BUFFER_H_
12 #define TEST_BUFFER_H_
13 
14 #include <stdio.h>
15 
16 #include <limits>
17 
18 #include "third_party/googletest/src/include/gtest/gtest.h"
19 
20 #include "test/acm_random.h"
21 #include "vpx/vpx_integer.h"
22 
23 namespace libvpx_test {
24 
25 template <typename T>
26 class Buffer {
27  public:
Buffer(int width,int height,int top_padding,int left_padding,int right_padding,int bottom_padding)28   Buffer(int width, int height, int top_padding, int left_padding,
29          int right_padding, int bottom_padding)
30       : width_(width), height_(height), top_padding_(top_padding),
31         left_padding_(left_padding), right_padding_(right_padding),
32         bottom_padding_(bottom_padding) {
33     Init();
34   }
35 
Buffer(int width,int height,int padding)36   Buffer(int width, int height, int padding)
37       : width_(width), height_(height), top_padding_(padding),
38         left_padding_(padding), right_padding_(padding),
39         bottom_padding_(padding) {
40     Init();
41   }
42 
~Buffer()43   ~Buffer() { delete[] raw_buffer_; }
44 
45   T *TopLeftPixel() const;
46 
stride()47   int stride() const { return stride_; }
48 
49   // Set the buffer (excluding padding) to 'value'.
50   void Set(const int value);
51 
52   // Set the buffer (excluding padding) to the output of ACMRandom function 'b'.
53   void Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)());
54 
55   // Copy the contents of Buffer 'a' (excluding padding).
56   void CopyFrom(const Buffer<T> &a);
57 
58   void DumpBuffer() const;
59 
60   // Highlight the differences between two buffers if they are the same size.
61   void PrintDifference(const Buffer<T> &a) const;
62 
63   bool HasPadding() const;
64 
65   // Sets all the values in the buffer to 'padding_value'.
66   void SetPadding(const int padding_value);
67 
68   // Checks if all the values (excluding padding) are equal to 'value' if the
69   // Buffers are the same size.
70   bool CheckValues(const int value) const;
71 
72   // Check that padding matches the expected value or there is no padding.
73   bool CheckPadding() const;
74 
75   // Compare the non-padding portion of two buffers if they are the same size.
76   bool CheckValues(const Buffer<T> &a) const;
77 
78  private:
Init()79   void Init() {
80     ASSERT_GT(width_, 0);
81     ASSERT_GT(height_, 0);
82     ASSERT_GE(top_padding_, 0);
83     ASSERT_GE(left_padding_, 0);
84     ASSERT_GE(right_padding_, 0);
85     ASSERT_GE(bottom_padding_, 0);
86     stride_ = left_padding_ + width_ + right_padding_;
87     raw_size_ = stride_ * (top_padding_ + height_ + bottom_padding_);
88     raw_buffer_ = new (std::nothrow) T[raw_size_];
89     ASSERT_TRUE(raw_buffer_ != NULL);
90     SetPadding(std::numeric_limits<T>::max());
91   }
92 
93   bool BufferSizesMatch(const Buffer<T> &a) const;
94 
95   const int width_;
96   const int height_;
97   const int top_padding_;
98   const int left_padding_;
99   const int right_padding_;
100   const int bottom_padding_;
101   int padding_value_;
102   int stride_;
103   int raw_size_;
104   T *raw_buffer_;
105 };
106 
107 template <typename T>
TopLeftPixel()108 T *Buffer<T>::TopLeftPixel() const {
109   return raw_buffer_ + (top_padding_ * stride()) + left_padding_;
110 }
111 
112 template <typename T>
Set(const int value)113 void Buffer<T>::Set(const int value) {
114   T *src = TopLeftPixel();
115   for (int height = 0; height < height_; ++height) {
116     for (int width = 0; width < width_; ++width) {
117       src[width] = value;
118     }
119     src += stride();
120   }
121 }
122 
123 template <typename T>
Set(ACMRandom * rand_class,T (ACMRandom::* rand_func)())124 void Buffer<T>::Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)()) {
125   T *src = TopLeftPixel();
126   for (int height = 0; height < height_; ++height) {
127     for (int width = 0; width < width_; ++width) {
128       src[width] = (*rand_class.*rand_func)();
129     }
130     src += stride();
131   }
132 }
133 
134 template <typename T>
CopyFrom(const Buffer<T> & a)135 void Buffer<T>::CopyFrom(const Buffer<T> &a) {
136   if (!BufferSizesMatch(a)) {
137     return;
138   }
139 
140   T *a_src = a.TopLeftPixel();
141   T *b_src = this->TopLeftPixel();
142   for (int height = 0; height < height_; ++height) {
143     for (int width = 0; width < width_; ++width) {
144       b_src[width] = a_src[width];
145     }
146     a_src += a.stride();
147     b_src += this->stride();
148   }
149 }
150 
151 template <typename T>
DumpBuffer()152 void Buffer<T>::DumpBuffer() const {
153   for (int height = 0; height < height_ + top_padding_ + bottom_padding_;
154        ++height) {
155     for (int width = 0; width < stride(); ++width) {
156       printf("%4d", raw_buffer_[height + width * stride()]);
157     }
158     printf("\n");
159   }
160 }
161 
162 template <typename T>
HasPadding()163 bool Buffer<T>::HasPadding() const {
164   return top_padding_ || left_padding_ || right_padding_ || bottom_padding_;
165 }
166 
167 template <typename T>
PrintDifference(const Buffer<T> & a)168 void Buffer<T>::PrintDifference(const Buffer<T> &a) const {
169   if (!BufferSizesMatch(a)) {
170     return;
171   }
172 
173   T *a_src = a.TopLeftPixel();
174   T *b_src = TopLeftPixel();
175 
176   printf("This buffer:\n");
177   for (int height = 0; height < height_; ++height) {
178     for (int width = 0; width < width_; ++width) {
179       if (a_src[width] != b_src[width]) {
180         printf("*%3d", b_src[width]);
181       } else {
182         printf("%4d", b_src[width]);
183       }
184     }
185     printf("\n");
186     a_src += a.stride();
187     b_src += this->stride();
188   }
189 
190   a_src = a.TopLeftPixel();
191   b_src = TopLeftPixel();
192 
193   printf("Reference buffer:\n");
194   for (int height = 0; height < height_; ++height) {
195     for (int width = 0; width < width_; ++width) {
196       if (a_src[width] != b_src[width]) {
197         printf("*%3d", a_src[width]);
198       } else {
199         printf("%4d", a_src[width]);
200       }
201     }
202     printf("\n");
203     a_src += a.stride();
204     b_src += this->stride();
205   }
206 }
207 
208 template <typename T>
SetPadding(const int padding_value)209 void Buffer<T>::SetPadding(const int padding_value) {
210   padding_value_ = padding_value;
211 
212   T *src = raw_buffer_;
213   for (int i = 0; i < raw_size_; ++i) {
214     src[i] = padding_value;
215   }
216 }
217 
218 template <typename T>
CheckValues(const int value)219 bool Buffer<T>::CheckValues(const int value) const {
220   T *src = TopLeftPixel();
221   for (int height = 0; height < height_; ++height) {
222     for (int width = 0; width < width_; ++width) {
223       if (value != src[width]) {
224         return false;
225       }
226     }
227     src += stride();
228   }
229   return true;
230 }
231 
232 template <typename T>
CheckPadding()233 bool Buffer<T>::CheckPadding() const {
234   if (!HasPadding()) {
235     return true;
236   }
237 
238   // Top padding.
239   T const *top = raw_buffer_;
240   for (int i = 0; i < stride() * top_padding_; ++i) {
241     if (padding_value_ != top[i]) {
242       return false;
243     }
244   }
245 
246   // Left padding.
247   T const *left = TopLeftPixel() - left_padding_;
248   for (int height = 0; height < height_; ++height) {
249     for (int width = 0; width < left_padding_; ++width) {
250       if (padding_value_ != left[width]) {
251         return false;
252       }
253     }
254     left += stride();
255   }
256 
257   // Right padding.
258   T const *right = TopLeftPixel() + width_;
259   for (int height = 0; height < height_; ++height) {
260     for (int width = 0; width < right_padding_; ++width) {
261       if (padding_value_ != right[width]) {
262         return false;
263       }
264     }
265     right += stride();
266   }
267 
268   // Bottom padding
269   T const *bottom = raw_buffer_ + (top_padding_ + height_) * stride();
270   for (int i = 0; i < stride() * bottom_padding_; ++i) {
271     if (padding_value_ != bottom[i]) {
272       return false;
273     }
274   }
275 
276   return true;
277 }
278 
279 template <typename T>
CheckValues(const Buffer<T> & a)280 bool Buffer<T>::CheckValues(const Buffer<T> &a) const {
281   if (!BufferSizesMatch(a)) {
282     return false;
283   }
284 
285   T *a_src = a.TopLeftPixel();
286   T *b_src = this->TopLeftPixel();
287   for (int height = 0; height < height_; ++height) {
288     for (int width = 0; width < width_; ++width) {
289       if (a_src[width] != b_src[width]) {
290         return false;
291       }
292     }
293     a_src += a.stride();
294     b_src += this->stride();
295   }
296   return true;
297 }
298 
299 template <typename T>
BufferSizesMatch(const Buffer<T> & a)300 bool Buffer<T>::BufferSizesMatch(const Buffer<T> &a) const {
301   if (a.width_ != this->width_ || a.height_ != this->height_) {
302     printf(
303         "Reference buffer of size %dx%d does not match this buffer which is "
304         "size %dx%d\n",
305         a.width_, a.height_, this->width_, this->height_);
306     return false;
307   }
308 
309   return true;
310 }
311 }  // namespace libvpx_test
312 #endif  // TEST_BUFFER_H_
313