<commit_before>#include "viewer/interaction/ui2d.hh"
#include "viewer/primitives/simple_geometry.hh"
#include "viewer/window_3d.hh"

#include "estimation/calibration/nonlinear_camera_model.hh"
#include "estimation/vision/sample_bilinear.hh"

#include "estimation/visualization/visualize_camera_frustum.hh"

#include "geometry/plane.hh"

#include "viewer/primitives/image.hh"
#include "viewer/primitives/scene_tree.hh"

#include <opencv2/aruco.hpp>
#include <opencv2/opencv.hpp>

namespace estimation {
namespace {

constexpr float FIDUCIAL_WIDTH_METERS = 99.0 / 1000;
constexpr float FIDUCIAL_GAP_WIDTH_METERS = 50.0 / 1000;

inline cv::Ptr<cv::aruco::Dictionary> get_aruco_dictionary() {
  return cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_250);
}

inline cv::Ptr<cv::aruco::GridBoard> get_aruco_board() {
  return cv::aruco::GridBoard::create(4, 4, FIDUCIAL_WIDTH_METERS,
                                      FIDUCIAL_GAP_WIDTH_METERS, get_aruco_dictionary());
}

NonlinearCameraModel make_model() {
  estimation::ProjectionCoefficients proj_coeffs;
  proj_coeffs.fx = 279.76;
  proj_coeffs.fy = 280.034;
  proj_coeffs.cx = 235.992;
  proj_coeffs.cy = 141.951;
  proj_coeffs.k1 = 0.0669332;
  proj_coeffs.k2 = -0.224151;
  proj_coeffs.p1 = 0.00993584;
  proj_coeffs.p2 = 0.00848696;
  proj_coeffs.k3 = 0.10179;
  proj_coeffs.rows = 270;
  proj_coeffs.cols = 480;

  const NonlinearCameraModel model(proj_coeffs);
  return model;
}

cv::Mat render_at_pose(const SE3& camera_from_fiducial, const cv::Mat& fiducial_image) {
  const geometry::Plane im_plane_fiducial_frame{
      .origin = jcc::Vec3::Zero(),        //
      .normal = geometry::Unit3::UnitZ()  //
  };

  const auto im_plane_camera_frame = camera_from_fiducial * im_plane_fiducial_frame;

  const auto view = viewer::get_window3d("Calibration");
  const auto ui2d = view->add_primitive<viewer::Ui2d>();
  const auto geo = view->add_primitive<viewer::SimpleGeometry>();

  geo->add_axes({camera_from_fiducial});

  const auto model = make_model();

  cv::Mat out_image(cv::Size(480, 270), CV_8UC1, cv::Scalar(0));
  // cv::Mat out_image(cv::Size(48, 27), CV_8UC1);

  const double width_per_height = out_image.cols / static_cast<double>(out_image.rows);

  ui2d->add_image(fiducial_image, 1.0);

  jcc::Vec3 intersection_camera_frame;
  for (int u = 0; u < out_image.cols; ++u) {
    for (int v = 0; v < out_image.rows; ++v) {
      const auto optl_ray = model.unproject(jcc::Vec2(u + 0.5, v + 0.5));
      // Could not produce a projection
      if (!optl_ray) {
        std::cout << "Lost a ray at : " << u << ", " << v << std::endl;
        continue;
      }

      const bool intersected =
          im_plane_camera_frame.intersect(*optl_ray, out(intersection_camera_frame));

      // Did not hit the plane
      if (!intersected) {
        continue;
      }

      const jcc::Vec3 intersection_fiducial_frame =
          camera_from_fiducial.inverse() * intersection_camera_frame;

      const bool out_x = intersection_fiducial_frame.x() < 0.0 ||
                         intersection_fiducial_frame.x() >= width_per_height;
      const bool out_y =
          intersection_fiducial_frame.y() < 0.0 || intersection_fiducial_frame.y() >= 1.0;
      // Out of the frame
      if (out_x || out_y) {
        continue;
      }

      const jcc::Vec2 pt_fiducial_image_frame(intersection_fiducial_frame.x(),
                                              intersection_fiducial_frame.y());

      ui2d->add_point({pt_fiducial_image_frame, jcc::Vec4(0.0, 1.0, 0.0, 1.0), 1.0});

      // const double result =
      // interpolate_nearest(fiducial_image, pt_fiducial_image_frame * model.rows());
      const double result = interpolate_bilinear(
          fiducial_image, pt_fiducial_image_frame * fiducial_image.rows);

      out_image.at<uint8_t>(v, u) = static_cast<uint8_t>(result);

      // if ((v % 10 == 0) && (u % 10 == 0)) {
      if ((v % 50 == 0)) {
        geo->add_ray(*optl_ray, 5.0);
        geo->flush();
      }
    }
    if (u % 50 == 0) {
      // ui2d->add_image(out_image, 1.0);
      ui2d->flush();
      view->spin_until_step();
    }
  }
  ui2d->clear();
  ui2d->add_image(out_image, 1.0);
  ui2d->flip();
  view->spin_until_step();

  return out_image;
}

}  // namespace

void go() {
  const auto view = viewer::get_window3d("Calibration");
  const auto ui2d = view->add_primitive<viewer::Ui2d>();
  const auto geo = view->add_primitive<viewer::SimpleGeometry>();

  visualize_camera_frustum(*geo, *ui2d, make_model());
  geo->flip();
  ui2d->flip();

  cv::Mat board_image;
  get_aruco_board()->draw(cv::Size(900, 900), board_image, 50, 1);
  const SE3 camera_from_fiducial(SO3(), jcc::Vec3(0.0, 0.0, 1.0));

  {
    const auto image_tree = view->add_primitive<viewer::SceneTree>();

    const auto board_texture_image =
        std::make_shared<viewer::Image>(board_image, 1.0, 1.0);

    image_tree->add_primitive("root", camera_from_fiducial, "fiducial",
                              board_texture_image);
  }

  render_at_pose(camera_from_fiducial, board_image);

  // OK: Now render some good bullshit
  jcc::Success() << "Finished rendering." << std::endl;
  view->flip();
  view->spin_until_step();
  jcc::Success() << "Done." << std::endl;
}
}  // namespace estimation

int main() {
  estimation::go();
}<commit_msg>Add rolling shutter to sample_demo<commit_after>#include "viewer/interaction/ui2d.hh"
#include "viewer/primitives/simple_geometry.hh"
#include "viewer/window_3d.hh"

#include "estimation/calibration/nonlinear_camera_model.hh"
#include "estimation/vision/sample_bilinear.hh"

#include "estimation/visualization/visualize_camera_frustum.hh"

#include "geometry/plane.hh"

#include "viewer/primitives/image.hh"
#include "viewer/primitives/scene_tree.hh"

#include <opencv2/aruco.hpp>
#include <opencv2/opencv.hpp>

namespace estimation {
namespace {

constexpr float FIDUCIAL_WIDTH_METERS = 99.0 / 1000;
constexpr float FIDUCIAL_GAP_WIDTH_METERS = 50.0 / 1000;

inline cv::Ptr<cv::aruco::Dictionary> get_aruco_dictionary() {
  return cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_250);
}

inline cv::Ptr<cv::aruco::GridBoard> get_aruco_board() {
  return cv::aruco::GridBoard::create(4, 4, FIDUCIAL_WIDTH_METERS,
                                      FIDUCIAL_GAP_WIDTH_METERS, get_aruco_dictionary());
}

NonlinearCameraModel make_model() {
  estimation::ProjectionCoefficients proj_coeffs;
  proj_coeffs.fx = 279.76;
  proj_coeffs.fy = 280.034;
  proj_coeffs.cx = 235.992;
  proj_coeffs.cy = 141.951;
  proj_coeffs.k1 = 0.0669332;
  proj_coeffs.k2 = -0.224151;
  proj_coeffs.p1 = 0.00993584;
  proj_coeffs.p2 = 0.00848696;
  proj_coeffs.k3 = 0.10179;
  proj_coeffs.rows = 270;
  proj_coeffs.cols = 480;

  const NonlinearCameraModel model(proj_coeffs);
  return model;
}

cv::Mat normal_render_at_pose(const SE3& camera_from_fiducial,
                              const cv::Mat& fiducial_image) {
  const geometry::Plane im_plane_fiducial_frame{
      .origin = jcc::Vec3::Zero(),        //
      .normal = geometry::Unit3::UnitZ()  //
  };

  const auto im_plane_camera_frame = camera_from_fiducial * im_plane_fiducial_frame;

  const auto model = make_model();

  cv::Mat out_image(cv::Size(480, 270), CV_8UC1, cv::Scalar(0));

  const double width_per_height = out_image.cols / static_cast<double>(out_image.rows);

  jcc::Vec3 intersection_camera_frame;
  for (int u = 0; u < out_image.cols; ++u) {
    for (int v = 0; v < out_image.rows; ++v) {
      const auto optl_ray = model.unproject(jcc::Vec2(u + 0.5, v + 0.5));
      // Could not produce a projection
      if (!optl_ray) {
        continue;
      }

      const bool intersected =
          im_plane_camera_frame.intersect(*optl_ray, out(intersection_camera_frame));

      // Did not hit the plane
      if (!intersected) {
        continue;
      }

      const jcc::Vec3 intersection_fiducial_frame =
          camera_from_fiducial.inverse() * intersection_camera_frame;

      const bool out_x = intersection_fiducial_frame.x() < 0.0 ||
                         intersection_fiducial_frame.x() >= width_per_height;
      const bool out_y =
          intersection_fiducial_frame.y() < 0.0 || intersection_fiducial_frame.y() >= 1.0;
      // Out of the frame
      if (out_x || out_y) {
        continue;
      }

      const jcc::Vec2 pt_fiducial_image_frame(intersection_fiducial_frame.x(),
                                              intersection_fiducial_frame.y());

      // const double result =
      // interpolate_nearest(fiducial_image, pt_fiducial_image_frame * model.rows());
      const double result = interpolate_bilinear(
          fiducial_image, pt_fiducial_image_frame * fiducial_image.rows);

      out_image.at<uint8_t>(v, u) = static_cast<uint8_t>(result);
    }
  }

  return out_image;
}

cv::Mat moving_render_at_pose(const SE3& camera_from_fiducial_0,
                              const jcc::Vec6 fiducial_velocity,
                              const double lines_per_second,
                              const cv::Mat& fiducial_image) {
  const geometry::Plane im_plane_fiducial_frame{
      .origin = jcc::Vec3::Zero(),        //
      .normal = geometry::Unit3::UnitZ()  //
  };

  const auto view = viewer::get_window3d("Calibration");
  const auto ui2d = view->add_primitive<viewer::Ui2d>();
  const auto geo = view->add_primitive<viewer::SimpleGeometry>();

  geo->add_axes({camera_from_fiducial_0});

  const auto model = make_model();

  cv::Mat out_image(cv::Size(480, 270), CV_8UC1, cv::Scalar(0));
  // cv::Mat out_image(cv::Size(48, 27), CV_8UC1);

  const double width_per_height =
      fiducial_image.cols / static_cast<double>(fiducial_image.rows);

  ui2d->add_image(fiducial_image, 1.0);

  jcc::Vec3 intersection_camera_frame;
  for (int u = 0; u < out_image.cols; ++u) {
    const double t = u * lines_per_second;
    const SE3 camera_from_fiducial =
        SE3::exp(fiducial_velocity * t) * camera_from_fiducial_0;

    const auto im_plane_camera_frame = camera_from_fiducial * im_plane_fiducial_frame;

    geo->add_axes({camera_from_fiducial});

    for (int v = 0; v < out_image.rows; ++v) {
      const auto optl_ray = model.unproject(jcc::Vec2(u + 0.5, v + 0.5));
      // Could not produce a projection
      if (!optl_ray) {
        std::cout << "Lost a ray at : " << u << ", " << v << std::endl;
        continue;
      }

      const bool intersected =
          im_plane_camera_frame.intersect(*optl_ray, out(intersection_camera_frame));

      // Did not hit the plane
      if (!intersected) {
        continue;
      }

      const jcc::Vec3 intersection_fiducial_frame =
          camera_from_fiducial.inverse() * intersection_camera_frame;

      const bool out_x = intersection_fiducial_frame.x() < 0.0 ||
                         intersection_fiducial_frame.x() >= width_per_height;
      const bool out_y =
          intersection_fiducial_frame.y() < 0.0 || intersection_fiducial_frame.y() >= 1.0;
      // Out of the frame
      if (out_x || out_y) {
        continue;
      }

      const jcc::Vec2 pt_fiducial_image_frame(intersection_fiducial_frame.x(),
                                              intersection_fiducial_frame.y());

      ui2d->add_point({pt_fiducial_image_frame, jcc::Vec4(0.0, 1.0, 0.0, 1.0), 1.0});

      // const double result =
      // interpolate_nearest(fiducial_image, pt_fiducial_image_frame * model.rows());
      const double result = interpolate_bilinear(
          fiducial_image, pt_fiducial_image_frame * fiducial_image.rows);

      out_image.at<uint8_t>(v, u) = static_cast<uint8_t>(result);

      if ((v % 50 == 0)) {
        geo->add_ray(*optl_ray, intersection_camera_frame.norm(), jcc::Vec4(1.0, 1.0, 1.0, 0.6));
        geo->flush();
      }
    }
    if (u % 50 == 0) {
      // ui2d->add_image(out_image, 1.0);
      ui2d->flush();
      view->spin_until_step();
    }
  }
  ui2d->clear();
  ui2d->add_image(out_image, 1.0);
  ui2d->flip();
  view->spin_until_step();

  return out_image;
}

}  // namespace

