<commit_before>// ========================================================================== //
// This file is part of Sara, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2018 David Ok <david.ok8@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.
// ========================================================================== //

#define BOOST_TEST_MODULE "MultiViewGeometry/Essential Matrix"

#include <DO/Sara/FeatureMatching.hpp>
#include <DO/Sara/ImageIO.hpp>
#include <DO/Sara/ImageProcessing/GemmBasedConvolution.hpp>

#include <boost/test/unit_test.hpp>

#include <iomanip>
#include <sstream>

using namespace std;
using namespace DO::Sara;

void load(Image<Rgb8>& image1, Image<Rgb8>& image2,
          Set<OERegion, RealDescriptor>& keys1,
          Set<OERegion, RealDescriptor>& keys2,  //
          vector<Match>& matches)
{
  cout << "Loading images" << endl;

  auto data_dir = std::string{"/home/david/Desktop/Datasets/sfm/castle_int"};
  auto file1 = "0000.png";
  auto file2 = "0001.png";

  image1 = imread<Rgb8>(data_dir + "/" + file1);
  image2 = imread<Rgb8>(data_dir + "/" + file2);

#ifdef COMPUTE_KEYPOINTS
  cout << "Computing/Reading keypoints" << endl;
  auto sifts1 = compute_sift_keypoints(image1.convert<float>());
  auto sifts2 = compute_sift_keypoints(image2.convert<float>());
  keys1.append(sifts1);
  keys2.append(sifts2);
  cout << "Image 1: " << keys1.size() << " keypoints" << endl;
  cout << "Image 2: " << keys2.size() << " keypoints" << endl;

  write_keypoints(sifts1.features, sifts1.descriptors,
                  data_dir + "/" + "0000.key");
  write_keypoints(sifts2.features, sifts2.descriptors,
                  data_dir + "/" + "0001.key");

#else
  read_keypoints(keys1.features, keys1.descriptors,
                 data_dir + "/" + "0000.key");
  read_keypoints(keys2.features, keys2.descriptors,
                 data_dir + "/" + "0001.key");
#endif

  // Compute/read matches
  cout << "Computing Matches" << endl;
  AnnMatcher matcher{keys1, keys2, 1.0f};
  matches = matcher.compute_matches();
  cout << matches.size() << " matches" << endl;

  // Debug this.
  //write_matches(matches, data_dir + "/" + "0000_0001.match");
}

// NumPy-like interface for Tensors
auto range(int n) -> Tensor_<int, 1>
{
  auto indices = Tensor_<int, 1>{n};
  std::iota(indices.begin(), indices.end(), 0);
  return indices;
}

auto random_shuffle(const Tensor_<int, 1>& x) -> Tensor_<int, 1>
{
  Tensor_<int, 1> x_shuffled = x;
  std::random_shuffle(x_shuffled.begin(), x_shuffled.end());
  return x_shuffled;
}

auto random_samples(int num_samples, int sample_size, int num_data_points)
    -> Tensor_<int, 2>
{
  auto indices = range(num_data_points);

  auto samples = Tensor_<int, 2>{sample_size, num_samples};
  for (int i = 0; i < sample_size; ++i)
    samples[i].flat_array() =
        random_shuffle(indices).flat_array().head(num_samples);

  samples = samples.transpose({1, 0});

  return samples;
}

// Data transformations.
auto extract_centers(const std::vector<OERegion>& features) -> Tensor_<float, 2>
{
  auto centers = Tensor_<float, 2>(features.size(), 3);
  auto mat = centers.matrix();

  for (auto i = 0; i < centers.size(0); ++i)
    mat.row(i) << features[i].x(), features[i].y(), 1.f;

  return centers;
}

auto to_point_indices(const Tensor_<int, 2>& samples, const Tensor_<int, 2>& matches)
  -> Tensor_<int, 3>
{
  const auto num_samples = samples.size(0);
  const auto sample_size = samples.size(1);

  auto point_indices = Tensor_<int, 3>{num_samples, sample_size, 2};
  for (auto s = 0; s < num_samples; ++s)
    for (auto m = 0; m < sample_size; ++m)
      point_indices[s][m].flat_array() = matches[samples(s, m)].flat_array();

  return point_indices;
}

auto to_coordinates(const Tensor_<int, 3>& point_indices,
                    const Tensor_<float, 2>& p1,
                    const Tensor_<float, 2>& p2)
  -> Tensor_<float, 4>
{
  auto num_samples = point_indices.size(0);
  auto sample_size = point_indices.size(1);
  auto num_points = 2;
  auto coords_dim = 2;

  auto p =
      Tensor_<float, 4>{{num_samples, sample_size, num_points, coords_dim}};

  for (auto s = 0; s < num_samples; ++s)
    for (auto m = 0; m < sample_size; ++m)
    {
      auto p1_idx = point_indices(s, m, 0);
      auto p2_idx = point_indices(s, m, 1);

      p[s][m][0].flat_array() = p1[p1_idx].flat_array();
      p[s][m][1].flat_array() = p2[p2_idx].flat_array();
    }

  return p;
}

// Point transformations.
auto compute_normalizer(const Tensor_<float, 2>& X) -> Matrix3f
{
  const RowVector3f min = X.matrix().colwise().minCoeff();
  const RowVector3f max = X.matrix().colwise().maxCoeff();

  const Matrix2f scale = (max - min).cwiseInverse().head(2).asDiagonal();

  Matrix3f T = Matrix3f::Zero();
  T.topLeftCorner<2, 2>() = scale;
  T.col(2) << -min.cwiseQuotient(max - min).transpose().head(2), 1.f;

  return T;
}

auto apply_transform(const Matrix3f& T, const Tensor_<float, 2>& X)
  -> Tensor_<float, 2>
{
  auto TX = Tensor_<float, 2>{X.sizes()};
  auto TX_ = TX.colmajor_view().matrix();
  TX_ = T * X.colmajor_view().matrix();
  TX_.array().rowwise() /= TX_.array().row(2);
  return TX;
}

BOOST_AUTO_TEST_SUITE(TestMultiViewGeometry)

BOOST_AUTO_TEST_CASE(test_range)
{
  auto a = range(3);
  BOOST_CHECK(vec(a) == Vector3i(0, 1, 2));
}

BOOST_AUTO_TEST_CASE(test_random_shuffle)
{
  auto a = range(4);
  a = random_shuffle(a);
  BOOST_CHECK(vec(a) != Vector4i(0, 1, 2, 3));
}

BOOST_AUTO_TEST_CASE(test_random_samples)
{
  constexpr auto num_samples = 2;
  constexpr auto sample_size = 5;
  constexpr auto num_data_points = 10;
  auto samples = random_samples(num_samples, sample_size, num_data_points);

  BOOST_CHECK_EQUAL(samples.size(0), num_samples);
  BOOST_CHECK_EQUAL(samples.size(1), sample_size);
  BOOST_CHECK(samples.matrix().minCoeff() >=  0);
  BOOST_CHECK(samples.matrix().maxCoeff() <  10);
}

BOOST_AUTO_TEST_CASE(test_extract_centers)
{
  auto features = std::vector<OERegion>{{Point2f::Ones() * 0, 1.f},
                                        {Point2f::Ones() * 1, 1.f},
                                        {Point2f::Ones() * 2, 1.f}};

  auto centers = extract_centers(features);
  auto expected_centers = Tensor_<float, 2>{centers.sizes()};
  expected_centers.matrix() <<
    0, 0, 1,
    1, 1, 1,
    2, 2, 1;

  BOOST_CHECK(centers.matrix() == expected_centers.matrix());
}

BOOST_AUTO_TEST_CASE(test_to_point_indices)
{
  constexpr auto num_matches = 5;
  constexpr auto num_samples = 2;
  constexpr auto sample_size = 4;

  auto matches = Tensor_<int, 2>{num_matches, 2};
  matches.matrix() <<
    0, 0,
    1, 1,
    2, 2,
    3, 3,
    4, 0;

  auto samples = Tensor_<int, 2>{num_samples, sample_size};
  samples.matrix() <<
    0, 1, 2, 3,
    4, 2, 3, 1;

  auto point_indices = to_point_indices(samples, matches);

  auto expected_point_indices = Tensor_<int, 3>{num_samples, sample_size, 2};
  expected_point_indices[0].matrix() <<
    0, 0,
    1, 1,
    2, 2,
    3, 3;
  expected_point_indices[1].matrix() <<
    4, 0,
    2, 2,
    3, 3,
    1, 1;

  BOOST_CHECK(vec(point_indices) == vec(expected_point_indices));
}

template <typename T>
void print_3d_array(const TensorView_<T, 3>& x)
{
  const auto max = x.flat_array().abs().maxCoeff();
  std::stringstream ss;
  ss << max;
  const auto pad_size = ss.str().size();

  cout << "[";
  for (auto i = 0; i < x.size(0); ++i)
  {
    cout << "[";
    for (auto j = 0; j < x.size(1); ++j)
    {
      cout << "[";
      for (auto k = 0; k < x.size(2); ++k)
      {
        cout << std::setw(pad_size) << x(i,j,k);
        if (k != x.size(2) - 1)
          cout << ", ";
      }
      cout << "]";

      if (j != x.size(1) - 1)
        cout << ", ";
      else
        cout << "]";
    }

    if (i != x.size(0) - 1)
      cout << ",\n ";
  }
  cout << "]" << endl;
}

BOOST_AUTO_TEST_CASE(test_to_coordinates)
{
  constexpr auto num_matches = 5;
  constexpr auto num_samples = 2;
  constexpr auto sample_size = 4;

  const auto features1 = std::vector<OERegion>{{Point2f::Ones() * 0, 1.f},
                                               {Point2f::Ones() * 1, 1.f},
                                               {Point2f::Ones() * 2, 1.f}};
  const auto features2 = std::vector<OERegion>{{Point2f::Ones() * 1, 1.f},
                                               {Point2f::Ones() * 2, 1.f},
                                               {Point2f::Ones() * 3, 1.f}};

  const auto points1 = extract_centers(features1);
  const auto points2 = extract_centers(features2);

  auto matches = Tensor_<int, 2>{num_matches, 2};
  matches.matrix() <<
    0, 0,
    1, 1,
    2, 2,
    0, 1,
    1, 2;

  auto samples = Tensor_<int, 2>{num_samples, sample_size};
  samples.matrix() <<
    0, 1, 2, 3,
    1, 2, 3, 4;

  const auto point_indices = to_point_indices(samples, matches);
  const auto coords = to_coordinates(point_indices, points1, points2);

  //                                        N            K            P  C
  auto expected_coords = Tensor_<float, 4>{{num_samples, sample_size, 2, 2}};
  expected_coords[0].flat_array() <<
    0.f, 0.f, 1.f, 1.f,
    1.f, 1.f, 2.f, 2.f,
    2.f, 2.f, 3.f, 3.f,
    0.f, 0.f, 2.f, 2.f;

  expected_coords[1].flat_array() <<
    1.f, 1.f, 2.f, 2.f,
    2.f, 2.f, 3.f, 3.f,
    0.f, 0.f, 2.f, 2.f,
    1.f, 1.f, 3.f, 3.f;

  BOOST_CHECK(vec(expected_coords) == vec(coords));
  BOOST_CHECK(expected_coords.sizes() == coords.sizes());

  const auto coords_t = coords.transpose({0, 2, 1, 3});
  const auto sample1 = coords_t[0];

  auto expected_sample1 = Tensor_<float, 3>{sample1.sizes()};
  expected_sample1.flat_array() <<
    // P1
    0.f, 0.f,
    1.f, 1.f,
    2.f, 2.f,
    0.f, 0.f,
    // P2
    1.f, 1.f,
    2.f, 2.f,
    3.f, 3.f,
    2.f, 2.f;

  //print_3d_array(expected_sample1);
  //print_3d_array(sample1);
  BOOST_CHECK(vec(expected_sample1) == vec(sample1));
}

BOOST_AUTO_TEST_CASE(test_compute_normalizer)
{
  auto X = Tensor_<float, 2>{3, 3};
  X.matrix() <<
    1, 1, 1,
    2, 2, 1,
    3, 3, 1;

  auto T = compute_normalizer(X);

  Matrix3f expected_T;
  expected_T <<
    0.5, 0.0, -0.5,
    0.0, 0.5, -0.5,
    0.0, 0.0,  1.0;

  BOOST_CHECK((T - expected_T).norm() < 1e-12);
}

