<commit_before>/*
Copyright (c) 2013 Daniele Bartolini, Michele Rossi
Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

#include "Compiler.h"
#include "Filesystem.h"
#include "DiskFileSource.h"
#include "ResourceFormat.h"
#include "File.h"

namespace crown
{

//-----------------------------------------------------------------------------
bool Compiler::compile(const char* root_path, const char* dest_path, const char* name_in, const char* name_out)
{
	DiskFileSource root_disk(root_path);
	DiskFileSource dest_disk(dest_path);
	Filesystem root_fs(root_disk);
	Filesystem dest_fs(dest_disk);

	// The compilation fails when returned size is zero
	size_t resource_size = 0;
	if ((resource_size = compile_impl(root_fs, name_in)) == 0)
	{
		Log::e("Compilation failed");
		return false;
	}

	// Setup resource header
	ResourceHeader resource_header;
	resource_header.magic = RESOURCE_MAGIC_NUMBER;
	resource_header.version = RESOURCE_VERSION;
	resource_header.size = resource_size;

	// Open destination file and write the header
	File* out_file = dest_fs.open(name_out, FOM_WRITE);

	if (out_file)
	{
		// Write header
		out_file->write((char*)&resource_header, sizeof(ResourceHeader));

		// Write resource-specific data
		write_impl(out_file);

		dest_fs.close(out_file);

		cleanup();
		return true;
	}

	Log::e("Unable to write compiled file.");
	return false;
}

//-----------------------------------------------------------------------------
void Compiler::cleanup()
{
}

} // namespace crown

<commit_msg>Fix Compiler building<commit_after>/*
Copyright (c) 2013 Daniele Bartolini, Michele Rossi
Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

#include "Compiler.h"
#include "Filesystem.h"
#include "DiskFilesystem.h"
#include "ResourceFormat.h"
#include "File.h"

namespace crown
{

//-----------------------------------------------------------------------------
bool Compiler::compile(const char* root_path, const char* dest_path, const char* name_in, const char* name_out)
{
	DiskFilesystem root_fs(root_path);
	DiskFilesystem dest_fs(dest_path);

	// The compilation fails when returned size is zero
	size_t resource_size = 0;
	if ((resource_size = compile_impl(root_fs, name_in)) == 0)
	{
		Log::e("Compilation failed");
		return false;
	}

	// Setup resource header
	ResourceHeader resource_header;
	resource_header.magic = RESOURCE_MAGIC_NUMBER;
	resource_header.version = RESOURCE_VERSION;
	resource_header.size = resource_size;

	// Open destination file and write the header
	File* out_file = dest_fs.open(name_out, FOM_WRITE);

	if (out_file)
	{
		// Write header
		out_file->write((char*)&resource_header, sizeof(ResourceHeader));

		// Write resource-specific data
		write_impl(out_file);

		dest_fs.close(out_file);

		cleanup();
		return true;
	}

	Log::e("Unable to write compiled file.");
	return false;
}

//-----------------------------------------------------------------------------
void Compiler::cleanup()
{
}

} // namespace crown

<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 *
 */

#ifdef RTC_ENABLE_VP9

#include "modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.h"

#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/ref_counted_object.h"
#include "vpx/vpx_codec.h"
#include "vpx/vpx_decoder.h"
#include "vpx/vpx_frame_buffer.h"

namespace webrtc {

uint8_t* Vp9FrameBufferPool::Vp9FrameBuffer::GetData() {
  return data_.data<uint8_t>();
}

size_t Vp9FrameBufferPool::Vp9FrameBuffer::GetDataSize() const {
  return data_.size();
}

void Vp9FrameBufferPool::Vp9FrameBuffer::SetSize(size_t size) {
  data_.SetSize(size);
}

bool Vp9FrameBufferPool::InitializeVpxUsePool(
    vpx_codec_ctx* vpx_codec_context) {
  RTC_DCHECK(vpx_codec_context);
  // Tell libvpx to use this pool.
  if (vpx_codec_set_frame_buffer_functions(
          // In which context to use these callback functions.
          vpx_codec_context,
          // Called by libvpx when it needs another frame buffer.
          &Vp9FrameBufferPool::VpxGetFrameBuffer,
          // Called by libvpx when it no longer uses a frame buffer.
          &Vp9FrameBufferPool::VpxReleaseFrameBuffer,
          // |this| will be passed as |user_priv| to VpxGetFrameBuffer.
          this)) {
    // Failed to configure libvpx to use Vp9FrameBufferPool.
    return false;
  }
  return true;
}

rtc::scoped_refptr<Vp9FrameBufferPool::Vp9FrameBuffer>
Vp9FrameBufferPool::GetFrameBuffer(size_t min_size) {
  RTC_DCHECK_GT(min_size, 0);
  rtc::scoped_refptr<Vp9FrameBuffer> available_buffer = nullptr;
  {
    rtc::CritScope cs(&buffers_lock_);
    // Do we have a buffer we can recycle?
    for (const auto& buffer : allocated_buffers_) {
      if (buffer->HasOneRef()) {
        available_buffer = buffer;
        break;
      }
    }
    // Otherwise create one.
    if (available_buffer == nullptr) {
      available_buffer = new rtc::RefCountedObject<Vp9FrameBuffer>();
      allocated_buffers_.push_back(available_buffer);
      if (allocated_buffers_.size() > max_num_buffers_) {
        RTC_LOG(LS_WARNING)
            << allocated_buffers_.size() << " Vp9FrameBuffers have been "
            << "allocated by a Vp9FrameBufferPool (exceeding what is "
            << "considered reasonable, " << max_num_buffers_ << ").";

        // TODO(phoglund): this limit is being hit in tests since Oct 5 2016.
        // See https://bugs.chromium.org/p/webrtc/issues/detail?id=6484.
        // RTC_NOTREACHED();
      }
    }
  }

  available_buffer->SetSize(min_size);
  return available_buffer;
}

int Vp9FrameBufferPool::GetNumBuffersInUse() const {
  int num_buffers_in_use = 0;
  rtc::CritScope cs(&buffers_lock_);
  for (const auto& buffer : allocated_buffers_) {
    if (!buffer->HasOneRef())
      ++num_buffers_in_use;
  }
  return num_buffers_in_use;
}

void Vp9FrameBufferPool::ClearPool() {
  rtc::CritScope cs(&buffers_lock_);
  allocated_buffers_.clear();
}

// static
int32_t Vp9FrameBufferPool::VpxGetFrameBuffer(void* user_priv,
                                              size_t min_size,
                                              vpx_codec_frame_buffer* fb) {
  RTC_DCHECK(user_priv);
  RTC_DCHECK(fb);
  Vp9FrameBufferPool* pool = static_cast<Vp9FrameBufferPool*>(user_priv);

  rtc::scoped_refptr<Vp9FrameBuffer> buffer = pool->GetFrameBuffer(min_size);
  fb->data = buffer->GetData();
  fb->size = buffer->GetDataSize();
  // Store Vp9FrameBuffer* in |priv| for use in VpxReleaseFrameBuffer.
  // This also makes vpx_codec_get_frame return images with their |fb_priv| set
  // to |buffer| which is important for external reference counting.
  // Release from refptr so that the buffer's |ref_count_| remains 1 when
  // |buffer| goes out of scope.
  fb->priv = static_cast<void*>(buffer.release());
  return 0;
}

// static
int32_t Vp9FrameBufferPool::VpxReleaseFrameBuffer(void* user_priv,
                                                  vpx_codec_frame_buffer* fb) {
  RTC_DCHECK(user_priv);
  RTC_DCHECK(fb);
  Vp9FrameBuffer* buffer = static_cast<Vp9FrameBuffer*>(fb->priv);
  if (buffer != nullptr) {
    buffer->Release();
    // When libvpx fails to decode and you continue to try to decode (and fail)
    // libvpx can for some reason try to release the same buffer multiple times.
    // Setting |priv| to null protects against trying to Release multiple times.
    fb->priv = nullptr;
  }
  return 0;
}

}  // namespace webrtc

#endif  // RTC_ENABLE_VP9
<commit_msg>Cap vp9 fuzzer frame size to prevent OOM<commit_after>/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 *
 */

#ifdef RTC_ENABLE_VP9

#include "modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.h"

#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/ref_counted_object.h"
#include "vpx/vpx_codec.h"
#include "vpx/vpx_decoder.h"
#include "vpx/vpx_frame_buffer.h"

