<commit_before>/*
 * deinvert - a voice inversion descrambler
 * Copyright (c) Oona Räisänen
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */
#include "src/deinvert.h"

#include <getopt.h>
#include <algorithm>
#include <iostream>
#include <stdexcept>
#include <string>

#include "config.h"
#include "src/liquid_wrappers.h"
#include "src/wdsp.h"

namespace deinvert {

namespace {

const float kLowpassFilterLengthSeconds = 0.0018f;
const int   kMaxFilterLength            = 2047;

}

void PrintUsage() {
  std::cout <<
     "deinvert [OPTIONS]\n"
     "\n"
     "-f, --frequency FREQ   Frequency of the inversion carrier, in Hertz.\n"
     "\n"
     "-h, --help             Display this usage help.\n"
     "\n"
     "-i, --input-file FILE  Use an audio file as input. All formats\n"
     "                       supported by libsndfile should work.\n"
     "\n"
     "-n, --nofilter         Disable filtering (faster).\n"
     "\n"
     "-o, --output-file FILE Write output to a WAV file instead of stdout. An\n"
     "                       existing file will be overwritten.\n"
     "\n"
     "-p, --preset NUM       Scrambler frequency preset (1-8), referring to\n"
     "                       the set of common carrier frequencies used by\n"
     "                       e.g. the Selectone ST-20B scrambler.\n"
     "\n"
     "-r, --samplerate RATE  Sampling rate of raw input audio, in Hertz.\n"
     "\n"
     "-v, --version          Display version string.\n";
}

void PrintVersion() {
#ifdef DEBUG
  std::cout << PACKAGE_STRING << "-debug by OH2EIQ" << std::endl;
#else
  std::cout << PACKAGE_STRING << " by OH2EIQ" << std::endl;
#endif
}

Options GetOptions(int argc, char** argv) {
  deinvert::Options options;

  static struct option long_options[] = {
    { "frequency",     no_argument, 0, 'f'},
    { "preset",        1,           0, 'p'},
    { "input-file",    1,           0, 'i'},
    { "help",          no_argument, 0, 'h'},
    { "nofilter",      no_argument, 0, 'n'},
    { "samplerate",    1,           0, 'r'},
    { "version",       no_argument, 0, 'v'},
    {0,                0,           0,  0}};

  static const std::vector<float> selectone_carriers({
      2632.f, 2718.f, 2868.f, 3023.f, 3196.f, 3339.f, 3495.f, 3729.f
  });

  options.frequency = selectone_carriers.at(0);

  int option_index = 0;
  int option_char;
  int selectone_num;

  while ((option_char = getopt_long(argc, argv, "f:hi:no:p:r:v",
                                    long_options,
         &option_index)) >= 0) {
    switch (option_char) {
      case 'i':
#ifdef HAVE_SNDFILE
        options.infilename = std::string(optarg);
        options.input_type = deinvert::INPUT_SNDFILE;
#else
        std::cerr << "error: deinvert was compiled without libsndfile"
                  << std::endl;
        options.just_exit = true;
#endif
        break;
      case 'f':
        options.frequency = std::atoi(optarg);
        break;
      case 'n':
        options.nofilter = true;
        break;
      case 'o':
#ifdef HAVE_SNDFILE
        options.output_type = deinvert::OUTPUT_WAVFILE;
        options.outfilename = std::string(optarg);
#else
        std::cerr << "error: deinvert was compiled without libsndfile"
                  << std::endl;
        options.just_exit = true;
#endif
        break;
      case 'p':
        selectone_num = std::atoi(optarg);
        if (selectone_num >= 1 &&
            selectone_num <= 8) {
          options.frequency = selectone_carriers.at(selectone_num - 1);
        } else {
          std::cerr << "error: please specify scrambler group from 1 to 8"
                    << std::endl;
          options.just_exit = true;
        }
        break;
      case 'r':
        options.samplerate = std::atoi(optarg);
        if (options.samplerate < 6000.f) {
          std::cerr << "error: sample rate must be 6000 Hz or higher"
                    << std::endl;
          options.just_exit = true;
        }
        break;
      case 'v':
        PrintVersion();
        options.just_exit = true;
        break;
      case 'h':
      default:
        PrintUsage();
        options.just_exit = true;
        break;
    }
    if (options.just_exit)
      break;
  }

  return options;
}

AudioReader::~AudioReader() {
}

bool AudioReader::eof() const {
  return is_eof_;
}

StdinReader::StdinReader(const Options& options) :
    samplerate_(options.samplerate) {
  is_eof_ = false;
}

StdinReader::~StdinReader() {
}

std::vector<float> StdinReader::ReadBlock() {
  int num_read = fread(buffer_, sizeof(buffer_[0]), bufsize_, stdin);

  if (num_read < bufsize_)
    is_eof_ = true;

  std::vector<float> result(num_read);
  for (int i = 0; i < num_read; i++)
    result[i] = buffer_[i] * (1.f / 32768.f);

  return result;
}

float StdinReader::samplerate() const {
  return samplerate_;
}

#ifdef HAVE_SNDFILE
SndfileReader::SndfileReader(const Options& options) :
    info_({0, 0, 0, 0, 0, 0}),
    file_(sf_open(options.infilename.c_str(), SFM_READ, &info_)) {
  is_eof_ = false;
  if (info_.frames == 0) {
    std::cerr << "error: couldn't open " << options.infilename << std::endl;
    is_eof_ = true;
  }
  if (info_.samplerate < 6000.f) {
    std::cerr << "error: sample rate must be 6000 Hz or higher" << std::endl;
    is_eof_ = true;
  }
}

SndfileReader::~SndfileReader() {
  sf_close(file_);
}

std::vector<float> SndfileReader::ReadBlock() {
  std::vector<float> result;
  if (is_eof_)
    return result;

  sf_count_t num_read = sf_readf_float(file_, buffer_, bufsize_);
  if (num_read != bufsize_)
    is_eof_ = true;

  if (info_.channels == 1) {
    result = std::vector<float>(buffer_, buffer_ + num_read);
  } else {
    result = std::vector<float>(num_read);
    for (size_t i = 0; i < result.size(); i++)
      result[i] = buffer_[i * info_.channels];
  }
  return result;
}

float SndfileReader::samplerate() const {
  return info_.samplerate;
}
#endif

AudioWriter::~AudioWriter() {
}

RawPCMWriter::RawPCMWriter() : ptr_(0) {
}

bool RawPCMWriter::push(float sample) {
  int16_t outsample = sample * 32767.f;
  buffer_[ptr_] = outsample;
  ptr_++;
  if (ptr_ == bufsize_) {
    fwrite(buffer_, sizeof(buffer_[0]), bufsize_, stdout);
    ptr_ = 0;
  }
  return true;
}

#ifdef HAVE_SNDFILE
SndfileWriter::SndfileWriter(const std::string& fname, int rate) :
    info_({0, rate, 1, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 0, 0}),
    file_(sf_open(fname.c_str(), SFM_WRITE, &info_)),
    ptr_(0) {
}

SndfileWriter::~SndfileWriter() {
  write(ptr_);
  sf_close(file_);
}

bool SndfileWriter::push(float sample) {
  bool success = true;
  buffer_[ptr_] = sample;
  if (ptr_ == bufsize_ - 1) {
    success = write(ptr_);
  }

  ptr_ = (ptr_ + 1) % bufsize_;
  return success;
}

bool SndfileWriter::write(sf_count_t numsamples) {
  return (file_ != nullptr &&
          sf_write_float(file_, buffer_, numsamples) == numsamples);
}
#endif

}  // namespace deinvert

int main(int argc, char** argv) {
  deinvert::Options options = deinvert::GetOptions(argc, argv);

  if (options.just_exit)
    return EXIT_FAILURE;

  deinvert::AudioReader* reader;
  deinvert::AudioWriter* writer;

#ifdef HAVE_SNDFILE
  if (options.input_type == deinvert::INPUT_SNDFILE)
    reader = new deinvert::SndfileReader(options);
  else
#endif
    reader = new deinvert::StdinReader(options);

#ifdef HAVE_SNDFILE
  if (options.output_type == deinvert::OUTPUT_WAVFILE)
    writer = new deinvert::SndfileWriter(options.outfilename,
                                         options.samplerate);
  else
#endif
    writer = new deinvert::RawPCMWriter();

  int filter_length = 2 * std::round(options.samplerate *
                                     deinvert::kLowpassFilterLengthSeconds) + 1;
  filter_length = std::min(deinvert::kMaxFilterLength, filter_length);

#ifdef HAVE_LIQUID
  liquid::NCO nco(LIQUID_VCO,
                  options.frequency * 2.0f * M_PI / options.samplerate);
  liquid::FIRFilter prefilter(filter_length,
                           options.frequency / options.samplerate);
  liquid::FIRFilter postfilter(filter_length,
                           (options.frequency - 150.f) / options.samplerate);
#else
  wdsp::NCO nco(options.frequency * 2.0f * M_PI / options.samplerate);
#endif

  while (!reader->eof()) {
    for (float insample : reader->ReadBlock()) {
      nco.Step();
#ifdef HAVE_LIQUID
      if (options.nofilter) {
        writer->push(nco.MixUp({insample, 0.0f}).real() * M_SQRT2);
      } else {
        prefilter.push({insample, 0.0f});
        std::complex<float> mixed = nco.MixUp(prefilter.execute());
        postfilter.push(mixed.real());
        writer->push(postfilter.execute().real() * 2.f);
      }
#else
      writer->push(nco.MixUp({insample, 0.0f}).real());
#endif
    }
  }

  delete reader;
  delete writer;
}
<commit_msg>don't overflow when channels > 1<commit_after>/*
 * deinvert - a voice inversion descrambler
 * Copyright (c) Oona Räisänen
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */
#include "src/deinvert.h"

#include <getopt.h>
#include <algorithm>
#include <iostream>
#include <stdexcept>
#include <string>

#include "config.h"
#include "src/liquid_wrappers.h"
#include "src/wdsp.h"