void go() {
  const auto view = viewer::get_window3d("Calibration");
  const auto ui2d = view->add_primitive<viewer::Ui2d>();
  const auto geo = view->add_primitive<viewer::SimpleGeometry>();

  visualize_camera_frustum(*geo, *ui2d, make_model());
  geo->flip();
  ui2d->flip();

  cv::Mat board_image;
  get_aruco_board()->draw(cv::Size(1500, 1500), board_image, 50, 1);
  const SE3 camera_from_fiducial(SO3::exp(jcc::Vec3::Zero()),
                                 jcc::Vec3(-0.5, -0.5, 1.0));

  {
    const auto image_tree = view->add_primitive<viewer::SceneTree>();

    const auto board_texture_image =
        std::make_shared<viewer::Image>(board_image, 1.0, 1.0);

    image_tree->add_primitive("root", camera_from_fiducial, "fiducial",
                              board_texture_image);
  }

  // normal_render_at_pose(camera_from_fiducial, board_image);
  const jcc::Vec6 vel = (jcc::Vec6() << 0.0, 0.0, 0.04, 0.0, 0.01, 0.01).finished();

  moving_render_at_pose(camera_from_fiducial, vel, 0.01, board_image);

  // OK: Now render some good bullshit
  jcc::Success() << "Finished rendering." << std::endl;
  view->flip();
  view->spin_until_step();
  jcc::Success() << "Done." << std::endl;
}
}  // namespace estimation

int main() {
  estimation::go();
}<|endoftext|>


<commit_before>#include "SpecificVolumeIC.h"

template <>
InputParameters
validParams<SpecificVolumeIC>()
{
  InputParameters params = validParams<InitialCondition>();
  params.addRequiredCoupledVar("rhoA",
                               "Density of the phase (conserved), \alpha \rho A for 2-phase model");
  params.addRequiredCoupledVar("area", "Cross-sectional area");
  params.addCoupledVar("alpha", 1., "Volume fraction");
  return params;
}

SpecificVolumeIC::SpecificVolumeIC(const InputParameters & parameters)
  : InitialCondition(parameters),
    _rhoA(coupledValue("rhoA")),
    _area(coupledValue("area")),
    _alpha(coupledValue("alpha"))
{
}

Real
SpecificVolumeIC::value(const Point & /*p*/)
{
  mooseAssert(_rhoA[_qp] != 0, "Detected zero density.");
  return _alpha[_qp] * _area[_qp] / _rhoA[_qp];
}
<commit_msg>Applied naming conventions to area<commit_after>#include "SpecificVolumeIC.h"

template <>
InputParameters
validParams<SpecificVolumeIC>()
{
  InputParameters params = validParams<InitialCondition>();
  params.addRequiredCoupledVar("rhoA",
                               "Density of the phase (conserved), \alpha \rho A for 2-phase model");
  params.addRequiredCoupledVar("A", "Cross-sectional area");
  params.addCoupledVar("alpha", 1., "Volume fraction");
  return params;
}

SpecificVolumeIC::SpecificVolumeIC(const InputParameters & parameters)
  : InitialCondition(parameters),
    _rhoA(coupledValue("rhoA")),
    _area(coupledValue("A")),
    _alpha(coupledValue("alpha"))
{
}

Real
SpecificVolumeIC::value(const Point & /*p*/)
{
  mooseAssert(_rhoA[_qp] != 0, "Detected zero density.");
  return _alpha[_qp] * _area[_qp] / _rhoA[_qp];
}
<|endoftext|>


<commit_before>
/*
    Olimpíada Brasileira de Informática
    Seletiva para a IOI, Teste I, 2007
    Problema: Alfândega

    Data de submissão: 29/05/2012
    Autor da solução: Luiz Rodrigo <@lurodrigo> <luizrodri.go@hotmail.com>
    Tags: programacao-dinamica
    Complexidade: O(n³)
*/

#include <iostream>
#include <cstdio>
using namespace std;

const int MAX_COTA = 501;
const int MAX_N = 100;

bool possivel[2*MAX_COTA][2*MAX_COTA];
struct Par {
    int set1, set2;
    Par(int a = 0, int b = 0) : set1(a), set2(b) {}
} pares[4*MAX_COTA*MAX_COTA];

int cota, aliquota, total;
int preco[MAX_N];

int imposto(int set1, int set2) {
    return max(0, set1-cota) + max(0, set2 - cota) + max(0, total - set1 - set2 - cota);
}

void mostra(int imp) {
    int val = aliquota * imp;
    // trick para evitar usar aritmética de ponto flutuante
    printf("%d.%02d\n", val / 100, val % 100);
}

int main() {

    int n, i, j, k, num_pares, set1, set2, menor = 1 << 28;

    cin >> n >> cota >> aliquota;

    for (i = 0; i < n; i++) {
        cin >> preco[i];
        total += preco[i];
    }

    if ( total >= 6*cota ) { // nesse caso, não há o que minimizar
        mostra(imposto(total-3*cota, total-3*cota));
        return 0;
    }

    possivel[0][0] = true;
    pares[0] = Par(0, 0);
    num_pares = 1;

    // a cada item, testa todas as possibilidades de custo que podem
    // ser formadas
    for (i = 0; i < n; i++) {
        for (j = 0, k = num_pares; j < k; j++) {
            // testa pondo item no primeiro set
            set1 = min(pares[j].set1 + preco[i], pares[j].set2);
            set2 = max(pares[j].set1 + preco[i], pares[j].set2);

            if ( set2 < 2*cota && !possivel[set1][set2] ) {
                possivel[set1][set2] = true;
                pares[num_pares++] = Par(set1, set2);
                menor = min(menor, imposto(set1, set2));
            }

            // testa pondo item no segundo set
            set1 = min(pares[j].set1, pares[j].set2 + preco[i]);
            set2 = max(pares[j].set1, pares[j].set2 + preco[i]);

            if ( set2 < 2*cota && !possivel[set1][set2] ) {
                possivel[set1][set2] = true;
                pares[num_pares++] = Par(set1, set2);
                menor = min(menor, imposto(set1, set2));
            }
        }
    }

    mostra(menor);

    return 0;
}<commit_msg>Corrigida boundary condition<commit_after>
/*
    Olimpíada Brasileira de Informática
    Seletiva para a IOI, Teste I, 2007
    Problema: Alfândega

    Data de submissão: 29/05/2012
    Autor da solução: Luiz Rodrigo <@lurodrigo> <luizrodri.go@hotmail.com>
    Tags: programacao-dinamica
    Complexidade: O(n³)
*/

#include <iostream>
#include <cstdio>
using namespace std;

const int MAX_COTA = 501;
const int MAX_N = 100;

bool possivel[2*MAX_COTA][2*MAX_COTA];
struct Par {
    int set1, set2;
    Par(int a = 0, int b = 0) : set1(a), set2(b) {}
} pares[4*MAX_COTA*MAX_COTA];

int cota, aliquota, total;
int preco[MAX_N];

int imposto(int set1, int set2) {
    return max(0, set1-cota) + max(0, set2 - cota) + max(0, total - set1 - set2 - cota);
}

void mostra(int imp) {
    int val = aliquota * imp;
    // trick para evitar usar aritmética de ponto flutuante
    printf("%d.%02d\n", val / 100, val % 100);
}