namespace webrtc {

uint8_t* Vp9FrameBufferPool::Vp9FrameBuffer::GetData() {
  return data_.data<uint8_t>();
}

size_t Vp9FrameBufferPool::Vp9FrameBuffer::GetDataSize() const {
  return data_.size();
}

void Vp9FrameBufferPool::Vp9FrameBuffer::SetSize(size_t size) {
  data_.SetSize(size);
}

bool Vp9FrameBufferPool::InitializeVpxUsePool(
    vpx_codec_ctx* vpx_codec_context) {
  RTC_DCHECK(vpx_codec_context);
  // Tell libvpx to use this pool.
  if (vpx_codec_set_frame_buffer_functions(
          // In which context to use these callback functions.
          vpx_codec_context,
          // Called by libvpx when it needs another frame buffer.
          &Vp9FrameBufferPool::VpxGetFrameBuffer,
          // Called by libvpx when it no longer uses a frame buffer.
          &Vp9FrameBufferPool::VpxReleaseFrameBuffer,
          // |this| will be passed as |user_priv| to VpxGetFrameBuffer.
          this)) {
    // Failed to configure libvpx to use Vp9FrameBufferPool.
    return false;
  }
  return true;
}

rtc::scoped_refptr<Vp9FrameBufferPool::Vp9FrameBuffer>
Vp9FrameBufferPool::GetFrameBuffer(size_t min_size) {
  RTC_DCHECK_GT(min_size, 0);
  rtc::scoped_refptr<Vp9FrameBuffer> available_buffer = nullptr;
  {
    rtc::CritScope cs(&buffers_lock_);
    // Do we have a buffer we can recycle?
    for (const auto& buffer : allocated_buffers_) {
      if (buffer->HasOneRef()) {
        available_buffer = buffer;
        break;
      }
    }
    // Otherwise create one.
    if (available_buffer == nullptr) {
      available_buffer = new rtc::RefCountedObject<Vp9FrameBuffer>();
      allocated_buffers_.push_back(available_buffer);
      if (allocated_buffers_.size() > max_num_buffers_) {
        RTC_LOG(LS_WARNING)
            << allocated_buffers_.size() << " Vp9FrameBuffers have been "
            << "allocated by a Vp9FrameBufferPool (exceeding what is "
            << "considered reasonable, " << max_num_buffers_ << ").";

        // TODO(phoglund): this limit is being hit in tests since Oct 5 2016.
        // See https://bugs.chromium.org/p/webrtc/issues/detail?id=6484.
        // RTC_NOTREACHED();
      }
    }
  }

  available_buffer->SetSize(min_size);
  return available_buffer;
}

int Vp9FrameBufferPool::GetNumBuffersInUse() const {
  int num_buffers_in_use = 0;
  rtc::CritScope cs(&buffers_lock_);
  for (const auto& buffer : allocated_buffers_) {
    if (!buffer->HasOneRef())
      ++num_buffers_in_use;
  }
  return num_buffers_in_use;
}

void Vp9FrameBufferPool::ClearPool() {
  rtc::CritScope cs(&buffers_lock_);
  allocated_buffers_.clear();
}

// static
int32_t Vp9FrameBufferPool::VpxGetFrameBuffer(void* user_priv,
                                              size_t min_size,
                                              vpx_codec_frame_buffer* fb) {
  RTC_DCHECK(user_priv);
  RTC_DCHECK(fb);

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  // Limit size of 8k YUV highdef frame
  size_t size_limit = 7680 * 4320 * 3 / 2 * 2;
  if (min_size > size_limit)
    return -1;
#endif

  Vp9FrameBufferPool* pool = static_cast<Vp9FrameBufferPool*>(user_priv);

  rtc::scoped_refptr<Vp9FrameBuffer> buffer = pool->GetFrameBuffer(min_size);
  fb->data = buffer->GetData();
  fb->size = buffer->GetDataSize();
  // Store Vp9FrameBuffer* in |priv| for use in VpxReleaseFrameBuffer.
  // This also makes vpx_codec_get_frame return images with their |fb_priv| set
  // to |buffer| which is important for external reference counting.
  // Release from refptr so that the buffer's |ref_count_| remains 1 when
  // |buffer| goes out of scope.
  fb->priv = static_cast<void*>(buffer.release());
  return 0;
}

// static
int32_t Vp9FrameBufferPool::VpxReleaseFrameBuffer(void* user_priv,
                                                  vpx_codec_frame_buffer* fb) {
  RTC_DCHECK(user_priv);
  RTC_DCHECK(fb);
  Vp9FrameBuffer* buffer = static_cast<Vp9FrameBuffer*>(fb->priv);
  if (buffer != nullptr) {
    buffer->Release();
    // When libvpx fails to decode and you continue to try to decode (and fail)
    // libvpx can for some reason try to release the same buffer multiple times.
    // Setting |priv| to null protects against trying to Release multiple times.
    fb->priv = nullptr;
  }
  return 0;
}

}  // namespace webrtc

#endif  // RTC_ENABLE_VP9
<|endoftext|>


<commit_before>#include "PenaltyCircuitPotential.h"
#include "MooseMesh.h"

template<>
InputParameters validParams<PenaltyCircuitPotential>()
{
  InputParameters p = validParams<NonlocalIntegratedBC>();
  p.addRequiredParam<UserObjectName>("current", "The postprocessor response for calculating the current passing through the needle surface.");
  p.addRequiredParam<Real>("surface_potential", "The electrical potential applied to the surface if no current was flowing in the circuit.");
  p.addRequiredParam<std::string>("surface", "Whether you are specifying the potential on the anode or the cathode with the requirement that the other metal surface be grounded.");
  p.addRequiredParam<Real>("penalty", "The constant multiplying the penalty term.");
  p.addRequiredParam<UserObjectName>("data_provider", "The name of the UserObject that can provide some data to materials, bcs, etc.");
  p.addRequiredCoupledVar("em", "The electron variable.");
  p.addRequiredCoupledVar("ip", "The ion variable.");
  p.addRequiredCoupledVar("mean_en", "The ion variable.");
  p.addParam<Real>("area", "Must be provided when the number of dimensions equals 1.");
  p.addRequiredParam<std::string>("potential_units", "The potential units.");
  p.addRequiredParam<Real>("position_units", "Units of position.");
  p.addRequiredParam<Real>("resistance", "The ballast resistance in Ohms.");
  return p;
}

PenaltyCircuitPotential::PenaltyCircuitPotential(const InputParameters & parameters) :
  NonlocalIntegratedBC(parameters),
  _current_uo(getUserObject<CurrentDensityShapeSideUserObject>("current")),
  _current(_current_uo.getIntegral()),
  _current_jac(_current_uo.getJacobian()),
  _surface_potential(getParam<Real>("surface_potential")),
  _surface(getParam<std::string>("surface")),
  _p(getParam<Real>("penalty")),
  _data(getUserObject<ProvideMobility>("data_provider")),
  _var_dofs(_var.dofIndices()),
  _em_id(coupled("em")),
  _em_dofs(getVar("em", 0)->dofIndices()),
  _ip_id(coupled("ip")),
  _ip_dofs(getVar("ip", 0)->dofIndices()),
  _mean_en_id(coupled("mean_en")),
  _mean_en_dofs(getVar("mean_en", 0)->dofIndices()),
  _r_units(1. / getParam<Real>("position_units")),
  _resistance(getParam<Real>("resistance"))
{
  if (_surface.compare("anode") == 0)
    _current_sign = -1.;
  else if (_surface.compare("cathode") == 0)
    _current_sign = 1.;

  if (_mesh.dimension() == 1 && isParamValid("area"))
  {
    _area = getParam<Real>("area");
    _use_area = true;
  }
  else if (_mesh.dimension() == 1 && !(isParamValid("area")))
    mooseError("In a one-dimensional simulation, the area parameter must be set.");
  else
    _use_area = false;

  if (getParam<std::string>("potential_units").compare("V") == 0)
    _voltage_scaling = 1.;
  else if (getParam<std::string>("potential_units").compare("kV") == 0)
    _voltage_scaling = 1000;
  else
    mooseError("Potential specified must be either 'V' or 'kV'.");
}

Real
PenaltyCircuitPotential::computeQpResidual()
{
  Real curr_times_resist = _current_sign * _current * _resistance / _voltage_scaling;
  if (_use_area)
    curr_times_resist *= _area;

  return _test[_i][_qp] * _p * (_surface_potential - _u[_qp] + curr_times_resist);
}

Real
PenaltyCircuitPotential::computeQpJacobian()
{
  Real d_curr_times_resist_d_potential = _current_sign * _current_jac[_var_dofs[_j]] * _resistance / _voltage_scaling;
  if (_use_area)
    d_curr_times_resist_d_potential *= _area;

  return _test[_i][_qp] * _p * (-_phi[_j][_qp] + d_curr_times_resist_d_potential);
}

Real
PenaltyCircuitPotential::computeQpOffDiagJacobian(unsigned int jvar)
{
  if (jvar == _em_id)
  {
    Real d_curr_times_resist_d_em = _current_sign * _current_jac[_em_dofs[_j]] * _resistance / _voltage_scaling;
    if (_use_area)
      d_curr_times_resist_d_em *= _area;

    return _test[_i][_qp] * _p * d_curr_times_resist_d_em;
  }

  else if (jvar == _ip_id)
  {
    Real d_curr_times_resist_d_ip = _current_sign * _current_jac[_ip_dofs[_j]] * _resistance / _voltage_scaling;
    if (_use_area)
      d_curr_times_resist_d_ip *= _area;

    return _test[_i][_qp] * _p * d_curr_times_resist_d_ip;
  }

  else if (jvar == _mean_en_id)
  {
    Real d_curr_times_resist_d_mean_en = _current_sign * _current_jac[_mean_en_dofs[_j]] * _resistance / _voltage_scaling;
    if (_use_area)
      d_curr_times_resist_d_mean_en *= _area;

    return _test[_i][_qp] * _p * d_curr_times_resist_d_mean_en;
  }

  else
    return 0;
}

Real
PenaltyCircuitPotential::computeQpNonlocalJacobian(dof_id_type dof_index)
{
  Real d_curr_times_resist_d_potential = _current_sign * _current_jac[dof_index] * _resistance / _voltage_scaling;
  if (_use_area)
    d_curr_times_resist_d_potential *= _area;

  return _test[_i][_qp] * _p * d_curr_times_resist_d_potential;
}

Real
PenaltyCircuitPotential::computeQpNonlocalOffDiagJacobian(unsigned int jvar, dof_id_type dof_index)
{
  if (jvar == _em_id || jvar == _ip_id || jvar == _mean_en_id)
  {
    Real d_curr_times_resist_d_coupled_var = _current_sign * _current_jac[dof_index] * _resistance / _voltage_scaling;
    if (_use_area)
      d_curr_times_resist_d_coupled_var *= _area;

    return _test[_i][_qp] * _p * d_curr_times_resist_d_coupled_var;
  }

  return 0;
}
<commit_msg>Add r_units.<commit_after>#include "PenaltyCircuitPotential.h"
#include "MooseMesh.h"

template<>
InputParameters validParams<PenaltyCircuitPotential>()
{
  InputParameters p = validParams<NonlocalIntegratedBC>();
  p.addRequiredParam<UserObjectName>("current", "The postprocessor response for calculating the current passing through the needle surface.");
  p.addRequiredParam<Real>("surface_potential", "The electrical potential applied to the surface if no current was flowing in the circuit.");
  p.addRequiredParam<std::string>("surface", "Whether you are specifying the potential on the anode or the cathode with the requirement that the other metal surface be grounded.");
  p.addRequiredParam<Real>("penalty", "The constant multiplying the penalty term.");
  p.addRequiredParam<UserObjectName>("data_provider", "The name of the UserObject that can provide some data to materials, bcs, etc.");
  p.addRequiredCoupledVar("em", "The electron variable.");
  p.addRequiredCoupledVar("ip", "The ion variable.");
  p.addRequiredCoupledVar("mean_en", "The ion variable.");
  p.addParam<Real>("area", "Must be provided when the number of dimensions equals 1.");
  p.addRequiredParam<std::string>("potential_units", "The potential units.");
  p.addRequiredParam<Real>("position_units", "Units of position.");
  p.addRequiredParam<Real>("resistance", "The ballast resistance in Ohms.");
  return p;
}