namespace deinvert {

namespace {

const float kLowpassFilterLengthSeconds = 0.0018f;
const int   kMaxFilterLength            = 2047;

}

void PrintUsage() {
  std::cout <<
     "deinvert [OPTIONS]\n"
     "\n"
     "-f, --frequency FREQ   Frequency of the inversion carrier, in Hertz.\n"
     "\n"
     "-h, --help             Display this usage help.\n"
     "\n"
     "-i, --input-file FILE  Use an audio file as input. All formats\n"
     "                       supported by libsndfile should work.\n"
     "\n"
     "-n, --nofilter         Disable filtering (faster).\n"
     "\n"
     "-o, --output-file FILE Write output to a WAV file instead of stdout. An\n"
     "                       existing file will be overwritten.\n"
     "\n"
     "-p, --preset NUM       Scrambler frequency preset (1-8), referring to\n"
     "                       the set of common carrier frequencies used by\n"
     "                       e.g. the Selectone ST-20B scrambler.\n"
     "\n"
     "-r, --samplerate RATE  Sampling rate of raw input audio, in Hertz.\n"
     "\n"
     "-v, --version          Display version string.\n";
}

void PrintVersion() {
#ifdef DEBUG
  std::cout << PACKAGE_STRING << "-debug by OH2EIQ" << std::endl;
#else
  std::cout << PACKAGE_STRING << " by OH2EIQ" << std::endl;
#endif
}

Options GetOptions(int argc, char** argv) {
  deinvert::Options options;

  static struct option long_options[] = {
    { "frequency",     no_argument, 0, 'f'},
    { "preset",        1,           0, 'p'},
    { "input-file",    1,           0, 'i'},
    { "help",          no_argument, 0, 'h'},
    { "nofilter",      no_argument, 0, 'n'},
    { "samplerate",    1,           0, 'r'},
    { "version",       no_argument, 0, 'v'},
    {0,                0,           0,  0}};

  static const std::vector<float> selectone_carriers({
      2632.f, 2718.f, 2868.f, 3023.f, 3196.f, 3339.f, 3495.f, 3729.f
  });

  options.frequency = selectone_carriers.at(0);

  int option_index = 0;
  int option_char;
  int selectone_num;

  while ((option_char = getopt_long(argc, argv, "f:hi:no:p:r:v",
                                    long_options,
         &option_index)) >= 0) {
    switch (option_char) {
      case 'i':
#ifdef HAVE_SNDFILE
        options.infilename = std::string(optarg);
        options.input_type = deinvert::INPUT_SNDFILE;
#else
        std::cerr << "error: deinvert was compiled without libsndfile"
                  << std::endl;
        options.just_exit = true;
#endif
        break;
      case 'f':
        options.frequency = std::atoi(optarg);
        break;
      case 'n':
        options.nofilter = true;
        break;
      case 'o':
#ifdef HAVE_SNDFILE
        options.output_type = deinvert::OUTPUT_WAVFILE;
        options.outfilename = std::string(optarg);
#else
        std::cerr << "error: deinvert was compiled without libsndfile"
                  << std::endl;
        options.just_exit = true;
#endif
        break;
      case 'p':
        selectone_num = std::atoi(optarg);
        if (selectone_num >= 1 &&
            selectone_num <= 8) {
          options.frequency = selectone_carriers.at(selectone_num - 1);
        } else {
          std::cerr << "error: please specify scrambler group from 1 to 8"
                    << std::endl;
          options.just_exit = true;
        }
        break;
      case 'r':
        options.samplerate = std::atoi(optarg);
        if (options.samplerate < 6000.f) {
          std::cerr << "error: sample rate must be 6000 Hz or higher"
                    << std::endl;
          options.just_exit = true;
        }
        break;
      case 'v':
        PrintVersion();
        options.just_exit = true;
        break;
      case 'h':
      default:
        PrintUsage();
        options.just_exit = true;
        break;
    }
    if (options.just_exit)
      break;
  }

  return options;
}

AudioReader::~AudioReader() {
}

bool AudioReader::eof() const {
  return is_eof_;
}

StdinReader::StdinReader(const Options& options) :
    samplerate_(options.samplerate) {
  is_eof_ = false;
}

StdinReader::~StdinReader() {
}

std::vector<float> StdinReader::ReadBlock() {
  int num_read = fread(buffer_, sizeof(buffer_[0]), bufsize_, stdin);

  if (num_read < bufsize_)
    is_eof_ = true;

  std::vector<float> result(num_read);
  for (int i = 0; i < num_read; i++)
    result[i] = buffer_[i] * (1.f / 32768.f);

  return result;
}

float StdinReader::samplerate() const {
  return samplerate_;
}

#ifdef HAVE_SNDFILE
SndfileReader::SndfileReader(const Options& options) :
    info_({0, 0, 0, 0, 0, 0}),
    file_(sf_open(options.infilename.c_str(), SFM_READ, &info_)) {
  is_eof_ = false;
  if (info_.frames == 0) {
    std::cerr << "error: couldn't open " << options.infilename << std::endl;
    is_eof_ = true;
  }
  if (info_.samplerate < 6000.f) {
    std::cerr << "error: sample rate must be 6000 Hz or higher" << std::endl;
    is_eof_ = true;
  }
}

SndfileReader::~SndfileReader() {
  sf_close(file_);
}

std::vector<float> SndfileReader::ReadBlock() {
  std::vector<float> result;
  if (is_eof_)
    return result;

  sf_count_t num_read = sf_readf_float(file_, buffer_,
      bufsize_ / info_.channels);
  if (num_read != bufsize_)
    is_eof_ = true;

  if (info_.channels == 1) {
    result = std::vector<float>(buffer_, buffer_ + num_read);
  } else {
    result = std::vector<float>(num_read);
    for (size_t i = 0; i < result.size(); i++)
      result[i] = buffer_[i * info_.channels];
  }
  return result;
}

float SndfileReader::samplerate() const {
  return info_.samplerate;
}
#endif

AudioWriter::~AudioWriter() {
}

RawPCMWriter::RawPCMWriter() : ptr_(0) {
}

bool RawPCMWriter::push(float sample) {
  int16_t outsample = sample * 32767.f;
  buffer_[ptr_] = outsample;
  ptr_++;
  if (ptr_ == bufsize_) {
    fwrite(buffer_, sizeof(buffer_[0]), bufsize_, stdout);
    ptr_ = 0;
  }
  return true;
}

#ifdef HAVE_SNDFILE
SndfileWriter::SndfileWriter(const std::string& fname, int rate) :
    info_({0, rate, 1, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 0, 0}),
    file_(sf_open(fname.c_str(), SFM_WRITE, &info_)),
    ptr_(0) {
}

SndfileWriter::~SndfileWriter() {
  write(ptr_);
  sf_close(file_);
}

bool SndfileWriter::push(float sample) {
  bool success = true;
  buffer_[ptr_] = sample;
  if (ptr_ == bufsize_ - 1) {
    success = write(ptr_);
  }

  ptr_ = (ptr_ + 1) % bufsize_;
  return success;
}

bool SndfileWriter::write(sf_count_t numsamples) {
  return (file_ != nullptr &&
          sf_write_float(file_, buffer_, numsamples) == numsamples);
}
#endif

}  // namespace deinvert

int main(int argc, char** argv) {
  deinvert::Options options = deinvert::GetOptions(argc, argv);

  if (options.just_exit)
    return EXIT_FAILURE;

  deinvert::AudioReader* reader;
  deinvert::AudioWriter* writer;

#ifdef HAVE_SNDFILE
  if (options.input_type == deinvert::INPUT_SNDFILE)
    reader = new deinvert::SndfileReader(options);
  else
#endif
    reader = new deinvert::StdinReader(options);

#ifdef HAVE_SNDFILE
  if (options.output_type == deinvert::OUTPUT_WAVFILE)
    writer = new deinvert::SndfileWriter(options.outfilename,
                                         options.samplerate);
  else
#endif
    writer = new deinvert::RawPCMWriter();

  int filter_length = 2 * std::round(options.samplerate *
                                     deinvert::kLowpassFilterLengthSeconds) + 1;
  filter_length = std::min(deinvert::kMaxFilterLength, filter_length);

#ifdef HAVE_LIQUID
  liquid::NCO nco(LIQUID_VCO,
                  options.frequency * 2.0f * M_PI / options.samplerate);
  liquid::FIRFilter prefilter(filter_length,
                           options.frequency / options.samplerate);
  liquid::FIRFilter postfilter(filter_length,
                           (options.frequency - 150.f) / options.samplerate);
#else
  wdsp::NCO nco(options.frequency * 2.0f * M_PI / options.samplerate);
#endif

  while (!reader->eof()) {
    for (float insample : reader->ReadBlock()) {
      nco.Step();
#ifdef HAVE_LIQUID
      if (options.nofilter) {
        writer->push(nco.MixUp({insample, 0.0f}).real() * M_SQRT2);
      } else {
        prefilter.push({insample, 0.0f});
        std::complex<float> mixed = nco.MixUp(prefilter.execute());
        postfilter.push(mixed.real());
        writer->push(postfilter.execute().real() * 2.f);
      }
#else
      writer->push(nco.MixUp({insample, 0.0f}).real());
#endif
    }
  }

  delete reader;
  delete writer;
}
<|endoftext|>


<commit_before>#define PY_SSIZE_T_CLEAN
#include <Python.h>

#if PY_MAJOR_VERSION == 3
#define BO_OUT "y#"
#endif

#if PY_MAJOR_VERSION == 2
#define BO_OUT "s#"
#endif

#define BYBYTESOP_FUNC(NAME,OP) \
static PyObject * NAME(PyObject *self, PyObject *args){ \
	Py_buffer ab,bb; \
	char * a; \
	char * b; \
	char * out; \
	Py_ssize_t out_size; \
	if (!PyArg_ParseTuple(args, "s*s*", &ab,&bb)) \
        return NULL; \
	if (ab.suboffsets!=NULL||ab.strides!=NULL){ \
		PyBuffer_Release(&ab); \
		PyBuffer_Release(&bb); \
		PyErr_SetString(PyExc_ValueError,"First argument must export buffer as PyBUF_CONTIG_RO"); \
		return NULL; \
	} \
	if (bb.suboffsets!=NULL||ab.strides!=NULL){ \
		PyBuffer_Release(&ab); \
		PyBuffer_Release(&bb); \
		PyErr_SetString(PyExc_ValueError,"First argument must export buffer as PyBUF_CONTIG_RO"); \
		return NULL; \
	} \
	Py_BEGIN_ALLOW_THREADS \
	if (bb.len<ab.len){ \
		out_size=bb.len; \
	}else{ \
		out_size=ab.len; \
	} \
	a=(char*)ab.buf; \
	b=(char*)bb.buf; \
	out=(char*)malloc(out_size); \
	for (int i=0;i<out_size;i++){ \
		out[i]=a[i] OP b[i]; \
	} \
	PyBuffer_Release(&ab); \
	PyBuffer_Release(&bb); \
	Py_END_ALLOW_THREADS \
	return Py_BuildValue(BO_OUT,out,out_size); \
} \

#define BYBYTESOP_N_FUNC(NAME,OP) \
static PyObject * NAME(PyObject *self, PyObject *args){ \
	Py_buffer ab,bb; \
	char * a; \
	char * b; \
	char * out; \
	Py_ssize_t out_size; \
	if (!PyArg_ParseTuple(args, "s*s*", &ab,&bb)) \
        return NULL; \
	if (ab.suboffsets!=NULL||ab.strides!=NULL){ \
		PyBuffer_Release(&ab); \
		PyBuffer_Release(&bb); \
		PyErr_SetString(PyExc_ValueError,"First argument must export buffer as PyBUF_CONTIG_RO"); \
		return NULL; \
	} \
	if (bb.suboffsets!=NULL||ab.strides!=NULL){ \
		PyBuffer_Release(&ab); \
		PyBuffer_Release(&bb); \
		PyErr_SetString(PyExc_ValueError,"First argument must export buffer as PyBUF_CONTIG_RO"); \
		return NULL; \
	} \
	Py_BEGIN_ALLOW_THREADS \
	if (bb.len<ab.len){ \
		out_size=bb.len; \
	}else{ \
		out_size=ab.len; \
	} \
	a=(char*)ab.buf; \
	b=(char*)bb.buf; \
	out=(char*)malloc(out_size); \
	for (int i=0;i<out_size;i++){ \
		out[i]=~(a[i] OP b[i]); \
	} \
	PyBuffer_Release(&ab); \
	PyBuffer_Release(&bb); \
	Py_END_ALLOW_THREADS \
	return Py_BuildValue(BO_OUT,out,out_size); \
} \

BYBYTESOP_FUNC(bytesop_op_xor, ^)

BYBYTESOP_FUNC(bytesop_op_or, | )

BYBYTESOP_FUNC(bytesop_op_and, &)