BOOST_AUTO_TEST_CASE(test_apply_transform)
{
  auto X = Tensor_<float, 2>{3, 3};
  X.matrix() <<
    1, 1, 1,
    2, 2, 1,
    3, 3, 1;

  auto T = compute_normalizer(X);

  auto TX = apply_transform(T, X);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>WIP: fix tests.<commit_after>// ========================================================================== //
// This file is part of Sara, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2018 David Ok <david.ok8@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.
// ========================================================================== //

#define BOOST_TEST_MODULE "MultiViewGeometry/Essential Matrix"

#include <DO/Sara/FeatureMatching.hpp>
#include <DO/Sara/ImageIO.hpp>
#include <DO/Sara/ImageProcessing/GemmBasedConvolution.hpp>

#include <boost/test/unit_test.hpp>

#include <iomanip>
#include <sstream>

using namespace std;
using namespace DO::Sara;

template <typename T>
void print_3d_array(const TensorView_<T, 3>& x)
{
  const auto max = x.flat_array().abs().maxCoeff();
  std::stringstream ss;
  ss << max;
  const auto pad_size = ss.str().size();

  cout << "[";
  for (auto i = 0; i < x.size(0); ++i)
  {
    cout << "[";
    for (auto j = 0; j < x.size(1); ++j)
    {
      cout << "[";
      for (auto k = 0; k < x.size(2); ++k)
      {
        cout << std::setw(pad_size) << x(i,j,k);
        if (k != x.size(2) - 1)
          cout << ", ";
      }
      cout << "]";

      if (j != x.size(1) - 1)
        cout << ", ";
      else
        cout << "]";
    }

    if (i != x.size(0) - 1)
      cout << ",\n ";
  }
  cout << "]" << endl;
}

void print_3d_array(const TensorView_<float, 3>& x)
{
  cout << "[";
  for (auto i = 0; i < x.size(0); ++i)
  {
    cout << "[";
    for (auto j = 0; j < x.size(1); ++j)
    {
      cout << "[";
      for (auto k = 0; k < x.size(2); ++k)
      {
        cout << fixed << x(i,j,k);
        if (k != x.size(2) - 1)
          cout << ", ";
      }
      cout << "]";

      if (j != x.size(1) - 1)
        cout << ", ";
      else
        cout << "]";
    }

    if (i != x.size(0) - 1)
      cout << ",\n ";
  }
  cout << "]" << endl;
}

void load(Image<Rgb8>& image1, Image<Rgb8>& image2,
          Set<OERegion, RealDescriptor>& keys1,
          Set<OERegion, RealDescriptor>& keys2,  //
          vector<Match>& matches)
{
  cout << "Loading images" << endl;

  auto data_dir = std::string{"/home/david/Desktop/Datasets/sfm/castle_int"};
  auto file1 = "0000.png";
  auto file2 = "0001.png";

  image1 = imread<Rgb8>(data_dir + "/" + file1);
  image2 = imread<Rgb8>(data_dir + "/" + file2);

#ifdef COMPUTE_KEYPOINTS
  cout << "Computing/Reading keypoints" << endl;
  auto sifts1 = compute_sift_keypoints(image1.convert<float>());
  auto sifts2 = compute_sift_keypoints(image2.convert<float>());
  keys1.append(sifts1);
  keys2.append(sifts2);
  cout << "Image 1: " << keys1.size() << " keypoints" << endl;
  cout << "Image 2: " << keys2.size() << " keypoints" << endl;

  write_keypoints(sifts1.features, sifts1.descriptors,
                  data_dir + "/" + "0000.key");
  write_keypoints(sifts2.features, sifts2.descriptors,
                  data_dir + "/" + "0001.key");

#else
  read_keypoints(keys1.features, keys1.descriptors,
                 data_dir + "/" + "0000.key");
  read_keypoints(keys2.features, keys2.descriptors,
                 data_dir + "/" + "0001.key");
#endif

  // Compute/read matches
  cout << "Computing Matches" << endl;
  AnnMatcher matcher{keys1, keys2, 1.0f};
  matches = matcher.compute_matches();
  cout << matches.size() << " matches" << endl;

  // Debug this.
  //write_matches(matches, data_dir + "/" + "0000_0001.match");
}

// NumPy-like interface for Tensors
auto range(int n) -> Tensor_<int, 1>
{
  auto indices = Tensor_<int, 1>{n};
  std::iota(indices.begin(), indices.end(), 0);
  return indices;
}

auto random_shuffle(const Tensor_<int, 1>& x) -> Tensor_<int, 1>
{
  Tensor_<int, 1> x_shuffled = x;
  std::random_shuffle(x_shuffled.begin(), x_shuffled.end());
  return x_shuffled;
}

auto random_samples(int num_samples, int sample_size, int num_data_points)
    -> Tensor_<int, 2>
{
  auto indices = range(num_data_points);

  auto samples = Tensor_<int, 2>{sample_size, num_samples};
  for (int i = 0; i < sample_size; ++i)
    samples[i].flat_array() =
        random_shuffle(indices).flat_array().head(num_samples);

  samples = samples.transpose({1, 0});

  return samples;
}

// Data transformations.
auto extract_centers(const std::vector<OERegion>& features) -> Tensor_<float, 2>
{
  auto centers = Tensor_<float, 2>{int(features.size()), 2};
  auto mat = centers.matrix();

  for (auto i = 0; i < centers.size(0); ++i)
    mat.row(i) = features[i].center().transpose();

  return centers;
}

auto homogeneous(const TensorView_<float, 2>& x)
  -> Tensor_<float, 2>
{
  auto X = Tensor_<float, 2>(x.size(0), x.size(1) + 1);
  X.matrix().leftCols(x.size(1)) = x.matrix();
  X.matrix().col(x.size(1)).setOnes();
  return X;
}

auto to_point_indices(const TensorView_<int, 2>& samples, const TensorView_<int, 2>& matches)
  -> Tensor_<int, 3>
{
  const auto num_samples = samples.size(0);
  const auto sample_size = samples.size(1);

  auto point_indices = Tensor_<int, 3>{num_samples, sample_size, 2};
  for (auto s = 0; s < num_samples; ++s)
    for (auto m = 0; m < sample_size; ++m)
      point_indices[s][m].flat_array() = matches[samples(s, m)].flat_array();

  return point_indices;
}

auto to_coordinates(const Tensor_<int, 3>& point_indices,
                    const Tensor_<float, 2>& p1,
                    const Tensor_<float, 2>& p2)
  -> Tensor_<float, 4>
{
  const auto num_samples = point_indices.size(0);
  const auto sample_size = point_indices.size(1);
  const auto num_points = 2;
  const auto coords_dim = p1.size(1);

  auto p =
      Tensor_<float, 4>{{num_samples, sample_size, num_points, coords_dim}};

  for (auto s = 0; s < num_samples; ++s)
    for (auto m = 0; m < sample_size; ++m)
    {
      auto p1_idx = point_indices(s, m, 0);
      auto p2_idx = point_indices(s, m, 1);

      p[s][m][0].flat_array() = p1[p1_idx].flat_array();
      p[s][m][1].flat_array() = p2[p2_idx].flat_array();
    }

  return p;
}

// Point transformations.
auto compute_normalizer(const Tensor_<float, 2>& X) -> Matrix3f
{
  const RowVector3f min = X.matrix().colwise().minCoeff();
  const RowVector3f max = X.matrix().colwise().maxCoeff();

  const Matrix2f scale = (max - min).cwiseInverse().head(2).asDiagonal();

  Matrix3f T = Matrix3f::Zero();
  T.topLeftCorner<2, 2>() = scale;
  T.col(2) << -min.cwiseQuotient(max - min).transpose().head(2), 1.f;

  return T;
}

auto apply_transform(const Matrix3f& T, const Tensor_<float, 2>& X)
  -> Tensor_<float, 2>
{
  auto TX = Tensor_<float, 2>{X.sizes()};
  auto TX_ = TX.colmajor_view().matrix();
  TX_ = T * X.colmajor_view().matrix();
  TX_.array().rowwise() /= TX_.array().row(2);
  return TX;
}

BOOST_AUTO_TEST_SUITE(TestMultiViewGeometry)

BOOST_AUTO_TEST_CASE(test_range)
{
  auto a = range(3);
  BOOST_CHECK(vec(a) == Vector3i(0, 1, 2));
}

BOOST_AUTO_TEST_CASE(test_random_shuffle)
{
  auto a = range(4);
  a = random_shuffle(a);
  BOOST_CHECK(vec(a) != Vector4i(0, 1, 2, 3));
}

BOOST_AUTO_TEST_CASE(test_random_samples)
{
  constexpr auto num_samples = 2;
  constexpr auto sample_size = 5;
  constexpr auto num_data_points = 10;
  auto samples = random_samples(num_samples, sample_size, num_data_points);

  BOOST_CHECK_EQUAL(samples.size(0), num_samples);
  BOOST_CHECK_EQUAL(samples.size(1), sample_size);
  BOOST_CHECK(samples.matrix().minCoeff() >=  0);
  BOOST_CHECK(samples.matrix().maxCoeff() <  10);
}

BOOST_AUTO_TEST_CASE(test_extract_centers)
{
  auto features = std::vector<OERegion>{{Point2f::Ones() * 0, 1.f},
                                        {Point2f::Ones() * 1, 1.f},
                                        {Point2f::Ones() * 2, 1.f}};

  const auto x = extract_centers(features);
  auto expected_x = Tensor_<float, 2>{x.sizes()};
  expected_x.matrix() <<
    0, 0,
    1, 1,
    2, 2;

  BOOST_CHECK(x.matrix() == expected_x.matrix());

  const auto X = homogeneous(x);
  auto expected_X = Tensor_<float, 2>{X.sizes()};
  expected_X.matrix() <<
    0, 0, 1,
    1, 1, 1,
    2, 2, 1;
  BOOST_CHECK(X.matrix() == expected_X.matrix());
}

BOOST_AUTO_TEST_CASE(test_to_point_indices)
{
  constexpr auto num_matches = 5;
  constexpr auto num_samples = 2;
  constexpr auto sample_size = 4;

  auto matches = Tensor_<int, 2>{num_matches, 2};
  matches.matrix() <<
    0, 0,
    1, 1,
    2, 2,
    3, 3,
    4, 0;

  auto samples = Tensor_<int, 2>{num_samples, sample_size};
  samples.matrix() <<
    0, 1, 2, 3,
    4, 2, 3, 1;

  auto point_indices = to_point_indices(samples, matches);

  auto expected_point_indices = Tensor_<int, 3>{num_samples, sample_size, 2};
  expected_point_indices[0].matrix() <<
    0, 0,
    1, 1,
    2, 2,
    3, 3;
  expected_point_indices[1].matrix() <<
    4, 0,
    2, 2,
    3, 3,
    1, 1;

  BOOST_CHECK(vec(point_indices) == vec(expected_point_indices));
}

BOOST_AUTO_TEST_CASE(test_to_coordinates)
{
  constexpr auto num_matches = 5;
  constexpr auto num_samples = 2;
  constexpr auto sample_size = 4;

  const auto features1 = std::vector<OERegion>{{Point2f::Ones() * 0, 1.f},
                                               {Point2f::Ones() * 1, 1.f},
                                               {Point2f::Ones() * 2, 1.f}};
  const auto features2 = std::vector<OERegion>{{Point2f::Ones() * 1, 1.f},
                                               {Point2f::Ones() * 2, 1.f},
                                               {Point2f::Ones() * 3, 1.f}};

  const auto points1 = extract_centers(features1);
  const auto points2 = extract_centers(features2);

  auto matches = Tensor_<int, 2>{num_matches, 2};
  matches.matrix() <<
    0, 0,
    1, 1,
    2, 2,
    0, 1,
    1, 2;

  auto samples = Tensor_<int, 2>{num_samples, sample_size};
  samples.matrix() <<
    0, 1, 2, 3,
    1, 2, 3, 4;

  const auto point_indices = to_point_indices(samples, matches);
  const auto coords = to_coordinates(point_indices, points1, points2);

  //                                        N            K            P  C
  auto expected_coords = Tensor_<float, 4>{{num_samples, sample_size, 2, 2}};
  expected_coords[0].flat_array() <<
    0.f, 0.f, 1.f, 1.f,
    1.f, 1.f, 2.f, 2.f,
    2.f, 2.f, 3.f, 3.f,
    0.f, 0.f, 2.f, 2.f;

  expected_coords[1].flat_array() <<
    1.f, 1.f, 2.f, 2.f,
    2.f, 2.f, 3.f, 3.f,
    0.f, 0.f, 2.f, 2.f,
    1.f, 1.f, 3.f, 3.f;

  BOOST_CHECK(vec(expected_coords) == vec(coords));
  BOOST_CHECK(expected_coords.sizes() == coords.sizes());

  const auto coords_t = coords.transpose({0, 2, 1, 3});
  const auto sample1 = coords_t[0];

  auto expected_sample1 = Tensor_<float, 3>{sample1.sizes()};
  expected_sample1.flat_array() <<
    // P1
    0.f, 0.f,
    1.f, 1.f,
    2.f, 2.f,
    0.f, 0.f,
    // P2
    1.f, 1.f,
    2.f, 2.f,
    3.f, 3.f,
    2.f, 2.f;

  //print_3d_array(expected_sample1);
  //print_3d_array(sample1);
  BOOST_CHECK(vec(expected_sample1) == vec(sample1));
}

BOOST_AUTO_TEST_CASE(test_compute_normalizer)
{
  auto X = Tensor_<float, 2>{3, 3};
  X.matrix() <<
    1, 1, 1,
    2, 2, 1,
    3, 3, 1;

  auto T = compute_normalizer(X);

  Matrix3f expected_T;
  expected_T <<
    0.5, 0.0, -0.5,
    0.0, 0.5, -0.5,
    0.0, 0.0,  1.0;

  BOOST_CHECK((T - expected_T).norm() < 1e-12);
}

BOOST_AUTO_TEST_CASE(test_apply_transform)
{
  auto X = Tensor_<float, 2>{3, 3};
  X.matrix() <<
    1, 1, 1,
    2, 2, 1,
    3, 3, 1;

  auto T = compute_normalizer(X);

  auto TX = apply_transform(T, X);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/********************************************************************************
  $Header$

  purpose:

  notes:

  to do:

  author(s):
   - Dirk Farin, farin@ti.uni-mannheim.de
     University Mannheim, Dept. Circuitry and Simulation
     L 15,16 room 410 / D-68131 Mannheim / Germany

  modifications:
    24/Jan/2002 - Dirk Farin - Complete reimplementation based on old Image type.
    02/Jun/1999 - Dirk Farin - first implementation
 ********************************************************************************
    Copyright (C) 2002 Dirk Farin

    This program is distributed under GNU Public License (GPL) as
    outlined in the COPYING file that comes with the source distribution.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 ********************************************************************************/

#ifndef LIBVIDEOGFX_GRAPHICS_BASIC_IMAGE_HH
#define LIBVIDEOGFX_GRAPHICS_BASIC_IMAGE_HH

#include <assert.h>

#include <libvideogfx/types.hh>
#include <libvideogfx/graphics/basic/bitmap.hh>
#include <algorithm>

enum Colorspace
  {
    Colorspace_RGB, Colorspace_YUV, Colorspace_Greyscale, Colorspace_HSV,
    Colorspace_Invalid
  };

enum ChromaFormat {
  /** Subsampling h:2 v:2 */ Chroma_420,
  /** Subsampling h:2 v:1 */ Chroma_422,
  /** No subsampling      */ Chroma_444,
  Chroma_Invalid
};

enum BitmapChannel { Bitmap_Red = 0, Bitmap_Green = 1, Bitmap_Blue = 2,
		     Bitmap_Y   = 0, Bitmap_Cb    = 1, Bitmap_Cr   = 2,
  		                     Bitmap_U     = 1, Bitmap_V    = 2,
		     Bitmap_Hue = 0, Bitmap_Saturation = 1, Bitmap_Value = 2,
		     Bitmap_Alpha=3
};

/** Check if chroma is horizontally subsampled. Usage of the more general #ChromaSubH()# is recommended. */
inline bool IsSubH(ChromaFormat cf) { return cf != Chroma_444; }
/** Check if chroma is vertically subsampled. Usage of the more general #ChromaSubV()# is recommended. */
inline bool IsSubV(ChromaFormat cf) { return cf == Chroma_420; }
/** Get horizontal subsampling factor. */
inline int  ChromaSubH(ChromaFormat cf) { return (cf != Chroma_444) ? 2 : 1; }
/** Get vertical subsampling factor. */
inline int  ChromaSubV(ChromaFormat cf) { return (cf == Chroma_420) ? 2 : 1; }

struct ImageParam
{
  ImageParam() : width(0), height(0), halign(1), valign(1), border(0),
		 colorspace(Colorspace_Invalid), has_alpha(false),
		 chroma(Chroma_420), reduced_chroma_resolution(true),
		 chroma_border(-1), chroma_halign(-1), chroma_valign(-1)
  { }

  int width,height;
  int halign,valign;
  int border;

  Colorspace colorspace;
  bool has_alpha;

  ChromaFormat chroma;
  bool reduced_chroma_resolution;
  int  chroma_border;
  int  chroma_halign;
  int  chroma_valign;

#if 0
  /** If set to #true#: don't allow the alignment or the border to be greater than specified.
      {\bf Explanation}: As it is more efficient to keep and older bitmap if the new one
      is smaller than the old one, the old one is sometimes used instead of creating
      a new one. This does not work if you are depending on the exact memory layout of
      the image. So you can disable it by setting exact\_size to true. */
  bool exact_size;
#endif

  int  AskChromaWidth()  const { return (width +ChromaSubH(chroma)-1)/ChromaSubH(chroma); }
  int  AskChromaHeight() const { return (height+ChromaSubV(chroma)-1)/ChromaSubV(chroma); }
  void AskChromaSizes(int& w,int &h) const;
  int  AskChromaBorder() const;
  int  AskChromaHAlign() const;
  int  AskChromaVAlign() const;
};

template <class Pel> class Image
{
public:
  virtual ~Image() { }

  void Create(const ImageParam&);
  void Release();

  /// Get colorspace independent image parameters.
  ImageParam AskParam() const { return d_param; }
  int  AskWidth()  const { return d_param.width; }
  int  AskHeight() const { return d_param.height; }
  int  AskBorder() const { return d_param.border; }
  void GetSize(int& w,int& h) const { w=d_param.width; h=d_param.height; }

  Bitmap<Pel>&       AskBitmap(BitmapChannel pm_id)       { return d_pm[pm_id]; }
  const Bitmap<Pel>& AskBitmap(BitmapChannel pm_id) const { return d_pm[pm_id]; }

  Pel*const*       AskFrame(BitmapChannel pm_id)       { return d_pm[pm_id].AskFrame(); }
  const Pel*const* AskFrame(BitmapChannel pm_id) const { return d_pm[pm_id].AskFrame(); }

  /** Replace a complete bitmap. Note that the new bitmap either has to be empty or has to
      be exactly the same size as the old one.
      Furthermore you are responsible that all alignments and the border size is sufficient
      for your application. This is not checked!

      If you insert or remove (by replacing a bitmap by an empty one) an alpha bitmap,
      the alphamask-flag in ImageParam will be set accordingly.
  */
  void ReplaceBitmap(BitmapChannel id,const Bitmap<Pel>&);
  /// Set new image parameters.
  void SetParam(const ImageParam& param) { d_param=param; }

  Image<Pel> Clone() const;

  Image<Pel> CreateSubView  (int x0,int y0,int w,int h) const;
  Image<Pel> CreateFieldView(bool top) const;

  bool IsEmpty() const { return d_pm[0].IsEmpty(); }

        Pel*const* AskFrameR()        { return d_pm[Bitmap_Red].AskFrame(); }
  const Pel*const* AskFrameR()  const { return d_pm[Bitmap_Red].AskFrame(); }
        Pel*const* AskFrameG()        { return d_pm[Bitmap_Green].AskFrame(); }
  const Pel*const* AskFrameG()  const { return d_pm[Bitmap_Green].AskFrame(); }
        Pel*const* AskFrameB()        { return d_pm[Bitmap_Blue].AskFrame(); }
  const Pel*const* AskFrameB()  const { return d_pm[Bitmap_Blue].AskFrame(); }
        Pel*const* AskFrameY()        { return d_pm[Bitmap_Y].AskFrame(); }
  const Pel*const* AskFrameY()  const { return d_pm[Bitmap_Y].AskFrame(); }
        Pel*const* AskFrameU()        { return d_pm[Bitmap_U].AskFrame(); }
  const Pel*const* AskFrameU()  const { return d_pm[Bitmap_U].AskFrame(); }
        Pel*const* AskFrameV()        { return d_pm[Bitmap_V].AskFrame(); }
  const Pel*const* AskFrameV()  const { return d_pm[Bitmap_V].AskFrame(); }
        Pel*const* AskFrameCb()       { return d_pm[Bitmap_Cb].AskFrame(); }
  const Pel*const* AskFrameCb() const { return d_pm[Bitmap_Cb].AskFrame(); }
        Pel*const* AskFrameCr()       { return d_pm[Bitmap_Cr].AskFrame(); }
  const Pel*const* AskFrameCr() const { return d_pm[Bitmap_Cr].AskFrame(); }
        Pel*const* AskFrameA()        { return d_pm[Bitmap_Alpha].AskFrame(); }
  const Pel*const* AskFrameA()  const { return d_pm[Bitmap_Alpha].AskFrame(); }

        Bitmap<Pel>& AskBitmapR()        { return d_pm[Bitmap_Red]; }
  const Bitmap<Pel>& AskBitmapR()  const { return d_pm[Bitmap_Red]; }
        Bitmap<Pel>& AskBitmapG()        { return d_pm[Bitmap_Green]; }
  const Bitmap<Pel>& AskBitmapG()  const { return d_pm[Bitmap_Green]; }
        Bitmap<Pel>& AskBitmapB()        { return d_pm[Bitmap_Blue]; }
  const Bitmap<Pel>& AskBitmapB()  const { return d_pm[Bitmap_Blue]; }
        Bitmap<Pel>& AskBitmapY()        { return d_pm[Bitmap_Y]; }
  const Bitmap<Pel>& AskBitmapY()  const { return d_pm[Bitmap_Y]; }
        Bitmap<Pel>& AskBitmapU()        { return d_pm[Bitmap_U]; }
  const Bitmap<Pel>& AskBitmapU()  const { return d_pm[Bitmap_U]; }
        Bitmap<Pel>& AskBitmapV()        { return d_pm[Bitmap_V]; }
  const Bitmap<Pel>& AskBitmapV()  const { return d_pm[Bitmap_V]; }
        Bitmap<Pel>& AskBitmapCb()       { return d_pm[Bitmap_Cb]; }
  const Bitmap<Pel>& AskBitmapCb() const { return d_pm[Bitmap_Cb]; }
        Bitmap<Pel>& AskBitmapCr()       { return d_pm[Bitmap_Cr]; }
  const Bitmap<Pel>& AskBitmapCr() const { return d_pm[Bitmap_Cr]; }
        Bitmap<Pel>& AskBitmapA()        { return d_pm[Bitmap_Alpha]; }
  const Bitmap<Pel>& AskBitmapA()  const { return d_pm[Bitmap_Alpha]; }

  bool IsShared() const
  {
    for (int i=0;i<4;i++)
      if (d_pm[i].IsShared())
	return true;

    return false;
  }

private:
  Bitmap<Pel> d_pm[4];
  ImageParam  d_param;
};

template <class Pel> void Image<Pel>::Create(const ImageParam& param)
{
  d_pm[0].Create(param.width, param.height, param.border,param.halign,param.valign);

  switch (param.colorspace)
    {
    case Colorspace_RGB:
    case Colorspace_HSV:
      d_pm[1].Create(param.width, param.height, param.border,param.halign,param.valign);
      d_pm[2].Create(param.width, param.height, param.border,param.halign,param.valign);
      break;

    case Colorspace_YUV:
      if (param.reduced_chroma_resolution)
	{
	  d_pm[1].Create(param.AskChromaWidth(), param.AskChromaHeight(), param.AskChromaBorder(),
			 param.AskChromaHAlign(),param.AskChromaVAlign());
	  d_pm[2].Create(param.AskChromaWidth(), param.AskChromaHeight(), param.AskChromaBorder(),
			 param.AskChromaHAlign(),param.AskChromaVAlign());
	}
      else
	{
	  d_pm[1].Create(param.width, param.height, param.border,param.halign,param.valign);
	  d_pm[2].Create(param.width, param.height, param.border,param.halign,param.valign);
	}
      break;

    case Colorspace_Greyscale:
      d_pm[1].Release();
      d_pm[2].Release();
      break;
    }

  if (param.has_alpha)
    d_pm[Bitmap_Alpha].Create(param.width, param.height, param.border,param.halign,param.valign);
  else
    d_pm[Bitmap_Alpha].Release();

  d_param = param;
}

template <class Pel> void Image<Pel>::Release()
{
  for (int i=0;i<4;i++)
    d_pm[i].Release();

  d_param = ImageParam();
}

template <class Pel> Image<Pel> Image<Pel>::Clone() const
{
  Image<Pel> img;
  for (int i=0;i<4;i++)
    img.d_pm[i] = d_pm[i].Clone();

  img.d_param = d_param;

  return img;
}

template <class Pel> Image<Pel> Image<Pel>::CreateSubView(int x0,int y0,int w,int h) const
{
  Image<Pel> newimg;
  newimg.d_param = d_param;

  newimg.d_param.width  = w;
  newimg.d_param.height = h;
  newimg.d_param.halign = 1;
  newimg.d_param.valign = 1;
  newimg.d_param.border = 0;
  newimg.d_param.chroma_border = -1;
  newimg.d_param.chroma_halign = -1;
  newimg.d_param.chroma_valign = -1;

  if (d_param.colorspace == Colorspace_YUV)
    {
      newimg.d_pm[0] = d_pm[0].CreateSubView(x0,y0,w,h);
      newimg.d_pm[3] = d_pm[3].CreateSubView(x0,y0,w,h);

      int subh = ChromaSubH(d_param.chroma);
      int subv = ChromaSubV(d_param.chroma);

      newimg.d_pm[1] = d_pm[1].CreateSubView(x0/subh,y0/subv,(w+subh-1)/subh,(h+subv-1)/subv);
      newimg.d_pm[2] = d_pm[2].CreateSubView(x0/subh,y0/subv,(w+subh-1)/subh,(h+subv-1)/subv);
    }
  else
    {
      for (int i=0;i<4;i++)
	newimg.d_pm[i] = d_pm[i].CreateSubView(x0,y0,w,h);
    }

  return newimg;
}

template <class Pel> Image<Pel> Image<Pel>::CreateFieldView(bool top) const
{
  if (!top && d_param.colorspace==Colorspace_YUV && d_param.chroma==Chroma_420 &&
      (d_pm[0].AskHeight()%2)==0 && (d_pm[1].AskHeight()%2)==1)
    {
      AssertDescr(false,"not enough chroma information for bottom field");
    }

  Image<Pel> newimg;
  newimg.d_param = d_param;

  for (int i=0;i<4;i++)
    newimg.d_pm[i] = d_pm[i].CreateFieldView(top);

  newimg.d_param.width  = newimg.d_pm[0].AskWidth();
  newimg.d_param.height = newimg.d_pm[0].AskHeight();
  newimg.d_param.halign = 1;
  newimg.d_param.valign = 1;
  newimg.d_param.border = 0;
  newimg.d_param.chroma_border = -1;
  newimg.d_param.chroma_halign = -1;
  newimg.d_param.chroma_valign = -1;

  return newimg;
}

#endif
<commit_msg>utility methods in ImageParam: scale pixel coordinates according to chroma type<commit_after>/********************************************************************************
  $Header$

  purpose:

  notes:

  to do:

  author(s):
   - Dirk Farin, farin@ti.uni-mannheim.de
     University Mannheim, Dept. Circuitry and Simulation
     L 15,16 room 410 / D-68131 Mannheim / Germany

  modifications:
    24/Jan/2002 - Dirk Farin - Complete reimplementation based on old Image type.
    02/Jun/1999 - Dirk Farin - first implementation
 ********************************************************************************
    Copyright (C) 2002 Dirk Farin

    This program is distributed under GNU Public License (GPL) as
    outlined in the COPYING file that comes with the source distribution.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 ********************************************************************************/

#ifndef LIBVIDEOGFX_GRAPHICS_BASIC_IMAGE_HH
#define LIBVIDEOGFX_GRAPHICS_BASIC_IMAGE_HH

#include <assert.h>

#include <libvideogfx/types.hh>
#include <libvideogfx/graphics/basic/bitmap.hh>
#include <algorithm>

enum Colorspace
  {
    Colorspace_RGB, Colorspace_YUV, Colorspace_Greyscale, Colorspace_HSV,
    Colorspace_Invalid
  };

enum ChromaFormat {
  /** Subsampling h:2 v:2 */ Chroma_420,
  /** Subsampling h:2 v:1 */ Chroma_422,
  /** No subsampling      */ Chroma_444,
  Chroma_Invalid
};

enum BitmapChannel { Bitmap_Red = 0, Bitmap_Green = 1, Bitmap_Blue = 2,
		     Bitmap_Y   = 0, Bitmap_Cb    = 1, Bitmap_Cr   = 2,
  		                     Bitmap_U     = 1, Bitmap_V    = 2,
		     Bitmap_Hue = 0, Bitmap_Saturation = 1, Bitmap_Value = 2,
		     Bitmap_Alpha=3
};

/** Check if chroma is horizontally subsampled. Usage of the more general #ChromaSubH()# is recommended. */
inline bool IsSubH(ChromaFormat cf) { return cf != Chroma_444; }
/** Check if chroma is vertically subsampled. Usage of the more general #ChromaSubV()# is recommended. */
inline bool IsSubV(ChromaFormat cf) { return cf == Chroma_420; }
/** Get horizontal subsampling factor. */
inline int  ChromaSubH(ChromaFormat cf) { return (cf != Chroma_444) ? 2 : 1; }
/** Get vertical subsampling factor. */
inline int  ChromaSubV(ChromaFormat cf) { return (cf == Chroma_420) ? 2 : 1; }

struct ImageParam
{
  ImageParam() : width(0), height(0), halign(1), valign(1), border(0),
		 colorspace(Colorspace_Invalid), has_alpha(false),
		 chroma(Chroma_444), reduced_chroma_resolution(true),
		 chroma_border(-1), chroma_halign(-1), chroma_valign(-1)
  { }

  int width,height;
  int halign,valign;
  int border;

  Colorspace colorspace;
  bool has_alpha;

  ChromaFormat chroma;
  bool reduced_chroma_resolution;
  int  chroma_border;
  int  chroma_halign;
  int  chroma_valign;

#if 0
  /** If set to #true#: don't allow the alignment or the border to be greater than specified.
      {\bf Explanation}: As it is more efficient to keep and older bitmap if the new one
      is smaller than the old one, the old one is sometimes used instead of creating
      a new one. This does not work if you are depending on the exact memory layout of
      the image. So you can disable it by setting exact\_size to true. */
  bool exact_size;
#endif

  int  AskChromaWidth()  const
  {
    if (colorspace==Colorspace_YUV)
      return (width +ChromaSubH(chroma)-1)/ChromaSubH(chroma);
    else
      return width;
  }
  int  AskChromaHeight() const
  {
    if (colorspace==Colorspace_YUV)
      return (height+ChromaSubV(chroma)-1)/ChromaSubV(chroma);
    else
      return height;
  }
  void AskChromaSizes(int& w,int &h) const;
  int  AskChromaBorder() const;
  int  AskChromaHAlign() const;
  int  AskChromaVAlign() const;

  int  BitmapWidth (BitmapChannel b) const { if (b==1||b==2) return AskChromaWidth();  else return width; }
  int  BitmapHeight(BitmapChannel b) const { if (b==1||b==2) return AskChromaHeight(); else return height; }
  int  ChromaScaleH(BitmapChannel b,int x) const
  { if ((b==1||b==2) && colorspace==Colorspace_YUV) return x/ChromaSubH(chroma); else return x; }
  int  ChromaScaleV(BitmapChannel b,int y) const
  { if ((b==1||b==2) && colorspace==Colorspace_YUV) return y/ChromaSubV(chroma); else return y; }
};

template <class Pel> class Image
{
public:
  virtual ~Image() { }

  void Create(const ImageParam&);
  void Release();

  /// Get colorspace independent image parameters.
  ImageParam AskParam() const { return d_param; }
  int  AskWidth()  const { return d_param.width; }
  int  AskHeight() const { return d_param.height; }
  int  AskBorder() const { return d_param.border; }
  void GetSize(int& w,int& h) const { w=d_param.width; h=d_param.height; }

  Bitmap<Pel>&       AskBitmap(BitmapChannel pm_id)       { return d_pm[pm_id]; }
  const Bitmap<Pel>& AskBitmap(BitmapChannel pm_id) const { return d_pm[pm_id]; }

  Pel*const*       AskFrame(BitmapChannel pm_id)       { return d_pm[pm_id].AskFrame(); }
  const Pel*const* AskFrame(BitmapChannel pm_id) const { return d_pm[pm_id].AskFrame(); }

  /** Replace a complete bitmap. Note that the new bitmap either has to be empty or has to
      be exactly the same size as the old one.
      Furthermore you are responsible that all alignments and the border size is sufficient
      for your application. This is not checked!

      If you insert or remove (by replacing a bitmap by an empty one) an alpha bitmap,
      the alphamask-flag in ImageParam will be set accordingly.
  */
  void ReplaceBitmap(BitmapChannel id,const Bitmap<Pel>&);
  /// Set new image parameters.
  void SetParam(const ImageParam& param) { d_param=param; }

  Image<Pel> Clone() const;

  Image<Pel> CreateSubView  (int x0,int y0,int w,int h) const;
  Image<Pel> CreateFieldView(bool top) const;

  bool IsEmpty() const { return d_pm[0].IsEmpty(); }

        Pel*const* AskFrameR()        { return d_pm[Bitmap_Red].AskFrame(); }
  const Pel*const* AskFrameR()  const { return d_pm[Bitmap_Red].AskFrame(); }
        Pel*const* AskFrameG()        { return d_pm[Bitmap_Green].AskFrame(); }
  const Pel*const* AskFrameG()  const { return d_pm[Bitmap_Green].AskFrame(); }
        Pel*const* AskFrameB()        { return d_pm[Bitmap_Blue].AskFrame(); }
  const Pel*const* AskFrameB()  const { return d_pm[Bitmap_Blue].AskFrame(); }
        Pel*const* AskFrameY()        { return d_pm[Bitmap_Y].AskFrame(); }
  const Pel*const* AskFrameY()  const { return d_pm[Bitmap_Y].AskFrame(); }
        Pel*const* AskFrameU()        { return d_pm[Bitmap_U].AskFrame(); }
  const Pel*const* AskFrameU()  const { return d_pm[Bitmap_U].AskFrame(); }
        Pel*const* AskFrameV()        { return d_pm[Bitmap_V].AskFrame(); }
  const Pel*const* AskFrameV()  const { return d_pm[Bitmap_V].AskFrame(); }
        Pel*const* AskFrameCb()       { return d_pm[Bitmap_Cb].AskFrame(); }
  const Pel*const* AskFrameCb() const { return d_pm[Bitmap_Cb].AskFrame(); }
        Pel*const* AskFrameCr()       { return d_pm[Bitmap_Cr].AskFrame(); }
  const Pel*const* AskFrameCr() const { return d_pm[Bitmap_Cr].AskFrame(); }
        Pel*const* AskFrameA()        { return d_pm[Bitmap_Alpha].AskFrame(); }
  const Pel*const* AskFrameA()  const { return d_pm[Bitmap_Alpha].AskFrame(); }

        Bitmap<Pel>& AskBitmapR()        { return d_pm[Bitmap_Red]; }
  const Bitmap<Pel>& AskBitmapR()  const { return d_pm[Bitmap_Red]; }
        Bitmap<Pel>& AskBitmapG()        { return d_pm[Bitmap_Green]; }
  const Bitmap<Pel>& AskBitmapG()  const { return d_pm[Bitmap_Green]; }
        Bitmap<Pel>& AskBitmapB()        { return d_pm[Bitmap_Blue]; }
  const Bitmap<Pel>& AskBitmapB()  const { return d_pm[Bitmap_Blue]; }
        Bitmap<Pel>& AskBitmapY()        { return d_pm[Bitmap_Y]; }
  const Bitmap<Pel>& AskBitmapY()  const { return d_pm[Bitmap_Y]; }
        Bitmap<Pel>& AskBitmapU()        { return d_pm[Bitmap_U]; }
  const Bitmap<Pel>& AskBitmapU()  const { return d_pm[Bitmap_U]; }
        Bitmap<Pel>& AskBitmapV()        { return d_pm[Bitmap_V]; }
  const Bitmap<Pel>& AskBitmapV()  const { return d_pm[Bitmap_V]; }
        Bitmap<Pel>& AskBitmapCb()       { return d_pm[Bitmap_Cb]; }
  const Bitmap<Pel>& AskBitmapCb() const { return d_pm[Bitmap_Cb]; }
        Bitmap<Pel>& AskBitmapCr()       { return d_pm[Bitmap_Cr]; }
  const Bitmap<Pel>& AskBitmapCr() const { return d_pm[Bitmap_Cr]; }
        Bitmap<Pel>& AskBitmapA()        { return d_pm[Bitmap_Alpha]; }
  const Bitmap<Pel>& AskBitmapA()  const { return d_pm[Bitmap_Alpha]; }

  bool IsShared() const
  {
    for (int i=0;i<4;i++)
      if (d_pm[i].IsShared())
	return true;

    return false;
  }

private:
  Bitmap<Pel> d_pm[4];
  ImageParam  d_param;
};

template <class Pel> void Image<Pel>::Create(const ImageParam& param)
{
  d_pm[0].Create(param.width, param.height, param.border,param.halign,param.valign);

  switch (param.colorspace)
    {
    case Colorspace_RGB:
    case Colorspace_HSV:
      d_pm[1].Create(param.width, param.height, param.border,param.halign,param.valign);
      d_pm[2].Create(param.width, param.height, param.border,param.halign,param.valign);
      break;

    case Colorspace_YUV:
      if (param.reduced_chroma_resolution)
	{
	  d_pm[1].Create(param.AskChromaWidth(), param.AskChromaHeight(), param.AskChromaBorder(),
			 param.AskChromaHAlign(),param.AskChromaVAlign());
	  d_pm[2].Create(param.AskChromaWidth(), param.AskChromaHeight(), param.AskChromaBorder(),
			 param.AskChromaHAlign(),param.AskChromaVAlign());
	}
      else
	{
	  d_pm[1].Create(param.width, param.height, param.border,param.halign,param.valign);
	  d_pm[2].Create(param.width, param.height, param.border,param.halign,param.valign);
	}
      break;

    case Colorspace_Greyscale:
      d_pm[1].Release();
      d_pm[2].Release();
      break;
    }

  if (param.has_alpha)
    d_pm[Bitmap_Alpha].Create(param.width, param.height, param.border,param.halign,param.valign);
  else
    d_pm[Bitmap_Alpha].Release();

  d_param = param;
}

template <class Pel> void Image<Pel>::Release()
{
  for (int i=0;i<4;i++)
    d_pm[i].Release();

  d_param = ImageParam();
}

template <class Pel> Image<Pel> Image<Pel>::Clone() const
{
  Image<Pel> img;
  for (int i=0;i<4;i++)
    img.d_pm[i] = d_pm[i].Clone();

  img.d_param = d_param;

  return img;
}

template <class Pel> Image<Pel> Image<Pel>::CreateSubView(int x0,int y0,int w,int h) const
{
  Image<Pel> newimg;
  newimg.d_param = d_param;

  newimg.d_param.width  = w;
  newimg.d_param.height = h;
  newimg.d_param.halign = 1;
  newimg.d_param.valign = 1;
  newimg.d_param.border = 0;
  newimg.d_param.chroma_border = -1;
  newimg.d_param.chroma_halign = -1;
  newimg.d_param.chroma_valign = -1;

  if (d_param.colorspace == Colorspace_YUV)
    {
      newimg.d_pm[0] = d_pm[0].CreateSubView(x0,y0,w,h);
      newimg.d_pm[3] = d_pm[3].CreateSubView(x0,y0,w,h);

      int subh = ChromaSubH(d_param.chroma);
      int subv = ChromaSubV(d_param.chroma);

      newimg.d_pm[1] = d_pm[1].CreateSubView(x0/subh,y0/subv,(w+subh-1)/subh,(h+subv-1)/subv);
      newimg.d_pm[2] = d_pm[2].CreateSubView(x0/subh,y0/subv,(w+subh-1)/subh,(h+subv-1)/subv);
    }
  else
    {
      for (int i=0;i<4;i++)
	newimg.d_pm[i] = d_pm[i].CreateSubView(x0,y0,w,h);
    }

  return newimg;
}

template <class Pel> Image<Pel> Image<Pel>::CreateFieldView(bool top) const
{
  if (!top && d_param.colorspace==Colorspace_YUV && d_param.chroma==Chroma_420 &&
      (d_pm[0].AskHeight()%2)==0 && (d_pm[1].AskHeight()%2)==1)
    {
      AssertDescr(false,"not enough chroma information for bottom field");
    }

  Image<Pel> newimg;
  newimg.d_param = d_param;

  for (int i=0;i<4;i++)
    newimg.d_pm[i] = d_pm[i].CreateFieldView(top);

  newimg.d_param.width  = newimg.d_pm[0].AskWidth();
  newimg.d_param.height = newimg.d_pm[0].AskHeight();
  newimg.d_param.halign = 1;
  newimg.d_param.valign = 1;
  newimg.d_param.border = 0;
  newimg.d_param.chroma_border = -1;
  newimg.d_param.chroma_halign = -1;
  newimg.d_param.chroma_valign = -1;

  return newimg;
}

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <string>

#include "test/opt/pass_fixture.h"
#include "test/opt/pass_utils.h"

namespace spvtools {
namespace opt {
namespace {

using StripLineReflectInfoTest = PassTest<::testing::Test>;

TEST_F(StripLineReflectInfoTest, StripHlslSemantic) {
  // This is a non-sensical example, but exercises the instructions.
  std::string before = R"(OpCapability Shader
OpCapability Linkage
OpExtension "SPV_GOOGLE_decorate_string"
OpExtension "SPV_GOOGLE_hlsl_functionality1"
OpMemoryModel Logical Simple
OpDecorateStringGOOGLE %float HlslSemanticGOOGLE "foobar"
OpDecorateStringGOOGLE %void HlslSemanticGOOGLE "my goodness"
%void = OpTypeVoid
%float = OpTypeFloat 32
)";
  std::string after = R"(OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical Simple
%void = OpTypeVoid
%float = OpTypeFloat 32
)";

  SinglePassRunAndCheck<StripReflectInfoPass>(before, after, false);
}

TEST_F(StripLineReflectInfoTest, StripHlslCounterBuffer) {
  std::string before = R"(OpCapability Shader
OpCapability Linkage
OpExtension "SPV_GOOGLE_hlsl_functionality1"
OpMemoryModel Logical Simple
OpDecorateId %void HlslCounterBufferGOOGLE %float
%void = OpTypeVoid
%float = OpTypeFloat 32
)";
  std::string after = R"(OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical Simple
%void = OpTypeVoid
%float = OpTypeFloat 32
)";

  SinglePassRunAndCheck<StripReflectInfoPass>(before, after, false);
}

TEST_F(StripLineReflectInfoTest, StripHlslSemanticOnMember) {
  // This is a non-sensical example, but exercises the instructions.
  std::string before = R"(OpCapability Shader
OpCapability Linkage
OpExtension "SPV_GOOGLE_decorate_string"
OpExtension "SPV_GOOGLE_hlsl_functionality1"
OpMemoryModel Logical Simple
OpMemberDecorateStringGOOGLE %struct 0 HlslSemanticGOOGLE "foobar"
%float = OpTypeFloat 32
%_struct_3 = OpTypeStruct %float
)";
  std::string after = R"(OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical Simple
%float = OpTypeFloat 32
%_struct_3 = OpTypeStruct %float
)";

  SinglePassRunAndCheck<StripReflectInfoPass>(before, after, false);
}

}  // namespace
}  // namespace opt
}  // namespace spvtools
<commit_msg>Add test with explicit example of stripping reflection info (#3064)<commit_after>// Copyright (c) 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <string>
#include "gmock/gmock.h"

#include "spirv-tools/optimizer.hpp"

#include "test/opt/pass_fixture.h"
#include "test/opt/pass_utils.h"

namespace spvtools {
namespace opt {
namespace {

using StripLineReflectInfoTest = PassTest<::testing::Test>;

// This test acts as an end-to-end code example on how to strip
// reflection info from a SPIR-V module.  Use this code pattern
// when you have compiled HLSL code with Glslang or DXC using
// option -fhlsl_functionality1 to insert reflection information,
// but then want to filter out the extra instructions before sending
// it to a driver that does not implement VK_GOOGLE_hlsl_functionality1.
TEST_F(StripLineReflectInfoTest, StripReflectEnd2EndExample) {
  // This is a non-sensical example, but exercises the instructions.
  std::string before = R"(OpCapability Shader
OpCapability Linkage
OpExtension "SPV_GOOGLE_decorate_string"
OpExtension "SPV_GOOGLE_hlsl_functionality1"
OpMemoryModel Logical Simple
OpDecorateStringGOOGLE %float HlslSemanticGOOGLE "foobar"
OpDecorateStringGOOGLE %void HlslSemanticGOOGLE "my goodness"
%void = OpTypeVoid
%float = OpTypeFloat 32
)";
  SpirvTools tools(SPV_ENV_UNIVERSAL_1_1);
  std::vector<uint32_t> binary_in;
  tools.Assemble(before, &binary_in);

  // Instantiate the optimizer, and run the strip-reflection-info
  // pass over the |binary_in| module, and place the modified module
  // into |binary_out|.
  spvtools::Optimizer optimizer(SPV_ENV_UNIVERSAL_1_1);
  optimizer.RegisterPass(spvtools::CreateStripReflectInfoPass());
  std::vector<uint32_t> binary_out;
  optimizer.Run(binary_in.data(), binary_in.size(), &binary_out);

  // Check results
  std::string disassembly;
  tools.Disassemble(binary_out.data(), binary_out.size(), &disassembly);
  std::string after = R"(OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical Simple
%void = OpTypeVoid
%float = OpTypeFloat 32
)";
  EXPECT_THAT(disassembly, testing::Eq(after));
}

// This test is functionally the same as the end-to-end test above,
// but uses the test SinglePassRunAndCheck test fixture instead.
TEST_F(StripLineReflectInfoTest, StripHlslSemantic) {
  // This is a non-sensical example, but exercises the instructions.
  std::string before = R"(OpCapability Shader
OpCapability Linkage
OpExtension "SPV_GOOGLE_decorate_string"
OpExtension "SPV_GOOGLE_hlsl_functionality1"
OpMemoryModel Logical Simple
OpDecorateStringGOOGLE %float HlslSemanticGOOGLE "foobar"
OpDecorateStringGOOGLE %void HlslSemanticGOOGLE "my goodness"
%void = OpTypeVoid
%float = OpTypeFloat 32
)";
  std::string after = R"(OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical Simple
%void = OpTypeVoid
%float = OpTypeFloat 32
)";

  SinglePassRunAndCheck<StripReflectInfoPass>(before, after, false);
}