PenaltyCircuitPotential::PenaltyCircuitPotential(const InputParameters & parameters) :
  NonlocalIntegratedBC(parameters),
  _current_uo(getUserObject<CurrentDensityShapeSideUserObject>("current")),
  _current(_current_uo.getIntegral()),
  _current_jac(_current_uo.getJacobian()),
  _surface_potential(getParam<Real>("surface_potential")),
  _surface(getParam<std::string>("surface")),
  _p(getParam<Real>("penalty")),
  _data(getUserObject<ProvideMobility>("data_provider")),
  _var_dofs(_var.dofIndices()),
  _em_id(coupled("em")),
  _em_dofs(getVar("em", 0)->dofIndices()),
  _ip_id(coupled("ip")),
  _ip_dofs(getVar("ip", 0)->dofIndices()),
  _mean_en_id(coupled("mean_en")),
  _mean_en_dofs(getVar("mean_en", 0)->dofIndices()),
  _r_units(1. / getParam<Real>("position_units")),
  _resistance(getParam<Real>("resistance"))
{
  if (_surface.compare("anode") == 0)
    _current_sign = -1.;
  else if (_surface.compare("cathode") == 0)
    _current_sign = 1.;

  if (_mesh.dimension() == 1 && isParamValid("area"))
  {
    _area = getParam<Real>("area");
    _use_area = true;
  }
  else if (_mesh.dimension() == 1 && !(isParamValid("area")))
    mooseError("In a one-dimensional simulation, the area parameter must be set.");
  else
    _use_area = false;

  if (getParam<std::string>("potential_units").compare("V") == 0)
    _voltage_scaling = 1.;
  else if (getParam<std::string>("potential_units").compare("kV") == 0)
    _voltage_scaling = 1000;
  else
    mooseError("Potential specified must be either 'V' or 'kV'.");
}

Real
PenaltyCircuitPotential::computeQpResidual()
{
  Real curr_times_resist = _current_sign * _current * _resistance / _voltage_scaling;
  if (_use_area)
    curr_times_resist *= _area;

  return _test[_i][_qp] * _r_units * _p * (_surface_potential - _u[_qp] + curr_times_resist);
}

Real
PenaltyCircuitPotential::computeQpJacobian()
{
  Real d_curr_times_resist_d_potential = _current_sign * _current_jac[_var_dofs[_j]] * _resistance / _voltage_scaling;
  if (_use_area)
    d_curr_times_resist_d_potential *= _area;

  return _test[_i][_qp] * _r_units * _p * (-_phi[_j][_qp] + d_curr_times_resist_d_potential);
}

Real
PenaltyCircuitPotential::computeQpOffDiagJacobian(unsigned int jvar)
{
  if (jvar == _em_id)
  {
    Real d_curr_times_resist_d_em = _current_sign * _current_jac[_em_dofs[_j]] * _resistance / _voltage_scaling;
    if (_use_area)
      d_curr_times_resist_d_em *= _area;

    return _test[_i][_qp] * _r_units * _p * d_curr_times_resist_d_em;
  }

  else if (jvar == _ip_id)
  {
    Real d_curr_times_resist_d_ip = _current_sign * _current_jac[_ip_dofs[_j]] * _resistance / _voltage_scaling;
    if (_use_area)
      d_curr_times_resist_d_ip *= _area;

    return _test[_i][_qp] * _r_units * _p * d_curr_times_resist_d_ip;
  }

  else if (jvar == _mean_en_id)
  {
    Real d_curr_times_resist_d_mean_en = _current_sign * _current_jac[_mean_en_dofs[_j]] * _resistance / _voltage_scaling;
    if (_use_area)
      d_curr_times_resist_d_mean_en *= _area;

    return _test[_i][_qp] * _r_units * _p * d_curr_times_resist_d_mean_en;
  }

  else
    return 0;
}

Real
PenaltyCircuitPotential::computeQpNonlocalJacobian(dof_id_type dof_index)
{
  Real d_curr_times_resist_d_potential = _current_sign * _current_jac[dof_index] * _resistance / _voltage_scaling;
  if (_use_area)
    d_curr_times_resist_d_potential *= _area;

  return _test[_i][_qp] * _r_units * _p * d_curr_times_resist_d_potential;
}

Real
PenaltyCircuitPotential::computeQpNonlocalOffDiagJacobian(unsigned int jvar, dof_id_type dof_index)
{
  if (jvar == _em_id || jvar == _ip_id || jvar == _mean_en_id)
  {
    Real d_curr_times_resist_d_coupled_var = _current_sign * _current_jac[dof_index] * _resistance / _voltage_scaling;
    if (_use_area)
      d_curr_times_resist_d_coupled_var *= _area;

    return _test[_i][_qp] * _r_units * _p * d_curr_times_resist_d_coupled_var;
  }

  return 0;
}
<|endoftext|>


<commit_before>#ifndef PCL_TRACKING_IMPL_KLD_ADAPTIVE_PARTICLE_FILTER_H_
#define PCL_TRACKING_IMPL_KLD_ADAPTIVE_PARTICLE_FILTER_H_

#include <pcl/tracking/kld_adaptive_particle_filter.h>

template <typename PointInT, typename StateT> bool
pcl::tracking::KLDAdaptiveParticleFilterTracker<PointInT, StateT>::initCompute ()
{
  if (!Tracker<PointInT, StateT>::initCompute ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
    return (false);
  }

  if (transed_reference_vector_.empty ())
  {
    // only one time allocation
    transed_reference_vector_.resize (maximum_particle_number_);
    for (unsigned int i = 0; i < maximum_particle_number_; i++)
    {
      transed_reference_vector_[i] = PointCloudInPtr (new PointCloudIn ());
    }
  }

  coherence_->setTargetCloud (input_);

  if (!change_detector_)
    change_detector_ = boost::shared_ptr<pcl::octree::OctreePointCloudChangeDetector<PointInT> >(new pcl::octree::OctreePointCloudChangeDetector<PointInT> (change_detector_resolution_));

  if (!particles_ || particles_->points.empty ())
    initParticles (true);
  return (true);
}

template <typename PointInT, typename StateT> bool
pcl::tracking::KLDAdaptiveParticleFilterTracker<PointInT, StateT>::insertIntoBins
(std::vector<int> bin, std::vector<std::vector<int> > &B)
{
  for (size_t i = 0; i < B.size (); i++)
  {
    if (equalBin (bin, B[i]))
      return false;
  }
  B.push_back (bin);
  return true;
}

template <typename PointInT, typename StateT> void
pcl::tracking::KLDAdaptiveParticleFilterTracker<PointInT, StateT>::resample ()
{
  unsigned int k = 0;
  unsigned int n = 0;
  PointCloudStatePtr S (new PointCloudState);
  std::vector<std::vector<int> > B; // bins

  // initializing for sampling without replacement
  std::vector<int> a (particles_->points.size ());
  std::vector<double> q (particles_->points.size ());
  this->genAliasTable (a, q, particles_);

  const std::vector<double> zero_mean (StateT::stateDimension (), 0.0);

  // select the particles with KLD sampling
  do
  {
    int j_n = sampleWithReplacement (a, q);
    StateT x_t = particles_->points[j_n];
    x_t.sample (zero_mean, step_noise_covariance_);

    // motion
    if (rand () / double (RAND_MAX) < motion_ratio_)
      x_t = x_t + motion_;

    S->points.push_back (x_t);
    // calc bin
    std::vector<int> bin (StateT::stateDimension ());
    for (int i = 0; i < StateT::stateDimension (); i++)
      bin[i] = static_cast<int> (x_t[i] / bin_size_[i]);

    // calc bin index... how?
    if (insertIntoBins (bin, B))
      ++k;
    ++n;
  }
  while (k < 2 || (n < maximum_particle_number_ && n < calcKLBound (k)));

  particles_ = S;               // swap
  particle_num_ = static_cast<int> (particles_->points.size ());
}

#define PCL_INSTANTIATE_KLDAdaptiveParticleFilterTracker(T,ST) template class PCL_EXPORTS pcl::tracking::KLDAdaptiveParticleFilterTracker<T,ST>;

#endif
<commit_msg>Fix occasional seg fault with KLDAdaptiveParticleFilterOMPTracker<commit_after>#ifndef PCL_TRACKING_IMPL_KLD_ADAPTIVE_PARTICLE_FILTER_H_
#define PCL_TRACKING_IMPL_KLD_ADAPTIVE_PARTICLE_FILTER_H_

#include <pcl/tracking/kld_adaptive_particle_filter.h>

template <typename PointInT, typename StateT> bool
pcl::tracking::KLDAdaptiveParticleFilterTracker<PointInT, StateT>::initCompute ()
{
  if (!Tracker<PointInT, StateT>::initCompute ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
    return (false);
  }

  if (transed_reference_vector_.empty ())
  {
    // only one time allocation
    transed_reference_vector_.resize (maximum_particle_number_);
    for (unsigned int i = 0; i < maximum_particle_number_; i++)
    {
      transed_reference_vector_[i] = PointCloudInPtr (new PointCloudIn ());
    }
  }

  coherence_->setTargetCloud (input_);

  if (!change_detector_)
    change_detector_ = boost::shared_ptr<pcl::octree::OctreePointCloudChangeDetector<PointInT> >(new pcl::octree::OctreePointCloudChangeDetector<PointInT> (change_detector_resolution_));

  if (!particles_ || particles_->points.empty ())
    initParticles (true);
  return (true);
}

template <typename PointInT, typename StateT> bool
pcl::tracking::KLDAdaptiveParticleFilterTracker<PointInT, StateT>::insertIntoBins
(std::vector<int> bin, std::vector<std::vector<int> > &B)
{
  for (size_t i = 0; i < B.size (); i++)
  {
    if (equalBin (bin, B[i]))
      return false;
  }
  B.push_back (bin);
  return true;
}

template <typename PointInT, typename StateT> void
pcl::tracking::KLDAdaptiveParticleFilterTracker<PointInT, StateT>::resample ()
{
  unsigned int k = 0;
  unsigned int n = 0;
  PointCloudStatePtr S (new PointCloudState);
  std::vector<std::vector<int> > B; // bins

  // initializing for sampling without replacement
  std::vector<int> a (particles_->points.size ());
  std::vector<double> q (particles_->points.size ());
  this->genAliasTable (a, q, particles_);

  const std::vector<double> zero_mean (StateT::stateDimension (), 0.0);

  // select the particles with KLD sampling
  do
  {
    int j_n = sampleWithReplacement (a, q);
    StateT x_t = particles_->points[j_n];
    x_t.sample (zero_mean, step_noise_covariance_);

    // motion
    if (rand () / double (RAND_MAX) < motion_ratio_)
      x_t = x_t + motion_;

    S->points.push_back (x_t);
    // calc bin
    std::vector<int> bin (StateT::stateDimension ());
    for (int i = 0; i < StateT::stateDimension (); i++)
      bin[i] = static_cast<int> (x_t[i] / bin_size_[i]);

    // calc bin index... how?
    if (insertIntoBins (bin, B))
      ++k;
    ++n;
  }
  while (n < maximum_particle_number_ && (k < 2 || n < calcKLBound (k)));

  particles_ = S;               // swap
  particle_num_ = static_cast<int> (particles_->points.size ());
}