BYBYTESOP_N_FUNC(bytesop_op_xnor, ^)

BYBYTESOP_N_FUNC(bytesop_op_nor, | )

BYBYTESOP_N_FUNC(bytesop_op_nand, &)

static PyObject * bytesop_op_not(PyObject *self, PyObject *args){
	Py_buffer b;
	char * a;
	char * out;
	Py_ssize_t out_size;
	if (!PyArg_ParseTuple(args, "s*", &b))
		return NULL;
	if (b.suboffsets!=NULL||b.strides!=NULL){
		PyBuffer_Release(&b);
		PyErr_SetString(PyExc_ValueError,"Argument must export buffer as PyBUF_CONTIG_RO");
		return NULL;
	}
	Py_BEGIN_ALLOW_THREADS
	a=(char*)b.buf;
	out_size = b.len;
	out = (char*)malloc(out_size);
	for (int i = 0; i < out_size; i++){
		out[i] = ~a[i];
	}
	PyBuffer_Release(&b);
	Py_END_ALLOW_THREADS
	return Py_BuildValue(BO_OUT, out, out_size);
}

static PyMethodDef BytesOpMethods[] =
{
	{ "op_xor", bytesop_op_xor, METH_VARARGS,
	"XOR two bytes-like objects." },
	{ "op_or", bytesop_op_or, METH_VARARGS,
	"OR two bytes-like objects." },
	{ "op_and", bytesop_op_and, METH_VARARGS,
	"AND two bytes-like objects." },
	{ "op_xnor", bytesop_op_xnor, METH_VARARGS,
	"XNOR (NXOR) two bytes-like objects." },
	{ "op_nor", bytesop_op_nor, METH_VARARGS,
	"NOR two bytes-like objects." },
	{ "op_nand", bytesop_op_nand, METH_VARARGS,
	"NAND two bytes-like objects." },
	{ "op_not", bytesop_op_not, METH_VARARGS,
	"NOT a bytes-like object." },
	{ NULL, NULL, 0, NULL }
};

#define BO_N "bytesop"
#define BO_DOC "Bitwise operations on bytes-like objects"

#if PY_MAJOR_VERSION == 3
static struct PyModuleDef bytesopmodule = {
	PyModuleDef_HEAD_INIT,
	BO_N,   /* name of module */
	BO_DOC, /* module documentation, may be NULL */
	-1,       /* size of per-interpreter state of the module,
				 or -1 if the module keeps state in global variables. */
				 BytesOpMethods
};

PyMODINIT_FUNC PyInit_bytesop(void)
{
	return PyModule_Create(&bytesopmodule);
}
#endif

#if PY_MAJOR_VERSION == 2
PyMODINIT_FUNC initbytesop(void)
{
	(void)Py_InitModule3(BO_N, BytesOpMethods, BO_DOC);
}

#endif<commit_msg>add function signatures<commit_after>#define PY_SSIZE_T_CLEAN
#include <Python.h>

#if PY_MAJOR_VERSION == 3
#define BO_OUT "y#"
#endif

#if PY_MAJOR_VERSION == 2
#define BO_OUT "s#"
#endif

#define BYBYTESOP_FUNC(NAME,OP) \
static PyObject * NAME(PyObject *self, PyObject *args){ \
	Py_buffer ab,bb; \
	char * a; \
	char * b; \
	char * out; \
	Py_ssize_t out_size; \
	if (!PyArg_ParseTuple(args, "s*s*", &ab,&bb)) \
        return NULL; \
	if (ab.suboffsets!=NULL||ab.strides!=NULL){ \
		PyBuffer_Release(&ab); \
		PyBuffer_Release(&bb); \
		PyErr_SetString(PyExc_ValueError,"First argument must export buffer as PyBUF_CONTIG_RO"); \
		return NULL; \
	} \
	if (bb.suboffsets!=NULL||ab.strides!=NULL){ \
		PyBuffer_Release(&ab); \
		PyBuffer_Release(&bb); \
		PyErr_SetString(PyExc_ValueError,"First argument must export buffer as PyBUF_CONTIG_RO"); \
		return NULL; \
	} \
	Py_BEGIN_ALLOW_THREADS \
	if (bb.len<ab.len){ \
		out_size=bb.len; \
	}else{ \
		out_size=ab.len; \
	} \
	a=(char*)ab.buf; \
	b=(char*)bb.buf; \
	out=(char*)malloc(out_size); \
	for (int i=0;i<out_size;i++){ \
		out[i]=a[i] OP b[i]; \
	} \
	PyBuffer_Release(&ab); \
	PyBuffer_Release(&bb); \
	Py_END_ALLOW_THREADS \
	return Py_BuildValue(BO_OUT,out,out_size); \
} \

#define BYBYTESOP_N_FUNC(NAME,OP) \
static PyObject * NAME(PyObject *self, PyObject *args){ \
	Py_buffer ab,bb; \
	char * a; \
	char * b; \
	char * out; \
	Py_ssize_t out_size; \
	if (!PyArg_ParseTuple(args, "s*s*", &ab,&bb)) \
        return NULL; \
	if (ab.suboffsets!=NULL||ab.strides!=NULL){ \
		PyBuffer_Release(&ab); \
		PyBuffer_Release(&bb); \
		PyErr_SetString(PyExc_ValueError,"First argument must export buffer as PyBUF_CONTIG_RO"); \
		return NULL; \
	} \
	if (bb.suboffsets!=NULL||ab.strides!=NULL){ \
		PyBuffer_Release(&ab); \
		PyBuffer_Release(&bb); \
		PyErr_SetString(PyExc_ValueError,"First argument must export buffer as PyBUF_CONTIG_RO"); \
		return NULL; \
	} \
	Py_BEGIN_ALLOW_THREADS \
	if (bb.len<ab.len){ \
		out_size=bb.len; \
	}else{ \
		out_size=ab.len; \
	} \
	a=(char*)ab.buf; \
	b=(char*)bb.buf; \
	out=(char*)malloc(out_size); \
	for (int i=0;i<out_size;i++){ \
		out[i]=~(a[i] OP b[i]); \
	} \
	PyBuffer_Release(&ab); \
	PyBuffer_Release(&bb); \
	Py_END_ALLOW_THREADS \
	return Py_BuildValue(BO_OUT,out,out_size); \
} \

BYBYTESOP_FUNC(bytesop_op_xor, ^)

BYBYTESOP_FUNC(bytesop_op_or, | )

BYBYTESOP_FUNC(bytesop_op_and, &)

BYBYTESOP_N_FUNC(bytesop_op_xnor, ^)

BYBYTESOP_N_FUNC(bytesop_op_nor, | )

BYBYTESOP_N_FUNC(bytesop_op_nand, &)

static PyObject * bytesop_op_not(PyObject *self, PyObject *args){
	Py_buffer b;
	char * a;
	char * out;
	Py_ssize_t out_size;
	if (!PyArg_ParseTuple(args, "s*", &b))
		return NULL;
	if (b.suboffsets!=NULL||b.strides!=NULL){
		PyBuffer_Release(&b);
		PyErr_SetString(PyExc_ValueError,"Argument must export buffer as PyBUF_CONTIG_RO");
		return NULL;
	}
	Py_BEGIN_ALLOW_THREADS
	a=(char*)b.buf;
	out_size = b.len;
	out = (char*)malloc(out_size);
	for (int i = 0; i < out_size; i++){
		out[i] = ~a[i];
	}
	PyBuffer_Release(&b);
	Py_END_ALLOW_THREADS
	return Py_BuildValue(BO_OUT, out, out_size);
}

static PyMethodDef BytesOpMethods[] =
{
	{ "op_xor", bytesop_op_xor, METH_VARARGS,
	"(a, b)\nXOR two bytes-like objects." },
	{ "op_or", bytesop_op_or, METH_VARARGS,
	"(a, b)\nOR two bytes-like objects." },
	{ "op_and", bytesop_op_and, METH_VARARGS,
	"(a, b)\nAND two bytes-like objects." },
	{ "op_xnor", bytesop_op_xnor, METH_VARARGS,
	"(a, b)\nXNOR (NXOR) two bytes-like objects." },
	{ "op_nor", bytesop_op_nor, METH_VARARGS,
	"(a, b)\nNOR two bytes-like objects." },
	{ "op_nand", bytesop_op_nand, METH_VARARGS,
	"(a, b)\nNAND two bytes-like objects." },
	{ "op_not", bytesop_op_not, METH_VARARGS,
	"(b)\nNOT a bytes-like object." },
	{ NULL, NULL, 0, NULL }
};

#define BO_N "bytesop"
#define BO_DOC "Bitwise operations on bytes-like objects"

#if PY_MAJOR_VERSION == 3
static struct PyModuleDef bytesopmodule = {
	PyModuleDef_HEAD_INIT,
	BO_N,   /* name of module */
	BO_DOC, /* module documentation, may be NULL */
	-1,       /* size of per-interpreter state of the module,
				 or -1 if the module keeps state in global variables. */
				 BytesOpMethods
};

PyMODINIT_FUNC PyInit_bytesop(void)
{
	return PyModule_Create(&bytesopmodule);
}
#endif

#if PY_MAJOR_VERSION == 2
PyMODINIT_FUNC initbytesop(void)
{
	(void)Py_InitModule3(BO_N, BytesOpMethods, BO_DOC);
}

#endif<|endoftext|>


<commit_before>/* Copyright (c) 2017, EPL-Vizards
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the EPL-Vizards nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL EPL-Vizards BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*!
 * \file qwtplotmodel.cpp
 */

#include "qwtplotmodel.hpp"
using namespace EPL_Viz;

QWTPlotModel::QWTPlotModel() : BaseModel() {}

QWTPlotModel::init() {
  plot  = MainWindow::mainWindow->findChild<QwtPlot *>("plotCanvas");
  log   = MainWindow::mainWindow->getCaptureInstance()->getEventLog();
  appid = log->getAppID();
}

QWTPlotModel::update(EPL_DataCollect::Cycle *cycle) {
  // TODO Image Event?
}
<commit_msg>compile fix<commit_after>/* Copyright (c) 2017, EPL-Vizards
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the EPL-Vizards nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL EPL-Vizards BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*!
 * \file qwtplotmodel.cpp
 */

#include "qwtplotmodel.hpp"
using namespace EPL_Viz;

QWTPlotModel::QWTPlotModel() : BaseModel() {}

void QWTPlotModel::init() {
  plot  = MainWindow::mainWindow->findChild<QwtPlot *>("plotCanvas");
  log   = MainWindow::mainWindow->getCaptureInstance()->getEventLog();
  appid = log->getAppID();
}

void QWTPlotModel::update(EPL_DataCollect::Cycle *cycle) {
  // TODO Image Event?
}
<|endoftext|>


<commit_before>
#ifdef HAVE_STD_IOSTREAM
#include <iostream>
#include <fstream>
#else
#include <iostream.h>
#include <fstream.h>
#endif
#include <vector>

#include <sys/stat.h>

#include "dircoll.h"