TEST_F(StripLineReflectInfoTest, StripHlslCounterBuffer) {
  std::string before = R"(OpCapability Shader
OpCapability Linkage
OpExtension "SPV_GOOGLE_hlsl_functionality1"
OpMemoryModel Logical Simple
OpDecorateId %void HlslCounterBufferGOOGLE %float
%void = OpTypeVoid
%float = OpTypeFloat 32
)";
  std::string after = R"(OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical Simple
%void = OpTypeVoid
%float = OpTypeFloat 32
)";

  SinglePassRunAndCheck<StripReflectInfoPass>(before, after, false);
}

TEST_F(StripLineReflectInfoTest, StripHlslSemanticOnMember) {
  // This is a non-sensical example, but exercises the instructions.
  std::string before = R"(OpCapability Shader
OpCapability Linkage
OpExtension "SPV_GOOGLE_decorate_string"
OpExtension "SPV_GOOGLE_hlsl_functionality1"
OpMemoryModel Logical Simple
OpMemberDecorateStringGOOGLE %struct 0 HlslSemanticGOOGLE "foobar"
%float = OpTypeFloat 32
%_struct_3 = OpTypeStruct %float
)";
  std::string after = R"(OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical Simple
%float = OpTypeFloat 32
%_struct_3 = OpTypeStruct %float
)";

  SinglePassRunAndCheck<StripReflectInfoPass>(before, after, false);
}

}  // namespace
}  // namespace opt
}  // namespace spvtools
<|endoftext|>