#define PCL_INSTANTIATE_KLDAdaptiveParticleFilterTracker(T,ST) template class PCL_EXPORTS pcl::tracking::KLDAdaptiveParticleFilterTracker<T,ST>;

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <list>
#include <map>
#include <algorithm>
#include <locale>
#include <getopt.h>
#include <stdlib.h>
#include <unordered_map>

#include "search.h"
#include "stats.h"
#include "seq.h"

void build_patterns(std::ifstream & kmers_f, int polyG, std::vector <std::pair <std::string, Node::Type> > & patterns)
{
    std::string tmp;
    while (!kmers_f.eof()) {
        std::getline(kmers_f, tmp);
        std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
        if (!tmp.empty()) {
            size_t tab = tmp.find('\t');
            if (tab == std::string::npos) {
                patterns.push_back(std::make_pair(tmp, Node::Type::adapter));
            } else {
                patterns.push_back(std::make_pair(tmp.substr(0, tab), Node::Type::adapter));
            }
        }
    }
    kmers_f.close();
    patterns.push_back(std::make_pair("NNNNN", Node::Type::n));
    if (polyG) {
        patterns.push_back(std::make_pair(std::string(polyG, 'G'), Node::Type::polyG));
        patterns.push_back(std::make_pair(std::string(polyG, 'C'), Node::Type::polyC));
    }
}

double get_dust_score(std::string const & read, int k)
{
    std::unordered_map <int, int> counts;
    static std::unordered_map <char, int> hashes = {{'N', 1},
                                          {'A', 2},
                                          {'C', 3},
                                          {'G', 4},
                                          {'T', 5}};
    unsigned int hash = 0;
    unsigned int max_pow = pow(10, k - 1);
    for (auto it = read.begin(); it != read.end(); ++it) {
        char c = (*it > 96) ? (*it - 32) : *it;
        hash = hash * 10 + hashes[c];
        if (it - read.begin() >= k - 1) {
            ++counts[hash];
            hash = hash - (hash / max_pow) * max_pow;
        }
    }
    double score = 0;
    double total = 0;
    for (auto it = counts.begin(); it != counts.end(); ++it) {
        score += it->second * (it->second - 1) / 2;
        total += score;
    }
//    std::cout << (total / (read.size() - k + 1)) << std::endl;
    return (total / (read.size() - k + 1));
}

ReadType check_read(std::string const & read, Node * root, std::vector <std::pair<std::string, Node::Type> > const & patterns,
                    unsigned int length, int dust_k, int dust_cutoff, int errors)
{
    if (length && read.size() < length) {
        return ReadType::length;
    }
    if (dust_cutoff && get_dust_score(read, dust_k) > dust_cutoff) {
        return ReadType::dust;
    }

    if (errors) {
        return (ReadType)search_inexact(read, root, patterns, errors);
    } else {
        return (ReadType)search_any(read, root);
    }
}

void filter_single_reads(std::ifstream & reads_f, std::ofstream & ok_f, std::ofstream & bad_f,
                         Stats & stats, Node * root, std::vector <std::pair<std::string, Node::Type> > const & patterns,
                         int length, int dust_k, int dust_cutoff, int errors)
{
    Seq read;

    while (read.read_seq(reads_f)) {
        ReadType type = check_read(read.seq, root, patterns, length, dust_k, dust_cutoff, errors);
        stats.update(type);
        if (type == ReadType::ok) {
            read.write_seq(ok_f);
        } else {
            read.update_id(type);
            read.write_seq(bad_f);
        }
    }
}

void filter_paired_reads(std::ifstream & reads1_f, std::ifstream & reads2_f,
                         std::ofstream & ok1_f, std::ofstream & ok2_f,
                         std::ofstream & bad1_f, std::ofstream & bad2_f,
                         std::ofstream & se1_f, std::ofstream & se2_f,
                         Stats & stats1, Stats & stats2,
                         Node * root, std::vector <std::pair<std::string, Node::Type> > const & patterns,
                         int length, int dust_k, int dust_cutoff, int errors)
{
    Seq read1;
    Seq read2;

    while (read1.read_seq(reads1_f) && read2.read_seq(reads2_f)) {
        ReadType type1 = check_read(read1.seq, root, patterns, length, dust_k, dust_cutoff, errors);
        ReadType type2 = check_read(read2.seq, root, patterns, length, dust_k, dust_cutoff, errors);
        if (type1 == ReadType::ok && type2 == ReadType::ok) {
            read1.write_seq(ok1_f);
            read2.write_seq(ok2_f);
            stats1.update(type1, true);
            stats2.update(type2, true);
        } else {
            stats1.update(type1, false);
            stats2.update(type2, false);
            if (type1 == ReadType::ok) {
                read1.write_seq(se1_f);
                read2.update_id(type2);
                read2.write_seq(bad2_f);
            } else if (type2 == ReadType::ok) {
                read1.update_id(type1);
                read1.write_seq(bad1_f);
                read2.write_seq(se2_f);
            } else {
                read1.update_id(type1);
                read2.update_id(type2);
                read1.write_seq(bad1_f);
                read2.write_seq(bad2_f);
            }
        }
    }
}

std::string basename(std::string const & path)
{
    std::string res(path);
    size_t pos = res.find_last_of('/');
    if (pos != std::string::npos) {
        res.erase(0, pos);
    }
    pos = res.find('.');
    if (pos != std::string::npos) {
        res.erase(pos, path.size());
    }
    return res;
}

void print_help()
{
    std::cout << "./rm_reads [-i raw_data.fastq | -1 raw_data1.fastq -2 raw_data2.fastq] -o output_dir --polyG 13 --length 50 --fragments fragments.dat --dust_cutoff cutoff --dust_k k -e 1" << std::endl;
}

int main(int argc, char ** argv)
{
    Node root('0');
    std::vector <std::pair<std::string, Node::Type> > patterns;

    std::string kmers, reads, out_dir;
    std::string reads1, reads2;
    char rez = 0;
    int length = 0;
    int polyG = 0;
    int dust_k = 4;
    int dust_cutoff = 0;
    int errors = 0;

    const struct option long_options[] = {
        {"length",required_argument,NULL,'l'},
        {"polyG",required_argument,NULL,'p'},
        {"fragments",required_argument,NULL,'a'},
        {"dust_k",required_argument,NULL,'k'},
        {"dust_cutoff",required_argument,NULL,'c'},
        {"errors",required_argument,NULL,'e'},
        {NULL,0,NULL,0}
    };

    while ((rez = getopt_long(argc, argv, "1:2:l:p:a:i:o:e:", long_options, NULL)) != -1) {
        switch (rez) {
        case 'l':
            length = std::atoi(optarg);
            break;
        case 'p':
            polyG = std::atoi(optarg);
            // polyG = boost::lexical_cast<int>(optarg);
            break;
        case 'a':
            kmers = optarg;
            break;
        case 'i':
            reads = optarg;
            break;
        case '1':
            reads1 = optarg;
            break;
        case '2':
            reads2 = optarg;
            break;
        case 'o':
            out_dir = optarg;
            break;
        case 'c':
            dust_cutoff = std::atoi(optarg);
            break;
        case 'k':
            dust_k = std::atoi(optarg);
            break;
        case 'e':
            errors = std::atoi(optarg);
            break;
        case '?':
            print_help();
            return -1;
        }
    }

    if (errors < 0 || errors > 2) {
        std::cout << "possible errors count are 0, 1, 2" << std::endl;
        return -1;
    }

    if (kmers.empty() || out_dir.empty() || (
            reads.empty() &&
            (reads1.empty() || reads2.empty()))) {
        print_help();
        return -1;
    }

    std::ifstream kmers_f (kmers.c_str());
    if (!kmers_f.good()) {
        std::cout << "Cannot open kmers file" << std::endl;
        print_help();
        return -1;
    }

    init_type_names(length, polyG, dust_k, dust_cutoff);

    build_patterns(kmers_f, polyG, patterns);

/*
    for (std::vector <std::string> ::iterator it = patterns.begin(); it != patterns.end(); ++it) {
        std::cout << *it << std::endl;
    }
    */

    if (patterns.empty()) {
        std::cout << "patterns are empty" << std::endl;
        return -1;
    }

    build_trie(root, patterns, errors);
	add_failures(root);

    if (!reads.empty()) {
        std::string reads_base = basename(reads);
        std::ifstream reads_f (reads.c_str());
        std::ofstream ok_f((out_dir + "/" + reads_base + ".ok.fastq").c_str(), std::ofstream::out);
        std::ofstream bad_f((out_dir + "/" + reads_base + ".filtered.fastq").c_str(), std::ofstream::out);

        if (!reads_f.good()) {
            std::cout << "Cannot open reads file" << std::endl;
            print_help();
            return -1;
        }

        if (!ok_f.good() || !bad_f.good()) {
            std::cout << "Cannot open output file" << std::endl;
            print_help();
            return -1;
        }

        Stats stats(reads);

        filter_single_reads(reads_f, ok_f, bad_f, stats, &root, patterns, length, dust_k, dust_cutoff, errors);

        std::cout << stats;

        ok_f.close();
        bad_f.close();
        reads_f.close();
    } else {
        std::string reads1_base = basename(reads1);
        std::string reads2_base = basename(reads2);
        std::ifstream reads1_f(reads1.c_str());
        std::ifstream reads2_f(reads2.c_str());
        std::ofstream ok1_f((out_dir + "/" + reads1_base + ".ok.fastq").c_str(),
                            std::ofstream::out);
        std::ofstream ok2_f((out_dir + "/" + reads2_base + ".ok.fastq").c_str(),
                            std::ofstream::out);
        std::ofstream se1_f((out_dir + "/" + reads1_base + ".se.fastq").c_str(),
                            std::ofstream::out);
        std::ofstream se2_f((out_dir + "/" + reads2_base + ".se.fastq").c_str(),
                            std::ofstream::out);
        std::ofstream bad1_f((out_dir + "/" + reads1_base + ".filtered.fastq").c_str(),
                            std::ofstream::out);
        std::ofstream bad2_f((out_dir + "/" + reads2_base + ".filtered.fastq").c_str(),
                            std::ofstream::out);

        if (!reads1_f.good() || !reads2_f.good()) {
            std::cout << "reads file is bad" << std::endl;
            print_help();
            return -1;
        }

        if (!ok1_f.good() || !ok2_f.good() || !bad1_f.good() || !bad2_f.good() ||
                !se1_f.good() || !se2_f.good()) {
            std::cout << "out file is bad" << std::endl;
            print_help();
            return -1;
        }

        Stats stats1(reads1);
        Stats stats2(reads2);

        filter_paired_reads(reads1_f, reads2_f, ok1_f, ok2_f,
                            bad1_f, bad2_f, se1_f, se2_f,
                            stats1, stats2,
                            &root, patterns, length, dust_k, dust_cutoff, errors);

        std::cout << stats1;
        std::cout << stats2;

        ok1_f.close();
        ok2_f.close();
        bad1_f.close();
        bad2_f.close();
        reads1_f.close();
        reads2_f.close();
    }
}
<commit_msg>Change NNNN with NN pattern<commit_after>#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <list>
#include <map>
#include <algorithm>
#include <locale>
#include <getopt.h>
#include <stdlib.h>
#include <unordered_map>