namespace zipios {

using std::cerr ;
using std::endl ;
using std::vector ;

DirectoryCollection::DirectoryCollection( const string &path ) {
  // Check path is actually a directory
  if ( isDir( path ) ) {
    _filename = path ;
    _valid = true ;
  } else {
    _valid = false ;
  }
}

void DirectoryCollection::close() {
  _valid = false ;
}

vector< ConstEntryPointer > DirectoryCollection::entries() const {
  if ( ! _valid )
    throw InvalidStateException( "Attempt to use an invalid DirectoryCollection" ) ;

  cerr << "DirectoryCollection::entries not implemented yet" << endl ;

  // FIXME: Return the real thing.
  return vector< ConstEntryPointer >() ;
}

ConstEntryPointer
DirectoryCollection::getEntry( const string &name,
			       MatchPath matchpath = MATCH ) const {
  if ( ! _valid )
    throw InvalidStateException( "Attempt to use an invalid DirectoryCollection" ) ;

  if ( matchpath != MATCH ) {
    cerr <<
      "DirectoryCollection::getEntry not implemented for matchpath = IGNORE"
	 << endl ;
    return 0 ;
  }

  return new DirEntry( name, "", _filename ) ;
}

istream *DirectoryCollection::getInputStream( const ConstEntryPointer &entry ) {
  if ( ! _valid )
    throw InvalidStateException( "Attempt to use an invalid DirectoryCollection" ) ;

  return getInputStream( entry->getName() ) ;
}

istream *DirectoryCollection::getInputStream( const string &entry_name,
					      MatchPath matchpath = MATCH ) {
  if ( ! _valid )
    throw InvalidStateException( "Attempt to use an invalid DirectoryCollection" ) ;

  if ( matchpath != MATCH ) {
    cerr <<
      "DirectoryCollection::getInputStream not implemented for matchpath = IGNORE"
	 << endl ;
    return 0 ;
  }

  string real_path( _filename + entry_name ) ;
  ifstream *ifs = new ifstream( real_path.c_str() ) ;
  if( ! *ifs ) {
    delete ifs ;
    return 0 ;
  } else
    return ifs ;
}

int DirectoryCollection::size() const {
  if ( ! _valid )
    throw InvalidStateException( "Attempt to use an invalid DirectoryCollection" ) ;
  // FIXME: implement this method.
}

DirectoryCollection::~DirectoryCollection() {}

bool DirectoryCollection::isDir( const string &path ) const {
  struct stat buf ;
  // If stat fails something is wrong, and we
  // may as well return false.
  if( stat( path.c_str(), &buf ) != 0 )
    return false ;
  else
    return S_ISDIR( buf.st_mode ) ;
}

} // namespace

/** \file
    Implementation of DirectoryCollection.
*/

/*
  Zipios++ - a small C++ library that provides easy access to .zip files.
  Copyright (C) 2000  Thomas Sndergaard

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

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

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
<commit_msg>DirectoryCollection::getInputStream() now returns a 0 pointer (wrapped in a ConstEntryPointer) if the specified entry is invalid, as it should.<commit_after>
#ifdef HAVE_STD_IOSTREAM
#include <iostream>
#include <fstream>
#else
#include <iostream.h>
#include <fstream.h>
#endif
#include <vector>

#include <sys/stat.h>

#include "dircoll.h"

namespace zipios {

using std::cerr ;
using std::endl ;
using std::vector ;

DirectoryCollection::DirectoryCollection( const string &path ) {
  // Check path is actually a directory
  if ( isDir( path ) ) {
    _filename = path ;
    _valid = true ;
  } else {
    _valid = false ;
  }

  // In order to be able to simply prepend _filename
  // we need to transform it slightly. If it ends in a
  // slash thats fine.
  // if not we have to append a slash, unless the specified path is the
  // empty string.
  if ( _filename.size() > 0 && _filename[ _filename.size() -1 ] != '/' )
    _filename.append( 1, '/' ) ;
}

void DirectoryCollection::close() {
  _valid = false ;
}

vector< ConstEntryPointer > DirectoryCollection::entries() const {
  if ( ! _valid )
    throw InvalidStateException( "Attempt to use an invalid DirectoryCollection" ) ;

  cerr << "DirectoryCollection::entries not implemented yet" << endl ;

  // FIXME: Return the real thing.
  return vector< ConstEntryPointer >() ;
}

ConstEntryPointer
DirectoryCollection::getEntry( const string &name,
			       MatchPath matchpath = MATCH ) const {
  if ( ! _valid )
    throw InvalidStateException( "Attempt to use an invalid DirectoryCollection" ) ;

  if ( matchpath != MATCH ) {
    cerr <<
      "DirectoryCollection::getEntry not implemented for matchpath = IGNORE"
	 << endl ;
    return 0 ;
  }
  ConstEntryPointer ent ( new DirEntry( name, "", _filename ) ) ;
  if ( ent->isValid() )
    return ent ;
  else
    return 0 ;
}

istream *DirectoryCollection::getInputStream( const ConstEntryPointer &entry ) {
  if ( ! _valid )
    throw InvalidStateException( "Attempt to use an invalid DirectoryCollection" ) ;

  return getInputStream( entry->getName() ) ;
}

istream *DirectoryCollection::getInputStream( const string &entry_name,
					      MatchPath matchpath = MATCH ) {
  if ( ! _valid )
    throw InvalidStateException( "Attempt to use an invalid DirectoryCollection" ) ;

  if ( matchpath != MATCH ) {
    cerr <<
      "DirectoryCollection::getInputStream not implemented for matchpath = IGNORE"
	 << endl ;
    return 0 ;
  }

  string real_path( _filename + entry_name ) ;
  ifstream *ifs = new ifstream( real_path.c_str() ) ;
  if( ! *ifs ) {
    delete ifs ;
    return 0 ;
  } else
    return ifs ;
}

int DirectoryCollection::size() const {
  if ( ! _valid )
    throw InvalidStateException( "Attempt to use an invalid DirectoryCollection" ) ;
  // FIXME: implement this method.
}

DirectoryCollection::~DirectoryCollection() {}

bool DirectoryCollection::isDir( const string &path ) const {
  struct stat buf ;
  // If stat fails something is wrong, and we
  // may as well return false.
  if( stat( path.c_str(), &buf ) != 0 )
    return false ;
  else
    return S_ISDIR( buf.st_mode ) ;
}

} // namespace

/** \file
    Implementation of DirectoryCollection.
*/