<commit_before>#include <Halide.h>
#include <stdio.h>
#include "clock.h"
#include <memory>

using namespace Halide;

enum {
    scalar_trans,
    vec_y_trans,
    vec_x_trans
};

void test_transpose(int mode) {
    Func input, block, block_transpose, output;
    Var x, y;

    input(x, y) = cast<uint16_t>(x + y);
    input.compute_root();

    block(x, y) = input(x, y);
    block_transpose(x, y) = block(y, x);
    output(x, y) = block_transpose(x, y);

    Var xi, yi;
    output.tile(x, y, xi, yi, 8, 8).vectorize(xi).unroll(yi);

    // Do 8 vectorized loads from the input.
    block.compute_at(output, x).vectorize(x).unroll(y);

    std::string algorithm;
    switch(mode) {
        case scalar_trans:
            block_transpose.compute_at(output, x).unroll(x).unroll(y);
            algorithm = "Scalar transpose";
            break;
        case vec_y_trans:
            block_transpose.compute_at(output, x).vectorize(y).unroll(x);
            algorithm = "Transpose vectorized in y";
            break;
        case vec_x_trans:
            block_transpose.compute_at(output, x).vectorize(x).unroll(y);
            algorithm = "Transpose vectorized in x";
            break;
    }

    output.compile_to_lowered_stmt("fast_transpose.stmt");
    output.compile_to_assembly("fast_transpose.s", std::vector<Argument>());

    Image<uint16_t> result(1024, 1024);
    output.compile_jit();

    output.realize(result);

    double t1 = current_time();
    for (int i = 0; i < 10; i++) {
        output.realize(result);
    }
    double t2 = current_time();

    std::cout << algorithm << " bandwidth " << ((1024*1024 / (t2 - t1)) * 1000 * 10) << " byte/s.\n";
}