#include "search.h"
#include "stats.h"
#include "seq.h"

void build_patterns(std::ifstream & kmers_f, int polyG, std::vector <std::pair <std::string, Node::Type> > & patterns)
{
    std::string tmp;
    while (!kmers_f.eof()) {
        std::getline(kmers_f, tmp);
        std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper);
        if (!tmp.empty()) {
            size_t tab = tmp.find('\t');
            if (tab == std::string::npos) {
                patterns.push_back(std::make_pair(tmp, Node::Type::adapter));
            } else {
                patterns.push_back(std::make_pair(tmp.substr(0, tab), Node::Type::adapter));
            }
        }
    }
    kmers_f.close();
    patterns.push_back(std::make_pair("NN", Node::Type::n));
    if (polyG) {
        patterns.push_back(std::make_pair(std::string(polyG, 'G'), Node::Type::polyG));
        patterns.push_back(std::make_pair(std::string(polyG, 'C'), Node::Type::polyC));
    }
}

double get_dust_score(std::string const & read, int k)
{
    std::unordered_map <int, int> counts;
    static std::unordered_map <char, int> hashes = {{'N', 1},
                                          {'A', 2},
                                          {'C', 3},
                                          {'G', 4},
                                          {'T', 5}};
    unsigned int hash = 0;
    unsigned int max_pow = pow(10, k - 1);
    for (auto it = read.begin(); it != read.end(); ++it) {
        char c = (*it > 96) ? (*it - 32) : *it;
        hash = hash * 10 + hashes[c];
        if (it - read.begin() >= k - 1) {
            ++counts[hash];
            hash = hash - (hash / max_pow) * max_pow;
        }
    }
    double score = 0;
    double total = 0;
    for (auto it = counts.begin(); it != counts.end(); ++it) {
        score += it->second * (it->second - 1) / 2;
        total += score;
    }
//    std::cout << (total / (read.size() - k + 1)) << std::endl;
    return (total / (read.size() - k + 1));
}

ReadType check_read(std::string const & read, Node * root, std::vector <std::pair<std::string, Node::Type> > const & patterns,
                    unsigned int length, int dust_k, int dust_cutoff, int errors)
{
    if (length && read.size() < length) {
        return ReadType::length;
    }
    if (dust_cutoff && get_dust_score(read, dust_k) > dust_cutoff) {
        return ReadType::dust;
    }

    if (errors) {
        return (ReadType)search_inexact(read, root, patterns, errors);
    } else {
        return (ReadType)search_any(read, root);
    }
}

void filter_single_reads(std::ifstream & reads_f, std::ofstream & ok_f, std::ofstream & bad_f,
                         Stats & stats, Node * root, std::vector <std::pair<std::string, Node::Type> > const & patterns,
                         int length, int dust_k, int dust_cutoff, int errors)
{
    Seq read;

    while (read.read_seq(reads_f)) {
        ReadType type = check_read(read.seq, root, patterns, length, dust_k, dust_cutoff, errors);
        stats.update(type);
        if (type == ReadType::ok) {
            read.write_seq(ok_f);
        } else {
            read.update_id(type);
            read.write_seq(bad_f);
        }
    }
}

void filter_paired_reads(std::ifstream & reads1_f, std::ifstream & reads2_f,
                         std::ofstream & ok1_f, std::ofstream & ok2_f,
                         std::ofstream & bad1_f, std::ofstream & bad2_f,
                         std::ofstream & se1_f, std::ofstream & se2_f,
                         Stats & stats1, Stats & stats2,
                         Node * root, std::vector <std::pair<std::string, Node::Type> > const & patterns,
                         int length, int dust_k, int dust_cutoff, int errors)
{
    Seq read1;
    Seq read2;

    while (read1.read_seq(reads1_f) && read2.read_seq(reads2_f)) {
        ReadType type1 = check_read(read1.seq, root, patterns, length, dust_k, dust_cutoff, errors);
        ReadType type2 = check_read(read2.seq, root, patterns, length, dust_k, dust_cutoff, errors);
        if (type1 == ReadType::ok && type2 == ReadType::ok) {
            read1.write_seq(ok1_f);
            read2.write_seq(ok2_f);
            stats1.update(type1, true);
            stats2.update(type2, true);
        } else {
            stats1.update(type1, false);
            stats2.update(type2, false);
            if (type1 == ReadType::ok) {
                read1.write_seq(se1_f);
                read2.update_id(type2);
                read2.write_seq(bad2_f);
            } else if (type2 == ReadType::ok) {
                read1.update_id(type1);
                read1.write_seq(bad1_f);
                read2.write_seq(se2_f);
            } else {
                read1.update_id(type1);
                read2.update_id(type2);
                read1.write_seq(bad1_f);
                read2.write_seq(bad2_f);
            }
        }
    }
}

std::string basename(std::string const & path)
{
    std::string res(path);
    size_t pos = res.find_last_of('/');
    if (pos != std::string::npos) {
        res.erase(0, pos);
    }
    pos = res.find('.');
    if (pos != std::string::npos) {
        res.erase(pos, path.size());
    }
    return res;
}

void print_help()
{
    std::cout << "./rm_reads [-i raw_data.fastq | -1 raw_data1.fastq -2 raw_data2.fastq] -o output_dir --polyG 13 --length 50 --fragments fragments.dat --dust_cutoff cutoff --dust_k k -e 1" << std::endl;
}

int main(int argc, char ** argv)
{
    Node root('0');
    std::vector <std::pair<std::string, Node::Type> > patterns;

    std::string kmers, reads, out_dir;
    std::string reads1, reads2;
    char rez = 0;
    int length = 0;
    int polyG = 0;
    int dust_k = 4;
    int dust_cutoff = 0;
    int errors = 0;

    const struct option long_options[] = {
        {"length",required_argument,NULL,'l'},
        {"polyG",required_argument,NULL,'p'},
        {"fragments",required_argument,NULL,'a'},
        {"dust_k",required_argument,NULL,'k'},
        {"dust_cutoff",required_argument,NULL,'c'},
        {"errors",required_argument,NULL,'e'},
        {NULL,0,NULL,0}
    };

    while ((rez = getopt_long(argc, argv, "1:2:l:p:a:i:o:e:", long_options, NULL)) != -1) {
        switch (rez) {
        case 'l':
            length = std::atoi(optarg);
            break;
        case 'p':
            polyG = std::atoi(optarg);
            // polyG = boost::lexical_cast<int>(optarg);
            break;
        case 'a':
            kmers = optarg;
            break;
        case 'i':
            reads = optarg;
            break;
        case '1':
            reads1 = optarg;
            break;
        case '2':
            reads2 = optarg;
            break;
        case 'o':
            out_dir = optarg;
            break;
        case 'c':
            dust_cutoff = std::atoi(optarg);
            break;
        case 'k':
            dust_k = std::atoi(optarg);
            break;
        case 'e':
            errors = std::atoi(optarg);
            break;
        case '?':
            print_help();
            return -1;
        }
    }

    if (errors < 0 || errors > 2) {
        std::cout << "possible errors count are 0, 1, 2" << std::endl;
        return -1;
    }

    if (kmers.empty() || out_dir.empty() || (
            reads.empty() &&
            (reads1.empty() || reads2.empty()))) {
        print_help();
        return -1;
    }

    std::ifstream kmers_f (kmers.c_str());
    if (!kmers_f.good()) {
        std::cout << "Cannot open kmers file" << std::endl;
        print_help();
        return -1;
    }

    init_type_names(length, polyG, dust_k, dust_cutoff);

    build_patterns(kmers_f, polyG, patterns);

/*
    for (std::vector <std::string> ::iterator it = patterns.begin(); it != patterns.end(); ++it) {
        std::cout << *it << std::endl;
    }
    */

    if (patterns.empty()) {
        std::cout << "patterns are empty" << std::endl;
        return -1;
    }

    build_trie(root, patterns, errors);
	add_failures(root);

    if (!reads.empty()) {
        std::string reads_base = basename(reads);
        std::ifstream reads_f (reads.c_str());
        std::ofstream ok_f((out_dir + "/" + reads_base + ".ok.fastq").c_str(), std::ofstream::out);
        std::ofstream bad_f((out_dir + "/" + reads_base + ".filtered.fastq").c_str(), std::ofstream::out);

        if (!reads_f.good()) {
            std::cout << "Cannot open reads file" << std::endl;
            print_help();
            return -1;
        }

        if (!ok_f.good() || !bad_f.good()) {
            std::cout << "Cannot open output file" << std::endl;
            print_help();
            return -1;
        }

        Stats stats(reads);

        filter_single_reads(reads_f, ok_f, bad_f, stats, &root, patterns, length, dust_k, dust_cutoff, errors);

        std::cout << stats;

        ok_f.close();
        bad_f.close();
        reads_f.close();
    } else {
        std::string reads1_base = basename(reads1);
        std::string reads2_base = basename(reads2);
        std::ifstream reads1_f(reads1.c_str());
        std::ifstream reads2_f(reads2.c_str());
        std::ofstream ok1_f((out_dir + "/" + reads1_base + ".ok.fastq").c_str(),
                            std::ofstream::out);
        std::ofstream ok2_f((out_dir + "/" + reads2_base + ".ok.fastq").c_str(),
                            std::ofstream::out);
        std::ofstream se1_f((out_dir + "/" + reads1_base + ".se.fastq").c_str(),
                            std::ofstream::out);
        std::ofstream se2_f((out_dir + "/" + reads2_base + ".se.fastq").c_str(),
                            std::ofstream::out);
        std::ofstream bad1_f((out_dir + "/" + reads1_base + ".filtered.fastq").c_str(),
                            std::ofstream::out);
        std::ofstream bad2_f((out_dir + "/" + reads2_base + ".filtered.fastq").c_str(),
                            std::ofstream::out);

        if (!reads1_f.good() || !reads2_f.good()) {
            std::cout << "reads file is bad" << std::endl;
            print_help();
            return -1;
        }

        if (!ok1_f.good() || !ok2_f.good() || !bad1_f.good() || !bad2_f.good() ||
                !se1_f.good() || !se2_f.good()) {
            std::cout << "out file is bad" << std::endl;
            print_help();
            return -1;
        }

        Stats stats1(reads1);
        Stats stats2(reads2);

        filter_paired_reads(reads1_f, reads2_f, ok1_f, ok2_f,
                            bad1_f, bad2_f, se1_f, se2_f,
                            stats1, stats2,
                            &root, patterns, length, dust_k, dust_cutoff, errors);

        std::cout << stats1;
        std::cout << stats2;

        ok1_f.close();
        ok2_f.close();
        bad1_f.close();
        bad2_f.close();
        reads1_f.close();
        reads2_f.close();
    }
}
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file Lexr.cxx
 ** Lexer for R, S, SPlus Statistics Program (Heavily derived from CPP Lexer).
 **
 **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static inline bool IsAWordChar(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}