/*
  Zipios++ - a small C++ library that provides easy access to .zip files.
  Copyright (C) 2000  Thomas Sndergaard

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

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

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


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/controls/native_control.h"

#include <atlbase.h>
#include <atlapp.h>
#include <atlcrack.h>
#include <atlframe.h>
#include <atlmisc.h>

#include "app/keyboard_code_conversion_win.h"
#include "app/keyboard_codes.h"
#include "app/l10n_util_win.h"
#include "base/logging.h"
#include "base/win_util.h"
#include "gfx/native_theme_win.h"
#include "views/background.h"
#include "views/border.h"
#include "views/controls/native/native_view_host.h"
#include "views/focus/focus_manager.h"
#include "views/widget/widget.h"

namespace views {

// Maps to the original WNDPROC for the controller window before we subclassed
// it.
static const wchar_t* const kHandlerKey =
    L"__CONTROL_ORIGINAL_MESSAGE_HANDLER__";

// Maps to the NativeControl.
static const wchar_t* const kNativeControlKey = L"__NATIVE_CONTROL__";

class NativeControlContainer : public CWindowImpl<NativeControlContainer,
                               CWindow,
                               CWinTraits<WS_CHILD | WS_CLIPSIBLINGS |
                                          WS_CLIPCHILDREN>> {
 public:

  explicit NativeControlContainer(NativeControl* parent) : parent_(parent),
                                                           control_(NULL) {
    Create(parent->GetWidget()->GetNativeView());
    ::ShowWindow(m_hWnd, SW_SHOW);
  }

  virtual ~NativeControlContainer() {
  }

  // NOTE: If you add a new message, be sure and verify parent_ is valid before
  // calling into parent_.
  DECLARE_FRAME_WND_CLASS(L"ChromeViewsNativeControlContainer", NULL);
  BEGIN_MSG_MAP(NativeControlContainer);
    MSG_WM_CREATE(OnCreate);
    MSG_WM_ERASEBKGND(OnEraseBkgnd);
    MSG_WM_PAINT(OnPaint);
    MSG_WM_SIZE(OnSize);
    MSG_WM_NOTIFY(OnNotify);
    MSG_WM_COMMAND(OnCommand);
    MSG_WM_DESTROY(OnDestroy);
    MSG_WM_CONTEXTMENU(OnContextMenu);
    MSG_WM_CTLCOLORBTN(OnCtlColorBtn);
    MSG_WM_CTLCOLORSTATIC(OnCtlColorStatic)
  END_MSG_MAP();

  HWND GetControl() {
    return control_;
  }

  // Called when the parent is getting deleted. This control stays around until
  // it gets the OnFinalMessage call.
  void ResetParent() {
    parent_ = NULL;
  }

  void OnFinalMessage(HWND hwnd) {
    if (parent_)
      parent_->NativeControlDestroyed();
    delete this;
  }

 private:
  LRESULT OnCreate(LPCREATESTRUCT create_struct) {
    control_ = parent_->CreateNativeControl(m_hWnd);

    // We subclass the control hwnd so we get the WM_KEYDOWN messages.
    WNDPROC original_handler =
        win_util::SetWindowProc(control_,
                                &NativeControl::NativeControlWndProc);
    BOOL set_prop_result = SetProp(control_, kHandlerKey, original_handler);
    CHECK(set_prop_result) << "Failed to SetProp in NativeControlContainer "
                           << win_util::FormatLastWin32Error();

    set_prop_result = SetProp(control_, kNativeControlKey, parent_);
    CHECK(set_prop_result) << "Failed to SetProp in NativeControlContainer "
                           << win_util::FormatLastWin32Error();

    ::ShowWindow(control_, SW_SHOW);
    return 1;
  }

  LRESULT OnEraseBkgnd(HDC dc) {
    return 1;
  }

  void OnPaint(HDC ignore) {
    PAINTSTRUCT ps;
    HDC dc = ::BeginPaint(*this, &ps);
    ::EndPaint(*this, &ps);
  }

  void OnSize(int type, const CSize& sz) {
    ::MoveWindow(control_, 0, 0, sz.cx, sz.cy, TRUE);
  }

  LRESULT OnCommand(UINT code, int id, HWND source) {
    return parent_ ? parent_->OnCommand(code, id, source) : 0;
  }

  LRESULT OnNotify(int w_param, LPNMHDR l_param) {
    if (parent_)
      return parent_->OnNotify(w_param, l_param);
    else
      return 0;
  }

  void OnDestroy() {
    if (parent_)
      parent_->OnDestroy();
  }

  void OnContextMenu(HWND window, const POINT& location) {
    if (parent_)
      parent_->OnContextMenu(location);
  }

  // We need to find an ancestor with a non-null background, and
  // ask it for a (solid color) brush that approximates
  // the background.  The caller will use this when drawing
  // the native control as a background color, particularly
  // for radiobuttons and XP style pushbuttons.
  LRESULT OnCtlColor(UINT msg, HDC dc, HWND control) {
    const View *ancestor = parent_;
    while (ancestor) {
      const Background *background = ancestor->background();
      if (background) {
        HBRUSH brush = background->GetNativeControlBrush();
        if (brush)
          return reinterpret_cast<LRESULT>(brush);
      }
      ancestor = ancestor->GetParent();
    }

    // COLOR_BTNFACE is the default for dialog box backgrounds.
    return reinterpret_cast<LRESULT>(GetSysColorBrush(COLOR_BTNFACE));
  }

  LRESULT OnCtlColorBtn(HDC dc, HWND control) {
    return OnCtlColor(WM_CTLCOLORBTN, dc, control);
  }

  LRESULT OnCtlColorStatic(HDC dc, HWND control) {
    return OnCtlColor(WM_CTLCOLORSTATIC, dc, control);
  }

  NativeControl* parent_;
  HWND control_;
  DISALLOW_COPY_AND_ASSIGN(NativeControlContainer);
};

NativeControl::NativeControl() : hwnd_view_(NULL),
                                 container_(NULL),
                                 fixed_width_(-1),
                                 horizontal_alignment_(CENTER),
                                 fixed_height_(-1),
                                 vertical_alignment_(CENTER) {
  enabled_ = true;
  focusable_ = true;
}

NativeControl::~NativeControl() {
  if (container_) {
    container_->ResetParent();
    ::DestroyWindow(*container_);
  }
}

void NativeControl::ValidateNativeControl() {
  if (hwnd_view_ == NULL) {
    hwnd_view_ = new NativeViewHost;
    AddChildView(hwnd_view_);
  }

  if (!container_ && IsVisible()) {
    container_ = new NativeControlContainer(this);
    hwnd_view_->Attach(*container_);
    if (!enabled_)
      EnableWindow(GetNativeControlHWND(), enabled_);

    // This message ensures that the focus border is shown.
    ::SendMessage(container_->GetControl(),
                  WM_CHANGEUISTATE,
                  MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS),
                  0);
  }
}

void NativeControl::ViewHierarchyChanged(bool is_add, View *parent,
                                         View *child) {
  if (is_add && parent != this && !container_ && GetWidget()) {
    ValidateNativeControl();
    Layout();
  }
}

void NativeControl::Layout() {
  if (!container_ && GetWidget())
    ValidateNativeControl();

  if (hwnd_view_) {
    gfx::Rect lb = GetLocalBounds(false);

    int x = lb.x();
    int y = lb.y();
    int width = lb.width();
    int height = lb.height();
    if (fixed_width_ > 0) {
      width = std::min(fixed_width_, width);
      switch (horizontal_alignment_) {
        case LEADING:
          // Nothing to do.
          break;
        case CENTER:
          x += (lb.width() - width) / 2;
          break;
        case TRAILING:
          x = x + lb.width() - width;
          break;
        default:
          NOTREACHED();
      }
    }

    if (fixed_height_ > 0) {
      height = std::min(fixed_height_, height);
      switch (vertical_alignment_) {
        case LEADING:
          // Nothing to do.
          break;
        case CENTER:
          y += (lb.height() - height) / 2;
          break;
        case TRAILING:
          y = y + lb.height() - height;
          break;
        default:
          NOTREACHED();
      }
    }

    hwnd_view_->SetBounds(x, y, width, height);
  }
}

void NativeControl::OnContextMenu(const POINT& location) {
  if (!GetContextMenuController())
    return;

  if (location.x == -1 && location.y == -1)
    ShowContextMenu(GetKeyboardContextMenuLocation(), false);
  else
    ShowContextMenu(gfx::Point(location), true);
}

void NativeControl::Focus() {
  if (container_) {
    DCHECK(container_->GetControl());
    ::SetFocus(container_->GetControl());
    NotifyAccessibilityEvent(AccessibilityTypes::EVENT_FOCUS, false);
  }
}

HWND NativeControl::GetNativeControlHWND() {
  if (container_)
    return container_->GetControl();
  else
    return NULL;
}

void NativeControl::NativeControlDestroyed() {
  if (hwnd_view_)
    hwnd_view_->Detach();
  container_ = NULL;
}

void NativeControl::SetVisible(bool f) {
  if (f != IsVisible()) {
    View::SetVisible(f);
    if (!f && container_) {
      ::DestroyWindow(*container_);
    } else if (f && !container_) {
      ValidateNativeControl();
    }
  }
}

void NativeControl::SetEnabled(bool enabled) {
  if (enabled_ != enabled) {
    View::SetEnabled(enabled);
    if (GetNativeControlHWND()) {
      EnableWindow(GetNativeControlHWND(), enabled_);
    }
  }
}

void NativeControl::Paint(gfx::Canvas* canvas) {
}

void NativeControl::VisibilityChanged(View* starting_from, bool is_visible) {
  SetVisible(is_visible);
}

void NativeControl::SetFixedWidth(int width, Alignment alignment) {
  DCHECK_GT(width, 0);
  fixed_width_ = width;
  horizontal_alignment_ = alignment;
}

void NativeControl::SetFixedHeight(int height, Alignment alignment) {
  DCHECK_GT(height, 0);
  fixed_height_ = height;
  vertical_alignment_ = alignment;
}

DWORD NativeControl::GetAdditionalExStyle() const {
  // If the UI for the view is mirrored, we should make sure we add the
  // extended window style for a right-to-left layout so the subclass creates
  // a mirrored HWND for the underlying control.
  DWORD ex_style = 0;
  if (base::i18n::IsRTL())
    ex_style |= l10n_util::GetExtendedStyles();

  return ex_style;
}

DWORD NativeControl::GetAdditionalRTLStyle() const {
  // If the UI for the view is mirrored, we should make sure we add the
  // extended window style for a right-to-left layout so the subclass creates
  // a mirrored HWND for the underlying control.
  DWORD ex_style = 0;
  if (base::i18n::IsRTL())
    ex_style |= l10n_util::GetExtendedTooltipStyles();

  return ex_style;
}

// static
LRESULT CALLBACK NativeControl::NativeControlWndProc(HWND window, UINT message,
                                                     WPARAM w_param,
                                                     LPARAM l_param) {
  HANDLE original_handler = GetProp(window, kHandlerKey);
  DCHECK(original_handler);
  NativeControl* native_control =
      static_cast<NativeControl*>(GetProp(window, kNativeControlKey));
  DCHECK(native_control);

  if (message == WM_KEYDOWN &&
      native_control->OnKeyDown(app::KeyboardCodeForWindowsKeyCode(w_param))) {
    return 0;
  } else if (message == WM_SETFOCUS) {
    // Let the focus manager know that the focus changed.
    FocusManager* focus_manager = native_control->GetFocusManager();
    if (focus_manager) {
      focus_manager->SetFocusedView(native_control);
    } else {
      NOTREACHED();
    }
  } else if (message == WM_DESTROY) {
    win_util::SetWindowProc(window,
                            reinterpret_cast<WNDPROC>(original_handler));
    RemoveProp(window, kHandlerKey);
    RemoveProp(window, kNativeControlKey);
  }

  return CallWindowProc(reinterpret_cast<WNDPROC>(original_handler), window,
                        message, w_param, l_param);
}

}  // namespace views
<commit_msg>Revert 63478 - Adds CHECKs in hopes of figuring out why we're crashing on some test bots.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/controls/native_control.h"

#include <atlbase.h>
#include <atlapp.h>
#include <atlcrack.h>
#include <atlframe.h>
#include <atlmisc.h>

#include "app/keyboard_code_conversion_win.h"
#include "app/keyboard_codes.h"
#include "app/l10n_util_win.h"
#include "base/logging.h"
#include "base/win_util.h"
#include "gfx/native_theme_win.h"
#include "views/background.h"
#include "views/border.h"
#include "views/controls/native/native_view_host.h"
#include "views/focus/focus_manager.h"
#include "views/widget/widget.h"

namespace views {

// Maps to the original WNDPROC for the controller window before we subclassed
// it.
static const wchar_t* const kHandlerKey =
    L"__CONTROL_ORIGINAL_MESSAGE_HANDLER__";

// Maps to the NativeControl.
static const wchar_t* const kNativeControlKey = L"__NATIVE_CONTROL__";

class NativeControlContainer : public CWindowImpl<NativeControlContainer,
                               CWindow,
                               CWinTraits<WS_CHILD | WS_CLIPSIBLINGS |
                                          WS_CLIPCHILDREN>> {
 public:

  explicit NativeControlContainer(NativeControl* parent) : parent_(parent),
                                                           control_(NULL) {
    Create(parent->GetWidget()->GetNativeView());
    ::ShowWindow(m_hWnd, SW_SHOW);
  }

  virtual ~NativeControlContainer() {
  }

  // NOTE: If you add a new message, be sure and verify parent_ is valid before
  // calling into parent_.
  DECLARE_FRAME_WND_CLASS(L"ChromeViewsNativeControlContainer", NULL);
  BEGIN_MSG_MAP(NativeControlContainer);
    MSG_WM_CREATE(OnCreate);
    MSG_WM_ERASEBKGND(OnEraseBkgnd);
    MSG_WM_PAINT(OnPaint);
    MSG_WM_SIZE(OnSize);
    MSG_WM_NOTIFY(OnNotify);
    MSG_WM_COMMAND(OnCommand);
    MSG_WM_DESTROY(OnDestroy);
    MSG_WM_CONTEXTMENU(OnContextMenu);
    MSG_WM_CTLCOLORBTN(OnCtlColorBtn);
    MSG_WM_CTLCOLORSTATIC(OnCtlColorStatic)
  END_MSG_MAP();

  HWND GetControl() {
    return control_;
  }

  // Called when the parent is getting deleted. This control stays around until
  // it gets the OnFinalMessage call.
  void ResetParent() {
    parent_ = NULL;
  }

  void OnFinalMessage(HWND hwnd) {
    if (parent_)
      parent_->NativeControlDestroyed();
    delete this;
  }
 private:

  LRESULT OnCreate(LPCREATESTRUCT create_struct) {
    control_ = parent_->CreateNativeControl(m_hWnd);

    // We subclass the control hwnd so we get the WM_KEYDOWN messages.
    WNDPROC original_handler =
        win_util::SetWindowProc(control_,
                                &NativeControl::NativeControlWndProc);
    SetProp(control_, kHandlerKey, original_handler);
    SetProp(control_, kNativeControlKey , parent_);

    ::ShowWindow(control_, SW_SHOW);
    return 1;
  }

  LRESULT OnEraseBkgnd(HDC dc) {
    return 1;
  }

  void OnPaint(HDC ignore) {
    PAINTSTRUCT ps;
    HDC dc = ::BeginPaint(*this, &ps);
    ::EndPaint(*this, &ps);
  }

  void OnSize(int type, const CSize& sz) {
    ::MoveWindow(control_, 0, 0, sz.cx, sz.cy, TRUE);
  }

  LRESULT OnCommand(UINT code, int id, HWND source) {
    return parent_ ? parent_->OnCommand(code, id, source) : 0;
  }

  LRESULT OnNotify(int w_param, LPNMHDR l_param) {
    if (parent_)
      return parent_->OnNotify(w_param, l_param);
    else
      return 0;
  }

  void OnDestroy() {
    if (parent_)
      parent_->OnDestroy();
  }

  void OnContextMenu(HWND window, const POINT& location) {
    if (parent_)
      parent_->OnContextMenu(location);
  }

  // We need to find an ancestor with a non-null background, and
  // ask it for a (solid color) brush that approximates
  // the background.  The caller will use this when drawing
  // the native control as a background color, particularly
  // for radiobuttons and XP style pushbuttons.
  LRESULT OnCtlColor(UINT msg, HDC dc, HWND control) {
    const View *ancestor = parent_;
    while (ancestor) {
      const Background *background = ancestor->background();
      if (background) {
        HBRUSH brush = background->GetNativeControlBrush();
        if (brush)
          return reinterpret_cast<LRESULT>(brush);
      }
      ancestor = ancestor->GetParent();
    }

    // COLOR_BTNFACE is the default for dialog box backgrounds.
    return reinterpret_cast<LRESULT>(GetSysColorBrush(COLOR_BTNFACE));
  }

  LRESULT OnCtlColorBtn(HDC dc, HWND control) {
    return OnCtlColor(WM_CTLCOLORBTN, dc, control);
  }

  LRESULT OnCtlColorStatic(HDC dc, HWND control) {
    return OnCtlColor(WM_CTLCOLORSTATIC, dc, control);
  }

  NativeControl* parent_;
  HWND control_;
  DISALLOW_COPY_AND_ASSIGN(NativeControlContainer);
};

NativeControl::NativeControl() : hwnd_view_(NULL),
                                 container_(NULL),
                                 fixed_width_(-1),
                                 horizontal_alignment_(CENTER),
                                 fixed_height_(-1),
                                 vertical_alignment_(CENTER) {
  enabled_ = true;
  focusable_ = true;
}

NativeControl::~NativeControl() {
  if (container_) {
    container_->ResetParent();
    ::DestroyWindow(*container_);
  }
}

void NativeControl::ValidateNativeControl() {
  if (hwnd_view_ == NULL) {
    hwnd_view_ = new NativeViewHost;
    AddChildView(hwnd_view_);
  }

  if (!container_ && IsVisible()) {
    container_ = new NativeControlContainer(this);
    hwnd_view_->Attach(*container_);
    if (!enabled_)
      EnableWindow(GetNativeControlHWND(), enabled_);

    // This message ensures that the focus border is shown.
    ::SendMessage(container_->GetControl(),
                  WM_CHANGEUISTATE,
                  MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS),
                  0);
  }
}

void NativeControl::ViewHierarchyChanged(bool is_add, View *parent,
                                         View *child) {
  if (is_add && parent != this && !container_ && GetWidget()) {
    ValidateNativeControl();
    Layout();
  }
}

void NativeControl::Layout() {
  if (!container_ && GetWidget())
    ValidateNativeControl();

  if (hwnd_view_) {
    gfx::Rect lb = GetLocalBounds(false);

    int x = lb.x();
    int y = lb.y();
    int width = lb.width();
    int height = lb.height();
    if (fixed_width_ > 0) {
      width = std::min(fixed_width_, width);
      switch (horizontal_alignment_) {
        case LEADING:
          // Nothing to do.
          break;
        case CENTER:
          x += (lb.width() - width) / 2;
          break;
        case TRAILING:
          x = x + lb.width() - width;
          break;
        default:
          NOTREACHED();
      }
    }

    if (fixed_height_ > 0) {
      height = std::min(fixed_height_, height);
      switch (vertical_alignment_) {
        case LEADING:
          // Nothing to do.
          break;
        case CENTER:
          y += (lb.height() - height) / 2;
          break;
        case TRAILING:
          y = y + lb.height() - height;
          break;
        default:
          NOTREACHED();
      }
    }

    hwnd_view_->SetBounds(x, y, width, height);
  }
}

void NativeControl::OnContextMenu(const POINT& location) {
  if (!GetContextMenuController())
    return;

  if (location.x == -1 && location.y == -1)
    ShowContextMenu(GetKeyboardContextMenuLocation(), false);
  else
    ShowContextMenu(gfx::Point(location), true);
}

void NativeControl::Focus() {
  if (container_) {
    DCHECK(container_->GetControl());
    ::SetFocus(container_->GetControl());
    NotifyAccessibilityEvent(AccessibilityTypes::EVENT_FOCUS, false);
  }
}

HWND NativeControl::GetNativeControlHWND() {
  if (container_)
    return container_->GetControl();
  else
    return NULL;
}

void NativeControl::NativeControlDestroyed() {
  if (hwnd_view_)
    hwnd_view_->Detach();
  container_ = NULL;
}

void NativeControl::SetVisible(bool f) {
  if (f != IsVisible()) {
    View::SetVisible(f);
    if (!f && container_) {
      ::DestroyWindow(*container_);
    } else if (f && !container_) {
      ValidateNativeControl();
    }
  }
}

void NativeControl::SetEnabled(bool enabled) {
  if (enabled_ != enabled) {
    View::SetEnabled(enabled);
    if (GetNativeControlHWND()) {
      EnableWindow(GetNativeControlHWND(), enabled_);
    }
  }
}

void NativeControl::Paint(gfx::Canvas* canvas) {
}

void NativeControl::VisibilityChanged(View* starting_from, bool is_visible) {
  SetVisible(is_visible);
}

void NativeControl::SetFixedWidth(int width, Alignment alignment) {
  DCHECK_GT(width, 0);
  fixed_width_ = width;
  horizontal_alignment_ = alignment;
}

void NativeControl::SetFixedHeight(int height, Alignment alignment) {
  DCHECK_GT(height, 0);
  fixed_height_ = height;
  vertical_alignment_ = alignment;
}

DWORD NativeControl::GetAdditionalExStyle() const {
  // If the UI for the view is mirrored, we should make sure we add the
  // extended window style for a right-to-left layout so the subclass creates
  // a mirrored HWND for the underlying control.
  DWORD ex_style = 0;
  if (base::i18n::IsRTL())
    ex_style |= l10n_util::GetExtendedStyles();

  return ex_style;
}

DWORD NativeControl::GetAdditionalRTLStyle() const {
  // If the UI for the view is mirrored, we should make sure we add the
  // extended window style for a right-to-left layout so the subclass creates
  // a mirrored HWND for the underlying control.
  DWORD ex_style = 0;
  if (base::i18n::IsRTL())
    ex_style |= l10n_util::GetExtendedTooltipStyles();

  return ex_style;
}

// static
LRESULT CALLBACK NativeControl::NativeControlWndProc(HWND window, UINT message,
                                                     WPARAM w_param,
                                                     LPARAM l_param) {
  HANDLE original_handler = GetProp(window, kHandlerKey);
  DCHECK(original_handler);
  NativeControl* native_control =
      static_cast<NativeControl*>(GetProp(window, kNativeControlKey));
  DCHECK(native_control);

  if (message == WM_KEYDOWN &&
      native_control->OnKeyDown(app::KeyboardCodeForWindowsKeyCode(w_param))) {
    return 0;
  } else if (message == WM_SETFOCUS) {
    // Let the focus manager know that the focus changed.
    FocusManager* focus_manager = native_control->GetFocusManager();
    if (focus_manager) {
      focus_manager->SetFocusedView(native_control);
    } else {
      NOTREACHED();
    }
  } else if (message == WM_DESTROY) {
    win_util::SetWindowProc(window,
                            reinterpret_cast<WNDPROC>(original_handler));
    RemoveProp(window, kHandlerKey);
    RemoveProp(window, kNativeControlKey);
  }

  return CallWindowProc(reinterpret_cast<WNDPROC>(original_handler), window,
                        message, w_param, l_param);
}

}  // namespace views
<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2014                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENCE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#ifndef CAF_TUPLE_CAST_HPP
#define CAF_TUPLE_CAST_HPP

#include <type_traits>

#include "caf/optional.hpp"
#include "caf/cow_tuple.hpp"

#include "caf/detail/matches.hpp"
#include "caf/detail/type_list.hpp"

namespace caf {

template <class... T>
optional<typename detail::tl_apply<
  typename detail::tl_filter_not<detail::type_list<T...>, is_anything>::type,
  cow_tuple
>::type>
tuple_cast(message) {
  return none; //TODO: implement me
}

} // namespace caf

#endif // CAF_TUPLE_CAST_HPP
<commit_msg>Remove obsolete file<commit_after><|endoftext|>


<commit_before>#include "gtest/gtest.h"
#include "Grid.hpp"
#include <algorithm>

namespace jakway_antf
{

/**
 * the square is a stable shape in the game of life
 * it should never change regardless of how many generations we run
 */