int main(int argc, char **argv) {
    test_transpose(scalar_trans);
    test_transpose(vec_y_trans);
    test_transpose(vec_x_trans);
    printf("Success!\n");
    return 0;
}
<commit_msg>Modified block_transpose performance test to ouput assembly code for each different algorithm.<commit_after>#include <Halide.h>
#include <stdio.h>
#include "clock.h"
#include <memory>

using namespace Halide;

enum {
    scalar_trans,
    vec_y_trans,
    vec_x_trans
};

void test_transpose(int mode) {
    Func input, block, block_transpose, output;
    Var x, y;

    input(x, y) = cast<uint16_t>(x + y);
    input.compute_root();

    block(x, y) = input(x, y);
    block_transpose(x, y) = block(y, x);
    output(x, y) = block_transpose(x, y);

    Var xi, yi;
    output.tile(x, y, xi, yi, 8, 8).vectorize(xi).unroll(yi);

    // Do 8 vectorized loads from the input.
    block.compute_at(output, x).vectorize(x).unroll(y);

    std::string algorithm;
    switch(mode) {
        case scalar_trans:
            block_transpose.compute_at(output, x).unroll(x).unroll(y);
            algorithm = "Scalar transpose";
            output.compile_to_assembly("scalar_transpose.s", std::vector<Argument>());
            break;
        case vec_y_trans:
            block_transpose.compute_at(output, x).vectorize(y).unroll(x);
            algorithm = "Transpose vectorized in y";
            output.compile_to_assembly("fast_transpose_y.s", std::vector<Argument>());
            break;
        case vec_x_trans:
            block_transpose.compute_at(output, x).vectorize(x).unroll(y);
            algorithm = "Transpose vectorized in x";
            output.compile_to_assembly("fast_transpose_x.s", std::vector<Argument>());
            break;
    }

    Image<uint16_t> result(1024, 1024);
    output.compile_jit();

    output.realize(result);

    double t1 = current_time();
    for (int i = 0; i < 10; i++) {
        output.realize(result);
    }
    double t2 = current_time();

    std::cout << algorithm << " bandwidth " << ((1024*1024 / (t2 - t1)) * 1000 * 10) << " byte/s.\n";
}

int main(int argc, char **argv) {
    test_transpose(scalar_trans);
    test_transpose(vec_y_trans);
    test_transpose(vec_x_trans);
    printf("Success!\n");
    return 0;
}
<|endoftext|>


<commit_before>#include <memory.h>
#include <string.h>

#include "wrapper.h"