static inline bool IsAWordStart(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

static inline bool IsAnOperator(const int ch) {
	if (isascii(ch) && isalnum(ch))
		return false;
	// '.' left out as it is used to make up numbers
	if (ch == '-' || ch == '+' || ch == '!' || ch == '~' ||
	        ch == '?' || ch == ':' || ch == '*' || ch == '/' ||
	        ch == '^' || ch == '<' || ch == '>' || ch == '=' ||
	        ch == '&' || ch == '|' || ch == '$' || ch == '(' ||
	        ch == ')' || ch == '}' || ch == '{' || ch == '[' ||
		ch == ']')
		return true;
	return false;
}

static void ColouriseRDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                            Accessor &styler) {

	WordList &keywords   = *keywordlists[0];
	WordList &keywords2 = *keywordlists[1];
	WordList &keywords3 = *keywordlists[2];

	// Do not leak onto next line
	if (initStyle == SCE_R_INFIXEOL)
		initStyle = SCE_R_DEFAULT;

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		if (sc.atLineStart && (sc.state == SCE_R_STRING)) {
			// Prevent SCE_R_STRINGEOL from leaking back to previous line
			sc.SetState(SCE_R_STRING);
		}

		// Determine if the current state should terminate.
		if (sc.state == SCE_R_OPERATOR) {
			sc.SetState(SCE_R_DEFAULT);
		} else if (sc.state == SCE_R_NUMBER) {
			if (!IsADigit(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {
				sc.SetState(SCE_R_DEFAULT);
			}
		} else if (sc.state == SCE_R_IDENTIFIER) {
			if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
				char s[100];
				sc.GetCurrentLowered(s, sizeof(s));
				if (keywords.InList(s)) {
					sc.ChangeState(SCE_R_KWORD);
				} else if  (keywords2.InList(s)) {
					sc.ChangeState(SCE_R_BASEKWORD);
				} else if  (keywords3.InList(s)) {
					sc.ChangeState(SCE_R_OTHERKWORD);
				}
				sc.SetState(SCE_R_DEFAULT);
			}
		} else if (sc.state == SCE_R_COMMENT) {
			if (sc.ch == '\r' || sc.ch == '\n') {
				sc.SetState(SCE_R_DEFAULT);
			}
		} else if (sc.state == SCE_R_STRING) {
			if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\"') {
				sc.ForwardSetState(SCE_R_DEFAULT);
			}
		} else if (sc.state == SCE_R_INFIX) {
			if (sc.ch == '%') {
				sc.ForwardSetState(SCE_R_DEFAULT);
			} else if (sc.atLineEnd) {
				sc.ChangeState(SCE_R_INFIXEOL);
				sc.ForwardSetState(SCE_R_DEFAULT);
			}
		}else if (sc.state == SCE_R_STRING2) {
			if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\'') {
				sc.ForwardSetState(SCE_R_DEFAULT);
			}
		}

		// Determine if a new state should be entered.
		if (sc.state == SCE_R_DEFAULT) {
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				sc.SetState(SCE_R_NUMBER);
			} else if (IsAWordStart(sc.ch) ) {
				sc.SetState(SCE_R_IDENTIFIER);
			} else if (sc.Match('#')) {
					sc.SetState(SCE_R_COMMENT);
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_R_STRING);
			} else if (sc.ch == '%') {
				sc.SetState(SCE_R_INFIX);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_R_STRING2);
			} else if (IsAnOperator(sc.ch)) {
				sc.SetState(SCE_R_OPERATOR);
			}
		}
	}
	sc.Complete();
}

// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
static void FoldRDoc(unsigned int startPos, int length, int, WordList *[],
                       Accessor &styler) {
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
	bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelCurrent = SC_FOLDLEVELBASE;
	if (lineCurrent > 0)
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
	int levelMinCurrent = levelCurrent;
	int levelNext = levelCurrent;
	char chNext = styler[startPos];
	int styleNext = styler.StyleAt(startPos);
	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		if (style == SCE_R_OPERATOR) {
			if (ch == '{') {
				// Measure the minimum before a '{' to allow
				// folding on "} else {"
				if (levelMinCurrent > levelNext) {
					levelMinCurrent = levelNext;
				}
				levelNext++;
			} else if (ch == '}') {
				levelNext--;
			}
		}
		if (atEOL) {
			int levelUse = levelCurrent;
			if (foldAtElse) {
				levelUse = levelMinCurrent;
			}
			int lev = levelUse | levelNext << 16;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if (levelUse < levelNext)
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelCurrent = levelNext;
			levelMinCurrent = levelCurrent;
			visibleChars = 0;
		}
		if (!isspacechar(ch))
			visibleChars++;
	}
}

static const char * const RWordLists[] = {
            "Language Keywords",
            "Base / Default package function",
            "Other Package Functions",
            "Unused",
            "Unused",
            0,
        };