TEST(GenerationTests, testSquare)
{
    const POS_TYPE width=4, height=4;
    Grid grid(width, height);

    ASSERT_TRUE(grid.getSize() == (width * height));

    /**
     * XXX--TODO:
     * check that the grid has 4 live tiles with a 1-cell dead tile buffer around them
     * grid.runGeneration will expand the grid since touchingEdges() is true
     * also change the name of GameRunner.runGeneration because 2 classes with different methods with the same name is confusing
     */
    auto checkGrid = [&grid]() {
        //check the top and bottom edges are dead--we expanded the graph
        for(POS_TYPE x = 0; x < width + 1; x++)
        {
            ASSERT_TRUE(grid.getTile(x, 0) == TILE_DEAD);
            ASSERT_TRUE(grid.getTile(x, height + 1) == TILE_DEAD);
        }

        //check the left and right edges are dead
        for(POS_TYPE y = 0; y < height + 1; y++)
        {
            ASSERT_TRUE(grid.getTile(y, 0) == TILE_DEAD);
            ASSERT_TRUE(grid.getTile(y, width + 1) == TILE_DEAD);
        }

        //the middle of the graph is the square--it should be alive
        ASSERT_TRUE(grid.getTile(1, 1) == TILE_ALIVE);
        ASSERT_TRUE(grid.getTile(2, 1) == TILE_ALIVE);
        ASSERT_TRUE(grid.getTile(1, 2) == TILE_ALIVE);
        ASSERT_TRUE(grid.getTile(2, 2) == TILE_ALIVE);
        };

    //set all tiles to alive
    std::for_each(grid.begin(), grid.end(), [](bool& tile) { tile = TILE_ALIVE; });

    //check the grid is OK
    std::for_each(grid.begin(), grid.end(), [](bool& tile) { ASSERT_TRUE(tile == TILE_ALIVE); });
    ASSERT_TRUE(grid.getSize() == (width * height));

    //after running the first generation the grid will be expanded--this requires a new checking function
    //run generations and assert nothing has changed
    const unsigned int numGenerations = 100;
    for(unsigned int i = 0; i < numGenerations ; i++)
    {
        //after each generation, check the size is still correct and all the tiles are the same
        grid.runGeneration();
        checkGrid();
        ASSERT_TRUE(grid.getSize() == ((width+2) * (height+2)));
    }
}

}
<commit_msg>moved tests out of the jakway_antf namespace<commit_after>#include "gtest/gtest.h"
#include "Grid.hpp"
#include <algorithm>

using namespace jakway_antf;

/**
 * the square is a stable shape in the game of life
 * it should never change regardless of how many generations we run
 */