extern "C"
{

/* bitmap/image helpers */
EWXWEXPORT(wxBitmap*,wxBitmap_CreateFromImage)(wxImage* image,int depth)
{
  return new wxBitmap(*image,depth);
}

EWXWEXPORT(wxImage*,wxImage_CreateFromDataEx)(int width,int height,wxUint8* data,bool isStaticData)
{
  return new wxImage(width, height, data, isStaticData);
}

EWXWEXPORT(void,wxImage_Delete)(wxImage* image)
{
  delete image;
}

/* colours */
EWXWEXPORT(wxColour*,wxColour_CreateFromInt)(int rgb)
{
  return new wxColour((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF);
}

EWXWEXPORT(int,wxColour_GetInt)(wxColour* colour)
{
  int r = colour->Red();
  int g = colour->Green();
  int b = colour->Blue();
  return ((r << 16) | (g << 8) | b);
}

/* basic pixel manipulation */
EWXWEXPORT(void,wxcSetPixelRGB)(wxUint8* buffer,int width,int x,int y,int rgb)
{
  int indexR = 3*(width*y + x);
  buffer[indexR]   = rgb >> 16;
  buffer[indexR+1] = rgb >>  8;
  buffer[indexR+2] = rgb;
}

EWXWEXPORT(int,wxcGetPixelRGB)(wxUint8* buffer,int width,int x,int y)
{
  int indexR = 3*(width*y + x);
  int r,g,b;
  r = buffer[indexR];
  g = buffer[indexR+1];
  b = buffer[indexR+2];
  return ((r << 16) | (g << 8) | b);
}

EWXWEXPORT(void,wxcSetPixelRowRGB)(wxUint8* buffer,int width,int x,int y,int rgb0,int rgb1,int count)
{
  int r0  = ((rgb0 >> 16) && 0xFF);
  int g0  = ((rgb0 >>  8) && 0xFF);
  int b0  = (rgb0 && 0xFF);
  int start = 3*(width*y+x);
  int i;

  if (rgb0 == rgb1) {
    /* same color */
    for( i=0; i < count*3; i +=3) {
      buffer[start+i]   = r0;
      buffer[start+i+1] = g0;
      buffer[start+i+2] = b0;
    }
  }
  else {
    /* do linear interpolation of the color */
    int r1  = ((rgb1 >> 16) && 0xFF);
    int g1  = ((rgb1 >>  8) && 0xFF);
    int b1  = (rgb1 && 0xFF);

    int rd  = ((r1 - r0) << 16) / (count-1);
    int gd  = ((g1 - g0) << 16) / (count-1);
    int bd  = ((b1 - b0) << 16) / (count-1);

    int r   = r0 << 16;
    int g   = g0 << 16;
    int b   = b0 << 16;

    for( i = 0; i < count*3; i += 3 ) {
      buffer[start+i]   = (r >> 16);
      buffer[start+i+1] = (g >> 16);
      buffer[start+i+2] = (b >> 16);
      r += rd;
      g += gd;
      b += bd;
    }
  }
}

EWXWEXPORT(void,wxcInitPixelsRGB)(wxUint8* buffer,int width,int height,int rgb)
{
  int count        = width*height*3;
  wxUint8 r  = ((rgb >> 16) && 0xFF);
  wxUint8 g  = ((rgb >>  8) && 0xFF);
  wxUint8 b  = rgb && 0xFF;
  int i;

  if (r==g && g==b) {
    for( i=0; i < count; i++ ) {
      buffer[i] = r;
    }
  }
  else {
    for( i=0; i < count; i += 3) {
      buffer[i]   = r;
      buffer[i+1] = g;
      buffer[i+2] = b;
    }
  }
}

EWXWEXPORT(wxColour*,wxColour_CreateFromUnsignedInt)(unsigned int rgba)
{
  return new wxColour((rgba >> 24) & 0xFF, (rgba >> 16) & 0xFF, (rgba >> 8) & 0xFF, rgba & 0xFF);
}

EWXWEXPORT(unsigned int,wxColour_GetUnsignedInt)(wxColour* colour)
{
  int r = colour->Red();
  int g = colour->Green();
  int b = colour->Blue();
  int a = colour->Alpha();
  return ((r << 24) | (g << 16) | (b << 8) | a);
}

/* basic pixel manipulation */
EWXWEXPORT(void,wxcSetPixelRGBA)(wxUint8* buffer,int width,int x,int y,unsigned int rgba)
{
  unsigned int indexR = 4*(width*y + x);
  buffer[indexR]   = rgba >> 24;
  buffer[indexR+1] = rgba >> 16;
  buffer[indexR+2] = rgba >>  8;
  buffer[indexR+3] = rgba;
}

EWXWEXPORT(int,wxcGetPixelRGBA)(wxUint8* buffer,int width,int x,int y)
{
  unsigned int indexR = 4*(width*y + x);
  int r,g,b,a;
  r = buffer[indexR];
  g = buffer[indexR+1];
  b = buffer[indexR+2];
  a = buffer[indexR+3];
  return ((r << 24) | (g << 16) | (b << 8) | a);
}

EWXWEXPORT(void,wxcSetPixelRowRGBA)(wxUint8* buffer,int width,int x,int y,unsigned int rgba0,unsigned int rgba1,unsigned int count)
{
  int r0  = ((rgba0 >> 24) && 0xFF);
  int g0  = ((rgba0 >> 16) && 0xFF);
  int b0  = ((rgba0 >>  8) && 0xFF);
  int a0  = (rgba0 && 0xFF);
  unsigned int start = 4*(width*y+x);
  unsigned int i;

  if (rgba0 == rgba1) {
    /* same color */
    for( i=0; i < count*4; i +=4) {
      buffer[start+i]   = r0;
      buffer[start+i+1] = g0;
      buffer[start+i+2] = b0;
      buffer[start+i+3] = a0;
    }
  }
  else {
    /* do linear interpolation of the color */
    int r1  = ((rgba1 >> 24) && 0xFF);
    int g1  = ((rgba1 >> 16) && 0xFF);
    int b1  = ((rgba1 >>  8) && 0xFF);
    int a1  = (rgba1 && 0xFF);

    int rd  = ((r1 - r0) << 24) / (count-1);
    int gd  = ((g1 - g0) << 24) / (count-1);
    int bd  = ((b1 - b0) << 24) / (count-1);
    int ad  = ((a1 - a0) << 24) / (count-1);

    int r   = r0 << 24;
    int g   = g0 << 24;
    int b   = b0 << 24;
    int a   = b0 << 24;

    for( i = 0; i < count*4; i += 4 ) {
      buffer[start+i]   = (r >> 24);
      buffer[start+i+1] = (g >> 24);
      buffer[start+i+2] = (b >> 24);
      buffer[start+i+3] = (a >> 24);
      r += rd;
      g += gd;
      b += bd;
      a += ad;
    }
  }
}

EWXWEXPORT(void,wxcInitPixelsRGBA)(wxUint8* buffer,int width,int height,int rgba)
{
  unsigned int count        = width*height*4;
  wxUint8 r  = ((rgba >> 24) && 0xFF);
  wxUint8 g  = ((rgba >> 16) && 0xFF);
  wxUint8 b  = ((rgba >>  8) && 0xFF);
  wxUint8 a  = rgba && 0xFF;
  unsigned int i;

  if (r==g && g==b && b==a) {
    for( i=0; i < count; i++ ) {
      buffer[i] = r;
    }
  }
  else {
    for( i=0; i < count; i += 4) {
      buffer[i]   = r;
      buffer[i+1] = g;
      buffer[i+2] = b;
      buffer[i+3] = a;
    }
  }
}

}
<commit_msg>Replaced '&&' with '&'  several times in wxc/src/cpp/image.cpp<commit_after>#include <memory.h>
#include <string.h>

#include "wrapper.h"

extern "C"
{

/* bitmap/image helpers */
EWXWEXPORT(wxBitmap*,wxBitmap_CreateFromImage)(wxImage* image,int depth)
{
  return new wxBitmap(*image,depth);
}

EWXWEXPORT(wxImage*,wxImage_CreateFromDataEx)(int width,int height,wxUint8* data,bool isStaticData)
{
  return new wxImage(width, height, data, isStaticData);
}

EWXWEXPORT(void,wxImage_Delete)(wxImage* image)
{
  delete image;
}

/* colours */
EWXWEXPORT(wxColour*,wxColour_CreateFromInt)(int rgb)
{
  return new wxColour((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF);
}

EWXWEXPORT(int,wxColour_GetInt)(wxColour* colour)
{
  int r = colour->Red();
  int g = colour->Green();
  int b = colour->Blue();
  return ((r << 16) | (g << 8) | b);
}

/* basic pixel manipulation */
EWXWEXPORT(void,wxcSetPixelRGB)(wxUint8* buffer,int width,int x,int y,int rgb)
{
  int indexR = 3*(width*y + x);
  buffer[indexR]   = rgb >> 16;
  buffer[indexR+1] = rgb >>  8;
  buffer[indexR+2] = rgb;
}

EWXWEXPORT(int,wxcGetPixelRGB)(wxUint8* buffer,int width,int x,int y)
{
  int indexR = 3*(width*y + x);
  int r,g,b;
  r = buffer[indexR];
  g = buffer[indexR+1];
  b = buffer[indexR+2];
  return ((r << 16) | (g << 8) | b);
}

EWXWEXPORT(void,wxcSetPixelRowRGB)(wxUint8* buffer,int width,int x,int y,int rgb0,int rgb1,int count)
{
  int r0  = ((rgb0 >> 16) & 0xFF);
  int g0  = ((rgb0 >>  8) & 0xFF);
  int b0  = (rgb0 & 0xFF);
  int start = 3*(width*y+x);
  int i;

  if (rgb0 == rgb1) {
    /* same color */
    for( i=0; i < count*3; i +=3) {
      buffer[start+i]   = r0;
      buffer[start+i+1] = g0;
      buffer[start+i+2] = b0;
    }
  }
  else {
    /* do linear interpolation of the color */
    int r1  = ((rgb1 >> 16) & 0xFF);
    int g1  = ((rgb1 >>  8) & 0xFF);
    int b1  = (rgb1 & 0xFF);

    int rd  = ((r1 - r0) << 16) / (count-1);
    int gd  = ((g1 - g0) << 16) / (count-1);
    int bd  = ((b1 - b0) << 16) / (count-1);

    int r   = r0 << 16;
    int g   = g0 << 16;
    int b   = b0 << 16;

    for( i = 0; i < count*3; i += 3 ) {
      buffer[start+i]   = (r >> 16);
      buffer[start+i+1] = (g >> 16);
      buffer[start+i+2] = (b >> 16);
      r += rd;
      g += gd;
      b += bd;
    }
  }
}

EWXWEXPORT(void,wxcInitPixelsRGB)(wxUint8* buffer,int width,int height,int rgb)
{
  int count        = width*height*3;
  wxUint8 r  = ((rgb >> 16) & 0xFF);
  wxUint8 g  = ((rgb >>  8) & 0xFF);
  wxUint8 b  = rgb & 0xFF;
  int i;

  if (r==g && g==b) {
    for( i=0; i < count; i++ ) {
      buffer[i] = r;
    }
  }
  else {
    for( i=0; i < count; i += 3) {
      buffer[i]   = r;
      buffer[i+1] = g;
      buffer[i+2] = b;
    }
  }
}

EWXWEXPORT(wxColour*,wxColour_CreateFromUnsignedInt)(unsigned int rgba)
{
  return new wxColour((rgba >> 24) & 0xFF, (rgba >> 16) & 0xFF, (rgba >> 8) & 0xFF, rgba & 0xFF);
}

EWXWEXPORT(unsigned int,wxColour_GetUnsignedInt)(wxColour* colour)
{
  int r = colour->Red();
  int g = colour->Green();
  int b = colour->Blue();
  int a = colour->Alpha();
  return ((r << 24) | (g << 16) | (b << 8) | a);
}

/* basic pixel manipulation */
EWXWEXPORT(void,wxcSetPixelRGBA)(wxUint8* buffer,int width,int x,int y,unsigned int rgba)
{
  unsigned int indexR = 4*(width*y + x);
  buffer[indexR]   = rgba >> 24;
  buffer[indexR+1] = rgba >> 16;
  buffer[indexR+2] = rgba >>  8;
  buffer[indexR+3] = rgba;
}

EWXWEXPORT(int,wxcGetPixelRGBA)(wxUint8* buffer,int width,int x,int y)
{
  unsigned int indexR = 4*(width*y + x);
  int r,g,b,a;
  r = buffer[indexR];
  g = buffer[indexR+1];
  b = buffer[indexR+2];
  a = buffer[indexR+3];
  return ((r << 24) | (g << 16) | (b << 8) | a);
}

EWXWEXPORT(void,wxcSetPixelRowRGBA)(wxUint8* buffer,int width,int x,int y,unsigned int rgba0,unsigned int rgba1,unsigned int count)
{
  int r0  = ((rgba0 >> 24) & 0xFF);
  int g0  = ((rgba0 >> 16) & 0xFF);
  int b0  = ((rgba0 >>  8) & 0xFF);
  int a0  = (rgba0 & 0xFF);
  unsigned int start = 4*(width*y+x);
  unsigned int i;

  if (rgba0 == rgba1) {
    /* same color */
    for( i=0; i < count*4; i +=4) {
      buffer[start+i]   = r0;
      buffer[start+i+1] = g0;
      buffer[start+i+2] = b0;
      buffer[start+i+3] = a0;
    }
  }
  else {
    /* do linear interpolation of the color */
    int r1  = ((rgba1 >> 24) & 0xFF);
    int g1  = ((rgba1 >> 16) & 0xFF);
    int b1  = ((rgba1 >>  8) & 0xFF);
    int a1  = (rgba1 & 0xFF);

    int rd  = ((r1 - r0) << 24) / (count-1);
    int gd  = ((g1 - g0) << 24) / (count-1);
    int bd  = ((b1 - b0) << 24) / (count-1);
    int ad  = ((a1 - a0) << 24) / (count-1);

    int r   = r0 << 24;
    int g   = g0 << 24;
    int b   = b0 << 24;
    int a   = b0 << 24;

    for( i = 0; i < count*4; i += 4 ) {
      buffer[start+i]   = (r >> 24);
      buffer[start+i+1] = (g >> 24);
      buffer[start+i+2] = (b >> 24);
      buffer[start+i+3] = (a >> 24);
      r += rd;
      g += gd;
      b += bd;
      a += ad;
    }
  }
}

EWXWEXPORT(void,wxcInitPixelsRGBA)(wxUint8* buffer,int width,int height,int rgba)
{
  unsigned int count        = width*height*4;
  wxUint8 r  = ((rgba >> 24) & 0xFF);
  wxUint8 g  = ((rgba >> 16) & 0xFF);
  wxUint8 b  = ((rgba >>  8) & 0xFF);
  wxUint8 a  = rgba & 0xFF;
  unsigned int i;

  if (r==g && g==b && b==a) {
    for( i=0; i < count; i++ ) {
      buffer[i] = r;
    }
  }
  else {
    for( i=0; i < count; i += 4) {
      buffer[i]   = r;
      buffer[i+1] = g;
      buffer[i+2] = b;
      buffer[i+3] = a;
    }
  }
}

}
<|endoftext|>


<commit_before>#ifndef __ENVIRE_MAPS_LOCAL_MAP_HPP__
#define __ENVIRE_MAPS_LOCAL_MAP_HPP__

#include <base/Eigen.hpp>

#include <boost/shared_ptr.hpp>

#include <string>

namespace envire { namespace maps
{
    /**@brief LocalMapType
     * The type of the LocalMap
     */

    // TODO: do we need unknown type?
    enum LocalMapType
    {
        GRID_MAP = 0,
        GEOMETRIC_MAP = 1,
        MLS_MAP = 2,
        TOPOLOGICAL_MAP = 3
    };

    struct LocalMapData
    {
        // TODO: which map_type should be set by default
        LocalMapData()
            : offset(base::Transform3d::Identity()) {};

        /**  string id of this local map **/
        std::string id;

        /** Offset within the grid. The description of the local map frame.
         * It will be the offset with respect
         * to the bottom left corner (origin) of the map.
         * For the time being we use 3D transformation.
         *
         *
         **/
        base::Transform3d offset;

        /** map_type of this local map **/
        LocalMapType map_type;

        /** EPSG_code that provides the geo-localized coordinate system **/
        std::string EPSG_code;

        /** The EPSG code depends in the coordinate system used for the
         * local map "NONE" in case of not geo-referenced map.
         * Example: "EPSG::4978" for the World Geodetic System 1984 (WGS-84)
         * Example: "EPSG::3199" Spain - Canary Islands onshore and offshore.
         * with bounds are [-21.93W, -11.75E] and [24.6S, 11.75N] using the
         * World Geodetic System 1984 (WGS-84) coordinate reference system
         * (CRS).
         * Example: "EPSG::5243" ETRS89 / LCC Germany (E-N) Bremen area with
         * WGS084 CRS
         * Reference: https://www.epsg-registry.org **/
    };

    /**@brief LocalMap
     * Local map with respect to a given reference frame
     * A local map is the basic element to form a global
     * map (set of local maps structured in a tree).
     */
    class LocalMap
    {
        public:
            typedef boost::shared_ptr<LocalMap> Ptr;

            LocalMap()
                : data_ptr(new LocalMapData())
            {
            }

            /**
             * @brief [brief description]
             * @details to share same content (LocalMapData) between various instance of LocalMap
             *
             * @param data [description]
             */
            LocalMap(const boost::shared_ptr<LocalMapData> &data)
                : data_ptr(data)
            {
            }

            /**
             * @brief make copy without sharing the content
             * @details the copy instance owns a new content (LocalMapData)
             *
             * @param other [description]
             */
            LocalMap(const LocalMap& other)
                : data_ptr(new LocalMapData(*(other.data_ptr.get())))
            {
            }

            virtual ~LocalMap() {};

            const std::string& getId() const
            {
                return data_ptr->id;
            }

            std::string& getId()
            {
                return data_ptr->id;
            }

            const base::Transform3d& getOffset() const
            {
                return data_ptr->offset;
            }

            base::Transform3d& getOffset()
            {
                return data_ptr->offset;
            }

            const boost::shared_ptr<LocalMapData>& getLocalMap() const
            {
                return data_ptr;
            }

        protected:
            boost::shared_ptr<LocalMapData> data_ptr;
    };
}}
#endif // __ENVIRE_MAPS_LOCAL_MAP_HPP__
<commit_msg>src: default LocalMap information and constructor<commit_after>#ifndef __ENVIRE_MAPS_LOCAL_MAP_HPP__
#define __ENVIRE_MAPS_LOCAL_MAP_HPP__

#include <base/Eigen.hpp>

#include <boost/shared_ptr.hpp>

#include <string>

namespace envire { namespace maps
{
    /**@brief LocalMapType
     * The type of the LocalMap
     */

    enum LocalMapType
    {
        GRID_MAP = 0,
        GEOMETRIC_MAP = 1,
        MLS_MAP = 2,
        TOPOLOGICAL_MAP = 3
    };

    const std::string DEFAULT_GRID_MAP_ID = "DEFAULT_GRID_MAP";
    const std::string DEFAULT_EPSG_CODE = "NONE";

    struct LocalMapData
    {
        /** Grid map is the map by default **/
        LocalMapData()
            :id(DEFAULT_GRID_MAP_ID),
            offset(base::Transform3d::Identity()),
            map_type(GRID_MAP),
            EPSG_code(DEFAULT_EPSG_CODE){};

        LocalMapData(const std::string _id, const base::Transform3d &_offset,
                    const LocalMapType _map_type, const std::string _EPSG_code)
            :id(_id), offset(_offset), map_type(_map_type), EPSG_code(_EPSG_code) {};

        /**  string id of this local map **/
        std::string id;

        /** Offset within the grid. The description of the local map frame.
         * It will be the offset with respect
         * to the bottom left corner (origin) of the map.
         * For the time being we use 3D transformation.
         *
         *
         **/
        base::Transform3d offset;

        /** map_type of this local map **/
        LocalMapType map_type;

        /** EPSG_code that provides the geo-localized coordinate system **/
        std::string EPSG_code;

        /** The EPSG code depends in the coordinate system used for the
         * local map "NONE" in case of not geo-referenced map.
         * Example: "EPSG::4978" for the World Geodetic System 1984 (WGS-84)
         * Example: "EPSG::3199" Spain - Canary Islands onshore and offshore.
         * with bounds are [-21.93W, -11.75E] and [24.6S, 11.75N] using the
         * World Geodetic System 1984 (WGS-84) coordinate reference system
         * (CRS).
         * Example: "EPSG::5243" ETRS89 / LCC Germany (E-N) Bremen area with
         * WGS084 CRS
         * Reference: https://www.epsg-registry.org **/
    };

    /**@brief LocalMap
     * Local map with respect to a given reference frame
     * A local map is the basic element to form a global
     * map (set of local maps structured in a tree).
     */
    class LocalMap
    {
        public:
            typedef boost::shared_ptr<LocalMap> Ptr;

            LocalMap()
                : data_ptr(new LocalMapData())
            {
            }

            /**
             * @brief [brief description]
             * @details to share same content (LocalMapData) between various instance of LocalMap
             *
             * @param data [description]
             */
            LocalMap(const boost::shared_ptr<LocalMapData> &data)
                : data_ptr(data)
            {
            }

            /**
             * @brief make copy without sharing the content
             * @details the copy instance owns a new content (LocalMapData)
             *
             * @param other [description]
             */
            LocalMap(const LocalMap& other)
                : data_ptr(new LocalMapData(*(other.data_ptr.get())))
            {
            }

            virtual ~LocalMap() {};

            const std::string& getId() const
            {
                return data_ptr->id;
            }

            std::string& getId()
            {
                return data_ptr->id;
            }

            const base::Transform3d& getOffset() const
            {
                return data_ptr->offset;
            }

            base::Transform3d& getOffset()
            {
                return data_ptr->offset;
            }

            const boost::shared_ptr<LocalMapData>& getLocalMap() const
            {
                return data_ptr;
            }

        protected:
            boost::shared_ptr<LocalMapData> data_ptr;
    };
}}
#endif // __ENVIRE_MAPS_LOCAL_MAP_HPP__
<|endoftext|>


<commit_before>#include "LuaTable.h"
#include "LuaObjectImpl.h"

LuaTable::LuaTable(LuaState* L)
	:LuaObject(L)
{

}

LuaTable::LuaTable(LuaObjectImpl* impl)
	:LuaObject(impl)
{

}

LuaTable::LuaTable(const LuaObject& rfs)
	:LuaObject(rfs)
{
}

LuaTable::LuaTable(const LuaTable& rfs)
	:LuaObject(rfs)
{
}

bool LuaTable::isValid()
{
	return getType()==LUA_TTABLE;
}

LuaObject LuaTable::getTable(const char* key)
{
	assert(isValid());
	return LuaObjectImpl::createGetTable(m_ptr->getCppLuaState(),m_ptr,key);
}

LuaObject LuaTable::getTable(lua_Integer key)
{
	assert(isValid());
	return LuaObjectImpl::createGetTable(m_ptr->getCppLuaState(),m_ptr,key);
}

LuaObject LuaTable::operator[](const char* key)
{
	assert(isValid());
	return LuaObjectImpl::createGetTable(m_ptr->getCppLuaState(),m_ptr,key);
}

LuaObject LuaTable::operator[](lua_Integer idx)
{
	assert(isValid());
	return LuaObjectImpl::createGetTable(m_ptr->getCppLuaState(),m_ptr,idx);
}

bool LuaTable::setTable(const char* key,LuaObject val)
{
	if(isValid())
	{
		lua_State* L=m_ptr->getLuaState();
		lua_pushstring(L,key);//key
		lua_pushvalue(L,val.getIndex());//value
		lua_settable(L,getIndex());
		return true;
	}
	return false;
}

bool LuaTable::setTable(lua_Integer key,LuaObject val)
{
	if(isValid())
	{
		lua_State* L=m_ptr->getLuaState();
		lua_pushinteger(L,key);//key
		lua_pushvalue(L,val.getIndex());//value
		lua_settable(L,getIndex());
		return true;
	}
	return false;
}<commit_msg>fixbug<commit_after>#include "LuaTable.h"
#include "LuaObjectImpl.h"

LuaTable::LuaTable(LuaState* L)
	:LuaObject(L)
{

}

LuaTable::LuaTable(LuaObjectImpl* impl)
	:LuaObject(impl)
{

}

LuaTable::LuaTable(const LuaObject& rfs)
	:LuaObject(rfs)
{
}

LuaTable::LuaTable(const LuaTable& rfs)
	:LuaObject(rfs)
{
}

bool LuaTable::isValid()
{
	return getType()==LUA_TTABLE;
}

LuaObject LuaTable::getTable(const char* key)
{
	assert(isValid());
	return LuaObjectImpl::createGetTable(m_ptr->getCppLuaState(),m_ptr,key);
}

LuaObject LuaTable::getTable(lua_Integer key)
{
	assert(isValid());
	return LuaObjectImpl::createGetTable(m_ptr->getCppLuaState(),m_ptr,key);
}

LuaObject LuaTable::operator[](const char* key)
{
	assert(isValid());
	return LuaObjectImpl::createGetTable(m_ptr->getCppLuaState(),m_ptr,key);
}

LuaObject LuaTable::operator[](lua_Integer idx)
{
	assert(isValid());
	return LuaObjectImpl::createGetTable(m_ptr->getCppLuaState(),m_ptr,idx);
}

bool LuaTable::setTable(const char* key,LuaObject val)
{
	if(isValid())
	{
		lua_State* L=m_ptr->getLuaState();
		lua_pushstring(L,key);//key
		if(val.isNone())
			lua_pushnil(L);
		else
			lua_pushvalue(L,val.getIndex());//value
		lua_settable(L,getIndex());
		return true;
	}
	return false;
}

bool LuaTable::setTable(lua_Integer key,LuaObject val)
{
	if(isValid())
	{
		lua_State* L=m_ptr->getLuaState();
		lua_pushinteger(L,key);//key
		if(val.isNone())
			lua_pushnil(L);
		else
			lua_pushvalue(L,val.getIndex());//value
		lua_settable(L,getIndex());
		return true;
	}
	return false;
}<|endoftext|>


<commit_before>// 'operator delete' redeclared without throw()

// originally found in package drscheme_1:208-1

// %%% progress: 0ms: done type checking (1 ms)
// a.ii:3:6: error: prior declaration of `operator delete' at <init>:1:1 had type `void ()(void *p) throw()', but this one uses `void ()(void */*anon*/)'
// typechecking results:
//   errors:   1
//   warnings: 0

void operator delete(void *) {
}
<commit_msg>(Comment)<commit_after>// 'operator delete' redeclared without throw()

// originally found in package drscheme_1:208-1

// a.ii:3:6: error: prior declaration of `operator delete' at <init>:1:1 had
// type `void ()(void *p) throw()', but this one uses `void ()(void
// */*anon*/)'

void operator delete(void *) {
}
<|endoftext|>


<commit_before>/*! \file MatTools.cpp
    \brief Implements the MatTools class used by the Generic Repository
    \author Kathryn D. Huff
 */
#include <iostream>
#include <fstream>
#include <deque>
#include <time.h>
#include <assert.h>

#include "CycException.h"
#include "CycLimits.h"
#include "MatTools.h"
#include "Material.h"
#include "Logger.h"
#include "Timer.h"

using namespace std;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pair<IsoVector, double> MatTools::sum_mats(deque<mat_rsrc_ptr> mats){
  IsoVector vec;
  CompMapPtr sum_comp = CompMapPtr(new CompMap(MASS));
  double tot = 0;
  double kg = 0;

  if( !mats.empty() ){
    CompMapPtr comp_to_add;
    deque<mat_rsrc_ptr>::iterator mat;
    int iso;
    CompMap::const_iterator comp;

    for(mat = mats.begin(); mat != mats.end(); ++mat){
      kg = (*mat)->mass(MassUnit(KG));
      tot += kg;
      comp_to_add = (*mat)->isoVector().comp();
      comp_to_add->massify();
      for(comp = (*comp_to_add).begin(); comp != (*comp_to_add).end(); ++comp) {
        iso = comp->first;
        if(sum_comp->count(iso)!=0) {
          (*sum_comp)[iso] += (comp->second)*kg;
        } else {
          (*sum_comp)[iso] = (comp->second)*kg;
        }
      }
    }
  } else {
    (*sum_comp)[92235] = 0;
  }
  vec = IsoVector(sum_comp);
  return make_pair(vec, tot);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mat_rsrc_ptr MatTools::extract(const CompMapPtr comp_to_rem, double kg_to_rem, deque<mat_rsrc_ptr>& mat_list){
  comp_to_rem->normalize();
  mat_rsrc_ptr left_over = mat_rsrc_ptr(new Material(comp_to_rem));
  left_over->setQuantity(0);
  while(!mat_list.empty()) {
    left_over->absorb(mat_list.back());
    mat_list.pop_back();
  }
  mat_rsrc_ptr to_ret = left_over->extract(comp_to_rem, kg_to_rem);
  if(left_over->mass(KG) > cyclus::eps_rsrc()){
    mat_list.push_back(left_over);
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap MatTools::comp_to_conc_map(CompMapPtr comp, double mass, double vol){
  MatTools::validate_finite_pos(vol);
  MatTools::validate_finite_pos(mass);

  IsoConcMap to_ret;
  if( vol==0 ) {
    to_ret = zeroConcMap();
  } else {
    int iso;
    double m_iso;
    CompMap::const_iterator it;
    it=(*comp).begin();
    while(it!= (*comp).end() ){
      iso = (*it).first;
      m_iso=((*it).second)*mass;
      to_ret.insert(make_pair(iso, m_iso/vol));
      ++it;
    }
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap MatTools::zeroConcMap(){
  IsoConcMap to_ret;
  to_ret[92235] = 0;
  return to_ret;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pair<CompMapPtr, double> MatTools::conc_to_comp_map(IsoConcMap conc, double vol){
  MatTools::validate_finite_pos(vol);

  CompMapPtr comp = CompMapPtr(new CompMap(MASS));
  double mass(0);
  int iso;
  double c_iso;
  double m_iso;
  CompMap::const_iterator it;
  it=conc.begin();
  while(it!= conc.end() ){
    iso = (*it).first;
    c_iso=((*it).second);
    m_iso = c_iso*vol;
    (*comp)[iso] = m_iso;
    mass+=m_iso;
    ++it;
  }
  (*comp).normalize();
  pair<CompMapPtr, double> to_ret = make_pair(CompMapPtr(comp), mass);
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_f(double V_T, double theta){
  validate_percent(theta);
  validate_finite_pos(V_T);
  return theta*V_T;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_ff(double V_T, double theta, double d){
  validate_percent(d);
  return d*V_f(V_T, theta);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_mf(double V_T, double theta, double d){
  return (V_f(V_T,theta) - V_ff(V_T, theta, d));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_s(double V_T, double theta){
  return (V_T - V_f(V_T, theta));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_ds(double V_T, double theta, double d){
  validate_percent(d);
  return d*V_s(V_T, theta);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_ms(double V_T, double theta, double d){
  return (V_s(V_T, theta) - V_ds(V_T, theta, d));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MatTools::validate_percent(double per){
  if( per <= 1 && per >= 0 ){
    return;
  } else if ( per < 0) {
    throw CycRangeException("The value is not a valid percent. It is less than zero.");
  } else if ( per > 1) {
    throw CycRangeException("The value is not a valid percent. It is greater than one.");
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MatTools::validate_finite_pos(double pos){
  if ( pos >= numeric_limits<double>::infinity() ) {
    throw CycRangeException("The value is not positive and finite. It is infinite.");
  }
  validate_pos(pos);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MatTools::validate_pos(double pos){
  if ( pos < 0) {
    throw CycRangeException("The value is not positive and finite. It is less than zero.");
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MatTools::validate_nonzero(double nonzero){
  if ( nonzero == 0 )
    throw CycRangeException("The value is zero.");
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap MatTools::scaleConcMap(IsoConcMap C_0, double scalar){
  MatTools::validate_finite_pos(scalar);
  double orig;
  IsoConcMap::iterator it;
  for(it = C_0.begin(); it != C_0.end(); ++it) {
    orig = C_0[(*it).first];
    C_0[(*it).first] = orig*scalar;
  }
  return C_0;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap MatTools::addConcMaps(IsoConcMap orig, IsoConcMap to_add){
  IsoConcMap to_ret;
  IsoConcMap::iterator it;
  for(it = orig.begin(); it != orig.end(); ++it) {
    Iso iso=(*it).first;
    if(to_add.find(iso) != to_add.end()) {
      to_ret[iso] = (*it).second + to_add[iso];
    } else {
      to_ret[iso] = (*it).second;
    }
  }
  for(it = to_add.begin(); it != to_add.end(); ++it) {
    Iso iso=(*it).first;
    if(orig.find(iso) == orig.end()) {
      to_ret[iso] = (*it).second;
    }
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int MatTools::isoToElem(int iso) {
  int N = iso % 1000;
  return (iso-N)/1000;
}
<commit_msg>extraction in grams<commit_after>/*! \file MatTools.cpp
    \brief Implements the MatTools class used by the Generic Repository
    \author Kathryn D. Huff
 */
#include <iostream>
#include <fstream>
#include <deque>
#include <time.h>
#include <assert.h>

#include "CycException.h"
#include "CycLimits.h"
#include "MatTools.h"
#include "Material.h"
#include "Logger.h"
#include "Timer.h"

using namespace std;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pair<IsoVector, double> MatTools::sum_mats(deque<mat_rsrc_ptr> mats){
  IsoVector vec;
  CompMapPtr sum_comp = CompMapPtr(new CompMap(MASS));
  double tot = 0;
  double kg = 0;

  if( !mats.empty() ){
    CompMapPtr comp_to_add;
    deque<mat_rsrc_ptr>::iterator mat;
    int iso;
    CompMap::const_iterator comp;

    for(mat = mats.begin(); mat != mats.end(); ++mat){
      kg = (*mat)->mass(MassUnit(KG));
      tot += kg;
      comp_to_add = (*mat)->isoVector().comp();
      comp_to_add->massify();
      for(comp = (*comp_to_add).begin(); comp != (*comp_to_add).end(); ++comp) {
        iso = comp->first;
        if(sum_comp->count(iso)!=0) {
          (*sum_comp)[iso] += (comp->second)*kg;
        } else {
          (*sum_comp)[iso] = (comp->second)*kg;
        }
      }
    }
  } else {
    (*sum_comp)[92235] = 0;
  }
  vec = IsoVector(sum_comp);
  return make_pair(vec, tot);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mat_rsrc_ptr MatTools::extract(const CompMapPtr comp_to_rem, double kg_to_rem, deque<mat_rsrc_ptr>& mat_list){
  comp_to_rem->normalize();
  mat_rsrc_ptr left_over = mat_rsrc_ptr(new Material(comp_to_rem));
  left_over->setQuantity(0);
  while(!mat_list.empty()) {
    left_over->absorb(mat_list.back());
    mat_list.pop_back();
  }
  mat_rsrc_ptr to_ret = left_over->extract(comp_to_rem, kg_to_rem*1000, G);
  if(left_over->mass(KG) > cyclus::eps_rsrc()){
    mat_list.push_back(left_over);
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap MatTools::comp_to_conc_map(CompMapPtr comp, double mass, double vol){
  MatTools::validate_finite_pos(vol);
  MatTools::validate_finite_pos(mass);

  IsoConcMap to_ret;
  if( vol==0 ) {
    to_ret = zeroConcMap();
  } else {
    int iso;
    double m_iso;
    CompMap::const_iterator it;
    it=(*comp).begin();
    while(it!= (*comp).end() ){
      iso = (*it).first;
      m_iso=((*it).second)*mass;
      to_ret.insert(make_pair(iso, m_iso/vol));
      ++it;
    }
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap MatTools::zeroConcMap(){
  IsoConcMap to_ret;
  to_ret[92235] = 0;
  return to_ret;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pair<CompMapPtr, double> MatTools::conc_to_comp_map(IsoConcMap conc, double vol){
  MatTools::validate_finite_pos(vol);

  CompMapPtr comp = CompMapPtr(new CompMap(MASS));
  double mass(0);
  int iso;
  double c_iso;
  double m_iso;
  CompMap::const_iterator it;
  it=conc.begin();
  while(it!= conc.end() ){
    iso = (*it).first;
    c_iso=((*it).second);
    m_iso = c_iso*vol;
    (*comp)[iso] = m_iso;
    mass+=m_iso;
    ++it;
  }
  (*comp).normalize();
  pair<CompMapPtr, double> to_ret = make_pair(CompMapPtr(comp), mass);
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_f(double V_T, double theta){
  validate_percent(theta);
  validate_finite_pos(V_T);
  return theta*V_T;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_ff(double V_T, double theta, double d){
  validate_percent(d);
  return d*V_f(V_T, theta);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_mf(double V_T, double theta, double d){
  return (V_f(V_T,theta) - V_ff(V_T, theta, d));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_s(double V_T, double theta){
  return (V_T - V_f(V_T, theta));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_ds(double V_T, double theta, double d){
  validate_percent(d);
  return d*V_s(V_T, theta);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double MatTools::V_ms(double V_T, double theta, double d){
  return (V_s(V_T, theta) - V_ds(V_T, theta, d));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MatTools::validate_percent(double per){
  if( per <= 1 && per >= 0 ){
    return;
  } else if ( per < 0) {
    throw CycRangeException("The value is not a valid percent. It is less than zero.");
  } else if ( per > 1) {
    throw CycRangeException("The value is not a valid percent. It is greater than one.");
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MatTools::validate_finite_pos(double pos){
  if ( pos >= numeric_limits<double>::infinity() ) {
    throw CycRangeException("The value is not positive and finite. It is infinite.");
  }
  validate_pos(pos);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MatTools::validate_pos(double pos){
  if ( pos < 0) {
    throw CycRangeException("The value is not positive and finite. It is less than zero.");
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MatTools::validate_nonzero(double nonzero){
  if ( nonzero == 0 )
    throw CycRangeException("The value is zero.");
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap MatTools::scaleConcMap(IsoConcMap C_0, double scalar){
  MatTools::validate_finite_pos(scalar);
  double orig;
  IsoConcMap::iterator it;
  for(it = C_0.begin(); it != C_0.end(); ++it) {
    orig = C_0[(*it).first];
    C_0[(*it).first] = orig*scalar;
  }
  return C_0;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IsoConcMap MatTools::addConcMaps(IsoConcMap orig, IsoConcMap to_add){
  IsoConcMap to_ret;
  IsoConcMap::iterator it;
  for(it = orig.begin(); it != orig.end(); ++it) {
    Iso iso=(*it).first;
    if(to_add.find(iso) != to_add.end()) {
      to_ret[iso] = (*it).second + to_add[iso];
    } else {
      to_ret[iso] = (*it).second;
    }
  }
  for(it = to_add.begin(); it != to_add.end(); ++it) {
    Iso iso=(*it).first;
    if(orig.find(iso) == orig.end()) {
      to_ret[iso] = (*it).second;
    }
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int MatTools::isoToElem(int iso) {
  int N = iso % 1000;
  return (iso-N)/1000;
}
<|endoftext|>


<commit_before><commit_msg>Spiral1 Soltuion from interviewbit<commit_after><|endoftext|>


<commit_before>/** @file main.cpp
 *  @brief
 *
 *  @author Viacheslav Kroilov (metopa) <slavakroilov@gmail.com>
 */

#include <iostream>
#include "murmurhash2functor.h"

int main() {
	mmh2::MurmurHash2<int> h;
	std::cout << h(700) << std::endl;
	return 0;
}
<commit_msg>Update example<commit_after>/** @file main.cpp
 *  @brief
 *
 *  @author Viacheslav Kroilov (metopa) <slavakroilov@gmail.com>
 */

#include <iostream>
#include "murmurhash2functor.h"
#include "murmurhash2_stl_specializations.h"

int main() {
	std::cout << mmh2::getMurmurHash2(std::string("")) << std::endl;
	std::cout << mmh2::getMurmurHash2(std::string("AB")) << std::endl;
	std::cout << mmh2::getMurmurHash2(std::string("BA")) << std::endl;
	std::cout << mmh2::getMurmurHash2(std::make_pair(0.f, 0.)) << std::endl;
	std::cout << mmh2::getMurmurHash2(std::make_tuple(0., 0.)) << std::endl;
	std::cout << mmh2::getMurmurHash2(std::make_tuple(-0., 0.)) << std::endl;
	std::cout << mmh2::getMurmurHash2(std::make_tuple(0.)) << std::endl;
	std::cout << mmh2::getMurmurHash2(std::make_tuple(0., 0., 0.)) << std::endl;
	std::cout << mmh2::getMurmurHash2(std::make_tuple(1., 0.)) << std::endl;
	std::cout << mmh2::getMurmurHash2(std::make_tuple(0., 1.)) << std::endl;
	std::cout << mmh2::getMurmurHash2(std::make_tuple(1., 1.)) << std::endl;
	std::cout << mmh2::getMurmurHash2(std::make_tuple(-1., 1.)) << std::endl;
	return 0;
}
<|endoftext|>