LexerModule lmR(SCLEX_R, ColouriseRDoc, "r", FoldRDoc, RWordLists);
<commit_msg>Bug #2956543, R Lexer is case insensitive for keywords<commit_after>// Scintilla source code edit control
/** @file Lexr.cxx
 ** Lexer for R, S, SPlus Statistics Program (Heavily derived from CPP Lexer).
 **
 **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static inline bool IsAWordChar(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}

static inline bool IsAWordStart(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

static inline bool IsAnOperator(const int ch) {
	if (isascii(ch) && isalnum(ch))
		return false;
	// '.' left out as it is used to make up numbers
	if (ch == '-' || ch == '+' || ch == '!' || ch == '~' ||
	        ch == '?' || ch == ':' || ch == '*' || ch == '/' ||
	        ch == '^' || ch == '<' || ch == '>' || ch == '=' ||
	        ch == '&' || ch == '|' || ch == '$' || ch == '(' ||
	        ch == ')' || ch == '}' || ch == '{' || ch == '[' ||
		ch == ']')
		return true;
	return false;
}

static void ColouriseRDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                            Accessor &styler) {

	WordList &keywords   = *keywordlists[0];
	WordList &keywords2 = *keywordlists[1];
	WordList &keywords3 = *keywordlists[2];

	// Do not leak onto next line
	if (initStyle == SCE_R_INFIXEOL)
		initStyle = SCE_R_DEFAULT;

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		if (sc.atLineStart && (sc.state == SCE_R_STRING)) {
			// Prevent SCE_R_STRINGEOL from leaking back to previous line
			sc.SetState(SCE_R_STRING);
		}

		// Determine if the current state should terminate.
		if (sc.state == SCE_R_OPERATOR) {
			sc.SetState(SCE_R_DEFAULT);
		} else if (sc.state == SCE_R_NUMBER) {
			if (!IsADigit(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {
				sc.SetState(SCE_R_DEFAULT);
			}
		} else if (sc.state == SCE_R_IDENTIFIER) {
			if (!IsAWordChar(sc.ch)) {
				char s[100];
				sc.GetCurrent(s, sizeof(s));
				if (keywords.InList(s)) {
					sc.ChangeState(SCE_R_KWORD);
				} else if  (keywords2.InList(s)) {
					sc.ChangeState(SCE_R_BASEKWORD);
				} else if  (keywords3.InList(s)) {
					sc.ChangeState(SCE_R_OTHERKWORD);
				}
				sc.SetState(SCE_R_DEFAULT);
			}
		} else if (sc.state == SCE_R_COMMENT) {
			if (sc.ch == '\r' || sc.ch == '\n') {
				sc.SetState(SCE_R_DEFAULT);
			}
		} else if (sc.state == SCE_R_STRING) {
			if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\"') {
				sc.ForwardSetState(SCE_R_DEFAULT);
			}
		} else if (sc.state == SCE_R_INFIX) {
			if (sc.ch == '%') {
				sc.ForwardSetState(SCE_R_DEFAULT);
			} else if (sc.atLineEnd) {
				sc.ChangeState(SCE_R_INFIXEOL);
				sc.ForwardSetState(SCE_R_DEFAULT);
			}
		}else if (sc.state == SCE_R_STRING2) {
			if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\'') {
				sc.ForwardSetState(SCE_R_DEFAULT);
			}
		}

		// Determine if a new state should be entered.
		if (sc.state == SCE_R_DEFAULT) {
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				sc.SetState(SCE_R_NUMBER);
			} else if (IsAWordStart(sc.ch) ) {
				sc.SetState(SCE_R_IDENTIFIER);
			} else if (sc.Match('#')) {
					sc.SetState(SCE_R_COMMENT);
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_R_STRING);
			} else if (sc.ch == '%') {
				sc.SetState(SCE_R_INFIX);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_R_STRING2);
			} else if (IsAnOperator(sc.ch)) {
				sc.SetState(SCE_R_OPERATOR);
			}
		}
	}
	sc.Complete();
}

// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
static void FoldRDoc(unsigned int startPos, int length, int, WordList *[],
                       Accessor &styler) {
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
	bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelCurrent = SC_FOLDLEVELBASE;
	if (lineCurrent > 0)
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
	int levelMinCurrent = levelCurrent;
	int levelNext = levelCurrent;
	char chNext = styler[startPos];
	int styleNext = styler.StyleAt(startPos);
	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		if (style == SCE_R_OPERATOR) {
			if (ch == '{') {
				// Measure the minimum before a '{' to allow
				// folding on "} else {"
				if (levelMinCurrent > levelNext) {
					levelMinCurrent = levelNext;
				}
				levelNext++;
			} else if (ch == '}') {
				levelNext--;
			}
		}
		if (atEOL) {
			int levelUse = levelCurrent;
			if (foldAtElse) {
				levelUse = levelMinCurrent;
			}
			int lev = levelUse | levelNext << 16;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if (levelUse < levelNext)
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelCurrent = levelNext;
			levelMinCurrent = levelCurrent;
			visibleChars = 0;
		}
		if (!isspacechar(ch))
			visibleChars++;
	}
}

static const char * const RWordLists[] = {
            "Language Keywords",
            "Base / Default package function",
            "Other Package Functions",
            "Unused",
            "Unused",
            0,
        };

LexerModule lmR(SCLEX_R, ColouriseRDoc, "r", FoldRDoc, RWordLists);
<|endoftext|>


<commit_before>/****************************************************************************
 **
 ** Copyright (C) 2015 The Qt Company Ltd.
 ** Copyright (C) 2015 Ruslan Baratov
 ** Contact: http://www.qt.io/licensing/
 **
 ** This file is part of the examples of the Qt Multimedia module.
 **
 ** $QT_BEGIN_LICENSE:LGPL21$
 ** Commercial License Usage
 ** Licensees holding valid commercial Qt licenses may use this file in
 ** accordance with the commercial license agreement provided with the
 ** Software or, alternatively, in accordance with the terms contained in
 ** a written agreement between you and The Qt Company. For licensing terms
 ** and conditions see http://www.qt.io/terms-conditions. For further
 ** information use the contact form at http://www.qt.io/contact-us.
 **
 ** GNU Lesser General Public License Usage
 ** Alternatively, this file may be used under the terms of the GNU Lesser
 ** General Public License version 2.1 or version 3 as published by the Free
 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
 ** following information to ensure the GNU Lesser General Public License
 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 **
 ** As a special exception, The Qt Company gives you certain additional
 ** rights. These rights are described in The Qt Company LGPL Exception
 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 **
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/

#include "VideoFilterRunnable.hpp"

#include <cassert> // assert

#include <graphics/GLExtra.h> // GATHERER_OPENGL_DEBUG

#include "VideoFilter.hpp"
#include "TextureBuffer.hpp"

#include "libyuv.h"

#include "OGLESGPGPUTest.h"

#include <opencv2/imgproc.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>

#include <QDateTime>

struct QVideoFrameScopeMap
{
    QVideoFrameScopeMap(QVideoFrame *frame, QAbstractVideoBuffer::MapMode mode) : frame(frame)
    {
        if(frame)
        {
            status = frame->map(mode);
            if (!status)
            {
                qWarning("Can't map!");
            }
        }
    }
    ~QVideoFrameScopeMap()
    {
        if(frame)
        {
            frame->unmap();
        }
    }
    operator bool() const { return status; }
    QVideoFrame *frame = nullptr;
    bool status = false;
};

static cv::Mat QVideoFrameToCV(QVideoFrame *input);

VideoFilterRunnable::VideoFilterRunnable(VideoFilter *filter) :
m_filter(filter),
m_outTexture(0),
m_lastInputTexture(0)
{
    QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();

    const char *vendor = (const char *) f->glGetString(GL_VENDOR);
    qDebug("GL_VENDOR: %s", vendor);
}

VideoFilterRunnable::~VideoFilterRunnable() {

}

QVideoFrame VideoFilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
{
    Q_UNUSED(surfaceFormat);
    Q_UNUSED(flags);

    float resolution = 1.0f;
    void* glContext = 0;
#if GATHERER_IOS
    glContext = ogles_gpgpu::Core::getCurrentEAGLContext();
    resolution = 2.0f;
#else
    QOpenGLContext * qContext = QOpenGLContext::currentContext();
    glContext = qContext;

    QOpenGLFunctions glFuncs(qContext);
#endif
    if(!m_pipeline)
    {
        QSize size = surfaceFormat.sizeHint();
        GLint backingWidth = size.width(), backingHeight = size.height();

        // TODO: These calls are failing on OS X
        glFuncs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
        glFuncs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
        ogles_gpgpu::Tools::checkGLErr("VideoFilterRunnable", "run");

        cv::Size screenSize(backingWidth, backingHeight);
        m_pipeline = std::make_shared<gatherer::graphics::OEGLGPGPUTest>(glContext, screenSize, resolution);
        m_pipeline->setDoDisplay(false);
    }

    // This example supports RGB data only, either in system memory (typical with
    // cameras on all platforms) or as an OpenGL texture (e.g. video playback on
    // OS X).  The latter is the fast path where everything happens on GPU. The
    // former involves a texture upload.

    if (!isFrameValid(*input)) {
        qWarning("Invalid input format");
        return *input;
    }

    if (isFrameFormatYUV(*input)) {
        qWarning("YUV data is not supported");
        return *input;
    }

    m_outTexture = createTextureForFrame(input);
    auto size = m_pipeline->getOutputSize();
    return TextureBuffer::createVideoFrame(m_outTexture, {size.width, size.height});
}

bool VideoFilterRunnable::isFrameValid(const QVideoFrame& frame) {
    if (!frame.isValid()) {
        return false;
    }
    if (frame.handleType() == QAbstractVideoBuffer::NoHandle) {
        return true;
    }
    if (frame.handleType() == QAbstractVideoBuffer::GLTextureHandle) {
        return true;
    }

    return false;
}

bool VideoFilterRunnable::isFrameFormatYUV(const QVideoFrame& frame) {
    if (frame.pixelFormat() == QVideoFrame::Format_YUV420P) {
        return true;
    }
    if (frame.pixelFormat() == QVideoFrame::Format_YV12) {
        return true;
    }
    return false;
}

// Create a texture from the image data.
GLuint VideoFilterRunnable::createTextureForFrame(QVideoFrame* input) {
    QOpenGLContext* openglContext = QOpenGLContext::currentContext();
    if (!openglContext) {
        qWarning("Can't get context!");
        return 0;
    }
    assert(openglContext->isValid());

    QOpenGLFunctions *f = openglContext->functions();
    assert(f != 0);

    // Already an OpenGL texture.
    if (input->handleType() == QAbstractVideoBuffer::GLTextureHandle) {
        assert(input->pixelFormat() == TextureBuffer::qtTextureFormat());
        GLuint texture = input->handle().toUInt();
        assert(texture != 0);
        f->glBindTexture(GL_TEXTURE_2D, texture);
        m_lastInputTexture = texture;

        const cv::Size size(input->width(), input->height());
        void* pixelBuffer = nullptr; //  we are using texture
        const bool useRawPixels = false; //  - // -
        m_pipeline->captureOutput(size, pixelBuffer, useRawPixels, texture);

        glActiveTexture(GL_TEXTURE0);
        GLuint outputTexture = m_pipeline->getLastShaderOutputTexture();
        f->glBindTexture(GL_TEXTURE_2D, outputTexture);

        m_outTexture = outputTexture;
    }
    else
    {
        // Scope based pixel buffer lock for no nios platforms
        QVideoFrameScopeMap scopeMap(GATHERER_IOS ? nullptr : input, QAbstractVideoBuffer::ReadOnly);
        if(!(GATHERER_IOS && !scopeMap)) // for non ios platforms
        {
            assert((input->pixelFormat() == QVideoFrame::Format_ARGB32) || (GATHERER_IOS && input->pixelFormat() == QVideoFrame::Format_NV12));

#if GATHERER_IOS || defined(Q_OS_OSX)
            const GLenum rgbaFormat = GL_BGRA;
#else
            const GLenum rgbaFormat = GL_RGBA;
#endif

#if GATHERER_IOS
            void * const pixelBuffer = input->pixelBufferRef()
#else
            void * const pixelBuffer = input->bits();
            //cv::Mat frame({input->width(), input->height()}, CV_8UC4, pixelBuffer );
            //cv::imwrite("/tmp/frame.png", frame);
#endif

            GLenum textureFormat = input->pixelFormat() == QVideoFrame::Format_ARGB32 ? rgbaFormat : 0; // 0 indicates YUV
            const bool useRawPixels = !(GATHERER_IOS); // ios uses texture cache / pixel buffer
            const GLuint inputTexture = 0;
            assert(pixelBuffer != nullptr);
            m_pipeline->captureOutput({input->width(), input->height()}, pixelBuffer, useRawPixels, inputTexture, textureFormat);

            // QT is expecting GL_TEXTURE0 to be active
            glActiveTexture(GL_TEXTURE0);
            GLuint outputTexture = m_pipeline->getLastShaderOutputTexture();
            //GLuint outputTexture = m_pipeline->getInputTexture();
            //GLuint outputTexture = m_pipeline->getDisplayTexture();
            f->glBindTexture(GL_TEXTURE_2D, outputTexture);
            m_outTexture = outputTexture;
        }
    }

    const QPoint oldPosition = m_filter->rectanglePosition();
    const QSize rectangleSize(100, 100);
    const bool visible = true;
    const int xDelta = std::rand() % 10;
    const int yDelta = std::rand() % 10;
    const int newX = (oldPosition.x() + xDelta) % input->size().width();
    const int newY = (oldPosition.y() + yDelta) % input->size().height();
    emit m_filter->updateRectangle(QPoint(newX, newY), rectangleSize, visible);

    emit m_filter->updateOutputString(QDateTime::currentDateTime().toString());
    return m_outTexture;
}

// We don't ever want to use this in any practical scenario.
// To be deprecated...
static cv::Mat QVideoFrameToCV(QVideoFrame *input)
{
    cv::Mat frame;
    switch(input->pixelFormat())
    {
        case QVideoFrame::Format_ARGB32:
        case QVideoFrame::Format_BGRA32:
            frame = cv::Mat(input->height(), input->width(), CV_8UC4, input->bits());
            break;
        case QVideoFrame::Format_NV21:
            frame.create(input->height(), input->width(), CV_8UC4);
            libyuv::NV21ToARGB(input->bits(),
                               input->bytesPerLine(),
                               input->bits(1),
                               input->bytesPerLine(1),
                               frame.ptr<uint8_t>(),
                               int(frame.step1()),
                               frame.cols,
                               frame.rows);
            break;
        case QVideoFrame::Format_NV12:
            frame.create(input->height(), input->width(), CV_8UC4);
            libyuv::NV12ToARGB(input->bits(),
                               input->bytesPerLine(),
                               input->bits(1),
                               input->bytesPerLine(1),
                               frame.ptr<uint8_t>(),
                               int(frame.step1()),
                               frame.cols,
                               frame.rows);
            break;
        default: CV_Assert(false);
    }
    return frame;
}
<commit_msg>minor changes<commit_after>/****************************************************************************
 **
 ** Copyright (C) 2015 The Qt Company Ltd.
 ** Copyright (C) 2015 Ruslan Baratov
 ** Contact: http://www.qt.io/licensing/
 **
 ** This file is part of the examples of the Qt Multimedia module.
 **
 ** $QT_BEGIN_LICENSE:LGPL21$
 ** Commercial License Usage
 ** Licensees holding valid commercial Qt licenses may use this file in
 ** accordance with the commercial license agreement provided with the
 ** Software or, alternatively, in accordance with the terms contained in
 ** a written agreement between you and The Qt Company. For licensing terms
 ** and conditions see http://www.qt.io/terms-conditions. For further
 ** information use the contact form at http://www.qt.io/contact-us.
 **
 ** GNU Lesser General Public License Usage
 ** Alternatively, this file may be used under the terms of the GNU Lesser
 ** General Public License version 2.1 or version 3 as published by the Free
 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
 ** following information to ensure the GNU Lesser General Public License
 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 **
 ** As a special exception, The Qt Company gives you certain additional
 ** rights. These rights are described in The Qt Company LGPL Exception
 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 **
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/

#include "VideoFilterRunnable.hpp"

#include <cassert> // assert

#include <graphics/GLExtra.h> // GATHERER_OPENGL_DEBUG

#include "VideoFilter.hpp"
#include "TextureBuffer.hpp"

#include "libyuv.h"

#include "OGLESGPGPUTest.h"

#include <opencv2/imgproc.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>

#include <QDateTime>

struct QVideoFrameScopeMap
{
    QVideoFrameScopeMap(QVideoFrame *frame, QAbstractVideoBuffer::MapMode mode) : frame(frame)
    {
        if(frame)
        {
            status = frame->map(mode);
            if (!status)
            {
                qWarning("Can't map!");
            }
        }
    }
    ~QVideoFrameScopeMap()
    {
        if(frame)
        {
            frame->unmap();
        }
    }
    operator bool() const { return status; }
    QVideoFrame *frame = nullptr;
    bool status = false;
};

static cv::Mat QVideoFrameToCV(QVideoFrame *input);

VideoFilterRunnable::VideoFilterRunnable(VideoFilter *filter) :
m_filter(filter),
m_outTexture(0),
m_lastInputTexture(0)
{
    QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();

    const char *vendor = (const char *) f->glGetString(GL_VENDOR);
    qDebug("GL_VENDOR: %s", vendor);
}

VideoFilterRunnable::~VideoFilterRunnable() {

}

QVideoFrame VideoFilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
{
    Q_UNUSED(surfaceFormat);
    Q_UNUSED(flags);

    float resolution = 1.0f;
    void* glContext = 0;
#if GATHERER_IOS
    glContext = ogles_gpgpu::Core::getCurrentEAGLContext();
    resolution = 2.0f;
#else
    QOpenGLContext * qContext = QOpenGLContext::currentContext();
    glContext = qContext;

    QOpenGLFunctions glFuncs(qContext);
#endif
    if(!m_pipeline)
    {
        QSize size = surfaceFormat.sizeHint();
        GLint backingWidth = size.width(), backingHeight = size.height();

        // TODO: These calls are failing on OS X
        glFuncs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
        glFuncs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
        ogles_gpgpu::Tools::checkGLErr("VideoFilterRunnable", "run");

        cv::Size screenSize(backingWidth, backingHeight);
        m_pipeline = std::make_shared<gatherer::graphics::OEGLGPGPUTest>(glContext, screenSize, resolution);
        m_pipeline->setDoDisplay(false);
    }

    // This example supports RGB data only, either in system memory (typical with
    // cameras on all platforms) or as an OpenGL texture (e.g. video playback on
    // OS X).  The latter is the fast path where everything happens on GPU. The
    // former involves a texture upload.

    if (!isFrameValid(*input)) {
        qWarning("Invalid input format");
        return *input;
    }

    if (isFrameFormatYUV(*input)) {
        qWarning("YUV data is not supported");
        return *input;
    }

    m_outTexture = createTextureForFrame(input);
    auto size = m_pipeline->getOutputSize();
    return TextureBuffer::createVideoFrame(m_outTexture, {size.width, size.height});
}

bool VideoFilterRunnable::isFrameValid(const QVideoFrame& frame) {
    if (!frame.isValid()) {
        return false;
    }
    if (frame.handleType() == QAbstractVideoBuffer::NoHandle) {
        return true;
    }
    if (frame.handleType() == QAbstractVideoBuffer::GLTextureHandle) {
        return true;
    }

    return false;
}

bool VideoFilterRunnable::isFrameFormatYUV(const QVideoFrame& frame) {
    if (frame.pixelFormat() == QVideoFrame::Format_YUV420P) {
        return true;
    }
    if (frame.pixelFormat() == QVideoFrame::Format_YV12) {
        return true;
    }
    return false;
}

// Create a texture from the image data.
GLuint VideoFilterRunnable::createTextureForFrame(QVideoFrame* input) {
    QOpenGLContext* openglContext = QOpenGLContext::currentContext();
    if (!openglContext) {
        qWarning("Can't get context!");
        return 0;
    }
    assert(openglContext->isValid());

    QOpenGLFunctions *f = openglContext->functions();
    assert(f != 0);

    // Already an OpenGL texture.
    if (input->handleType() == QAbstractVideoBuffer::GLTextureHandle) {
        assert(input->pixelFormat() == TextureBuffer::qtTextureFormat());
        GLuint texture = input->handle().toUInt();
        assert(texture != 0);
        f->glBindTexture(GL_TEXTURE_2D, texture);
        m_lastInputTexture = texture;

        const cv::Size size(input->width(), input->height());
        void* pixelBuffer = nullptr; //  we are using texture
        const bool useRawPixels = false; //  - // -
        m_pipeline->captureOutput(size, pixelBuffer, useRawPixels, texture);

        glActiveTexture(GL_TEXTURE0);
        GLuint outputTexture = m_pipeline->getLastShaderOutputTexture();
        f->glBindTexture(GL_TEXTURE_2D, outputTexture);

        m_outTexture = outputTexture;
    }
    else
    {
        // Scope based pixel buffer lock for no nios platforms
        QVideoFrameScopeMap scopeMap(GATHERER_IOS ? nullptr : input, QAbstractVideoBuffer::ReadOnly);
        if(!(GATHERER_IOS && !scopeMap)) // for non ios platforms
        {
            assert((input->pixelFormat() == QVideoFrame::Format_ARGB32) || (GATHERER_IOS && input->pixelFormat() == QVideoFrame::Format_NV12));

#if defined(Q_OS_IOS) || defined(Q_OS_OSX)
            const GLenum rgbaFormat = GL_BGRA;
#else
            const GLenum rgbaFormat = GL_RGBA;
#endif

#if defined(Q_OS_IOS)
            void * const pixelBuffer = input->pixelBufferRef()
#else
            void * const pixelBuffer = input->bits();
#endif

            // 0 indicates YUV
            GLenum textureFormat = input->pixelFormat() == QVideoFrame::Format_ARGB32 ? rgbaFormat : 0;
            const bool useRawPixels = !(GATHERER_IOS); // ios uses texture cache / pixel buffer
            const GLuint inputTexture = 0;
            assert(pixelBuffer != nullptr);
            m_pipeline->captureOutput({input->width(), input->height()}, pixelBuffer, useRawPixels, inputTexture, textureFormat);

            // QT is expecting GL_TEXTURE0 to be active
            glActiveTexture(GL_TEXTURE0);
            GLuint outputTexture = m_pipeline->getLastShaderOutputTexture();
            //GLuint outputTexture = m_pipeline->getInputTexture();
            f->glBindTexture(GL_TEXTURE_2D, outputTexture);
            m_outTexture = outputTexture;
        }
    }

    const QPoint oldPosition = m_filter->rectanglePosition();
    const QSize rectangleSize(100, 100);
    const bool visible = true;
    const int xDelta = std::rand() % 10;
    const int yDelta = std::rand() % 10;
    const int newX = (oldPosition.x() + xDelta) % input->size().width();
    const int newY = (oldPosition.y() + yDelta) % input->size().height();
    emit m_filter->updateRectangle(QPoint(newX, newY), rectangleSize, visible);

    emit m_filter->updateOutputString(QDateTime::currentDateTime().toString());
    return m_outTexture;
}

// We don't ever want to use this in any practical scenario.
// To be deprecated...
static cv::Mat QVideoFrameToCV(QVideoFrame *input)
{
    cv::Mat frame;
    switch(input->pixelFormat())
    {
        case QVideoFrame::Format_ARGB32:
        case QVideoFrame::Format_BGRA32:
            frame = cv::Mat(input->height(), input->width(), CV_8UC4, input->bits());
            break;
        case QVideoFrame::Format_NV21:
            frame.create(input->height(), input->width(), CV_8UC4);
            libyuv::NV21ToARGB(input->bits(),
                               input->bytesPerLine(),
                               input->bits(1),
                               input->bytesPerLine(1),
                               frame.ptr<uint8_t>(),
                               int(frame.step1()),
                               frame.cols,
                               frame.rows);
            break;
        case QVideoFrame::Format_NV12:
            frame.create(input->height(), input->width(), CV_8UC4);
            libyuv::NV12ToARGB(input->bits(),
                               input->bytesPerLine(),
                               input->bits(1),
                               input->bytesPerLine(1),
                               frame.ptr<uint8_t>(),
                               int(frame.step1()),
                               frame.cols,
                               frame.rows);
            break;
        default: CV_Assert(false);
    }
    return frame;
}
<|endoftext|>