TEST(GenerationTests, testSquare)
{
    const POS_TYPE width=4, height=4;
    Grid grid(width, height);

    ASSERT_TRUE(grid.getSize() == (width * height));

    /**
     * XXX--TODO:
     * check that the grid has 4 live tiles with a 1-cell dead tile buffer around them
     * grid.runGeneration will expand the grid since touchingEdges() is true
     * also change the name of GameRunner.runGeneration because 2 classes with different methods with the same name is confusing
     */
    auto checkGrid = [&grid]() {
        //check the top and bottom edges are dead--we expanded the graph
        for(POS_TYPE x = 0; x < width + 1; x++)
        {
            ASSERT_TRUE(grid.getTile(x, 0) == TILE_DEAD);
            ASSERT_TRUE(grid.getTile(x, height + 1) == TILE_DEAD);
        }

        //check the left and right edges are dead
        for(POS_TYPE y = 0; y < height + 1; y++)
        {
            ASSERT_TRUE(grid.getTile(y, 0) == TILE_DEAD);
            ASSERT_TRUE(grid.getTile(y, width + 1) == TILE_DEAD);
        }

        //the middle of the graph is the square--it should be alive
        ASSERT_TRUE(grid.getTile(1, 1) == TILE_ALIVE);
        ASSERT_TRUE(grid.getTile(2, 1) == TILE_ALIVE);
        ASSERT_TRUE(grid.getTile(1, 2) == TILE_ALIVE);
        ASSERT_TRUE(grid.getTile(2, 2) == TILE_ALIVE);
        };

    //set all tiles to alive
    std::for_each(grid.begin(), grid.end(), [](bool& tile) { tile = TILE_ALIVE; });

    //check the grid is OK
    std::for_each(grid.begin(), grid.end(), [](bool& tile) { ASSERT_TRUE(tile == TILE_ALIVE); });
    ASSERT_TRUE(grid.getSize() == (width * height));

    //after running the first generation the grid will be expanded--this requires a new checking function
    //run generations and assert nothing has changed
    const unsigned int numGenerations = 100;
    for(unsigned int i = 0; i < numGenerations ; i++)
    {
        //after each generation, check the size is still correct and all the tiles are the same
        grid.runGeneration();
        checkGrid();
        ASSERT_TRUE(grid.getSize() == ((width+2) * (height+2)));
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 mogemimi.
// Distributed under the MIT license. See LICENSE.md file for details.

#ifndef POMDOG_EFFECTPASSGL4_5C5F046F_HPP
#define POMDOG_EFFECTPASSGL4_5C5F046F_HPP

#include "OpenGLPrerequisites.hpp"
#include "BlendStateGL4.hpp"
#include "DepthStencilStateGL4.hpp"
#include "RasterizerStateGL4.hpp"
#include "TypesafeGL4.hpp"
#include "../RenderSystem/NativeEffectPass.hpp"
#include "Pomdog/Graphics/detail/ForwardDeclarations.hpp"
#include "Pomdog/Utility/Optional.hpp"
#include <cstdint>
#include <vector>

namespace Pomdog {
namespace Detail {
namespace RenderSystem {
namespace GL4 {

class InputLayoutGL4;

struct TextureBindingGL4 {
    GLint UniformLocation;
    std::uint16_t SlotIndex;
};

struct UniformBlockBindingGL4 {
    std::string Name;
    std::uint16_t SlotIndex;
};

class EffectPassGL4 final: public NativeEffectPass {
public:
    EffectPassGL4() = delete;

    explicit EffectPassGL4(EffectPassDescription const& description);

    ~EffectPassGL4();

    std::unique_ptr<NativeConstantLayout> CreateConstantLayout() override;

    void ApplyShaders();

    ShaderProgramGL4 GetShaderProgram() const;

    InputLayoutGL4* GetInputLayout() const;

private:
    std::vector<TextureBindingGL4> textureBindings;
    std::vector<UniformBlockBindingGL4> uniformBlockBindings;
    Optional<ShaderProgramGL4> shaderProgram;
    std::unique_ptr<InputLayoutGL4> inputLayout;
    BlendStateGL4 blendState;
    RasterizerStateGL4 rasterizerState;
    DepthStencilStateGL4 depthStencilState;
};

}// namespace GL4
}// namespace RenderSystem
}// namespace Detail
}// namespace Pomdog

#endif // POMDOG_EFFECTPASSGL4_5C5F046F_HPP
<commit_msg>Minor refactor<commit_after>// Copyright (c) 2013-2015 mogemimi.
// Distributed under the MIT license. See LICENSE.md file for details.

#ifndef POMDOG_EFFECTPASSGL4_5C5F046F_HPP
#define POMDOG_EFFECTPASSGL4_5C5F046F_HPP

#include "OpenGLPrerequisites.hpp"
#include "BlendStateGL4.hpp"
#include "DepthStencilStateGL4.hpp"
#include "RasterizerStateGL4.hpp"
#include "TypesafeGL4.hpp"
#include "../RenderSystem/NativeEffectPass.hpp"
#include "Pomdog/Graphics/detail/ForwardDeclarations.hpp"
#include "Pomdog/Utility/Optional.hpp"
#include <cstdint>
#include <vector>

namespace Pomdog {
namespace Detail {
namespace RenderSystem {
namespace GL4 {

class InputLayoutGL4;

struct TextureBindingGL4 {
    GLint UniformLocation;
    std::uint16_t SlotIndex;
};

struct UniformBlockBindingGL4 {
    std::string Name;
    std::uint16_t SlotIndex;
};

class EffectPassGL4 final: public NativeEffectPass {
public:
    EffectPassGL4() = delete;

    explicit EffectPassGL4(EffectPassDescription const& description);

    ~EffectPassGL4();

    std::unique_ptr<NativeConstantLayout> CreateConstantLayout() override;

    void ApplyShaders();

    ShaderProgramGL4 GetShaderProgram() const;

    InputLayoutGL4* GetInputLayout() const;

private:
    std::vector<TextureBindingGL4> textureBindings;
    std::vector<UniformBlockBindingGL4> uniformBlockBindings;
    BlendStateGL4 blendState;
    RasterizerStateGL4 rasterizerState;
    DepthStencilStateGL4 depthStencilState;
    Optional<ShaderProgramGL4> shaderProgram;
    std::unique_ptr<InputLayoutGL4> inputLayout;
};

}// namespace GL4
}// namespace RenderSystem
}// namespace Detail
}// namespace Pomdog

#endif // POMDOG_EFFECTPASSGL4_5C5F046F_HPP
<|endoftext|>


<commit_before>/*
 * Copyright 2017-present Facebook, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 <thrift/compiler/common.h>
#include <thrift/compiler/parse/parsing_driver.h>

#include <boost/filesystem.hpp>

namespace apache {
namespace thrift {
namespace compiler {

/**
 * Current compilation stage. One of: arguments, parse, generation
 */
std::string g_stage;

/**
 * Directory containing template files
 */
std::string g_template_dir;

/**
 * Should C++ include statements use path prefixes for other thrift-generated
 * header files
 */
bool g_cpp_use_include_prefix = false;

/**
 * Global debug state
 */
int g_debug = 0;

/**
 * Warning level
 */
int g_warn = 1;

/**
 * Verbose output
 */
int g_verbose = 0;

/**
 * The last parsed doctext comment.
 */
char* g_doctext;

/**
 * The location of the last parsed doctext comment.
 */
int g_doctext_lineno;

std::string compute_absolute_path(const std::string& path) {
  boost::filesystem::path abspath{path};
  try {
    abspath = boost::filesystem::canonical(abspath);
    return abspath.string();
  } catch (const boost::filesystem::filesystem_error& e) {
    failure("Could not find file: %s. Error: %s", path.c_str(), e.what());
  }
}

void pdebug(const char* fmt, ...) {
  if (g_debug == 0) {
    return;
  }
  va_list args;
  printf("[PARSE] ");
  va_start(args, fmt);
  vprintf(fmt, args);
  va_end(args);
  printf("\n");
}

void pverbose(const char* fmt, ...) {
  if (g_verbose == 0) {
    return;
  }
  va_list args;
  va_start(args, fmt);
  vprintf(fmt, args);
  va_end(args);
}

void pwarning(int level, const char* fmt, ...) {
  if (g_warn < level) {
    return;
  }
  va_list args;
  fprintf(stderr, "[WARNING:%s] ", g_stage.c_str());
  va_start(args, fmt);
  vfprintf(stderr, fmt, args);
  va_end(args);
  fprintf(stderr, "\n");
}

[[noreturn]] void failure(const char* fmt, ...) {
  va_list args;
  fprintf(stderr, "[FAILURE:%s] ", g_stage.c_str());
  va_start(args, fmt);
  vfprintf(stderr, fmt, args);
  va_end(args);
  fprintf(stderr, "\n");
  exit(1);
}

void dump_docstrings(t_program* program) {
  std::string progdoc = program->get_doc();
  if (!progdoc.empty()) {
    printf("Whole program doc:\n%s\n", progdoc.c_str());
  }
  const std::vector<t_typedef*>& typedefs = program->get_typedefs();
  std::vector<t_typedef*>::const_iterator t_iter;
  for (t_iter = typedefs.begin(); t_iter != typedefs.end(); ++t_iter) {
    t_typedef* td = *t_iter;
    if (td->has_doc()) {
      printf(
          "typedef %s:\n%s\n", td->get_name().c_str(), td->get_doc().c_str());
    }
  }
  const std::vector<t_enum*>& enums = program->get_enums();
  std::vector<t_enum*>::const_iterator e_iter;
  for (e_iter = enums.begin(); e_iter != enums.end(); ++e_iter) {
    t_enum* en = *e_iter;
    if (en->has_doc()) {
      printf("enum %s:\n%s\n", en->get_name().c_str(), en->get_doc().c_str());
    }
  }
  const std::vector<t_const*>& consts = program->get_consts();
  std::vector<t_const*>::const_iterator c_iter;
  for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
    t_const* co = *c_iter;
    if (co->has_doc()) {
      printf("const %s:\n%s\n", co->get_name().c_str(), co->get_doc().c_str());
    }
  }
  const std::vector<t_struct*>& structs = program->get_structs();
  std::vector<t_struct*>::const_iterator s_iter;
  for (s_iter = structs.begin(); s_iter != structs.end(); ++s_iter) {
    t_struct* st = *s_iter;
    if (st->has_doc()) {
      printf("struct %s:\n%s\n", st->get_name().c_str(), st->get_doc().c_str());
    }
  }
  const std::vector<t_struct*>& xceptions = program->get_xceptions();
  std::vector<t_struct*>::const_iterator x_iter;
  for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
    t_struct* xn = *x_iter;
    if (xn->has_doc()) {
      printf(
          "xception %s:\n%s\n", xn->get_name().c_str(), xn->get_doc().c_str());
    }
  }
  const std::vector<t_service*>& services = program->get_services();
  std::vector<t_service*>::const_iterator v_iter;
  for (v_iter = services.begin(); v_iter != services.end(); ++v_iter) {
    t_service* sv = *v_iter;
    if (sv->has_doc()) {
      printf(
          "service %s:\n%s\n", sv->get_name().c_str(), sv->get_doc().c_str());
    }
  }
}

/**
 * Parse with the given parameters, and dump all the diagnostic messages
 * returned.
 *
 * If the parsing fails, this function will exit(1).
 */
std::unique_ptr<t_program_bundle> parse_and_dump_diagnostics(
    std::string path,
    apache::thrift::parsing_params params) {
  apache::thrift::parsing_driver driver{path, std::move(params)};

  std::vector<apache::thrift::diagnostic_message> diagnostic_messages;
  auto program = driver.parse(diagnostic_messages);

  for (auto const& message : diagnostic_messages) {
    switch (message.level) {
      case apache::thrift::diagnostic_level::YY_ERROR:
        fprintf(
            stderr,
            "[ERROR:%s:%d] (last token was '%s')\n%s\n",
            message.filename.c_str(),
            message.lineno,
            message.last_token.c_str(),
            message.message.c_str());
        break;
      case apache::thrift::diagnostic_level::WARNING:
        fprintf(
            stderr,
            "[WARNING:%s:%d] %s\n",
            message.filename.c_str(),
            message.lineno,
            message.message.c_str());
        break;
      case apache::thrift::diagnostic_level::VERBOSE:
        fprintf(stderr, "%s", message.message.c_str());
        break;
      case apache::thrift::diagnostic_level::DEBUG:
        fprintf(
            stderr, "[PARSE:%d] %s\n", message.lineno, message.message.c_str());
        break;
      case apache::thrift::diagnostic_level::FAILURE:
        fprintf(
            stderr,
            "[FAILURE:%s:%d] %s\n",
            message.filename.c_str(),
            message.lineno,
            message.message.c_str());
        break;
    }
  }

  if (!program) {
    exit(1);
  }

  return program;
}

