382 lines · 11.0 KB · C
RawDownload
/* *  Copyright (c) 2016 The WebM project authors. All Rights Reserved. * *  Use of this source code is governed by a BSD-style license *  that can be found in the LICENSE file in the root of the source *  tree. An additional intellectual property rights grant can be found *  in the file PATENTS.  All contributing project authors may *  be found in the AUTHORS file in the root of the source tree. */ #ifndef VPX_TEST_BUFFER_H_#define VPX_TEST_BUFFER_H_ #include <stdio.h> #include <limits> #include "third_party/googletest/src/include/gtest/gtest.h" #include "test/acm_random.h"#include "vpx/vpx_integer.h"#include "vpx_mem/vpx_mem.h" namespace libvpx_test { template <typename T>class Buffer { public:  Buffer(int width, int height, int top_padding, int left_padding,         int right_padding, int bottom_padding)      : width_(width), height_(height), top_padding_(top_padding),        left_padding_(left_padding), right_padding_(right_padding),        bottom_padding_(bottom_padding), alignment_(0), padding_value_(0),        stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}   Buffer(int width, int height, int top_padding, int left_padding,         int right_padding, int bottom_padding, unsigned int alignment)      : width_(width), height_(height), top_padding_(top_padding),        left_padding_(left_padding), right_padding_(right_padding),        bottom_padding_(bottom_padding), alignment_(alignment),        padding_value_(0), stride_(0), raw_size_(0), num_elements_(0),        raw_buffer_(NULL) {}   Buffer(int width, int height, int padding)      : width_(width), height_(height), top_padding_(padding),        left_padding_(padding), right_padding_(padding),        bottom_padding_(padding), alignment_(0), padding_value_(0), stride_(0),        raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}   Buffer(int width, int height, int padding, unsigned int alignment)      : width_(width), height_(height), top_padding_(padding),        left_padding_(padding), right_padding_(padding),        bottom_padding_(padding), alignment_(alignment), padding_value_(0),        stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}   ~Buffer() {    if (alignment_) {      vpx_free(raw_buffer_);    } else {      delete[] raw_buffer_;    }  }   T *TopLeftPixel() const;   int stride() const { return stride_; }   // Set the buffer (excluding padding) to 'value'.  void Set(const T value);   // Set the buffer (excluding padding) to the output of ACMRandom function  // 'rand_func'.  void Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)());   // Set the buffer (excluding padding) to the output of ACMRandom function  // 'RandRange' with range 'low' to 'high' which typically must be within  // testing::internal::Random::kMaxRange (1u << 31). However, because we want  // to allow negative low (and high) values, it is restricted to INT32_MAX  // here.  void Set(ACMRandom *rand_class, const T low, const T high);   // Copy the contents of Buffer 'a' (excluding padding).  void CopyFrom(const Buffer<T> &a);   void DumpBuffer() const;   // Highlight the differences between two buffers if they are the same size.  void PrintDifference(const Buffer<T> &a) const;   bool HasPadding() const;   // Sets all the values in the buffer to 'padding_value'.  void SetPadding(const T padding_value);   // Checks if all the values (excluding padding) are equal to 'value' if the  // Buffers are the same size.  bool CheckValues(const T value) const;   // Check that padding matches the expected value or there is no padding.  bool CheckPadding() const;   // Compare the non-padding portion of two buffers if they are the same size.  bool CheckValues(const Buffer<T> &a) const;   bool Init() {    if (raw_buffer_ != NULL) return false;    EXPECT_GT(width_, 0);    EXPECT_GT(height_, 0);    EXPECT_GE(top_padding_, 0);    EXPECT_GE(left_padding_, 0);    EXPECT_GE(right_padding_, 0);    EXPECT_GE(bottom_padding_, 0);    stride_ = left_padding_ + width_ + right_padding_;    num_elements_ = stride_ * (top_padding_ + height_ + bottom_padding_);    raw_size_ = num_elements_ * sizeof(T);    if (alignment_) {      EXPECT_GE(alignment_, sizeof(T));      // Ensure alignment of the first value will be preserved.      EXPECT_EQ((left_padding_ * sizeof(T)) % alignment_, 0u);      // Ensure alignment of the subsequent rows will be preserved when there is      // a stride.      if (stride_ != width_) {        EXPECT_EQ((stride_ * sizeof(T)) % alignment_, 0u);      }      raw_buffer_ = reinterpret_cast<T *>(vpx_memalign(alignment_, raw_size_));    } else {      raw_buffer_ = new (std::nothrow) T[num_elements_];    }    EXPECT_TRUE(raw_buffer_ != NULL);    SetPadding(std::numeric_limits<T>::max());    return !::testing::Test::HasFailure();  }  private:  bool BufferSizesMatch(const Buffer<T> &a) const;   const int width_;  const int height_;  const int top_padding_;  const int left_padding_;  const int right_padding_;  const int bottom_padding_;  const unsigned int alignment_;  T padding_value_;  int stride_;  int raw_size_;  int num_elements_;  T *raw_buffer_;}; template <typename T>T *Buffer<T>::TopLeftPixel() const {  if (!raw_buffer_) return NULL;  return raw_buffer_ + (top_padding_ * stride_) + left_padding_;} template <typename T>void Buffer<T>::Set(const T value) {  if (!raw_buffer_) return;  T *src = TopLeftPixel();  for (int height = 0; height < height_; ++height) {    for (int width = 0; width < width_; ++width) {      src[width] = value;    }    src += stride_;  }} template <typename T>void Buffer<T>::Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)()) {  if (!raw_buffer_) return;  T *src = TopLeftPixel();  for (int height = 0; height < height_; ++height) {    for (int width = 0; width < width_; ++width) {      src[width] = (*rand_class.*rand_func)();    }    src += stride_;  }} template <typename T>void Buffer<T>::Set(ACMRandom *rand_class, const T low, const T high) {  if (!raw_buffer_) return;   EXPECT_LE(low, high);  EXPECT_LE(static_cast<int64_t>(high) - low,            std::numeric_limits<int32_t>::max());   T *src = TopLeftPixel();  for (int height = 0; height < height_; ++height) {    for (int width = 0; width < width_; ++width) {      // 'low' will be promoted to unsigned given the return type of RandRange.      // Store the value as an int to avoid unsigned overflow warnings when      // 'low' is negative.      const int32_t value =          static_cast<int32_t>((*rand_class).RandRange(high - low));      src[width] = static_cast<T>(value + low);    }    src += stride_;  }} template <typename T>void Buffer<T>::CopyFrom(const Buffer<T> &a) {  if (!raw_buffer_) return;  if (!BufferSizesMatch(a)) return;   T *a_src = a.TopLeftPixel();  T *b_src = this->TopLeftPixel();  for (int height = 0; height < height_; ++height) {    for (int width = 0; width < width_; ++width) {      b_src[width] = a_src[width];    }    a_src += a.stride();    b_src += this->stride();  }} template <typename T>void Buffer<T>::DumpBuffer() const {  if (!raw_buffer_) return;  for (int height = 0; height < height_ + top_padding_ + bottom_padding_;       ++height) {    for (int width = 0; width < stride_; ++width) {      printf("%4d", raw_buffer_[height + width * stride_]);    }    printf("\n");  }} template <typename T>bool Buffer<T>::HasPadding() const {  if (!raw_buffer_) return false;  return top_padding_ || left_padding_ || right_padding_ || bottom_padding_;} template <typename T>void Buffer<T>::PrintDifference(const Buffer<T> &a) const {  if (!raw_buffer_) return;  if (!BufferSizesMatch(a)) return;   T *a_src = a.TopLeftPixel();  T *b_src = TopLeftPixel();   printf("This buffer:\n");  for (int height = 0; height < height_; ++height) {    for (int width = 0; width < width_; ++width) {      if (a_src[width] != b_src[width]) {        printf("*%3d", b_src[width]);      } else {        printf("%4d", b_src[width]);      }    }    printf("\n");    a_src += a.stride();    b_src += this->stride();  }   a_src = a.TopLeftPixel();  b_src = TopLeftPixel();   printf("Reference buffer:\n");  for (int height = 0; height < height_; ++height) {    for (int width = 0; width < width_; ++width) {      if (a_src[width] != b_src[width]) {        printf("*%3d", a_src[width]);      } else {        printf("%4d", a_src[width]);      }    }    printf("\n");    a_src += a.stride();    b_src += this->stride();  }} template <typename T>void Buffer<T>::SetPadding(const T padding_value) {  if (!raw_buffer_) return;  padding_value_ = padding_value;   T *src = raw_buffer_;  for (int i = 0; i < num_elements_; ++i) {    src[i] = padding_value;  }} template <typename T>bool Buffer<T>::CheckValues(const T value) const {  if (!raw_buffer_) return false;  T *src = TopLeftPixel();  for (int height = 0; height < height_; ++height) {    for (int width = 0; width < width_; ++width) {      if (value != src[width]) {        return false;      }    }    src += stride_;  }  return true;} template <typename T>bool Buffer<T>::CheckPadding() const {  if (!raw_buffer_) return false;  if (!HasPadding()) return true;   // Top padding.  T const *top = raw_buffer_;  for (int i = 0; i < stride_ * top_padding_; ++i) {    if (padding_value_ != top[i]) {      return false;    }  }   // Left padding.  T const *left = TopLeftPixel() - left_padding_;  for (int height = 0; height < height_; ++height) {    for (int width = 0; width < left_padding_; ++width) {      if (padding_value_ != left[width]) {        return false;      }    }    left += stride_;  }   // Right padding.  T const *right = TopLeftPixel() + width_;  for (int height = 0; height < height_; ++height) {    for (int width = 0; width < right_padding_; ++width) {      if (padding_value_ != right[width]) {        return false;      }    }    right += stride_;  }   // Bottom padding  T const *bottom = raw_buffer_ + (top_padding_ + height_) * stride_;  for (int i = 0; i < stride_ * bottom_padding_; ++i) {    if (padding_value_ != bottom[i]) {      return false;    }  }   return true;} template <typename T>bool Buffer<T>::CheckValues(const Buffer<T> &a) const {  if (!raw_buffer_) return false;  if (!BufferSizesMatch(a)) return false;   T *a_src = a.TopLeftPixel();  T *b_src = this->TopLeftPixel();  for (int height = 0; height < height_; ++height) {    for (int width = 0; width < width_; ++width) {      if (a_src[width] != b_src[width]) {        return false;      }    }    a_src += a.stride();    b_src += this->stride();  }  return true;} template <typename T>bool Buffer<T>::BufferSizesMatch(const Buffer<T> &a) const {  if (!raw_buffer_) return false;  if (a.width_ != this->width_ || a.height_ != this->height_) {    printf(        "Reference buffer of size %dx%d does not match this buffer which is "        "size %dx%d\n",        a.width_, a.height_, this->width_, this->height_);    return false;  }   return true;}}  // namespace libvpx_test#endif  // VPX_TEST_BUFFER_H_

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t