int main() {

    int n, i, j, k, num_pares, set1, set2, menor = 1 << 28;

    cin >> n >> cota >> aliquota;

    for (i = 0; i < n; i++) {
        cin >> preco[i];
        total += preco[i];
    }

    possivel[0][0] = true;
    pares[0] = Par(0, 0);
    num_pares = 1;

    // a cada item, testa todas as possibilidades de custo que podem
    // ser formadas
    for (i = 0; i < n; i++) {
        for (j = 0, k = num_pares; j < k; j++) {
            // testa pondo item no primeiro set
            set1 = min(pares[j].set1 + preco[i], pares[j].set2);
            set2 = max(pares[j].set1 + preco[i], pares[j].set2);

            if ( set2 < 2*cota && !possivel[set1][set2] ) {
                possivel[set1][set2] = true;
                pares[num_pares++] = Par(set1, set2);
                menor = min(menor, imposto(set1, set2));
            }

            // testa pondo item no segundo set
            set1 = min(pares[j].set1, pares[j].set2 + preco[i]);
            set2 = max(pares[j].set1, pares[j].set2 + preco[i]);

            if ( set2 < 2*cota && !possivel[set1][set2] ) {
                possivel[set1][set2] = true;
                pares[num_pares++] = Par(set1, set2);
                menor = min(menor, imposto(set1, set2));
            }
        }
    }

    mostra(menor);

    return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "core/framework/data_types.h"
#include "core/framework/op_kernel.h"
#include "test/providers/provider_test_utils.h"
#include "test_utils.h"

#include "gtest/gtest.h"

using namespace ONNX_NAMESPACE;
using namespace onnxruntime::common;

namespace onnxruntime {
namespace test {

// Test kernel that will return success, or failure, or throw based on the input
struct TestOp {
  static constexpr const char* OpName = "TestOp";
  static constexpr const char* OpDomain = "testing";

  static ONNX_NAMESPACE::OpSchema OpSchema() {
    ONNX_NAMESPACE::OpSchema schema;
    schema.SetDoc("Return success, error, or throw based on the input.")
        .SetName(OpName)
        .SetDomain(OpDomain)
        .SinceVersion(10)
        .Input(0, "action", "Action to take.", "T", OpSchema::Single)
        .Output(0, "action_out", "Return input as is", "T", OpSchema::Single)
        .TypeConstraint("T", {"tensor(int64)"}, "Type of the action and values component");
    return schema;
  }

  class OpKernelImpl final : public OpKernel {
   public:
    OpKernelImpl(const OpKernelInfo& info) : OpKernel{info} {}

    Status Compute(OpKernelContext* ctx) const override {
      const Tensor& action_tensor = *ctx->Input<Tensor>(0);
      const int64_t* action = action_tensor.Data<int64_t>();

      Status status = Status::OK();

      switch (*action) {
        case 0: {
          // success
          Tensor* Y = ctx->Output(0, action_tensor.Shape());
          void* target = Y->MutableData<int64_t>();
          memcpy(target, action, action_tensor.SizeInBytes());
          break;
        }
        case 1: {
          // fail
          status = ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Action was ", *action);
          break;
        }
        default: {
          ORT_THROW("Throwing as action was ", *action);
        }
      }

      return status;
    }
  };

  static KernelDefBuilder KernelDef() {
    KernelDefBuilder def;
    def.SetName(OpName)
        .SetDomain(OpDomain)
        .SinceVersion(10)
        .TypeConstraint("T", DataTypeImpl::GetTensorType<int64_t>())
        .Provider(onnxruntime::kCpuExecutionProvider);

    return def;
  }
};

// test that the status from TestOp is correctly returned from InferenceSession::Run
TEST(ParallelExecutor, TestStatusPropagation) {
  auto registry = std::make_shared<CustomRegistry>();
  std::vector<OpSchema> schemas{TestOp::OpSchema()};
  Status status;
  ASSERT_TRUE((status = registry->RegisterOpSet(schemas, TestOp::OpDomain, 10, 11)).IsOK()) << status;
  KernelCreateFn kernel_create_fn = [](const OpKernelInfo& info) { return new typename TestOp::OpKernelImpl(info); };
  auto kernel_def = TestOp::KernelDef();
  ASSERT_TRUE((status = registry->RegisterCustomKernel(kernel_def, kernel_create_fn)).IsOK()) << status;

  {  // test success
    OpTester tester{"TestOp", 10, TestOp::OpDomain};
    tester.AddCustomOpRegistry(registry);

    tester.AddInput<int64_t>("action", {1}, {/*success*/ 0});
    tester.AddOutput<int64_t>("action_out", {1}, {0});
    // TensorRT doesn't handle a custom op. Possibly it should, but that would be a separate PR
    tester.Run(OpTester::ExpectResult::kExpectSuccess, {}, {kTensorrtExecutionProvider}, nullptr, nullptr, false);
  }

  {  // test failure
    OpTester tester{"TestOp", 10, TestOp::OpDomain};
    tester.AddCustomOpRegistry(registry);

    tester.AddInput<int64_t>("action", {1}, {/*failure*/ 1});
    tester.AddOutput<int64_t>("action_out", {1}, {0});
    tester.Run(OpTester::ExpectResult::kExpectFailure, "Action was 1", {kTensorrtExecutionProvider}, nullptr, nullptr, false);
  }

  {  // test exception
    OpTester tester{"TestOp", 10, TestOp::OpDomain};
    tester.AddCustomOpRegistry(registry);

    tester.AddInput<int64_t>("action", {1}, {/*exception*/ 2});
    tester.AddOutput<int64_t>("action_out", {1}, {0});
    tester.Run(OpTester::ExpectResult::kExpectFailure, "Throwing as action was 2", {kTensorrtExecutionProvider}, nullptr, nullptr, false);
  }
}
}  // namespace test
}  // namespace onnxruntime
<commit_msg>Ignore a test: ParallelExecutor.StatusPropagation (#2019)<commit_after>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "core/framework/data_types.h"
#include "core/framework/op_kernel.h"
#include "test/providers/provider_test_utils.h"
#include "test_utils.h"

#include "gtest/gtest.h"

using namespace ONNX_NAMESPACE;
using namespace onnxruntime::common;

namespace onnxruntime {
namespace test {

// Test kernel that will return success, or failure, or throw based on the input
struct TestOp {
  static constexpr const char* OpName = "TestOp";
  static constexpr const char* OpDomain = "testing";

  static ONNX_NAMESPACE::OpSchema OpSchema() {
    ONNX_NAMESPACE::OpSchema schema;
    schema.SetDoc("Return success, error, or throw based on the input.")
        .SetName(OpName)
        .SetDomain(OpDomain)
        .SinceVersion(10)
        .Input(0, "action", "Action to take.", "T", OpSchema::Single)
        .Output(0, "action_out", "Return input as is", "T", OpSchema::Single)
        .TypeConstraint("T", {"tensor(int64)"}, "Type of the action and values component");
    return schema;
  }

  class OpKernelImpl final : public OpKernel {
   public:
    OpKernelImpl(const OpKernelInfo& info) : OpKernel{info} {}

    Status Compute(OpKernelContext* ctx) const override {
      const Tensor& action_tensor = *ctx->Input<Tensor>(0);
      const int64_t* action = action_tensor.Data<int64_t>();

      Status status = Status::OK();

      switch (*action) {
        case 0: {
          // success
          Tensor* Y = ctx->Output(0, action_tensor.Shape());
          void* target = Y->MutableData<int64_t>();
          memcpy(target, action, action_tensor.SizeInBytes());
          break;
        }
        case 1: {
          // fail
          status = ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Action was ", *action);
          break;
        }
        default: {
          ORT_THROW("Throwing as action was ", *action);
        }
      }

      return status;
    }
  };

  static KernelDefBuilder KernelDef() {
    KernelDefBuilder def;
    def.SetName(OpName)
        .SetDomain(OpDomain)
        .SinceVersion(10)
        .TypeConstraint("T", DataTypeImpl::GetTensorType<int64_t>())
        .Provider(onnxruntime::kCpuExecutionProvider);

    return def;
  }
};

// test that the status from TestOp is correctly returned from InferenceSession::Run
TEST(ParallelExecutor, DISABLED_TestStatusPropagation) {
  auto registry = std::make_shared<CustomRegistry>();
  std::vector<OpSchema> schemas{TestOp::OpSchema()};
  Status status;
  ASSERT_TRUE((status = registry->RegisterOpSet(schemas, TestOp::OpDomain, 10, 11)).IsOK()) << status;
  KernelCreateFn kernel_create_fn = [](const OpKernelInfo& info) { return new typename TestOp::OpKernelImpl(info); };
  auto kernel_def = TestOp::KernelDef();
  ASSERT_TRUE((status = registry->RegisterCustomKernel(kernel_def, kernel_create_fn)).IsOK()) << status;

  {  // test success
    OpTester tester{"TestOp", 10, TestOp::OpDomain};
    tester.AddCustomOpRegistry(registry);

    tester.AddInput<int64_t>("action", {1}, {/*success*/ 0});
    tester.AddOutput<int64_t>("action_out", {1}, {0});
    // TensorRT doesn't handle a custom op. Possibly it should, but that would be a separate PR
    tester.Run(OpTester::ExpectResult::kExpectSuccess, {}, {kTensorrtExecutionProvider}, nullptr, nullptr, false);
  }

  {  // test failure
    OpTester tester{"TestOp", 10, TestOp::OpDomain};
    tester.AddCustomOpRegistry(registry);

    tester.AddInput<int64_t>("action", {1}, {/*failure*/ 1});
    tester.AddOutput<int64_t>("action_out", {1}, {0});
    tester.Run(OpTester::ExpectResult::kExpectFailure, "Action was 1", {kTensorrtExecutionProvider}, nullptr, nullptr, false);
  }

  {  // test exception
    OpTester tester{"TestOp", 10, TestOp::OpDomain};
    tester.AddCustomOpRegistry(registry);

    tester.AddInput<int64_t>("action", {1}, {/*exception*/ 2});
    tester.AddOutput<int64_t>("action_out", {1}, {0});
    tester.Run(OpTester::ExpectResult::kExpectFailure, "Throwing as action was 2", {kTensorrtExecutionProvider}, nullptr, nullptr, false);
  }
}
}  // namespace test
}  // namespace onnxruntime
<|endoftext|>


<commit_before>/**
* pty.js
* Copyright (c) 2012, Christopher Jeffrey, Peter Sunde (MIT License)
*
* pty.cc:
*   This file is responsible for starting processes
*   with pseudo-terminal file descriptors.
*/

#include <v8.h>
#include <node.h>
#include <node_buffer.h>
#include <string.h>
#include <stdlib.h>
#include <winpty.h>
#include <string>
#include <sstream>
#include <iostream>
#include <vector>

using namespace v8;
using namespace std;
using namespace node;

/**
* Misc
*/
extern "C" void init(Handle<Object>);

static std::vector<winpty_t *> ptyHandles;
static volatile LONG ptyCounter;

struct winpty_s {
	winpty_s();
	HANDLE controlPipe;
	HANDLE dataPipe;
};

winpty_s::winpty_s() : controlPipe(NULL), dataPipe(NULL)
{
}

/**
* Helpers
*/
const wchar_t* ToWChar(const String::Utf8Value& str)
{
	const char *bytes = *str;
	unsigned int iSizeOfStr = MultiByteToWideChar(CP_ACP, 0, bytes, -1, NULL, 0);
	wchar_t* wszTgt = new wchar_t[iSizeOfStr];
    MultiByteToWideChar(CP_ACP, 0, bytes, -1, wszTgt, iSizeOfStr);
	return wszTgt;
}

template <typename T>
void remove(std::vector<T>& vec, size_t pos)
{
	std::vector<T>::iterator it = vec.begin();
	std::advance(it, pos);
	vec.erase(it);
}

static winpty_t *getControlPipeHandle(int handle) {
	for(unsigned int i = 0; i < ptyHandles.size(); i++) {
		winpty_t *ptyHandle = ptyHandles[i];
		if((int)ptyHandle->controlPipe == handle) {
			return ptyHandle;
		}
	}
	return NULL;
}

static bool removePipeHandle(int handle) {
	for(unsigned int i = 0; i < ptyHandles.size(); i++) {
		winpty_t *ptyHandle = ptyHandles[i];
		if((int)ptyHandle->controlPipe == handle) {
			remove(ptyHandles, i);
		}
	}
	return false;
}

/*
* PtyOpen
* pty.open(dataPipe, cols, rows)
*
* If you need to debug winpty-agent.exe do the following:
* ======================================================
*
* 1) Install python 2.7
* 2) Install http://sourceforge.net/projects/pywin32/
* 3) Start deps/winpty/misc/DebugServer.py (Before you start node)
*
* Then you'll see output from winpty-agent.exe.
*
* Important part:
* ===============
* CreateProcess: success 8896 0 (Windows error code)
*
* Create test.js:
* ===============
*
* var pty = require('./');
*
* var term = pty.fork('cmd', [], {
*   name: 'Windows Shell',
*	cols: 80,
*	rows: 30,
*	cwd: process.env.HOME,
*	env: process.env,
*	debug: true
* });
*
* process.stdin.pipe(term);
* process.stdin.resume();
* term.pipe(process.stdout);
*
*/

static Handle<Value> PtyOpen(const Arguments& args) {
	HandleScope scope;

	if (args.Length() != 4
		|| !args[0]->IsString() // dataPipe
		|| !args[1]->IsNumber() // cols
		|| !args[2]->IsNumber() // rows
		|| !args[3]->IsBoolean()) // debug
	{
		return ThrowException(Exception::Error(
			String::New("Usage: pty.open(dataPipe, cols, rows, debug)")));
	}

	// Cols, rows, debug
	int cols = (int) args[1]->Int32Value();
	int rows = (int) args[2]->Int32Value();
	bool debug = (bool) args[3]->BooleanValue;

	// If debug is enabled, set environment variable
	if(debug) {
		SetEnvironmentVariableW(L"WINPTYDBG", L"1");
	}

	// Open a new pty session.
	winpty_t *pc = winpty_open_use_own_datapipe(ToWChar(String::Utf8Value(args[0]->ToString())), rows, cols);

	// Error occured during startup of agent process.
	if(pc == NULL) {
		return ThrowException(Exception::Error(String::New("Unable to start agent process.")));
	}

	// Save pty struct fpr later use.
	ptyHandles.insert(ptyHandles.end(), pc);

	// Pty object values.
	Local<Object> obj = Object::New();

	// Control pipe handle.
	obj->Set(String::New("pid"), Number::New((int)pc->controlPipe));

	// File descriptor is not available on Windows.
	obj->Set(String::New("fd"), Number::New(-1));

	// Id of current pty session.
	obj->Set(String::New("pty"), Number::New(InterlockedIncrement(&ptyCounter)));

	return scope.Close(obj);

}

/*
* PtyStartProcess
* pty.startProcess(pid, file, env, cwd);
*/

static Handle<Value> PtyStartProcess(const Arguments& args) {
	HandleScope scope;

	if (args.Length() != 5
		|| !args[0]->IsNumber() // pid
		|| !args[1]->IsString() // file
		|| !args[2]->IsString() // cmdline
		|| !args[3]->IsString() // env
		|| !args[4]->IsString()) // cwd
	{
		return ThrowException(Exception::Error(
			String::New("Usage: pty.startProcess(pid, file, cmdline, env, cwd)")));
	}

	// Native values.
	const wchar_t *file = ToWChar(String::Utf8Value(args[1]->ToString()));
	const wchar_t *cmdline = ToWChar(String::Utf8Value(args[2]->ToString()));
	const wchar_t *env = ToWChar(String::Utf8Value(args[3]->ToString()));
	const wchar_t *cwd = ToWChar(String::Utf8Value(args[4]->ToString()));

	// Get winpty_t by control pipe handle
	winpty_t *pc = getControlPipeHandle((int) args[0]->Int32Value());

	// Start new terminal
	if(pc != NULL) {
		winpty_start_process(pc, file, cmdline, cwd, env);
	} else {
		return ThrowException(Exception::Error(
			String::New("Invalid control pipe handle.")));
	}

	return scope.Close(Undefined());
}

/*
* PtyResize
* pty.resize(pid, cols, rows);
*/
static Handle<Value> PtyResize(const Arguments& args) {
	HandleScope scope;

	if (args.Length() != 3
		|| !args[0]->IsNumber() // pid
		|| !args[1]->IsNumber() // cols
		|| !args[2]->IsNumber()) // rows
	{
		return ThrowException(Exception::Error(
			String::New("Usage: pty.resize(pid, cols, rows)")));
	}

	int handle = (int) args[0]->Int32Value();
	int cols = (int) args[1]->Int32Value();
	int rows = (int) args[2]->Int32Value();

	winpty_t *pc = getControlPipeHandle(handle);

	if(pc == NULL) {
		return ThrowException(Exception::Error(String::New("Invalid pid.")));
	}

	winpty_set_size(pc, cols, rows);

	return scope.Close(Undefined());
}

/*
* PtyKill
* pty.kill(pid);
*/
static Handle<Value> PtyKill(const Arguments& args) {
	HandleScope scope;

	if (args.Length() != 1
		|| !args[0]->IsNumber()) // pid
	{
		return ThrowException(Exception::Error(
			String::New("Usage: pty.kill(pid)")));
	}

	int handle = (int) args[0]->Int32Value();

	winpty_t *pc = getControlPipeHandle(handle);

	if(pc == NULL) {
		return ThrowException(Exception::Error(
			String::New("Invalid pid.")));
	}

	winpty_exit(pc);
	removePipeHandle(handle);

	return scope.Close(Undefined());

}

/**
* Init
*/

extern "C" void init(Handle<Object> target) {
	HandleScope scope;
	NODE_SET_METHOD(target, "open", PtyOpen);
	NODE_SET_METHOD(target, "startProcess", PtyStartProcess);
	NODE_SET_METHOD(target, "resize", PtyResize);
	NODE_SET_METHOD(target, "kill", PtyKill);
};

NODE_MODULE(pty, init);
<commit_msg>massive code cleanup.<commit_after>/**
* pty.js
* Copyright (c) 2013, Christopher Jeffrey, Peter Sunde (MIT License)
*
* pty.cc:
*   This file is responsible for starting processes
*   with pseudo-terminal file descriptors.
*/

#include <v8.h>
#include <node.h>
#include <node_buffer.h>
#include <string.h>
#include <stdlib.h>
#include <winpty.h>
#include <string>
#include <sstream>
#include <iostream>
#include <vector>

using namespace v8;
using namespace std;
using namespace node;

/**
* Misc
*/
extern "C" void init(Handle<Object>);

#define WINPTY_DBG_VARIABLE TEXT("WINPTYDBG")

/**
* winpty
*/
static std::vector<winpty_t *> ptyHandles;
static volatile LONG ptyCounter;

struct winpty_s {
  winpty_s();
  HANDLE controlPipe;
  HANDLE dataPipe;
};

winpty_s::winpty_s() :
  controlPipe(nullptr),
  dataPipe(nullptr)
{
}

/**
* Helpers
*/

const wchar_t* to_wstring(const String::Utf8Value& str)
{
  auto bytes = *str;
  auto sizeOfStr = MultiByteToWideChar(CP_ACP, 0, bytes, -1, NULL, 0);
  auto output = new wchar_t[sizeOfStr];
  MultiByteToWideChar(CP_ACP, 0, bytes, -1, output, sizeOfStr);
  return output;
}

static winpty_t *get_pipe_handle(int handle) {
  for(auto &ptyHandle : ptyHandles) {
    int cmp = (int)ptyHandle->controlPipe;
    if(cmp == handle) {
      return ptyHandle;
    }
  }
  return nullptr;
}

static bool remove_pipe_handle(int handle) {
  for(auto *ptyHandle : ptyHandles) {
    if((int)ptyHandle->controlPipe == handle) {
      delete ptyHandle;
      ptyHandle = nullptr;
      return true;
    }
  }
  return false;
}

/*
* PtyOpen
* pty.open(dataPipe, cols, rows)
*
* If you need to debug winpty-agent.exe do the following:
* ======================================================
*
* 1) Install python 2.7
* 2) Install win32pipe
x86) http://sourceforge.net/projects/pywin32/files/pywin32/Build%20218/pywin32-218.win32-py2.7.exe/download
x64) http://sourceforge.net/projects/pywin32/files/pywin32/Build%20218/pywin32-218.win-amd64-py2.7.exe/download
* 3) Start deps/winpty/misc/DebugServer.py (Before you start node)
*
* Then you'll see output from winpty-agent.exe.
*
* Important part:
* ===============
* CreateProcess: success 8896 0 (Windows error code)
*
* Create test.js:
* ===============
*
* var pty = require('./');
*
* var term = pty.fork('cmd', [], {
*   name: 'Windows Shell',
*	cols: 80,
*	rows: 30,
*	cwd: process.env.HOME,
*	env: process.env,
*	debug: true
* });
*
* process.stdin.resume();
* process.stdin.pipe(term);
* term.pipe(process.stdout);
*
*/

static Handle<Value> PtyOpen(const Arguments& args) {
  HandleScope scope;

  if (args.Length() != 4
    || !args[0]->IsString() // dataPipe
    || !args[1]->IsNumber() // cols
    || !args[2]->IsNumber() // rows
    || !args[3]->IsBoolean()) // debug
  {
    return ThrowException(Exception::Error(
      String::New("Usage: pty.open(dataPipe, cols, rows, debug)")));
  }

  auto pipeName = to_wstring(String::Utf8Value(args[0]->ToString()));
  auto cols = args[1]->Int32Value();
  auto rows = args[2]->Int32Value();
  auto debug = args[3]->ToBoolean()->IsTrue();

  // Enable/disable debugging
  SetEnvironmentVariable(WINPTY_DBG_VARIABLE, debug ? "1" : NULL); // NULL = deletes variable

  // Open a new pty session.
  winpty_t *pc = winpty_open_use_own_datapipe(pipeName, rows, cols);

  // Error occured during startup of agent process.
  assert(pc != nullptr);

  // Save pty struct fpr later use.
  ptyHandles.insert(ptyHandles.end(), pc);

  // Pty object values.
  auto marshal = Object::New();
  marshal->Set(String::New("pid"), Number::New((int)pc->controlPipe));
  marshal->Set(String::New("pty"), Number::New(InterlockedIncrement(&ptyCounter)));
  marshal->Set(String::New("fd"), Number::New(-1));

  delete pipeName;

  return scope.Close(marshal);

}

/*
* PtyStartProcess
* pty.startProcess(pid, file, env, cwd);
*/

static Handle<Value> PtyStartProcess(const Arguments& args) {
  HandleScope scope;

  if (args.Length() != 5
    || !args[0]->IsNumber() // pid
    || !args[1]->IsString() // file
    || !args[2]->IsString() // cmdline
    || !args[3]->IsString() // env
    || !args[4]->IsString()) // cwd
  {
    return ThrowException(Exception::Error(
      String::New("Usage: pty.startProcess(pid, file, cmdline, env, cwd)")));
  }

  // Native values.
  auto pid = args[0]->Int32Value();
  auto file = to_wstring(String::Utf8Value(args[1]->ToString()));
  auto cmdline = to_wstring(String::Utf8Value(args[2]->ToString()));
  auto env = to_wstring(String::Utf8Value(args[3]->ToString()));
  auto cwd = to_wstring(String::Utf8Value(args[4]->ToString()));

  // Get winpty_t by control pipe handle
  auto pc = get_pipe_handle(pid);

  // Start new terminal
  assert(pc != nullptr);
  auto result = winpty_start_process(pc, file, cmdline, cwd, env);
  assert(0 == result);

  return scope.Close(Undefined());
}

/*
* PtyResize
* pty.resize(pid, cols, rows);
*/
static Handle<Value> PtyResize(const Arguments& args) {
  HandleScope scope;

  if (args.Length() != 3
    || !args[0]->IsNumber() // pid
    || !args[1]->IsNumber() // cols
    || !args[2]->IsNumber()) // rows
  {
    return ThrowException(Exception::Error(String::New("Usage: pty.resize(pid, cols, rows)")));
  }

  auto handle = args[0]->Int32Value();
  auto cols = args[1]->Int32Value();
  auto rows = args[2]->Int32Value();

  winpty_t *pc = get_pipe_handle(handle);

  assert(pc != nullptr);
  assert(0 == winpty_set_size(pc, cols, rows));

  return scope.Close(Undefined());
}

/*
* PtyKill
* pty.kill(pid);
*/
static Handle<Value> PtyKill(const Arguments& args) {
  HandleScope scope;

  if (args.Length() != 1
    || !args[0]->IsNumber()) // pid
  {
    return ThrowException(Exception::Error(String::New("Usage: pty.kill(pid)")));
  }

  auto handle = args[0]->Int32Value();

  winpty_t *pc = get_pipe_handle(handle);

  assert(pc != nullptr);
  winpty_exit(pc);
  assert(true == remove_pipe_handle(handle));

  return scope.Close(Undefined());

}

/**
* Init
*/

extern "C" void init(Handle<Object> target) {
  HandleScope scope;
  NODE_SET_METHOD(target, "open", PtyOpen);
  NODE_SET_METHOD(target, "startProcess", PtyStartProcess);
  NODE_SET_METHOD(target, "resize", PtyResize);
  NODE_SET_METHOD(target, "kill", PtyKill);
};

NODE_MODULE(pty, init);<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Akil Darjean (adarjean@uh.edu)
 * Distributed under the MIT License.
 * See accompanying file LICENSE.md or copy at http://opensource.org/licenses/MIT
 */

#include "window.h"
#include <SFML/Graphics.hpp>
#include <algorithm>
#include <boost/filesystem.hpp>
#include <exception>
#include <future>
#include <iterator>
#include <utility>

struct path_leaf_string {
    std::string operator()(const boost::filesystem::directory_entry& entry) const
    {
        return entry.path().leaf().string();
    }
};

Window::Window(const std::string&& filename)
{
    this->isFullscreen = false;
    this->filename = filename;

    // Run a seperate thread to get a list of all files in the directory
    auto f = std::async(std::launch::async, &Window::getFilesInDirectory, this);

    load();
    init();

    files = f.get();

    draw();
}

void Window::load()
{
    sf::Image image;
    image.loadFromFile(filename);

    if (!texture.loadFromImage(image)) {
        throw std::runtime_error("Error: Image not found");
    }
    texture.setSmooth(true);
    texture.update(image);
    sprite.setTexture(texture);
}

void Window::init()
{
    desktop = sf::VideoMode::getDesktopMode();

    window.create(sf::VideoMode(640, 480), "SFML Image Viewer");
    window.setKeyRepeatEnabled(false);
    window.setFramerateLimit(framerate);

    // Initialize view
    view.reset(sf::FloatRect(
        0.0f,
        0.0f,
        static_cast<float>(texture.getSize().x),
        static_cast<float>(texture.getSize().y)));
}

void Window::draw()
{
    while (window.isOpen()) {
        checkEvents();

        window.clear();
        window.setView(view);
        window.draw(sprite);
        window.display();
    }
}

void Window::checkEvents()
{
    sf::Event event;
    while (window.pollEvent(event)) {
        switch (event.type) {
        case sf::Event::EventType::Closed:
            window.close();
            break;

        case sf::Event::EventType::Resized:
            getLetterboxView();
            break;

        case sf::Event::KeyPressed:
            if (event.key.code == sf::Keyboard::Q) {
                window.close();
            }
            if (event.key.code == sf::Keyboard::F) {
                if (!isFullscreen) {
                    window.create(desktop, "SFML Image Viewer", sf::Style::Fullscreen);
                } else {
                    window.create(sf::VideoMode(640, 480), "SFML Image Viewer");
                }
                isFullscreen = !isFullscreen;
            }
            if ((event.key.code == sf::Keyboard::P) || (event.key.code == sf::Keyboard::N)) {
                auto it = find(files.begin(), files.end(), filename);
                if (it != files.end()) {
                    // Get position of current image
                    auto pos = std::distance(files.begin(), it);
                    auto size = static_cast<int>(files.size());
                    auto original = files.at(pos);

                    if ((event.key.code == sf::Keyboard::P) && (pos > 0)) {
                        filename = files.at(pos - 1);
                    }

                    if ((event.key.code == sf::Keyboard::N) && (pos < (size - 1))) {
                        filename = files.at(pos + 1);
                    }

                    try {
                        load();
                    } catch (std::exception& e) {
                        files.erase(std::remove(files.begin(), files.end(), filename), files.end());
                        filename = original;
                        load();
                    }
                }
            }

        default:
            break;
        }
    }
}

void Window::getLetterboxView()
{
    float windowRatio = window.getSize().x / static_cast<float>(window.getSize().y);
    float viewRatio = view.getSize().x / static_cast<float>(view.getSize().y);

    sf::Vector2f size;
    sf::Vector2f pos;

    if (windowRatio > viewRatio) {
        size.x = viewRatio / windowRatio;
        pos.x = (1.0f - size.x) / 2.0f;
        size.y = 1.0f;
        pos.y = 0.0f;
    } else {
        size.y = windowRatio / viewRatio;
        pos.y = (1.0f - size.y) / 2.0f;
        size.x = 1.0f;
        pos.x = 0.0f;
    }

    view.setViewport(sf::FloatRect(pos.x, pos.y, size.x, size.y));
}

std::vector<std::string> Window::getFilesInDirectory()
{
    std::vector<std::string> v;
    auto dir = boost::filesystem::current_path();

    boost::filesystem::path p(dir);
    boost::filesystem::directory_iterator start(p);
    boost::filesystem::directory_iterator end;
    std::transform(start, end, std::back_inserter(v), path_leaf_string());
    std::sort(v.begin(), v.end());

    return v;
}
<commit_msg>Scale image correctly when loading<commit_after>/*
 * Copyright (c) 2017 Akil Darjean (adarjean@uh.edu)
 * Distributed under the MIT License.
 * See accompanying file LICENSE.md or copy at http://opensource.org/licenses/MIT
 */

#include "window.h"
#include <SFML/Graphics.hpp>
#include <algorithm>
#include <boost/filesystem.hpp>
#include <exception>
#include <future>
#include <iterator>
#include <utility>

struct path_leaf_string {
    std::string operator()(const boost::filesystem::directory_entry& entry) const
    {
        return entry.path().leaf().string();
    }
};

Window::Window(const std::string&& filename)
{
    this->isFullscreen = false;
    this->filename = filename;

    // Run a seperate thread to get a list of all files in the directory
    auto f = std::async(std::launch::async, &Window::getFilesInDirectory, this);

    load();
    init();

    files = f.get();

    draw();
}

void Window::load()
{
    sf::Image image;
    image.loadFromFile(filename);

    if (!texture.loadFromImage(image)) {
        throw std::runtime_error("Error: Image not found");
    }
    texture.setSmooth(true);
    texture.update(image);

    sprite.setTexture(texture);
}

void Window::init()
{
    desktop = sf::VideoMode::getDesktopMode();

    window.create(sf::VideoMode(640, 480), "SFML Image Viewer");
    window.setKeyRepeatEnabled(false);
    window.setFramerateLimit(framerate);

    // Initialize view
    view.reset(sf::FloatRect(
        0.0f,
        0.0f,
        static_cast<float>(texture.getSize().x),
        static_cast<float>(texture.getSize().y)));
}

void Window::draw()
{
    while (window.isOpen()) {
        checkEvents();

        window.clear();
        window.setView(view);
        window.draw(sprite);
        window.display();
    }
}

void Window::checkEvents()
{
    sf::Event event;
    while (window.pollEvent(event)) {
        switch (event.type) {
        case sf::Event::EventType::Closed:
            window.close();
            break;

        case sf::Event::EventType::Resized:
            getLetterboxView();
            break;

        case sf::Event::KeyPressed:
            if (event.key.code == sf::Keyboard::Q) {
                window.close();
            }
            if (event.key.code == sf::Keyboard::F) {
                if (!isFullscreen) {
                    window.create(desktop, "SFML Image Viewer", sf::Style::Fullscreen);
                } else {
                    window.create(sf::VideoMode(640, 480), "SFML Image Viewer");
                }
                isFullscreen = !isFullscreen;
            }
            if ((event.key.code == sf::Keyboard::P) || (event.key.code == sf::Keyboard::N)) {
                auto it = find(files.begin(), files.end(), filename);
                if (it != files.end()) {
                    // Get position of current image
                    auto pos = std::distance(files.begin(), it);
                    auto size = static_cast<int>(files.size());
                    auto original = files.at(pos);

                    if ((event.key.code == sf::Keyboard::P) && (pos > 0)) {
                        filename = files.at(pos - 1);
                    }

                    if ((event.key.code == sf::Keyboard::N) && (pos < (size - 1))) {
                        filename = files.at(pos + 1);
                    }

                    try {
                        texture = sf::Texture();
                        sprite = sf::Sprite();
                        load();
                        view.reset(sf::FloatRect(
                            0,
                            0,
                            static_cast<float>(texture.getSize().x),
                            static_cast<float>(texture.getSize().y)));
                        getLetterboxView();
                    } catch (std::exception& e) {
                        files.erase(std::remove(files.begin(), files.end(), filename), files.end());
                        filename = original;
                        load();
                    }
                }
            }

        default:
            break;
        }
    }
}

void Window::getLetterboxView()
{
    float windowRatio = window.getSize().x / static_cast<float>(window.getSize().y);
    float viewRatio = view.getSize().x / static_cast<float>(view.getSize().y);

    sf::Vector2f size;
    sf::Vector2f pos;

    if (windowRatio > viewRatio) {
        size.x = viewRatio / windowRatio;
        pos.x = (1.0f - size.x) / 2.0f;
        size.y = 1.0f;
        pos.y = 0.0f;
    } else {
        size.y = windowRatio / viewRatio;
        pos.y = (1.0f - size.y) / 2.0f;
        size.x = 1.0f;
        pos.x = 0.0f;
    }

    view.setViewport(sf::FloatRect(pos.x, pos.y, size.x, size.y));
}

std::vector<std::string> Window::getFilesInDirectory()
{
    std::vector<std::string> v;
    auto dir = boost::filesystem::current_path();

    boost::filesystem::path p(dir);
    boost::filesystem::directory_iterator start(p);
    boost::filesystem::directory_iterator end;
    std::transform(start, end, std::back_inserter(v), path_leaf_string());
    std::sort(v.begin(), v.end());

    return v;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Akil Darjean (adarjean@uh.edu)
 * Distributed under the MIT License.
 * See accompanying file LICENSE.md or copy at http://opensource.org/licenses/MIT
 */

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

void Window::create()
{
    this->filename = "";

    init();
    draw();
}

void Window::create(std::string filename)
{
    this->filename = filename;

    load();
    init();
    draw();
}

void Window::load()
{
    if (!texture.loadFromFile(filename)) {
        std::cout << "Error: file does not exist" << std::endl;
    }
    texture.setSmooth(true);
    sprite.setTexture(texture);
}

void Window::init()
{
    window.create(sf::VideoMode(640, 480), "SFML Image Viewer");

    // Initialize view
    view.reset(sf::FloatRect(
        0,
        0,
        static_cast<float>(texture.getSize().x),
        static_cast<float>(texture.getSize().y)));
}

void Window::checkEvents()
{
    sf::Event event;
    while (window.pollEvent(event)) {
        switch (event.type) {
        case sf::Event::EventType::Closed:
            window.close();
            break;

        case sf::Event::EventType::Resized:
            getLetterboxView();
            break;

        case sf::Event::KeyPressed:
            if (event.key.code == sf::Keyboard::Q) {
                window.close();
            }

        default:
            break;
        }
    }
}

void Window::draw()
{
    while (window.isOpen()) {
        checkEvents();

        window.clear();
        window.setView(view);
        window.draw(sprite);
        window.display();
    }
}

void Window::getLetterboxView()
{
    float windowRatio = window.getSize().x / static_cast<float>(window.getSize().y);
    float viewRatio = view.getSize().x / static_cast<float>(view.getSize().y);

    sf::Vector2f size;
    sf::Vector2f pos;

    if (windowRatio > viewRatio) {
        size.x = viewRatio / windowRatio;
        pos.x = (1 - size.x) / 2.f;
        size.y = 1;
        pos.y = 0;
    } else {
        size.y = windowRatio / viewRatio;
        pos.y = (1 - size.y) / 2.f;
        size.x = 1;
        pos.x = 0;
    }

    view.setViewport(sf::FloatRect(pos.x, pos.y, size.x, size.y));
}
<commit_msg>Disable key repeating<commit_after>/*
 * Copyright (c) 2017 Akil Darjean (adarjean@uh.edu)
 * Distributed under the MIT License.
 * See accompanying file LICENSE.md or copy at http://opensource.org/licenses/MIT
 */

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

void Window::create()
{
    this->filename = "";

    init();
    draw();
}

void Window::create(std::string filename)
{
    this->filename = filename;

    load();
    init();
    draw();
}

void Window::load()
{
    if (!texture.loadFromFile(filename)) {
        std::cout << "Error: file does not exist" << std::endl;
    }
    texture.setSmooth(true);
    sprite.setTexture(texture);
}

void Window::init()
{
    window.create(sf::VideoMode(640, 480), "SFML Image Viewer");
    window.setKeyRepeatEnabled(false);

    // Initialize view
    view.reset(sf::FloatRect(
        0,
        0,
        static_cast<float>(texture.getSize().x),
        static_cast<float>(texture.getSize().y)));
}

void Window::checkEvents()
{
    sf::Event event;
    while (window.pollEvent(event)) {
        switch (event.type) {
        case sf::Event::EventType::Closed:
            window.close();
            break;

        case sf::Event::EventType::Resized:
            getLetterboxView();
            break;

        case sf::Event::KeyPressed:
            if (event.key.code == sf::Keyboard::Q) {
                window.close();
            }

        default:
            break;
        }
    }
}

void Window::draw()
{
    while (window.isOpen()) {
        checkEvents();

        window.clear();
        window.setView(view);
        window.draw(sprite);
        window.display();
    }
}

void Window::getLetterboxView()
{
    float windowRatio = window.getSize().x / static_cast<float>(window.getSize().y);
    float viewRatio = view.getSize().x / static_cast<float>(view.getSize().y);

    sf::Vector2f size;
    sf::Vector2f pos;

    if (windowRatio > viewRatio) {
        size.x = viewRatio / windowRatio;
        pos.x = (1 - size.x) / 2.f;
        size.y = 1;
        pos.y = 0;
    } else {
        size.y = windowRatio / viewRatio;
        pos.y = (1 - size.y) / 2.f;
        size.x = 1;
        pos.x = 0;
    }

    view.setViewport(sf::FloatRect(pos.x, pos.y, size.x, size.y));
}
<|endoftext|>


<commit_before>// Copyright 2018 The clvk authors.
//
// 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 "memory.hpp"

std::unique_ptr<cvk_mem> cvk_mem::create(cvk_context *context, cl_mem_flags flags, size_t size, void *host_ptr, cl_int *errcode_ret
){
    auto mem = std::make_unique<cvk_mem>(context, flags, size, host_ptr, nullptr, 0);

    if (!mem->init()) {
        *errcode_ret = CL_OUT_OF_RESOURCES;
        return nullptr;
    }

    *errcode_ret = CL_SUCCESS;
    return mem;
}

bool cvk_mem::init()
{
    auto device = m_context->device();
    auto vkdev = device->vulkan_device();

    // Create the buffer
    const VkBufferCreateInfo createInfo = {
        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
        nullptr, // pNext
        0, // flags
        m_size,
        cvk_mem::USAGE_FLAGS, // usage
        VK_SHARING_MODE_EXCLUSIVE,
        0, // queueFamilyIndexCount
        nullptr, // pQueueFamilyIndices
    };

    VkResult res = vkCreateBuffer(vkdev, &createInfo, nullptr, &m_buffer);

    if (res != VK_SUCCESS) {
        return false;
    }

    cvk_debug_fn("created Vk buffer handle = %p", m_buffer);

    // Get memory requirements
    VkMemoryRequirements memreqs;
    vkGetBufferMemoryRequirements(vkdev, m_buffer, &memreqs);

    // Select memory type
    uint32_t memoryTypeIndex = device->memory_type_index();

    if (memoryTypeIndex == VK_MAX_MEMORY_TYPES) {
        return false;
    }

    // Check against the memory requirements
    // TODO get the type index from the requirements
    if (!((1 << memoryTypeIndex) & memreqs.memoryTypeBits)) {
        return false;
    }

    // Allocate memory
    const VkMemoryAllocateInfo memoryAllocateInfo = {
        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
        nullptr,
        memreqs.size,
        memoryTypeIndex,
    };

    res = vkAllocateMemory(vkdev, &memoryAllocateInfo, 0, &m_memory);

    if(res != VK_SUCCESS) {
        return false;
    }

    // Bind the buffer to memory
    res = vkBindBufferMemory(vkdev, m_buffer, m_memory, 0);

    if(res != VK_SUCCESS) {
        return false;
    }

    if ((m_flags & CL_MEM_COPY_HOST_PTR) || (m_flags & CL_MEM_USE_HOST_PTR)) {
        if (!copy_from(m_host_ptr, 0, m_size)) {
            return false;
        }
    }

    return true;
}

cvk_mem* cvk_mem::create_subbuffer(cl_mem_flags flags, size_t origin, size_t size)
{
    std::unique_ptr<cvk_mem> mem(new cvk_mem(m_context, flags, size, nullptr, this, origin));

    if (!mem->init_subbuffer()) {
        return nullptr;
    }

    return mem.release();
}

bool cvk_mem::init_subbuffer() {

    // Create the buffer
    const VkBufferCreateInfo createInfo = {
        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
        nullptr, // pNext
        0, // flags
        m_size,
        cvk_mem::USAGE_FLAGS, // usage
        VK_SHARING_MODE_EXCLUSIVE,
        0, // queueFamilyIndexCount
        nullptr, // pQueueFamilyIndices
    };

    auto vkdev = m_context->device()->vulkan_device();
    VkResult res = vkCreateBuffer(vkdev, &createInfo, nullptr, &m_buffer);

    if (res != VK_SUCCESS) {
        return false;
    }

    cvk_debug_fn("created Vk buffer handle = %p", m_buffer);

    // Get memory requirements
    VkMemoryRequirements memreqs;
    vkGetBufferMemoryRequirements(vkdev, m_buffer, &memreqs);

    if (m_size != memreqs.size) {
        cvk_warn_fn("Sub-buffer %p requires more memory than its size, you're on your own!", this);
    }

    if (m_parent_offset != memreqs.alignment) {
        cvk_warn_fn("Sub-buffer %p offset does not satisfy the alignment "
                    "requirements of the Vulkan implementation, "
                    "you're on your own!", this);
    }

    // Bind the buffer to memory
    res = vkBindBufferMemory(vkdev, m_buffer, m_parent->m_memory, m_parent_offset);

    if(res != VK_SUCCESS) {
        return false;
    }

    return true;
}
<commit_msg>Fix stupid sub-buffer alignment check<commit_after>// Copyright 2018 The clvk authors.
//
// 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 "memory.hpp"

std::unique_ptr<cvk_mem> cvk_mem::create(cvk_context *context, cl_mem_flags flags, size_t size, void *host_ptr, cl_int *errcode_ret
){
    auto mem = std::make_unique<cvk_mem>(context, flags, size, host_ptr, nullptr, 0);

    if (!mem->init()) {
        *errcode_ret = CL_OUT_OF_RESOURCES;
        return nullptr;
    }

    *errcode_ret = CL_SUCCESS;
    return mem;
}

bool cvk_mem::init()
{
    auto device = m_context->device();
    auto vkdev = device->vulkan_device();

    // Create the buffer
    const VkBufferCreateInfo createInfo = {
        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
        nullptr, // pNext
        0, // flags
        m_size,
        cvk_mem::USAGE_FLAGS, // usage
        VK_SHARING_MODE_EXCLUSIVE,
        0, // queueFamilyIndexCount
        nullptr, // pQueueFamilyIndices
    };

    VkResult res = vkCreateBuffer(vkdev, &createInfo, nullptr, &m_buffer);

    if (res != VK_SUCCESS) {
        return false;
    }

    cvk_debug_fn("created Vk buffer handle = %p", m_buffer);

    // Get memory requirements
    VkMemoryRequirements memreqs;
    vkGetBufferMemoryRequirements(vkdev, m_buffer, &memreqs);

    // Select memory type
    uint32_t memoryTypeIndex = device->memory_type_index();

    if (memoryTypeIndex == VK_MAX_MEMORY_TYPES) {
        return false;
    }

    // Check against the memory requirements
    // TODO get the type index from the requirements
    if (!((1 << memoryTypeIndex) & memreqs.memoryTypeBits)) {
        return false;
    }

    // Allocate memory
    const VkMemoryAllocateInfo memoryAllocateInfo = {
        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
        nullptr,
        memreqs.size,
        memoryTypeIndex,
    };

    res = vkAllocateMemory(vkdev, &memoryAllocateInfo, 0, &m_memory);

    if(res != VK_SUCCESS) {
        return false;
    }

    // Bind the buffer to memory
    res = vkBindBufferMemory(vkdev, m_buffer, m_memory, 0);

    if(res != VK_SUCCESS) {
        return false;
    }

    if ((m_flags & CL_MEM_COPY_HOST_PTR) || (m_flags & CL_MEM_USE_HOST_PTR)) {
        if (!copy_from(m_host_ptr, 0, m_size)) {
            return false;
        }
    }

    return true;
}

cvk_mem* cvk_mem::create_subbuffer(cl_mem_flags flags, size_t origin, size_t size)
{
    std::unique_ptr<cvk_mem> mem(new cvk_mem(m_context, flags, size, nullptr, this, origin));

    if (!mem->init_subbuffer()) {
        return nullptr;
    }

    return mem.release();
}

bool cvk_mem::init_subbuffer() {

    // Create the buffer
    const VkBufferCreateInfo createInfo = {
        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
        nullptr, // pNext
        0, // flags
        m_size,
        cvk_mem::USAGE_FLAGS, // usage
        VK_SHARING_MODE_EXCLUSIVE,
        0, // queueFamilyIndexCount
        nullptr, // pQueueFamilyIndices
    };

    auto vkdev = m_context->device()->vulkan_device();
    VkResult res = vkCreateBuffer(vkdev, &createInfo, nullptr, &m_buffer);

    if (res != VK_SUCCESS) {
        return false;
    }

    cvk_debug_fn("created Vk buffer handle = %p", m_buffer);

    // Get memory requirements
    VkMemoryRequirements memreqs;
    vkGetBufferMemoryRequirements(vkdev, m_buffer, &memreqs);

    if (m_size != memreqs.size) {
        cvk_warn_fn("Sub-buffer %p requires more memory than its size, you're on your own!", this);
    }

    if (m_parent_offset % memreqs.alignment != 0) {
        cvk_warn_fn("Sub-buffer %p offset (%zu) does not satisfy the alignment "
                    "requirements (%lu) of the Vulkan implementation, "
                    "you're on your own!", this, m_parent_offset, memreqs.alignment);
    }

    // Bind the buffer to memory
    res = vkBindBufferMemory(vkdev, m_buffer, m_parent->m_memory, m_parent_offset);

    if(res != VK_SUCCESS) {
        return false;
    }

    return true;
}
<|endoftext|>


<commit_before>/*
    Copyright (c) 2007 Volker Krause <vkrause@kde.org>

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

    This library 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "list.h"

#include <QtCore/QDebug>

#include "storage/datastore.h"
#include "storage/entity.h"
#include "storage/selectquerybuilder.h"

#include "akonadiconnection.h"
#include "response.h"
#include "handlerhelper.h"
#include "imapstreamparser.h"

#include <libs/protocol_p.h>

using namespace Akonadi;

template <typename T>
static bool intersect( const QList<typename T::Id> &l1, const QList<T> &l2 )
{
  foreach ( const T& e2, l2 ) {
    if ( l1.contains( e2.id() ) )
      return true;
  }
  return false;
}

List::List( Scope::SelectionScope scope, bool onlySubscribed ):
    Handler(),
    mScope( scope ),
    mAncestorDepth( 0 ),
    mOnlySubscribed( onlySubscribed ),
    mIncludeStatistics( false )
{}

QStack<Collection> List::ancestorsForCollection( const Collection &col )
{
  if ( mAncestorDepth <= 0 )
    return QStack<Collection>();
  QStack<Collection> ancestors;
  Collection parent = col.parent();
  for ( int i = 0; i < mAncestorDepth; ++i ) {
    if ( !parent.isValid() )
      break;
    ancestors.prepend( parent );
    parent = parent.parent();
  }
  return ancestors;
}

bool List::listCollection(const Collection & root, int depth, const QStack<Collection> &ancestors )
{
  // recursive listing of child collections
  bool childrenFound = false;
  if ( depth > 0 ) {
    Collection::List children = root.children();
    QStack<Collection> ancestorsAndMe( ancestors );
    ancestorsAndMe.push( root );
    foreach ( const Collection &col, children ) {
      if ( listCollection( col, depth - 1, ancestorsAndMe ) )
        childrenFound = true;
    }
  }

  // filter if this node isn't needed by it's children
  bool hidden = (mResource.isValid() && root.resourceId() != mResource.id())
      || (mOnlySubscribed && !root.subscribed())
      || (!mMimeTypes.isEmpty() && !intersect( mMimeTypes, root.mimeTypes()) );

  if ( !childrenFound && hidden )
    return false;

  // write out collection details
  Collection dummy = root;
  DataStore *db = connection()->storageBackend();
  db->activeCachePolicy( dummy );
  const QByteArray b = HandlerHelper::collectionToByteArray( dummy, hidden, mIncludeStatistics, mAncestorDepth, ancestors );

  Response response;
  response.setUntagged();
  response.setString( b );
  emit responseAvailable( response );

  return true;
}

bool List::parseStream()
{
  qint64 baseCollection = -1;
  QString rid;
  if ( mScope == Scope::None || mScope == Scope::Uid ) {
    bool ok = false;
    baseCollection = m_streamParser->readNumber( &ok );
    if ( !ok )
      return failureResponse( "Invalid base collection" );
  } else if ( mScope == Scope::Rid ) {
    rid = m_streamParser->readUtf8String();
    if ( rid.isEmpty() )
      throw HandlerException( "No remote identifier specified" );
  } else
    throw HandlerException( "WTF" );

  int depth = HandlerHelper::parseDepth( m_streamParser->readString() );

  m_streamParser->beginList();
  while ( !m_streamParser->atListEnd() ) {
    const QByteArray filter = m_streamParser->readString();
    if ( filter == AKONADI_PARAM_RESOURCE ) {
      mResource = Resource::retrieveByName( m_streamParser->readUtf8String() );
      if ( !mResource.isValid() )
        return failureResponse( "Unknown resource" );
    } else if ( filter == AKONADI_PARAM_MIMETYPE ) {
      m_streamParser->beginList();
      while ( !m_streamParser->atListEnd() ) {
        const MimeType mt = MimeType::retrieveByName( m_streamParser->readUtf8String() );
        if ( !mt.isValid() )
          throw HandlerException( "Invalid mimetype filter" );
        mMimeTypes.append( mt.id() );
      }
    }
  }

  if ( m_streamParser->hasList() ) { // We got extra options
    m_streamParser->beginList();
    while ( !m_streamParser->atListEnd() ) {
      const QByteArray option = m_streamParser->readString();
      if ( option == "STATISTICS" ) {
        if ( m_streamParser->readString() == "true" )
          mIncludeStatistics = true;
      }
      if ( option == AKONADI_PARAM_ANCESTORS ) {
        const QByteArray argument = m_streamParser->readString();
        mAncestorDepth = HandlerHelper::parseDepth( argument );
      }
    }
  }

  Collection::List collections;
  QStack<Collection> ancestors;

  if ( baseCollection != 0 ) { // not root
    Collection col;
    if ( mScope == Scope::None || mScope == Scope::Uid ) {
       col = Collection::retrieveById( baseCollection );
    } else if ( mScope == Scope::Rid ) {
      SelectQueryBuilder<Collection> qb;
      qb.addTable( Resource::tableName() );
      qb.addValueCondition( Collection::remoteIdFullColumnName(), Query::Equals, rid );
      qb.addColumnCondition( Collection::resourceIdFullColumnName(), Query::Equals, Resource::idFullColumnName() );
      if ( mResource.isValid() )
        qb.addValueCondition( Resource::idFullColumnName(), Query::Equals, mResource.id() );
      else if ( connection()->resourceContext().isValid() )
        qb.addValueCondition( Resource::idFullColumnName(), Query::Equals, connection()->resourceContext().id() );
      else
        throw HandlerException( "Cannot retrieve collection based on remote identifier without a resource context" );
      if ( !qb.exec() )
        throw HandlerException( "Unable to retrieve collection for listing" );
      Collection::List results = qb.result();
      if ( results.count() != 1 )
        throw HandlerException( QByteArray::number( results.count() ) + " collections found" );
      col = results.first();
    } else {
      throw HandlerException( "WTF" );
    }

    if ( !col.isValid() )
      return failureResponse( "Collection " + QByteArray::number( baseCollection ) + " does not exist" );

    if ( depth == 0 ) {
      collections << col;
      ancestors = ancestorsForCollection( col );
    } else {
      collections << col.children();
      --depth;
      if ( !collections.isEmpty() )
        ancestors = ancestorsForCollection( collections.first() );
    }
  } else {
    if ( depth != 0 ) {
      Collection::List list = Collection::retrieveFiltered( Collection::parentIdColumn(), QVariant() );
      collections << list;
    }
    --depth;
  }

  foreach ( const Collection &col, collections )
    listCollection( col, depth, ancestors );

  Response response;
  response.setSuccess();
  response.setTag( tag() );
  response.setString( "List completed" );
  emit responseAvailable( response );
  deleteLater();
  return true;
}

#include "list.moc"
<commit_msg>Don't throw an error when the mimetype filter encounters a type it doesn't know yet. Ignore it instead.<commit_after>/*
    Copyright (c) 2007 Volker Krause <vkrause@kde.org>

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

    This library 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "list.h"

#include <QtCore/QDebug>

#include "storage/datastore.h"
#include "storage/entity.h"
#include "storage/selectquerybuilder.h"

#include "akonadiconnection.h"
#include "response.h"
#include "handlerhelper.h"
#include "imapstreamparser.h"

#include <libs/protocol_p.h>

using namespace Akonadi;

template <typename T>
static bool intersect( const QList<typename T::Id> &l1, const QList<T> &l2 )
{
  foreach ( const T& e2, l2 ) {
    if ( l1.contains( e2.id() ) )
      return true;
  }
  return false;
}

List::List( Scope::SelectionScope scope, bool onlySubscribed ):
    Handler(),
    mScope( scope ),
    mAncestorDepth( 0 ),
    mOnlySubscribed( onlySubscribed ),
    mIncludeStatistics( false )
{}

QStack<Collection> List::ancestorsForCollection( const Collection &col )
{
  if ( mAncestorDepth <= 0 )
    return QStack<Collection>();
  QStack<Collection> ancestors;
  Collection parent = col.parent();
  for ( int i = 0; i < mAncestorDepth; ++i ) {
    if ( !parent.isValid() )
      break;
    ancestors.prepend( parent );
    parent = parent.parent();
  }
  return ancestors;
}

bool List::listCollection(const Collection & root, int depth, const QStack<Collection> &ancestors )
{
  // recursive listing of child collections
  bool childrenFound = false;
  if ( depth > 0 ) {
    Collection::List children = root.children();
    QStack<Collection> ancestorsAndMe( ancestors );
    ancestorsAndMe.push( root );
    foreach ( const Collection &col, children ) {
      if ( listCollection( col, depth - 1, ancestorsAndMe ) )
        childrenFound = true;
    }
  }

  // filter if this node isn't needed by it's children
  bool hidden = (mResource.isValid() && root.resourceId() != mResource.id())
      || (mOnlySubscribed && !root.subscribed())
      || (!mMimeTypes.isEmpty() && !intersect( mMimeTypes, root.mimeTypes()) );

  if ( !childrenFound && hidden )
    return false;

  // write out collection details
  Collection dummy = root;
  DataStore *db = connection()->storageBackend();
  db->activeCachePolicy( dummy );
  const QByteArray b = HandlerHelper::collectionToByteArray( dummy, hidden, mIncludeStatistics, mAncestorDepth, ancestors );

  Response response;
  response.setUntagged();
  response.setString( b );
  emit responseAvailable( response );

  return true;
}

bool List::parseStream()
{
  qint64 baseCollection = -1;
  QString rid;
  if ( mScope == Scope::None || mScope == Scope::Uid ) {
    bool ok = false;
    baseCollection = m_streamParser->readNumber( &ok );
    if ( !ok )
      return failureResponse( "Invalid base collection" );
  } else if ( mScope == Scope::Rid ) {
    rid = m_streamParser->readUtf8String();
    if ( rid.isEmpty() )
      throw HandlerException( "No remote identifier specified" );
  } else
    throw HandlerException( "WTF" );

  int depth = HandlerHelper::parseDepth( m_streamParser->readString() );

  m_streamParser->beginList();
  while ( !m_streamParser->atListEnd() ) {
    const QByteArray filter = m_streamParser->readString();
    if ( filter == AKONADI_PARAM_RESOURCE ) {
      mResource = Resource::retrieveByName( m_streamParser->readUtf8String() );
      if ( !mResource.isValid() )
        return failureResponse( "Unknown resource" );
    } else if ( filter == AKONADI_PARAM_MIMETYPE ) {
      m_streamParser->beginList();
      while ( !m_streamParser->atListEnd() ) {
        const MimeType mt = MimeType::retrieveByName( m_streamParser->readUtf8String() );
        if ( mt.isValid() )
          mMimeTypes.append( mt.id() );
      }
    }
  }

  if ( m_streamParser->hasList() ) { // We got extra options
    m_streamParser->beginList();
    while ( !m_streamParser->atListEnd() ) {
      const QByteArray option = m_streamParser->readString();
      if ( option == "STATISTICS" ) {
        if ( m_streamParser->readString() == "true" )
          mIncludeStatistics = true;
      }
      if ( option == AKONADI_PARAM_ANCESTORS ) {
        const QByteArray argument = m_streamParser->readString();
        mAncestorDepth = HandlerHelper::parseDepth( argument );
      }
    }
  }

  Collection::List collections;
  QStack<Collection> ancestors;

  if ( baseCollection != 0 ) { // not root
    Collection col;
    if ( mScope == Scope::None || mScope == Scope::Uid ) {
       col = Collection::retrieveById( baseCollection );
    } else if ( mScope == Scope::Rid ) {
      SelectQueryBuilder<Collection> qb;
      qb.addTable( Resource::tableName() );
      qb.addValueCondition( Collection::remoteIdFullColumnName(), Query::Equals, rid );
      qb.addColumnCondition( Collection::resourceIdFullColumnName(), Query::Equals, Resource::idFullColumnName() );
      if ( mResource.isValid() )
        qb.addValueCondition( Resource::idFullColumnName(), Query::Equals, mResource.id() );
      else if ( connection()->resourceContext().isValid() )
        qb.addValueCondition( Resource::idFullColumnName(), Query::Equals, connection()->resourceContext().id() );
      else
        throw HandlerException( "Cannot retrieve collection based on remote identifier without a resource context" );
      if ( !qb.exec() )
        throw HandlerException( "Unable to retrieve collection for listing" );
      Collection::List results = qb.result();
      if ( results.count() != 1 )
        throw HandlerException( QByteArray::number( results.count() ) + " collections found" );
      col = results.first();
    } else {
      throw HandlerException( "WTF" );
    }

    if ( !col.isValid() )
      return failureResponse( "Collection " + QByteArray::number( baseCollection ) + " does not exist" );

    if ( depth == 0 ) {
      collections << col;
      ancestors = ancestorsForCollection( col );
    } else {
      collections << col.children();
      --depth;
      if ( !collections.isEmpty() )
        ancestors = ancestorsForCollection( collections.first() );
    }
  } else {
    if ( depth != 0 ) {
      Collection::List list = Collection::retrieveFiltered( Collection::parentIdColumn(), QVariant() );
      collections << list;
    }
    --depth;
  }

  foreach ( const Collection &col, collections )
    listCollection( col, depth, ancestors );

  Response response;
  response.setSuccess();
  response.setTag( tag() );
  response.setString( "List completed" );
  emit responseAvailable( response );
  deleteLater();
  return true;
}

#include "list.moc"
<|endoftext|>


<commit_before>// This file is part of playd.
// playd is licensed under the MIT licence: see LICENSE.txt.

/**
 * @file
 * Implementation of the AudioSink class.
 * @see audio/audio_sink.hpp
 */

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstring>
#include <string>

#include "portaudiocpp/PortAudioCpp.hxx"

#include "../errors.hpp"
#include "../sample_formats.hpp"
#include "../messages.h"
#include "audio_sink.hpp"
#include "audio_source.hpp"
#include "ringbuffer.hpp"

const size_t AudioSink::RINGBUF_POWER = 16;

AudioSink::AudioSink(const AudioSource &source,
                     const AudioSinkConfigurator &conf)
    : bytes_per_sample(source.BytesPerSample()),
      ring_buf(RINGBUF_POWER, source.BytesPerSample()),
      position_sample_count(0),
      just_started(false),
      input_ready(false)
{
	this->stream = decltype(this->stream)(conf.Configure(source, *this));
}

void AudioSink::Start()
{
	this->just_started = true;
	this->stream->start();
}

void AudioSink::Stop()
{
	if (!this->stream->isStopped()) {
		this->stream->abort();
	}
}

bool AudioSink::IsStopped()
{
	return !this->stream->isActive();
}

bool AudioSink::InputReady()
{
	return this->input_ready;
}

void AudioSink::SetInputReady(bool ready)
{
	this->input_ready = ready;
}

AudioSink::SamplePosition AudioSink::Position()
{
	return this->position_sample_count;
}

void AudioSink::SetPosition(AudioSink::SamplePosition samples)
{
	this->position_sample_count = samples;
	this->ring_buf.Flush();
}

void AudioSink::Transfer(AudioSink::TransferIterator &start,
                         const AudioSink::TransferIterator &end)
{
	assert(start < end);

	// No point transferring 0 bytes.
	if (start == end) return;

	unsigned long bytes = std::distance(start, end);
	// There should be a whole number of samples being transferred.
	assert(bytes % bytes_per_sample == 0);
	assert(0 < bytes);

	auto samples = bytes / this->bytes_per_sample;

	// Only transfer as many samples as the ring buffer can take.
	// Don't bother trying to write 0 samples!
	auto count = std::min(samples, this->ring_buf.WriteCapacity());
	assert(0 < count);
	if (count == 0) return;

	auto start_ptr = reinterpret_cast<char *>(&*start);
	unsigned long written_count = this->ring_buf.Write(start_ptr, count);
	// Since we never write more than the ring buffer can take, the written
	// count should equal the requested written count.
	assert(written_count == count);

	start += (written_count * this->bytes_per_sample);
	assert(start <= end);
}

int AudioSink::paCallbackFun(const void *, void *out,
                             unsigned long frames_per_buf,
                             const PaStreamCallbackTimeInfo *,
                             PaStreamCallbackFlags)
{
	char *cout = static_cast<char *>(out);

	std::pair<PaStreamCallbackResult, unsigned long> result =
	                std::make_pair(paContinue, 0);

	while (result.first == paContinue && result.second < frames_per_buf) {
		result = PlayCallbackStep(cout, frames_per_buf, result);
	}
	return static_cast<int>(result.first);
}

PlayCallbackStepResult AudioSink::PlayCallbackStep(char *out,
                                                   unsigned long frames_per_buf,
                                                   PlayCallbackStepResult in)
{
	unsigned long avail = this->ring_buf.ReadCapacity();
	bool empty = avail == 0;

	/* If we've just started this stream, we don't want to hand PortAudio
	   an incomplete frame—we'd rather wait until we have enough in the
	   ring buffer before starting to play out. */
	bool wait = this->just_started && (avail < frames_per_buf);

	bool failed = wait || empty;
	auto fn = failed ? &AudioSink::PlayCallbackFailure
	                 : &AudioSink::PlayCallbackSuccess;
	return (this->*fn)(out, avail, frames_per_buf, in);
}

PlayCallbackStepResult AudioSink::PlayCallbackSuccess(
                char *out, unsigned long avail, unsigned long frames_per_buf,
                PlayCallbackStepResult in)
{
	this->just_started = false;

	auto samples_pa_wants = frames_per_buf - in.second;
	auto samples_read = ReadSamplesToOutput(out, avail, samples_pa_wants);

	return std::make_pair(paContinue, in.second + samples_read);
}

PlayCallbackStepResult AudioSink::PlayCallbackFailure(
                char *out, unsigned long, unsigned long frames_per_buf,
                PlayCallbackStepResult in)
{
	decltype(in) result;

	if (this->InputReady()) {
		// There's been some sort of genuine issue.
		// Make up some silence to plug the gap.
		Debug() << "Buffer underflow" << std::endl;
		memset(out, 0, this->bytes_per_sample * frames_per_buf);
		result = std::make_pair(paContinue, frames_per_buf);
	} else {
		// End of input is ok, it means the stream can finish.
		result = std::make_pair(paComplete, in.second);
	}

	return result;
}

unsigned long AudioSink::ReadSamplesToOutput(char *&output,
                                             unsigned long output_capacity,
                                             unsigned long buffered_count)
{
	// Transfer the maximum that we can offer to PortAudio without
	// overshooting
	// its sample request limit.
	long transfer_sample_count = static_cast<long>(
	                std::min({ output_capacity, buffered_count,
		                   static_cast<unsigned long>(LONG_MAX) }));
	output += this->ring_buf.Read(output, transfer_sample_count);

	// Update the position count so it reflects the last position that was
	// sent
	// for playback (*not* the last position decoded).
	this->position_sample_count += transfer_sample_count;
	return transfer_sample_count;
}
<commit_msg>Clean up AudioSink a bit.<commit_after>// This file is part of playd.
// playd is licensed under the MIT licence: see LICENSE.txt.

/**
 * @file
 * Implementation of the AudioSink class.
 * @see audio/audio_sink.hpp
 */

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstring>
#include <string>

#include "portaudiocpp/PortAudioCpp.hxx"

#include "../errors.hpp"
#include "../sample_formats.hpp"
#include "../messages.h"
#include "audio_sink.hpp"
#include "audio_source.hpp"
#include "ringbuffer.hpp"

const size_t AudioSink::RINGBUF_POWER = 16;

AudioSink::AudioSink(const AudioSource &source,
                     const AudioSinkConfigurator &conf)
    : bytes_per_sample(source.BytesPerSample()),
      ring_buf(RINGBUF_POWER, source.BytesPerSample()),
      position_sample_count(0),
      just_started(false),
      input_ready(false)
{
	this->stream = decltype(this->stream)(conf.Configure(source, *this));
}

void AudioSink::Start()
{
	this->just_started = true;
	this->stream->start();
}

void AudioSink::Stop()
{
	if (!this->stream->isStopped()) {
		this->stream->abort();
	}
}

bool AudioSink::IsStopped()
{
	return !this->stream->isActive();
}

bool AudioSink::InputReady()
{
	return this->input_ready;
}

void AudioSink::SetInputReady(bool ready)
{
	this->input_ready = ready;
}

AudioSink::SamplePosition AudioSink::Position()
{
	return this->position_sample_count;
}

void AudioSink::SetPosition(AudioSink::SamplePosition samples)
{
	this->position_sample_count = samples;
	this->ring_buf.Flush();
}

void AudioSink::Transfer(AudioSink::TransferIterator &start,
                         const AudioSink::TransferIterator &end)
{
	assert(start < end);

	// No point transferring 0 bytes.
	if (start == end) return;

	unsigned long bytes = std::distance(start, end);
	// There should be a whole number of samples being transferred.
	assert(bytes % bytes_per_sample == 0);
	assert(0 < bytes);

	auto samples = bytes / this->bytes_per_sample;

	// Only transfer as many samples as the ring buffer can take.
	// Don't bother trying to write 0 samples!
	auto count = std::min(samples, this->ring_buf.WriteCapacity());
	assert(0 < count);
	if (count == 0) return;

	auto start_ptr = reinterpret_cast<char *>(&*start);
	unsigned long written_count = this->ring_buf.Write(start_ptr, count);
	// Since we never write more than the ring buffer can take, the written
	// count should equal the requested written count.
	assert(written_count == count);

	start += (written_count * this->bytes_per_sample);
	assert(start <= end);
}

int AudioSink::paCallbackFun(const void *, void *out,
                             unsigned long frames_per_buf,
                             const PaStreamCallbackTimeInfo *,
                             PaStreamCallbackFlags)
{
	char *cout = static_cast<char *>(out);

	std::pair<PaStreamCallbackResult, unsigned long> result =
	                std::make_pair(paContinue, 0);

	while (result.first == paContinue && result.second < frames_per_buf) {
		result = PlayCallbackStep(cout, frames_per_buf, result);
	}
	return static_cast<int>(result.first);
}

PlayCallbackStepResult AudioSink::PlayCallbackStep(char *out,
                                                   unsigned long frames_per_buf,
                                                   PlayCallbackStepResult in)
{
	unsigned long avail = this->ring_buf.ReadCapacity();
	bool empty = avail == 0;

	/* If we've just started this stream, we don't want to hand PortAudio
	   an incomplete frame—we'd rather wait until we have enough in the
	   ring buffer before starting to play out. */
	bool wait = this->just_started && (avail < frames_per_buf);

	bool failed = wait || empty;
	auto fn = failed ? &AudioSink::PlayCallbackFailure
	                 : &AudioSink::PlayCallbackSuccess;
	return (this->*fn)(out, avail, frames_per_buf, in);
}

PlayCallbackStepResult AudioSink::PlayCallbackSuccess(
                char *out, unsigned long avail, unsigned long frames_per_buf,
                PlayCallbackStepResult in)
{
	this->just_started = false;

	auto samples_pa_wants = frames_per_buf - in.second;
	auto samples_read = ReadSamplesToOutput(out, avail, samples_pa_wants);

	return std::make_pair(paContinue, in.second + samples_read);
}

PlayCallbackStepResult AudioSink::PlayCallbackFailure(
                char *out, unsigned long, unsigned long frames_per_buf,
                PlayCallbackStepResult in)
{
	decltype(in) result;

	// End of input is ok, it means the stream can finish.
	if (!this->InputReady()) return std::make_pair(paComplete, in.second);

	// There's been some sort of genuine issue.
	// Make up some silence to plug the gap.
	Debug() << "Buffer underflow" << std::endl;
	memset(out, 0, this->bytes_per_sample * frames_per_buf);
	return std::make_pair(paContinue, frames_per_buf);
}

unsigned long AudioSink::ReadSamplesToOutput(char *&output,
                                             unsigned long output_capacity,
                                             unsigned long buffered_count)
{
	// Transfer the maximum that we can offer to PortAudio without
	// overshooting its sample request limit.
	long transfer_sample_count = static_cast<long>(
	                std::min({ output_capacity, buffered_count,
		                   static_cast<unsigned long>(LONG_MAX) }));
	output += this->ring_buf.Read(output, transfer_sample_count);

	// Update the position count so it reflects the last position that was
	// sent for playback (*not* the last position decoded).
	this->position_sample_count += transfer_sample_count;
	return transfer_sample_count;
}
<|endoftext|>