void mark_file_executable(std::string const& path) {
  namespace fs = boost::filesystem;
  fs::permissions(
      path, fs::add_perms | fs::owner_exe | fs::group_exe | fs::others_exe);
}

} // namespace compiler
} // namespace thrift
} // namespace apache
<commit_msg>Fix issue of getting absolute path on Windows<commit_after>/*
 * Copyright 2017-present Facebook, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 <thrift/compiler/common.h>
#include <thrift/compiler/parse/parsing_driver.h>

#include <boost/filesystem.hpp>

namespace apache {
namespace thrift {
namespace compiler {

/**
 * Current compilation stage. One of: arguments, parse, generation
 */
std::string g_stage;

/**
 * Directory containing template files
 */
std::string g_template_dir;

/**
 * Should C++ include statements use path prefixes for other thrift-generated
 * header files
 */
bool g_cpp_use_include_prefix = false;

/**
 * Global debug state
 */
int g_debug = 0;

/**
 * Warning level
 */
int g_warn = 1;

/**
 * Verbose output
 */
int g_verbose = 0;

/**
 * The last parsed doctext comment.
 */
char* g_doctext;

/**
 * The location of the last parsed doctext comment.
 */
int g_doctext_lineno;

std::string compute_absolute_path(const std::string& path) {
  boost::filesystem::path abspath{path};
  try {
    abspath = boost::filesystem::absolute(abspath);
    return abspath.string();
  } catch (const boost::filesystem::filesystem_error& e) {
    failure("Could not find file: %s. Error: %s", path.c_str(), e.what());
  }
}

void pdebug(const char* fmt, ...) {
  if (g_debug == 0) {
    return;
  }
  va_list args;
  printf("[PARSE] ");
  va_start(args, fmt);
  vprintf(fmt, args);
  va_end(args);
  printf("\n");
}

void pverbose(const char* fmt, ...) {
  if (g_verbose == 0) {
    return;
  }
  va_list args;
  va_start(args, fmt);
  vprintf(fmt, args);
  va_end(args);
}

void pwarning(int level, const char* fmt, ...) {
  if (g_warn < level) {
    return;
  }
  va_list args;
  fprintf(stderr, "[WARNING:%s] ", g_stage.c_str());
  va_start(args, fmt);
  vfprintf(stderr, fmt, args);
  va_end(args);
  fprintf(stderr, "\n");
}

[[noreturn]] void failure(const char* fmt, ...) {
  va_list args;
  fprintf(stderr, "[FAILURE:%s] ", g_stage.c_str());
  va_start(args, fmt);
  vfprintf(stderr, fmt, args);
  va_end(args);
  fprintf(stderr, "\n");
  exit(1);
}

void dump_docstrings(t_program* program) {
  std::string progdoc = program->get_doc();
  if (!progdoc.empty()) {
    printf("Whole program doc:\n%s\n", progdoc.c_str());
  }
  const std::vector<t_typedef*>& typedefs = program->get_typedefs();
  std::vector<t_typedef*>::const_iterator t_iter;
  for (t_iter = typedefs.begin(); t_iter != typedefs.end(); ++t_iter) {
    t_typedef* td = *t_iter;
    if (td->has_doc()) {
      printf(
          "typedef %s:\n%s\n", td->get_name().c_str(), td->get_doc().c_str());
    }
  }
  const std::vector<t_enum*>& enums = program->get_enums();
  std::vector<t_enum*>::const_iterator e_iter;
  for (e_iter = enums.begin(); e_iter != enums.end(); ++e_iter) {
    t_enum* en = *e_iter;
    if (en->has_doc()) {
      printf("enum %s:\n%s\n", en->get_name().c_str(), en->get_doc().c_str());
    }
  }
  const std::vector<t_const*>& consts = program->get_consts();
  std::vector<t_const*>::const_iterator c_iter;
  for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
    t_const* co = *c_iter;
    if (co->has_doc()) {
      printf("const %s:\n%s\n", co->get_name().c_str(), co->get_doc().c_str());
    }
  }
  const std::vector<t_struct*>& structs = program->get_structs();
  std::vector<t_struct*>::const_iterator s_iter;
  for (s_iter = structs.begin(); s_iter != structs.end(); ++s_iter) {
    t_struct* st = *s_iter;
    if (st->has_doc()) {
      printf("struct %s:\n%s\n", st->get_name().c_str(), st->get_doc().c_str());
    }
  }
  const std::vector<t_struct*>& xceptions = program->get_xceptions();
  std::vector<t_struct*>::const_iterator x_iter;
  for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
    t_struct* xn = *x_iter;
    if (xn->has_doc()) {
      printf(
          "xception %s:\n%s\n", xn->get_name().c_str(), xn->get_doc().c_str());
    }
  }
  const std::vector<t_service*>& services = program->get_services();
  std::vector<t_service*>::const_iterator v_iter;
  for (v_iter = services.begin(); v_iter != services.end(); ++v_iter) {
    t_service* sv = *v_iter;
    if (sv->has_doc()) {
      printf(
          "service %s:\n%s\n", sv->get_name().c_str(), sv->get_doc().c_str());
    }
  }
}

/**
 * Parse with the given parameters, and dump all the diagnostic messages
 * returned.
 *
 * If the parsing fails, this function will exit(1).
 */
std::unique_ptr<t_program_bundle> parse_and_dump_diagnostics(
    std::string path,
    apache::thrift::parsing_params params) {
  apache::thrift::parsing_driver driver{path, std::move(params)};

  std::vector<apache::thrift::diagnostic_message> diagnostic_messages;
  auto program = driver.parse(diagnostic_messages);

  for (auto const& message : diagnostic_messages) {
    switch (message.level) {
      case apache::thrift::diagnostic_level::YY_ERROR:
        fprintf(
            stderr,
            "[ERROR:%s:%d] (last token was '%s')\n%s\n",
            message.filename.c_str(),
            message.lineno,
            message.last_token.c_str(),
            message.message.c_str());
        break;
      case apache::thrift::diagnostic_level::WARNING:
        fprintf(
            stderr,
            "[WARNING:%s:%d] %s\n",
            message.filename.c_str(),
            message.lineno,
            message.message.c_str());
        break;
      case apache::thrift::diagnostic_level::VERBOSE:
        fprintf(stderr, "%s", message.message.c_str());
        break;
      case apache::thrift::diagnostic_level::DEBUG:
        fprintf(
            stderr, "[PARSE:%d] %s\n", message.lineno, message.message.c_str());
        break;
      case apache::thrift::diagnostic_level::FAILURE:
        fprintf(
            stderr,
            "[FAILURE:%s:%d] %s\n",
            message.filename.c_str(),
            message.lineno,
            message.message.c_str());
        break;
    }
  }

  if (!program) {
    exit(1);
  }

  return program;
}

void mark_file_executable(std::string const& path) {
  namespace fs = boost::filesystem;
  fs::permissions(
      path, fs::add_perms | fs::owner_exe | fs::group_exe | fs::others_exe);
}

} // namespace compiler
} // namespace thrift
} // namespace apache
<|endoftext|>


<commit_before>#include<stdlib.h>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<time.h>
#pragma comment(lib,"opencv_world320.lib")

static const int N = 256;//文字列の長さ
int main(void) {
	//TODO 関数の分割
	char full_command[N];
	char front_command[] = "sudo raspistill -o ";//command
	char full_path[N];
	char directry_path[] = "/home/pi/object";//pathの先頭
	char name_path[N];//時間を文字列に変換するときに代入する変数
	char file_extention[] = ".jpg";//拡張子
	time_t timer;//時刻を受け取る変数
	struct tm *timeptr;//日時を集めた構造体ポインタ
	time(&timer);//現在時刻の取得
	timeptr = localtime(&timer);//ポインタ
	strftime(name_path, N, "%Y%m%d-%H%M%S", timeptr);//日時を文字列に変換してｓに代入
	sprintf(full_path, "%s%s%s",directry_path, name_path, file_extention);
	sprintf(full_command, "%s%s", front_command, full_path);//コマンドの文字列をつなげる。
	system(full_command);//raspistillで静止画を撮って日時を含むファイル名で保存。

	cv::Mat src,dst,dst_filtered;
	dst_filtered = cv::Scalar(0, 0, 0);//画像の初期化
	double count = 0; //赤色を認識したピクセルの数
	double percentage = 0; //割合
	src =cv::imread(full_path);
	cv::cvtColor(src, dst, CV_BGR2HSV);//入力画像(src)をhsv色空間(dst)に変換
	//inRange(入力画像,下界画像,上界画像,出力画像)
	//「HSV」は、色を色相(Hue)・彩度(Saturation)・明度(Value)
	cv::inRange(dst, cv::Scalar(160, 150, 0), cv::Scalar(190, 255, 255), dst_filtered);
	count = cv::countNonZero(dst_filtered);//赤色部分の面積を計算
	double Area = dst.rows*dst.cols;//全ピクセル数の計算
	percentage = (count / Area)*100;//百分率で計算
	printf("赤色の面積の割合は%f\n", percentage);
}
<commit_msg>関数の分割<commit_after>#include<stdlib.h>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<time.h>
#pragma comment(lib,"opencv_world320.lib")

static const int N = 256;//文字列の長さ

//写真をとってそのpathを返す
char* takePhoto(void)
{
	char full_command[N];
	char front_command[] = "sudo raspistill -o ";//command
	char full_path[N];
	char directry_path[] = "/home/pi/object";//pathの先頭
	char name_path[N];//時間を文字列に変換するときに代入する変数
	char file_extention[] = ".jpg";//拡張子
	time_t timer;//時刻を受け取る変数
	struct tm *timeptr;//日時を集めた構造体ポインタ
	time(&timer);//現在時刻の取得
	timeptr = localtime(&timer);//ポインタ
	strftime(name_path, N, "%Y%m%d-%H%M%S", timeptr);//日時を文字列に変換してｓに代入
	sprintf(full_path, "%s%s%s",directry_path, name_path, file_extention);
	sprintf(full_command, "%s%s", front_command, full_path);//コマンドの文字列をつなげる。
	system(full_command);//raspistillで静止画を撮って日時を含むファイル名で保存。
	return full_path;
}

int main(void) {
	cv::Mat src,hsv,hsv_filtered;/
	hsv_filtered = cv::Scalar(0, 0, 0);//画像の初期化
	double count = 0; //赤色を認識したピクセルの数
	double percentage = 0; //割合
	src =cv::imread(takePhoto());
	cv::cvtColor(src, hsv, CV_BGR2HSV);//入力画像(src)をhsv色空間(hsv)に変換
	//inRange(入力画像,下界画像,上界画像,出力画像)
	//「HSV」は、色を色相(Hue)・彩度(Saturation)・明度(Value)
	cv::inRange(hsv, cv::Scalar(160, 150, 0), cv::Scalar(190, 255, 255), hsv_filtered);
	count = cv::countNonZero(hsv_filtered);//赤色部分の面積を計算
	double Area = hsv.rows*hsv.cols;//全ピクセル数の計算
	percentage = (count / Area)*100;//百分率で計算
	printf("赤色の面積の割合は%f\n", percentage);
}
<|endoftext|>