<commit_before>/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* 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 "stdint.h"
#include "USBHAL.h"
#include "USBHID.h"

USBHID::USBHID(uint8_t output_report_length, uint8_t input_report_length, uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect): USBDevice(vendor_id, product_id, product_release)
{
    output_length = output_report_length;
    input_length = input_report_length;
    if(connect) {
        USBDevice::connect();
    }
}

bool USBHID::send(HID_REPORT *report)
{
    return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
}

bool USBHID::sendNB(HID_REPORT *report)
{
    return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
}

bool USBHID::read(HID_REPORT *report)
{
    uint32_t bytesRead = 0;
    bool result;
    result = USBDevice::readEP(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
    if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
        return false;
    report->length = bytesRead;
    return result;
}

bool USBHID::readNB(HID_REPORT *report)
{
    uint32_t bytesRead = 0;
    bool result;
    result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
    report->length = bytesRead;
    if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
        return false;
    return result;
}

uint16_t USBHID::reportDescLength() {
    reportDesc();
    return reportLength;
}

//
//  Route callbacks from lower layers to class(es)
//

// Called in ISR context
// Called by USBDevice on Endpoint0 request
// This is used to handle extensions to standard requests
// and class specific requests
// Return true if class handles this request
bool USBHID::USBCallback_request() {
    bool success = false;
    CONTROL_TRANSFER * transfer = getTransferPtr();
    uint8_t *hidDescriptor;

    // Process additional standard requests

    if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
    {
        switch (transfer->setup.bRequest)
        {
            case GET_DESCRIPTOR:
                switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
                {
                    case REPORT_DESCRIPTOR:
                        if ((reportDesc() != NULL) \
                            && (reportDescLength() != 0))
                        {
                            transfer->remaining = reportDescLength();
                            transfer->ptr = reportDesc();
                            transfer->direction = DEVICE_TO_HOST;
                            success = true;
                        }
                        break;
                    case HID_DESCRIPTOR:
                            // Find the HID descriptor, after the configuration descriptor
                            hidDescriptor = findDescriptor(HID_DESCRIPTOR);
                            if (hidDescriptor != NULL)
                            {
                                transfer->remaining = HID_DESCRIPTOR_LENGTH;
                                transfer->ptr = hidDescriptor;
                                transfer->direction = DEVICE_TO_HOST;
                                success = true;
                            }
                            break;

                    default:
                        break;
                }
                break;
            default:
                break;
        }
    }

    // Process class-specific requests

    if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
    {
        switch (transfer->setup.bRequest)
        {
             case SET_REPORT:
                // First byte will be used for report ID
                outputReport.data[0] = transfer->setup.wValue & 0xff;
                outputReport.length = transfer->setup.wLength + 1;

                transfer->remaining = sizeof(outputReport.data) - 1;
                transfer->ptr = &outputReport.data[1];
                transfer->direction = HOST_TO_DEVICE;
                transfer->notify = true;
                success = true;
            default:
                break;
        }
    }

    return success;
}

#define DEFAULT_CONFIGURATION (1)

// Called in ISR context
// Set configuration. Return false if the
// configuration is not supported
bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
    if (configuration != DEFAULT_CONFIGURATION) {
        return false;
    }

    // Configure endpoints > 0
    addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
    addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);

    // We activate the endpoint to be able to recceive data
    readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
    return true;
}

uint8_t * USBHID::stringIinterfaceDesc() {
    static uint8_t stringIinterfaceDescriptor[] = {
        0x08,               //bLength
        STRING_DESCRIPTOR,  //bDescriptorType 0x03
        'H',0,'I',0,'D',0,  //bString iInterface - HID
    };
    return stringIinterfaceDescriptor;
}

uint8_t * USBHID::stringIproductDesc() {
    static uint8_t stringIproductDescriptor[] = {
        0x16,                                                       //bLength
        STRING_DESCRIPTOR,                                          //bDescriptorType 0x03
        'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device
    };
    return stringIproductDescriptor;
}

uint8_t * USBHID::reportDesc() {
    static uint8_t reportDescriptor[] = {
        0x06, LSB(0xFFAB), MSB(0xFFAB),
        0x0A, LSB(0x0200), MSB(0x0200),
        0xA1, 0x01,         // Collection 0x01
        0x75, 0x08,         // report size = 8 bits
        0x15, 0x00,         // logical minimum = 0
        0x26, 0xFF, 0x00,   // logical maximum = 255
        0x95, input_length, // report count
        0x09, 0x01,         // usage
        0x81, 0x02,         // Input (array)
        0x95, output_length,// report count
        0x09, 0x02,         // usage
        0x91, 0x02,         // Output (array)
        0xC0                // end collection

    };
    reportLength = sizeof(reportDescriptor);
    return reportDescriptor;
}

#define DEFAULT_CONFIGURATION (1)
#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
                               + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
                               + (1 * HID_DESCRIPTOR_LENGTH) \
                               + (2 * ENDPOINT_DESCRIPTOR_LENGTH))

uint8_t * USBHID::configurationDesc() {
    static uint8_t configurationDescriptor[] = {
        CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
        CONFIGURATION_DESCRIPTOR,       // bDescriptorType
        LSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (LSB)
        MSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (MSB)
        0x01,                           // bNumInterfaces
        DEFAULT_CONFIGURATION,          // bConfigurationValue
        0x00,                           // iConfiguration
        C_RESERVED | C_SELF_POWERED,    // bmAttributes
        C_POWER(0),                     // bMaxPower

        INTERFACE_DESCRIPTOR_LENGTH,    // bLength
        INTERFACE_DESCRIPTOR,           // bDescriptorType
        0x00,                           // bInterfaceNumber
        0x00,                           // bAlternateSetting
        0x02,                           // bNumEndpoints
        HID_CLASS,                      // bInterfaceClass
        HID_SUBCLASS_NONE,              // bInterfaceSubClass
        HID_PROTOCOL_NONE,              // bInterfaceProtocol
        0x00,                           // iInterface

        HID_DESCRIPTOR_LENGTH,          // bLength
        HID_DESCRIPTOR,                 // bDescriptorType
        LSB(HID_VERSION_1_11),          // bcdHID (LSB)
        MSB(HID_VERSION_1_11),          // bcdHID (MSB)
        0x00,                           // bCountryCode
        0x01,                           // bNumDescriptors
        REPORT_DESCRIPTOR,              // bDescriptorType
        (uint8_t)(LSB(this->reportDescLength())),  // wDescriptorLength (LSB)
        (uint8_t)(MSB(this->reportDescLength())),  // wDescriptorLength (MSB)

        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
        ENDPOINT_DESCRIPTOR,            // bDescriptorType
        PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
        E_INTERRUPT,                    // bmAttributes
        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
        1,                             // bInterval (milliseconds)

        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
        ENDPOINT_DESCRIPTOR,            // bDescriptorType
        PHY_TO_DESC(EPINT_OUT),          // bEndpointAddress
        E_INTERRUPT,                    // bmAttributes
        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
        1,                             // bInterval (milliseconds)
    };
    return configurationDescriptor;
}
<commit_msg>Fixed readNB() bug<commit_after>/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* 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 "stdint.h"
#include "USBHAL.h"
#include "USBHID.h"

USBHID::USBHID(uint8_t output_report_length, uint8_t input_report_length, uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect): USBDevice(vendor_id, product_id, product_release)
{
    output_length = output_report_length;
    input_length = input_report_length;
    if(connect) {
        USBDevice::connect();
    }
}

bool USBHID::send(HID_REPORT *report)
{
    return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
}

bool USBHID::sendNB(HID_REPORT *report)
{
    return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
}

bool USBHID::read(HID_REPORT *report)
{
    uint32_t bytesRead = 0;
    bool result;
    result = USBDevice::readEP(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
    if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
        return false;
    report->length = bytesRead;
    return result;
}

bool USBHID::readNB(HID_REPORT *report)
{
    uint32_t bytesRead = 0;
    bool result;
    result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
    // if readEP_NB did not succeed, does not issue a readStart
    if (!result)
        return false;
    report->length = bytesRead;
    if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
        return false;
    return result;
}

uint16_t USBHID::reportDescLength() {
    reportDesc();
    return reportLength;
}

//
//  Route callbacks from lower layers to class(es)
//

// Called in ISR context
// Called by USBDevice on Endpoint0 request
// This is used to handle extensions to standard requests
// and class specific requests
// Return true if class handles this request
bool USBHID::USBCallback_request() {
    bool success = false;
    CONTROL_TRANSFER * transfer = getTransferPtr();
    uint8_t *hidDescriptor;

    // Process additional standard requests

    if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
    {
        switch (transfer->setup.bRequest)
        {
            case GET_DESCRIPTOR:
                switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
                {
                    case REPORT_DESCRIPTOR:
                        if ((reportDesc() != NULL) \
                            && (reportDescLength() != 0))
                        {
                            transfer->remaining = reportDescLength();
                            transfer->ptr = reportDesc();
                            transfer->direction = DEVICE_TO_HOST;
                            success = true;
                        }
                        break;
                    case HID_DESCRIPTOR:
                            // Find the HID descriptor, after the configuration descriptor
                            hidDescriptor = findDescriptor(HID_DESCRIPTOR);
                            if (hidDescriptor != NULL)
                            {
                                transfer->remaining = HID_DESCRIPTOR_LENGTH;
                                transfer->ptr = hidDescriptor;
                                transfer->direction = DEVICE_TO_HOST;
                                success = true;
                            }
                            break;

                    default:
                        break;
                }
                break;
            default:
                break;
        }
    }

    // Process class-specific requests

    if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
    {
        switch (transfer->setup.bRequest)
        {
             case SET_REPORT:
                // First byte will be used for report ID
                outputReport.data[0] = transfer->setup.wValue & 0xff;
                outputReport.length = transfer->setup.wLength + 1;

                transfer->remaining = sizeof(outputReport.data) - 1;
                transfer->ptr = &outputReport.data[1];
                transfer->direction = HOST_TO_DEVICE;
                transfer->notify = true;
                success = true;
            default:
                break;
        }
    }

    return success;
}

#define DEFAULT_CONFIGURATION (1)

// Called in ISR context
// Set configuration. Return false if the
// configuration is not supported
bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
    if (configuration != DEFAULT_CONFIGURATION) {
        return false;
    }

    // Configure endpoints > 0
    addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
    addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);

    // We activate the endpoint to be able to recceive data
    readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
    return true;
}

uint8_t * USBHID::stringIinterfaceDesc() {
    static uint8_t stringIinterfaceDescriptor[] = {
        0x08,               //bLength
        STRING_DESCRIPTOR,  //bDescriptorType 0x03
        'H',0,'I',0,'D',0,  //bString iInterface - HID
    };
    return stringIinterfaceDescriptor;
}

uint8_t * USBHID::stringIproductDesc() {
    static uint8_t stringIproductDescriptor[] = {
        0x16,                                                       //bLength
        STRING_DESCRIPTOR,                                          //bDescriptorType 0x03
        'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device
    };
    return stringIproductDescriptor;
}

uint8_t * USBHID::reportDesc() {
    static uint8_t reportDescriptor[] = {
        0x06, LSB(0xFFAB), MSB(0xFFAB),
        0x0A, LSB(0x0200), MSB(0x0200),
        0xA1, 0x01,         // Collection 0x01
        0x75, 0x08,         // report size = 8 bits
        0x15, 0x00,         // logical minimum = 0
        0x26, 0xFF, 0x00,   // logical maximum = 255
        0x95, input_length, // report count
        0x09, 0x01,         // usage
        0x81, 0x02,         // Input (array)
        0x95, output_length,// report count
        0x09, 0x02,         // usage
        0x91, 0x02,         // Output (array)
        0xC0                // end collection

    };
    reportLength = sizeof(reportDescriptor);
    return reportDescriptor;
}

#define DEFAULT_CONFIGURATION (1)
#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
                               + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
                               + (1 * HID_DESCRIPTOR_LENGTH) \
                               + (2 * ENDPOINT_DESCRIPTOR_LENGTH))

uint8_t * USBHID::configurationDesc() {
    static uint8_t configurationDescriptor[] = {
        CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
        CONFIGURATION_DESCRIPTOR,       // bDescriptorType
        LSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (LSB)
        MSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (MSB)
        0x01,                           // bNumInterfaces
        DEFAULT_CONFIGURATION,          // bConfigurationValue
        0x00,                           // iConfiguration
        C_RESERVED | C_SELF_POWERED,    // bmAttributes
        C_POWER(0),                     // bMaxPower

        INTERFACE_DESCRIPTOR_LENGTH,    // bLength
        INTERFACE_DESCRIPTOR,           // bDescriptorType
        0x00,                           // bInterfaceNumber
        0x00,                           // bAlternateSetting
        0x02,                           // bNumEndpoints
        HID_CLASS,                      // bInterfaceClass
        HID_SUBCLASS_NONE,              // bInterfaceSubClass
        HID_PROTOCOL_NONE,              // bInterfaceProtocol
        0x00,                           // iInterface

        HID_DESCRIPTOR_LENGTH,          // bLength
        HID_DESCRIPTOR,                 // bDescriptorType
        LSB(HID_VERSION_1_11),          // bcdHID (LSB)
        MSB(HID_VERSION_1_11),          // bcdHID (MSB)
        0x00,                           // bCountryCode
        0x01,                           // bNumDescriptors
        REPORT_DESCRIPTOR,              // bDescriptorType
        (uint8_t)(LSB(this->reportDescLength())),  // wDescriptorLength (LSB)
        (uint8_t)(MSB(this->reportDescLength())),  // wDescriptorLength (MSB)

        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
        ENDPOINT_DESCRIPTOR,            // bDescriptorType
        PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
        E_INTERRUPT,                    // bmAttributes
        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
        1,                             // bInterval (milliseconds)

        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
        ENDPOINT_DESCRIPTOR,            // bDescriptorType
        PHY_TO_DESC(EPINT_OUT),          // bEndpointAddress
        E_INTERRUPT,                    // bmAttributes
        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
        1,                             // bInterval (milliseconds)
    };
    return configurationDescriptor;
}
<|endoftext|>


<commit_before>/*
	This file is part of solidity.

	solidity 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 3 of the License, or
	(at your option) any later version.

	solidity 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 solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * Analyzer part of inline assembly.
 */

#include <libsolidity/inlineasm/AsmAnalysis.h>

#include <libsolidity/inlineasm/AsmData.h>
#include <libsolidity/inlineasm/AsmScopeFiller.h>
#include <libsolidity/inlineasm/AsmScope.h>
#include <libsolidity/inlineasm/AsmAnalysisInfo.h>

#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/interface/Utils.h>

#include <boost/range/adaptor/reversed.hpp>

#include <memory>
#include <functional>

using namespace std;
using namespace dev;
using namespace dev::solidity;
using namespace dev::solidity::assembly;

AsmAnalyzer::AsmAnalyzer(
	AsmAnalysisInfo& _analysisInfo,
	ErrorList& _errors,
	ExternalIdentifierAccess::Resolver const& _resolver
):
	m_resolver(_resolver), m_info(_analysisInfo), m_errors(_errors)
{
}

bool AsmAnalyzer::analyze(Block const& _block)
{
	if (!(ScopeFiller(m_info.scopes, m_errors))(_block))
		return false;

	return (*this)(_block);
}

bool AsmAnalyzer::operator()(Label const& _label)
{
	m_info.stackHeightInfo[&_label] = m_stackHeight;
	return true;
}

bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction)
{
	auto const& info = instructionInfo(_instruction.instruction);
	m_stackHeight += info.ret - info.args;
	m_info.stackHeightInfo[&_instruction] = m_stackHeight;
	return true;
}

bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
{
	++m_stackHeight;
	if (_literal.kind == assembly::LiteralKind::String && _literal.value.size() > 32)
	{
		m_errors.push_back(make_shared<Error>(
			Error::Type::TypeError,
			"String literal too long (" + boost::lexical_cast<std::string>(_literal.value.size()) + " > 32)",
			_literal.location
		));
		return false;
	}
	m_info.stackHeightInfo[&_literal] = m_stackHeight;
	return true;
}

bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier)
{
	size_t numErrorsBefore = m_errors.size();
	bool success = true;
	if (m_currentScope->lookup(_identifier.name, Scope::Visitor(
		[&](Scope::Variable const& _var)
		{
			if (!_var.active)
			{
				m_errors.push_back(make_shared<Error>(
					Error::Type::DeclarationError,
					"Variable " + _identifier.name + " used before it was declared.",
					_identifier.location
				));
				success = false;
			}
			++m_stackHeight;
		},
		[&](Scope::Label const&)
		{
			++m_stackHeight;
		},
		[&](Scope::Function const&)
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::TypeError,
				"Function " + _identifier.name + " used without being called.",
				_identifier.location
			));
			success = false;
		}
	)))
	{
	}
	else
	{
		size_t stackSize(-1);
		if (m_resolver)
			stackSize = m_resolver(_identifier, IdentifierContext::RValue);
		if (stackSize == size_t(-1))
		{
			// Only add an error message if the callback did not do it.
			if (numErrorsBefore == m_errors.size())
				m_errors.push_back(make_shared<Error>(
					Error::Type::DeclarationError,
					"Identifier not found.",
					_identifier.location
				));
			success = false;
		}
		m_stackHeight += stackSize == size_t(-1) ? 1 : stackSize;
	}
	m_info.stackHeightInfo[&_identifier] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr)
{
	bool success = true;
	for (auto const& arg: _instr.arguments | boost::adaptors::reversed)
	{
		int const stackHeight = m_stackHeight;
		if (!boost::apply_visitor(*this, arg))
			success = false;
		if (!expectDeposit(1, stackHeight, locationOf(arg)))
			success = false;
	}
	// Parser already checks that the number of arguments is correct.
	solAssert(instructionInfo(_instr.instruction.instruction).args == int(_instr.arguments.size()), "");
	if (!(*this)(_instr.instruction))
		success = false;
	m_info.stackHeightInfo[&_instr] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment)
{
	bool success = checkAssignment(_assignment.variableName, size_t(-1));
	m_info.stackHeightInfo[&_assignment] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(FunctionalAssignment const& _assignment)
{
	int const stackHeight = m_stackHeight;
	bool success = boost::apply_visitor(*this, *_assignment.value);
	solAssert(m_stackHeight >= stackHeight, "Negative value size.");
	if (!checkAssignment(_assignment.variableName, m_stackHeight - stackHeight))
		success = false;
	m_info.stackHeightInfo[&_assignment] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl)
{
	int const expectedItems = _varDecl.variables.size();
	int const stackHeight = m_stackHeight;
	bool success = boost::apply_visitor(*this, *_varDecl.value);
	solAssert(m_stackHeight - stackHeight == expectedItems, "Invalid value size.");

	for (auto const& variable: _varDecl.variables)
		boost::get<Scope::Variable>(m_currentScope->identifiers.at(variable.name)).active = true;
	m_info.stackHeightInfo[&_varDecl] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef)
{
	Scope& bodyScope = scope(&_funDef.body);
	for (auto const& var: _funDef.arguments + _funDef.returns)
		boost::get<Scope::Variable>(bodyScope.identifiers.at(var.name)).active = true;

	int const stackHeight = m_stackHeight;
	m_stackHeight = _funDef.arguments.size() + _funDef.returns.size();
	m_virtualVariablesInNextBlock = m_stackHeight;

	bool success = (*this)(_funDef.body);

	m_stackHeight = stackHeight;
	m_info.stackHeightInfo[&_funDef] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall)
{
	bool success = true;
	size_t arguments = 0;
	size_t returns = 0;
	if (!m_currentScope->lookup(_funCall.functionName.name, Scope::Visitor(
		[&](Scope::Variable const&)
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::TypeError,
				"Attempt to call variable instead of function.",
				_funCall.functionName.location
			));
			success = false;
		},
		[&](Scope::Label const&)
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::TypeError,
				"Attempt to call label instead of function.",
				_funCall.functionName.location
				));
			success = false;
		},
		[&](Scope::Function const& _fun)
		{
			/// TODO: compare types too
			arguments = _fun.arguments.size();
			returns = _fun.returns.size();
		}
	)))
	{
		m_errors.push_back(make_shared<Error>(
			Error::Type::DeclarationError,
			"Function not found.",
			_funCall.functionName.location
		));
		success = false;
	}
	if (success)
	{
		if (_funCall.arguments.size() != arguments)
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::TypeError,
				"Expected " +
				boost::lexical_cast<string>(arguments) +
				" arguments but got " +
				boost::lexical_cast<string>(_funCall.arguments.size()) +
				".",
				_funCall.functionName.location
				));
			success = false;
		}
	}
	for (auto const& arg: _funCall.arguments | boost::adaptors::reversed)
	{
		int const stackHeight = m_stackHeight;
		if (!boost::apply_visitor(*this, arg))
			success = false;
		if (!expectDeposit(1, stackHeight, locationOf(arg)))
			success = false;
	}
	m_stackHeight += int(returns) - int(arguments);
	m_info.stackHeightInfo[&_funCall] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(Block const& _block)
{
	bool success = true;
	m_currentScope = &scope(&_block);

	int const initialStackHeight = m_stackHeight - m_virtualVariablesInNextBlock;
	m_virtualVariablesInNextBlock = 0;

	for (auto const& s: _block.statements)
		if (!boost::apply_visitor(*this, s))
			success = false;

	for (auto const& identifier: scope(&_block).identifiers)
		if (identifier.second.type() == typeid(Scope::Variable))
			--m_stackHeight;

	int const stackDiff = m_stackHeight - initialStackHeight;
	if (stackDiff != 0)
	{
		m_errors.push_back(make_shared<Error>(
			Error::Type::DeclarationError,
			"Unbalanced stack at the end of a block: " +
			(
				stackDiff > 0 ?
				to_string(stackDiff) + string(" surplus item(s).") :
				to_string(-stackDiff) + string(" missing item(s).")
			),
			_block.location
		));
		success = false;
	}

	m_currentScope = m_currentScope->superScope;
	m_info.stackHeightInfo[&_block] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t _valueSize)
{
	bool success = true;
	size_t numErrorsBefore = m_errors.size();
	size_t variableSize(-1);
	if (Scope::Identifier const* var = m_currentScope->lookup(_variable.name))
	{
		// Check that it is a variable
		if (var->type() != typeid(Scope::Variable))
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::TypeError,
				"Assignment requires variable.",
				_variable.location
			));
			success = false;
		}
		else if (!boost::get<Scope::Variable>(*var).active)
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::DeclarationError,
				"Variable " + _variable.name + " used before it was declared.",
				_variable.location
			));
			success = false;
		}
		variableSize = 1;
	}
	else if (m_resolver)
		variableSize = m_resolver(_variable, IdentifierContext::LValue);
	if (variableSize == size_t(-1))
	{
		// Only add message if the callback did not.
		if (numErrorsBefore == m_errors.size())
			m_errors.push_back(make_shared<Error>(
				Error::Type::DeclarationError,
				"Variable not found or variable not lvalue.",
				_variable.location
			));
		success = false;
	}
	if (_valueSize == size_t(-1))
		_valueSize = variableSize == size_t(-1) ? 1 : variableSize;

	m_stackHeight -= _valueSize;

	if (_valueSize != variableSize && variableSize != size_t(-1))
	{
		m_errors.push_back(make_shared<Error>(
			Error::Type::TypeError,
			"Variable size (" +
			to_string(variableSize) +
			") and value size (" +
			to_string(_valueSize) +
			") do not match.",
			_variable.location
		));
		success = false;
	}
	return success;
}

bool AsmAnalyzer::expectDeposit(int const _deposit, int const _oldHeight, SourceLocation const& _location)
{
	int stackDiff = m_stackHeight - _oldHeight;
	if (stackDiff != _deposit)
	{
		m_errors.push_back(make_shared<Error>(
			Error::Type::TypeError,
			"Expected instruction(s) to deposit " +
			boost::lexical_cast<string>(_deposit) +
			" item(s) to the stack, but did deposit " +
			boost::lexical_cast<string>(stackDiff) +
			" item(s).",
			_location
		));
		return false;
	}
	else
		return true;
}

Scope& AsmAnalyzer::scope(Block const* _block)
{
	auto scopePtr = m_info.scopes.at(_block);
	solAssert(scopePtr, "Scope requested but not present.");
	return *scopePtr;
}
<commit_msg>Display actual error message and not assertion in analysis<commit_after>/*
	This file is part of solidity.

	solidity 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 3 of the License, or
	(at your option) any later version.

	solidity 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 solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * Analyzer part of inline assembly.
 */

#include <libsolidity/inlineasm/AsmAnalysis.h>

#include <libsolidity/inlineasm/AsmData.h>
#include <libsolidity/inlineasm/AsmScopeFiller.h>
#include <libsolidity/inlineasm/AsmScope.h>
#include <libsolidity/inlineasm/AsmAnalysisInfo.h>

#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/interface/Utils.h>

#include <boost/range/adaptor/reversed.hpp>

#include <memory>
#include <functional>

using namespace std;
using namespace dev;
using namespace dev::solidity;
using namespace dev::solidity::assembly;

AsmAnalyzer::AsmAnalyzer(
	AsmAnalysisInfo& _analysisInfo,
	ErrorList& _errors,
	ExternalIdentifierAccess::Resolver const& _resolver
):
	m_resolver(_resolver), m_info(_analysisInfo), m_errors(_errors)
{
}

bool AsmAnalyzer::analyze(Block const& _block)
{
	if (!(ScopeFiller(m_info.scopes, m_errors))(_block))
		return false;

	return (*this)(_block);
}

bool AsmAnalyzer::operator()(Label const& _label)
{
	m_info.stackHeightInfo[&_label] = m_stackHeight;
	return true;
}

bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction)
{
	auto const& info = instructionInfo(_instruction.instruction);
	m_stackHeight += info.ret - info.args;
	m_info.stackHeightInfo[&_instruction] = m_stackHeight;
	return true;
}

bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
{
	++m_stackHeight;
	if (_literal.kind == assembly::LiteralKind::String && _literal.value.size() > 32)
	{
		m_errors.push_back(make_shared<Error>(
			Error::Type::TypeError,
			"String literal too long (" + boost::lexical_cast<std::string>(_literal.value.size()) + " > 32)",
			_literal.location
		));
		return false;
	}
	m_info.stackHeightInfo[&_literal] = m_stackHeight;
	return true;
}

bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier)
{
	size_t numErrorsBefore = m_errors.size();
	bool success = true;
	if (m_currentScope->lookup(_identifier.name, Scope::Visitor(
		[&](Scope::Variable const& _var)
		{
			if (!_var.active)
			{
				m_errors.push_back(make_shared<Error>(
					Error::Type::DeclarationError,
					"Variable " + _identifier.name + " used before it was declared.",
					_identifier.location
				));
				success = false;
			}
			++m_stackHeight;
		},
		[&](Scope::Label const&)
		{
			++m_stackHeight;
		},
		[&](Scope::Function const&)
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::TypeError,
				"Function " + _identifier.name + " used without being called.",
				_identifier.location
			));
			success = false;
		}
	)))
	{
	}
	else
	{
		size_t stackSize(-1);
		if (m_resolver)
			stackSize = m_resolver(_identifier, IdentifierContext::RValue);
		if (stackSize == size_t(-1))
		{
			// Only add an error message if the callback did not do it.
			if (numErrorsBefore == m_errors.size())
				m_errors.push_back(make_shared<Error>(
					Error::Type::DeclarationError,
					"Identifier not found.",
					_identifier.location
				));
			success = false;
		}
		m_stackHeight += stackSize == size_t(-1) ? 1 : stackSize;
	}
	m_info.stackHeightInfo[&_identifier] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr)
{
	bool success = true;
	for (auto const& arg: _instr.arguments | boost::adaptors::reversed)
	{
		int const stackHeight = m_stackHeight;
		if (!boost::apply_visitor(*this, arg))
			success = false;
		if (!expectDeposit(1, stackHeight, locationOf(arg)))
			success = false;
	}
	// Parser already checks that the number of arguments is correct.
	solAssert(instructionInfo(_instr.instruction.instruction).args == int(_instr.arguments.size()), "");
	if (!(*this)(_instr.instruction))
		success = false;
	m_info.stackHeightInfo[&_instr] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment)
{
	bool success = checkAssignment(_assignment.variableName, size_t(-1));
	m_info.stackHeightInfo[&_assignment] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(FunctionalAssignment const& _assignment)
{
	int const stackHeight = m_stackHeight;
	bool success = boost::apply_visitor(*this, *_assignment.value);
	solAssert(m_stackHeight >= stackHeight, "Negative value size.");
	if (!checkAssignment(_assignment.variableName, m_stackHeight - stackHeight))
		success = false;
	m_info.stackHeightInfo[&_assignment] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl)
{
	int const expectedItems = _varDecl.variables.size();
	int const stackHeight = m_stackHeight;
	bool success = boost::apply_visitor(*this, *_varDecl.value);
	if ((m_stackHeight - stackHeight) != expectedItems)
	{
		m_errors.push_back(make_shared<Error>(
			Error::Type::DeclarationError,
			"Variable count mismatch.",
			_varDecl.location
		));
		return false;
	}

	for (auto const& variable: _varDecl.variables)
		boost::get<Scope::Variable>(m_currentScope->identifiers.at(variable.name)).active = true;
	m_info.stackHeightInfo[&_varDecl] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef)
{
	Scope& bodyScope = scope(&_funDef.body);
	for (auto const& var: _funDef.arguments + _funDef.returns)
		boost::get<Scope::Variable>(bodyScope.identifiers.at(var.name)).active = true;

	int const stackHeight = m_stackHeight;
	m_stackHeight = _funDef.arguments.size() + _funDef.returns.size();
	m_virtualVariablesInNextBlock = m_stackHeight;

	bool success = (*this)(_funDef.body);

	m_stackHeight = stackHeight;
	m_info.stackHeightInfo[&_funDef] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall)
{
	bool success = true;
	size_t arguments = 0;
	size_t returns = 0;
	if (!m_currentScope->lookup(_funCall.functionName.name, Scope::Visitor(
		[&](Scope::Variable const&)
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::TypeError,
				"Attempt to call variable instead of function.",
				_funCall.functionName.location
			));
			success = false;
		},
		[&](Scope::Label const&)
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::TypeError,
				"Attempt to call label instead of function.",
				_funCall.functionName.location
				));
			success = false;
		},
		[&](Scope::Function const& _fun)
		{
			/// TODO: compare types too
			arguments = _fun.arguments.size();
			returns = _fun.returns.size();
		}
	)))
	{
		m_errors.push_back(make_shared<Error>(
			Error::Type::DeclarationError,
			"Function not found.",
			_funCall.functionName.location
		));
		success = false;
	}
	if (success)
	{
		if (_funCall.arguments.size() != arguments)
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::TypeError,
				"Expected " +
				boost::lexical_cast<string>(arguments) +
				" arguments but got " +
				boost::lexical_cast<string>(_funCall.arguments.size()) +
				".",
				_funCall.functionName.location
				));
			success = false;
		}
	}
	for (auto const& arg: _funCall.arguments | boost::adaptors::reversed)
	{
		int const stackHeight = m_stackHeight;
		if (!boost::apply_visitor(*this, arg))
			success = false;
		if (!expectDeposit(1, stackHeight, locationOf(arg)))
			success = false;
	}
	m_stackHeight += int(returns) - int(arguments);
	m_info.stackHeightInfo[&_funCall] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::operator()(Block const& _block)
{
	bool success = true;
	m_currentScope = &scope(&_block);

	int const initialStackHeight = m_stackHeight - m_virtualVariablesInNextBlock;
	m_virtualVariablesInNextBlock = 0;

	for (auto const& s: _block.statements)
		if (!boost::apply_visitor(*this, s))
			success = false;

	for (auto const& identifier: scope(&_block).identifiers)
		if (identifier.second.type() == typeid(Scope::Variable))
			--m_stackHeight;

	int const stackDiff = m_stackHeight - initialStackHeight;
	if (stackDiff != 0)
	{
		m_errors.push_back(make_shared<Error>(
			Error::Type::DeclarationError,
			"Unbalanced stack at the end of a block: " +
			(
				stackDiff > 0 ?
				to_string(stackDiff) + string(" surplus item(s).") :
				to_string(-stackDiff) + string(" missing item(s).")
			),
			_block.location
		));
		success = false;
	}

	m_currentScope = m_currentScope->superScope;
	m_info.stackHeightInfo[&_block] = m_stackHeight;
	return success;
}

bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t _valueSize)
{
	bool success = true;
	size_t numErrorsBefore = m_errors.size();
	size_t variableSize(-1);
	if (Scope::Identifier const* var = m_currentScope->lookup(_variable.name))
	{
		// Check that it is a variable
		if (var->type() != typeid(Scope::Variable))
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::TypeError,
				"Assignment requires variable.",
				_variable.location
			));
			success = false;
		}
		else if (!boost::get<Scope::Variable>(*var).active)
		{
			m_errors.push_back(make_shared<Error>(
				Error::Type::DeclarationError,
				"Variable " + _variable.name + " used before it was declared.",
				_variable.location
			));
			success = false;
		}
		variableSize = 1;
	}
	else if (m_resolver)
		variableSize = m_resolver(_variable, IdentifierContext::LValue);
	if (variableSize == size_t(-1))
	{
		// Only add message if the callback did not.
		if (numErrorsBefore == m_errors.size())
			m_errors.push_back(make_shared<Error>(
				Error::Type::DeclarationError,
				"Variable not found or variable not lvalue.",
				_variable.location
			));
		success = false;
	}
	if (_valueSize == size_t(-1))
		_valueSize = variableSize == size_t(-1) ? 1 : variableSize;

	m_stackHeight -= _valueSize;

	if (_valueSize != variableSize && variableSize != size_t(-1))
	{
		m_errors.push_back(make_shared<Error>(
			Error::Type::TypeError,
			"Variable size (" +
			to_string(variableSize) +
			") and value size (" +
			to_string(_valueSize) +
			") do not match.",
			_variable.location
		));
		success = false;
	}
	return success;
}

bool AsmAnalyzer::expectDeposit(int const _deposit, int const _oldHeight, SourceLocation const& _location)
{
	int stackDiff = m_stackHeight - _oldHeight;
	if (stackDiff != _deposit)
	{
		m_errors.push_back(make_shared<Error>(
			Error::Type::TypeError,
			"Expected instruction(s) to deposit " +
			boost::lexical_cast<string>(_deposit) +
			" item(s) to the stack, but did deposit " +
			boost::lexical_cast<string>(stackDiff) +
			" item(s).",
			_location
		));
		return false;
	}
	else
		return true;
}

Scope& AsmAnalyzer::scope(Block const* _block)
{
	auto scopePtr = m_info.scopes.at(_block);
	solAssert(scopePtr, "Scope requested but not present.");
	return *scopePtr;
}
<|endoftext|>


<commit_before>/*!
 * \file SU2_DEF.cpp
 * \brief Main file of Mesh Deformation Code (SU2_DEF).
 * \author F. Palacios, T. Economon
 * \version 5.0.0 "Raven"
 *
 * SU2 Original Developers: Dr. Francisco D. Palacios.
 *                          Dr. Thomas D. Economon.
 *
 * SU2 Developers: Prof. Juan J. Alonso's group at Stanford University.
 *                 Prof. Piero Colonna's group at Delft University of Technology.
 *                 Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology.
 *                 Prof. Alberto Guardone's group at Polytechnic University of Milan.
 *                 Prof. Rafael Palacios' group at Imperial College London.
 *                 Prof. Edwin van der Weide's group at the University of Twente.
 *                 Prof. Vincent Terrapon's group at the University of Liege.
 *
 * Copyright (C) 2012-2017 SU2, the open-source CFD code.
 *
 * SU2 is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * SU2 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
 */

#include "../include/SU2_DEF.hpp"
using namespace std;

int main(int argc, char *argv[]) {

  unsigned short iZone, nZone = SINGLE_ZONE, iMarker;
  su2double StartTime = 0.0, StopTime = 0.0, UsedTime = 0.0;
  char config_file_name[MAX_STRING_SIZE];
  int rank = MASTER_NODE, size = SINGLE_NODE;
  string str;
  bool allmoving=true;

  /*--- MPI initialization ---*/

#ifdef HAVE_MPI
  SU2_MPI::Init(&argc,&argv);
  SU2_Comm MPICommunicator(MPI_COMM_WORLD);
  MPI_Comm_rank(MPICommunicator,&rank);
  MPI_Comm_size(MPICommunicator,&size);
#else
  SU2_Comm MPICommunicator(0);
#endif

  /*--- Pointer to different structures that will be used throughout
   the entire code ---*/

  CConfig **config_container         = NULL;
  CGeometry **geometry_container     = NULL;
  CSurfaceMovement **surface_movement = NULL;
  CVolumetricMovement **grid_movement = NULL;
  COutput *output                    = NULL;

  /*--- Load in the number of zones and spatial dimensions in the mesh file
   (if no config file is specified, default.cfg is used) ---*/

  if (argc == 2) { strcpy(config_file_name, argv[1]); }
  else { strcpy(config_file_name, "default.cfg"); }

  /*--- Read the name and format of the input mesh file to get from the mesh
   file the number of zones and dimensions from the numerical grid (required
   for variables allocation)  ---*/

  CConfig *config = NULL;
  config = new CConfig(config_file_name, SU2_DEF);

  nZone = CConfig::GetnZone(config->GetMesh_FileName(), config->GetMesh_FileFormat(), config);

  /*--- Definition of the containers per zones ---*/

  config_container = new CConfig*[nZone];
  geometry_container = new CGeometry*[nZone];
  surface_movement   = new CSurfaceMovement*[nZone];
  grid_movement      = new CVolumetricMovement*[nZone];
  output   = new COutput(config_container[iZone]);

  for (iZone = 0; iZone < nZone; iZone++) {
    config_container[iZone]       = NULL;
    geometry_container[iZone]     = NULL;
  }

  /*--- Loop over all zones to initialize the various classes. In most
   cases, nZone is equal to one. This represents the solution of a partial
   differential equation on a single block, unstructured mesh. ---*/

  for (iZone = 0; iZone < nZone; iZone++) {

    /*--- Definition of the configuration option class for all zones. In this
     constructor, the input configuration file is parsed and all options are
     read and stored. ---*/

    config_container[iZone] = new CConfig(config_file_name, SU2_DEF, iZone, nZone, 0, VERB_HIGH);
    config_container[iZone]->SetMPICommunicator(MPICommunicator);

    /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/

    CGeometry *geometry_aux = NULL;

    /*--- All ranks process the grid and call ParMETIS for partitioning ---*/

    geometry_aux = new CPhysicalGeometry(config_container[iZone], iZone, nZone);

    /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/

    geometry_aux->SetColorGrid_Parallel(config_container[iZone]);

    /*--- Allocate the memory of the current domain, and
     divide the grid between the nodes ---*/

    geometry_container[iZone] = new CPhysicalGeometry(geometry_aux, config_container[iZone]);

    /*--- Deallocate the memory of geometry_aux ---*/

    delete geometry_aux;

    /*--- Add the Send/Receive boundaries ---*/

    geometry_container[iZone]->SetSendReceive(config_container[iZone]);

    /*--- Add the Send/Receive boundaries ---*/

    geometry_container[iZone]->SetBoundaries(config_container[iZone]);

  }

  /*--- Set up a timer for performance benchmarking (preprocessing time is included) ---*/

#ifdef HAVE_MPI
  StartTime = MPI_Wtime();
#else
  StartTime = su2double(clock())/su2double(CLOCKS_PER_SEC);
#endif
  for (iZone = 0; iZone < nZone; iZone++) {

    /*--- Computational grid preprocesing ---*/

    if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl;

    /*--- Compute elements surrounding points, points surrounding points ---*/

    if (rank == MASTER_NODE) cout << "Setting local point connectivity." <<endl;
    geometry_container[iZone]->SetPoint_Connectivity();

    /*--- Check the orientation before computing geometrical quantities ---*/

    if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <<endl;
    geometry_container[iZone]->SetBoundVolume();
    geometry_container[iZone]->Check_IntElem_Orientation(config_container[iZone]);
    geometry_container[iZone]->Check_BoundElem_Orientation(config_container[iZone]);

    /*--- Create the edge structure ---*/

    if (rank == MASTER_NODE) cout << "Identify edges and vertices." <<endl;
    geometry_container[iZone]->SetEdges(); geometry_container[iZone]->SetVertex(config_container[iZone]);

    if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) {

      /*--- Compute center of gravity ---*/

      if (rank == MASTER_NODE) cout << "Computing centers of gravity." << endl;
      geometry_container[iZone]->SetCoord_CG();

      /*--- Create the dual control volume structures ---*/

      if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl;
      geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE);

    }

  }

  if (config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) {

    /*--- initialization of output structure  ---*/

    output  = new COutput(config_container[iZone]);

    /*--- Output original grid for visualization, if requested (surface and volumetric) ---*/

    if (config_container[ZONE_0]->GetVisualize_Deformation()) {

      output->SetMesh_Files(geometry_container, config_container, nZone, true, false);

    }

  }

  /*--- Surface grid deformation using design variables ---*/

  for (iZone = 0; iZone < nZone; iZone++){

    if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) {

      if (rank == MASTER_NODE) cout << endl << "--------------------- Surface grid deformation (ZONE " << iZone <<") -----------------" << endl;

      /*--- Definition and initialization of the surface deformation class ---*/

      surface_movement[iZone] = new CSurfaceMovement();

      /*--- Copy coordinates to the surface structure ---*/

      surface_movement[iZone]->CopyBoundary(geometry_container[iZone], config_container[iZone]);

      /*--- Surface grid deformation ---*/

      if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl;
      surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone], config_container[iZone]);

      if (config_container[iZone]->GetDesign_Variable(0) != FFD_SETTING) {

        if (rank == MASTER_NODE)
          cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl;

        /*--- Definition of the Class for grid movement ---*/
        grid_movement[iZone] = new CVolumetricMovement(geometry_container[iZone], config_container[iZone]);

      }

      /*--- For scale, translation and rotation if all boundaries are moving they are set via volume method
       * Otherwise, the surface deformation has been set already in SetSurface_Deformation.  --- */
      allmoving = true;
      /*--- Loop over markers, set flag to false if any are not moving ---*/
      for (iMarker = 0; iMarker < config_container[iZone]->GetnMarker_All(); iMarker++){
        if (config_container[iZone]->GetMarker_All_DV(iMarker) == NO)
          allmoving = false;
      }

      /*--- Volumetric grid deformation/transformations ---*/

      if (config_container[iZone]->GetDesign_Variable(0) == SCALE && allmoving) {

        if (rank == MASTER_NODE)
          cout << "Performing a scaling of the volumetric grid." << endl;

        grid_movement[iZone]->SetVolume_Scaling(geometry_container[iZone], config_container[iZone], false);

      } else if (config_container[iZone]->GetDesign_Variable(0) == TRANSLATION && allmoving) {

        if (rank == MASTER_NODE)
          cout << "Performing a translation of the volumetric grid." << endl;

        grid_movement[iZone]->SetVolume_Translation(geometry_container[iZone], config_container[iZone], false);

      } else if (config_container[iZone]->GetDesign_Variable(0) == ROTATION && allmoving) {

        if (rank == MASTER_NODE)
          cout << "Performing a rotation of the volumetric grid." << endl;

        grid_movement[iZone]->SetVolume_Rotation(geometry_container[iZone], config_container[iZone], false);

      } else if (config_container[iZone]->GetDesign_Variable(0) != FFD_SETTING) {

        if (rank == MASTER_NODE)
          cout << "Performing the deformation of the volumetric grid." << endl;

        grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone], config_container[iZone], false);

      }

    }

  }

  /*--- Computational grid preprocesing ---*/

  if (rank == MASTER_NODE) cout << endl << "----------------------- Write deformed grid files -----------------------" << endl;

  /*--- Output deformed grid for visualization, if requested (surface and volumetric), in parallel
   requires to move all the data to the master node---*/

  bool NewFile = false;
  if (config_container[iZone]->GetDesign_Variable(0) == NO_DEFORMATION) NewFile = true;

  output->SetMesh_Files(geometry_container, config_container, SINGLE_ZONE, NewFile, true);

  if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) {

    /*--- Write the the free-form deformation boxes after deformation. ---*/

    if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl;

    surface_movement[iZone]->WriteFFDInfo(surface_movement, geometry_container, config_container);

  }

  /*--- Synchronization point after a single solver iteration. Compute the
   wall clock time required. ---*/

#ifdef HAVE_MPI
  StopTime = MPI_Wtime();
#else
  StopTime = su2double(clock())/su2double(CLOCKS_PER_SEC);
#endif

  /*--- Compute/print the total time for performance benchmarking. ---*/

  UsedTime = StopTime-StartTime;
  if (rank == MASTER_NODE) {
    cout << "\nCompleted in " << fixed << UsedTime << " seconds on "<< size;
    if (size == 1) cout << " core." << endl; else cout << " cores." << endl;
  }

  /*--- Exit the solver cleanly ---*/

  if (rank == MASTER_NODE)
  cout << endl << "------------------------- Exit Success (SU2_DEF) ------------------------" << endl << endl;

  /*--- Finalize MPI parallelization ---*/

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  return EXIT_SUCCESS;

}
<commit_msg>Fixing a bug in SU2_DEF<commit_after>/*!
 * \file SU2_DEF.cpp
 * \brief Main file of Mesh Deformation Code (SU2_DEF).
 * \author F. Palacios, T. Economon
 * \version 5.0.0 "Raven"
 *
 * SU2 Original Developers: Dr. Francisco D. Palacios.
 *                          Dr. Thomas D. Economon.
 *
 * SU2 Developers: Prof. Juan J. Alonso's group at Stanford University.
 *                 Prof. Piero Colonna's group at Delft University of Technology.
 *                 Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology.
 *                 Prof. Alberto Guardone's group at Polytechnic University of Milan.
 *                 Prof. Rafael Palacios' group at Imperial College London.
 *                 Prof. Edwin van der Weide's group at the University of Twente.
 *                 Prof. Vincent Terrapon's group at the University of Liege.
 *
 * Copyright (C) 2012-2017 SU2, the open-source CFD code.
 *
 * SU2 is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * SU2 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
 */

#include "../include/SU2_DEF.hpp"
using namespace std;

int main(int argc, char *argv[]) {

  unsigned short iZone, nZone = SINGLE_ZONE, iMarker;
  su2double StartTime = 0.0, StopTime = 0.0, UsedTime = 0.0;
  char config_file_name[MAX_STRING_SIZE];
  int rank = MASTER_NODE, size = SINGLE_NODE;
  string str;
  bool allmoving=true;

  /*--- MPI initialization ---*/

#ifdef HAVE_MPI
  SU2_MPI::Init(&argc,&argv);
  SU2_Comm MPICommunicator(MPI_COMM_WORLD);
  MPI_Comm_rank(MPICommunicator,&rank);
  MPI_Comm_size(MPICommunicator,&size);
#else
  SU2_Comm MPICommunicator(0);
#endif

  /*--- Pointer to different structures that will be used throughout
   the entire code ---*/

  CConfig **config_container         = NULL;
  CGeometry **geometry_container     = NULL;
  CSurfaceMovement **surface_movement = NULL;
  CVolumetricMovement **grid_movement = NULL;
  COutput *output                    = NULL;

  /*--- Load in the number of zones and spatial dimensions in the mesh file
   (if no config file is specified, default.cfg is used) ---*/

  if (argc == 2) { strcpy(config_file_name, argv[1]); }
  else { strcpy(config_file_name, "default.cfg"); }

  /*--- Read the name and format of the input mesh file to get from the mesh
   file the number of zones and dimensions from the numerical grid (required
   for variables allocation)  ---*/

  CConfig *config = NULL;
  config = new CConfig(config_file_name, SU2_DEF);

  nZone = CConfig::GetnZone(config->GetMesh_FileName(), config->GetMesh_FileFormat(), config);

  /*--- Definition of the containers per zones ---*/

  config_container = new CConfig*[nZone];
  geometry_container = new CGeometry*[nZone];
  surface_movement   = new CSurfaceMovement*[nZone];
  grid_movement      = new CVolumetricMovement*[nZone];
  output             = new COutput(config_container[ZONE_0]);

  for (iZone = 0; iZone < nZone; iZone++) {
    config_container[iZone]       = NULL;
    geometry_container[iZone]     = NULL;
  }

  /*--- Loop over all zones to initialize the various classes. In most
   cases, nZone is equal to one. This represents the solution of a partial
   differential equation on a single block, unstructured mesh. ---*/

  for (iZone = 0; iZone < nZone; iZone++) {

    /*--- Definition of the configuration option class for all zones. In this
     constructor, the input configuration file is parsed and all options are
     read and stored. ---*/

    config_container[iZone] = new CConfig(config_file_name, SU2_DEF, iZone, nZone, 0, VERB_HIGH);
    config_container[iZone]->SetMPICommunicator(MPICommunicator);

    /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/

    CGeometry *geometry_aux = NULL;

    /*--- All ranks process the grid and call ParMETIS for partitioning ---*/

    geometry_aux = new CPhysicalGeometry(config_container[iZone], iZone, nZone);

    /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/

    geometry_aux->SetColorGrid_Parallel(config_container[iZone]);

    /*--- Allocate the memory of the current domain, and
     divide the grid between the nodes ---*/

    geometry_container[iZone] = new CPhysicalGeometry(geometry_aux, config_container[iZone]);

    /*--- Deallocate the memory of geometry_aux ---*/

    delete geometry_aux;

    /*--- Add the Send/Receive boundaries ---*/

    geometry_container[iZone]->SetSendReceive(config_container[iZone]);

    /*--- Add the Send/Receive boundaries ---*/

    geometry_container[iZone]->SetBoundaries(config_container[iZone]);

  }

  /*--- Set up a timer for performance benchmarking (preprocessing time is included) ---*/

#ifdef HAVE_MPI
  StartTime = MPI_Wtime();
#else
  StartTime = su2double(clock())/su2double(CLOCKS_PER_SEC);
#endif
  for (iZone = 0; iZone < nZone; iZone++) {

    /*--- Computational grid preprocesing ---*/

    if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl;

    /*--- Compute elements surrounding points, points surrounding points ---*/

    if (rank == MASTER_NODE) cout << "Setting local point connectivity." <<endl;
    geometry_container[iZone]->SetPoint_Connectivity();

    /*--- Check the orientation before computing geometrical quantities ---*/

    if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <<endl;
    geometry_container[iZone]->SetBoundVolume();
    geometry_container[iZone]->Check_IntElem_Orientation(config_container[iZone]);
    geometry_container[iZone]->Check_BoundElem_Orientation(config_container[iZone]);

    /*--- Create the edge structure ---*/

    if (rank == MASTER_NODE) cout << "Identify edges and vertices." <<endl;
    geometry_container[iZone]->SetEdges(); geometry_container[iZone]->SetVertex(config_container[iZone]);

    if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) {

      /*--- Compute center of gravity ---*/

      if (rank == MASTER_NODE) cout << "Computing centers of gravity." << endl;
      geometry_container[iZone]->SetCoord_CG();

      /*--- Create the dual control volume structures ---*/

      if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl;
      geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE);

    }

  }

  if (config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) {

    /*--- initialization of output structure  ---*/

    output  = new COutput(config_container[ZONE_0]);

    /*--- Output original grid for visualization, if requested (surface and volumetric) ---*/

    if (config_container[ZONE_0]->GetVisualize_Deformation()) {

      output->SetMesh_Files(geometry_container, config_container, nZone, true, false);

    }

  }

  /*--- Surface grid deformation using design variables ---*/

  for (iZone = 0; iZone < nZone; iZone++){

    if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) {

      if (rank == MASTER_NODE) cout << endl << "--------------------- Surface grid deformation (ZONE " << iZone <<") -----------------" << endl;

      /*--- Definition and initialization of the surface deformation class ---*/

      surface_movement[iZone] = new CSurfaceMovement();

      /*--- Copy coordinates to the surface structure ---*/

      surface_movement[iZone]->CopyBoundary(geometry_container[iZone], config_container[iZone]);

      /*--- Surface grid deformation ---*/

      if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl;
      surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone], config_container[iZone]);

      if (config_container[iZone]->GetDesign_Variable(0) != FFD_SETTING) {

        if (rank == MASTER_NODE)
          cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl;

        /*--- Definition of the Class for grid movement ---*/
        grid_movement[iZone] = new CVolumetricMovement(geometry_container[iZone], config_container[iZone]);

      }

      /*--- For scale, translation and rotation if all boundaries are moving they are set via volume method
       * Otherwise, the surface deformation has been set already in SetSurface_Deformation.  --- */
      allmoving = true;
      /*--- Loop over markers, set flag to false if any are not moving ---*/
      for (iMarker = 0; iMarker < config_container[iZone]->GetnMarker_All(); iMarker++){
        if (config_container[iZone]->GetMarker_All_DV(iMarker) == NO)
          allmoving = false;
      }

      /*--- Volumetric grid deformation/transformations ---*/

      if (config_container[iZone]->GetDesign_Variable(0) == SCALE && allmoving) {

        if (rank == MASTER_NODE)
          cout << "Performing a scaling of the volumetric grid." << endl;

        grid_movement[iZone]->SetVolume_Scaling(geometry_container[iZone], config_container[iZone], false);

      } else if (config_container[iZone]->GetDesign_Variable(0) == TRANSLATION && allmoving) {

        if (rank == MASTER_NODE)
          cout << "Performing a translation of the volumetric grid." << endl;

        grid_movement[iZone]->SetVolume_Translation(geometry_container[iZone], config_container[iZone], false);

      } else if (config_container[iZone]->GetDesign_Variable(0) == ROTATION && allmoving) {

        if (rank == MASTER_NODE)
          cout << "Performing a rotation of the volumetric grid." << endl;

        grid_movement[iZone]->SetVolume_Rotation(geometry_container[iZone], config_container[iZone], false);

      } else if (config_container[iZone]->GetDesign_Variable(0) != FFD_SETTING) {

        if (rank == MASTER_NODE)
          cout << "Performing the deformation of the volumetric grid." << endl;

        grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone], config_container[iZone], false);

      }

    }

  }

  /*--- Computational grid preprocesing ---*/

  if (rank == MASTER_NODE) cout << endl << "----------------------- Write deformed grid files -----------------------" << endl;

  /*--- Output deformed grid for visualization, if requested (surface and volumetric), in parallel
   requires to move all the data to the master node---*/

  bool NewFile = false;
  if (config_container[ZONE_0]->GetDesign_Variable(0) == NO_DEFORMATION) NewFile = true;

  output->SetMesh_Files(geometry_container, config_container, SINGLE_ZONE, NewFile, true);

  if (config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) {

    /*--- Write the the free-form deformation boxes after deformation. ---*/

    if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl;

    surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container);

  }

  /*--- Synchronization point after a single solver iteration. Compute the
   wall clock time required. ---*/

#ifdef HAVE_MPI
  StopTime = MPI_Wtime();
#else
  StopTime = su2double(clock())/su2double(CLOCKS_PER_SEC);
#endif

  /*--- Compute/print the total time for performance benchmarking. ---*/

  UsedTime = StopTime-StartTime;
  if (rank == MASTER_NODE) {
    cout << "\nCompleted in " << fixed << UsedTime << " seconds on "<< size;
    if (size == 1) cout << " core." << endl; else cout << " cores." << endl;
  }

  /*--- Exit the solver cleanly ---*/

  if (rank == MASTER_NODE)
  cout << endl << "------------------------- Exit Success (SU2_DEF) ------------------------" << endl << endl;

  /*--- Finalize MPI parallelization ---*/

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  return EXIT_SUCCESS;

}
<|endoftext|>


<commit_before>/*
 * SDL Hello World example for Gui-chan
 */

// Include all necessary headers.
#include <iostream>
#include <guichan.hpp>
#include <guichan/sdl.hpp>
#include <SDL/SDL.h>

/*
 * Common stuff we need
 */
bool running = true;

/*
 * SDL Stuff we need
 */
SDL_Surface* screen;
SDL_Event event;

/*
 * Gui-chan SDL stuff we need
 */
gcn::SDLInput* input;             // Input driver
gcn::SDLGraphics* graphics;       // Graphics driver
gcn::SDLImageLoader* imageLoader; // For loading images

/*
 * Gui-chan stuff we need
 */
gcn::Gui* gui;            // A Gui object - binds it all together
gcn::Container* top;      // A top container
gcn::ImageFont* font;     // A font
gcn::Label* label;        // And a label for the Hello World text

/**
 * Initializes the Hello World
 */
void init()
{
	/*
	 * Here we initialize SDL as we would do with any SDL application.
	 */
	SDL_Init(SDL_INIT_VIDEO);
	screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);
	// We want unicode
	SDL_EnableUNICODE(1);
	// We want to enable key repeat
	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);

	/*
	 * Now it's time for Gui-chan SDL stuff
	 */
	gcn::ImageLoader* imageLoader = new gcn::SDLImageLoader();
  // The ImageLoader in use is static and must be set to be
	// able to load images
	gcn::Image::setImageLoader(imageLoader);
	graphics = new gcn::SDLGraphics();
	// Set the target for the graphics object to be the screen.
	// In other words, we will draw to the screen.
	// Note, any surface will do, it doesn't have to be the screen.
	graphics->setTarget(screen);
	input = new gcn::SDLInput();

	/*
	 * Last but not least it's time to initialize and create the gui
	 * with Gui-chan stuff.
	 */
	top = new gcn::Container();
	// Set the dimension of the top container to match the screen.
	top->setDimension(gcn::Rectangle(0, 0, 640, 480));
	gui = new gcn::Gui();
	// Set gui to use the SDLGraphics object.
	gui->setGraphics(graphics);
	// Set gui to use the SDLInput object
	gui->setInput(input);
	// Set the top container
	gui->setTop(top);
	// Load the image font.
	font = new gcn::ImageFont("fixedfont.bmp", " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
	// The global font is static and must be set.
	gcn::Widget::setGlobalFont(font);

	// Create a label with test hello world
	label = new gcn::Label("Hello World");
	// Set the labels position
	label->setPosition(280, 220);
	// Add the label to the top container
	top->add(label);
}

/**
 * Halts the application
 */
void halt()
{
	/*
	 * Destroy Gui-chan stuff
	 */
	delete label;
	delete font;
	delete top;
	delete gui;

	/*
	 * Destroy Gui-chan SDL stuff
	 */
	delete input;
	delete graphics;
	delete imageLoader;

	/*
	 * Destroy SDL stuff
	 */
	SDL_Quit();
}

/**
 * Checks input. On escape halt the application.
 */
void checkInput()
{
	/*
	 * Poll SDL events
	 */
	while(SDL_PollEvent(&event))
	{
		if (event.type == SDL_KEYDOWN)
		{
			if (event.key.keysym.sym == SDLK_ESCAPE)
			{
				running = false;
			}
			if (event.key.keysym.sym == SDLK_f)
			{
				if (event.key.keysym.mod & KMOD_CTRL)
				{
					// Works with X11 only
					SDL_WM_ToggleFullScreen(screen);
				}
			}
		}
		else if(event.type == SDL_QUIT)
		{
			running = false;
		}

		/*
		 * Now that we are done polling and using SDL events we pass
		 * the leftovers to the SDLInput object to later be handled by
		 * the Gui. (This example doesn't require us to do this 'cause a
		 * label doesn't use input. But will do it anyway to show how to
		 * set up an SDL application with Gui-chan.)
		 */
		input->pushInput(event);
	}
}

/**
 * Runs the application
 */
void run()
{
	while(running)
	{
		// Poll input
		checkInput();
		// Let the gui perform it's logic (like handle input)
		gui->logic();
		// Draw the gui
		gui->draw();
		// Update the screen
		SDL_Flip(screen);
	}
}

int main(int argc, char **argv)
{
	try
	{
 		init();
		run();
		halt();
	}
	/*
	 * Catch all Gui-chan exceptions
	 */
	catch (gcn::Exception e)
	{
		std::cout << e.getMessage() << std::endl;
	}
	/*
	 * Catch all Std exceptions
	 */
	catch (std::exception e)
	{
	  std::cout << "Std exception: " << e.what() << std::endl;
  }
	/*
	 * Catch all Unknown exceptions
	 */
  catch (...)
  {
	  std::cout << "Unknown exception" << std::endl;
  }

  return 0;
}
<commit_msg>Updated comments<commit_after>/*
 * SDL Hello World example for Guichan
 */

// Include all necessary headers.
#include <iostream>
#include <guichan.hpp>
#include <guichan/sdl.hpp>
#include <SDL/SDL.h>

/*
 * Common stuff we need
 */
bool running = true;

/*
 * SDL Stuff we need
 */
SDL_Surface* screen;
SDL_Event event;

/*
 * Guichan SDL stuff we need
 */
gcn::SDLInput* input;             // Input driver
gcn::SDLGraphics* graphics;       // Graphics driver
gcn::SDLImageLoader* imageLoader; // For loading images

/*
 * Guichan stuff we need
 */
gcn::Gui* gui;            // A Gui object - binds it all together
gcn::Container* top;      // A top container
gcn::ImageFont* font;     // A font
gcn::Label* label;        // And a label for the Hello World text

/**
 * Initializes the Hello World
 */
void init()
{
	/*
	 * Here we initialize SDL as we would do with any SDL application.
	 */
	SDL_Init(SDL_INIT_VIDEO);
	screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);
	// We want unicode
	SDL_EnableUNICODE(1);
	// We want to enable key repeat
	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);

	/*
	 * Now it's time for Guichan SDL stuff
	 */
	gcn::ImageLoader* imageLoader = new gcn::SDLImageLoader();
  // The ImageLoader in use is static and must be set to be
	// able to load images
	gcn::Image::setImageLoader(imageLoader);
	graphics = new gcn::SDLGraphics();
	// Set the target for the graphics object to be the screen.
	// In other words, we will draw to the screen.
	// Note, any surface will do, it doesn't have to be the screen.
	graphics->setTarget(screen);
	input = new gcn::SDLInput();

	/*
	 * Last but not least it's time to initialize and create the gui
	 * with Guichan stuff.
	 */
	top = new gcn::Container();
	// Set the dimension of the top container to match the screen.
	top->setDimension(gcn::Rectangle(0, 0, 640, 480));
	gui = new gcn::Gui();
	// Set gui to use the SDLGraphics object.
	gui->setGraphics(graphics);
	// Set gui to use the SDLInput object
	gui->setInput(input);
	// Set the top container
	gui->setTop(top);
	// Load the image font.
	font = new gcn::ImageFont("fixedfont.bmp", " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
	// The global font is static and must be set.
	gcn::Widget::setGlobalFont(font);

	// Create a label with test hello world
	label = new gcn::Label("Hello World");
	// Set the labels position
	label->setPosition(280, 220);
	// Add the label to the top container
	top->add(label);
}

/**
 * Halts the application
 */
void halt()
{
	/*
	 * Destroy Guichan stuff
	 */
	delete label;
	delete font;
	delete top;
	delete gui;

	/*
	 * Destroy Guichan SDL stuff
	 */
	delete input;
	delete graphics;
	delete imageLoader;

	/*
	 * Destroy SDL stuff
	 */
	SDL_Quit();
}

/**
 * Checks input. On escape halt the application.
 */
void checkInput()
{
	/*
	 * Poll SDL events
	 */
	while(SDL_PollEvent(&event))
	{
		if (event.type == SDL_KEYDOWN)
		{
			if (event.key.keysym.sym == SDLK_ESCAPE)
			{
				running = false;
			}
			if (event.key.keysym.sym == SDLK_f)
			{
				if (event.key.keysym.mod & KMOD_CTRL)
				{
					// Works with X11 only
					SDL_WM_ToggleFullScreen(screen);
				}
			}
		}
		else if(event.type == SDL_QUIT)
		{
			running = false;
		}

		/*
		 * Now that we are done polling and using SDL events we pass
		 * the leftovers to the SDLInput object to later be handled by
		 * the Gui. (This example doesn't require us to do this 'cause a
		 * label doesn't use input. But will do it anyway to show how to
		 * set up an SDL application with Guichan.)
		 */
		input->pushInput(event);
	}
}

/**
 * Runs the application
 */
void run()
{
	while(running)
	{
		// Poll input
		checkInput();
		// Let the gui perform it's logic (like handle input)
		gui->logic();
		// Draw the gui
		gui->draw();
		// Update the screen
		SDL_Flip(screen);
	}
}

int main(int argc, char **argv)
{
	try
	{
 		init();
		run();
		halt();
	}
	/*
	 * Catch all Guichan exceptions
	 */
	catch (gcn::Exception e)
	{
		std::cout << e.getMessage() << std::endl;
	}
	/*
	 * Catch all Std exceptions
	 */
	catch (std::exception e)
	{
	  std::cout << "Std exception: " << e.what() << std::endl;
  }
	/*
	 * Catch all Unknown exceptions
	 */
  catch (...)
  {
	  std::cout << "Unknown exception" << std::endl;
  }

  return 0;
}
<|endoftext|>


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

#include <os>
#include <vga>
#include <cassert>
#include <net/inet4>
#include <hw/ps2.hpp>

#include "snake.hpp"

ConsoleVGA vga;

void begin_snake()
{
  static Snake snake {vga};

  hw::KBM::init();
  hw::KBM::set_virtualkey_handler(
  [] (int key) {
    if (key == hw::KBM::VK_RIGHT) {
      snake.set_dir(Snake::RIGHT);
    } else if (key == hw::KBM::VK_LEFT) {
      snake.set_dir(Snake::LEFT);
    } else if (key == hw::KBM::VK_UP) {
      snake.set_dir(Snake::UP);
    } else if (key == hw::KBM::VK_DOWN) {
      snake.set_dir(Snake::DOWN);
    } else if (key == hw::KBM::VK_SPACE and snake.is_gameover()) {
      snake.reset();
    }
  });
}

void Service::start()
{
  // Redirect stdout to vga screen
  // ... even though we aren't really using it after the game starts
  OS::set_rsprint(
  [] (const char* data, size_t len) {
    vga.write(data, len);
  });

  // We have to start snake later to avoid late text output
  hw::PIT::on_timeout(0.25, [] { begin_snake(); });

  // Stack with network interface (eth0) driven by VirtioNet
  // DNS address defaults to 8.8.8.8
  auto inet = net::new_ipv4_stack<>(0.15, [](bool timeout) {
    if (timeout) {
      printf("%s\n", "DHCP negotiation timed out\n");
    } else {
      printf("%s\n", "DHCP negotiation completed successfully\n");
    }
  });

  // Static IP configuration, until we (possibly) get DHCP
  inet->network_config({ 10,0,0,42 },      // IP
                       { 255,255,255,0 },  // Netmask
                       { 10,0,0,1 },       // Gateway
                       { 8,8,8,8 });       // DNS

  printf("*** TEST SERVICE STARTED ***\n");
}
<commit_msg>Removed unused include<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <os>
#include <vga>
#include <net/inet4>
#include <hw/ps2.hpp>

#include "snake.hpp"

ConsoleVGA vga;

void begin_snake()
{
  static Snake snake {vga};

  hw::KBM::init();
  hw::KBM::set_virtualkey_handler(
  [] (int key) {
    if (key == hw::KBM::VK_RIGHT) {
      snake.set_dir(Snake::RIGHT);
    } else if (key == hw::KBM::VK_LEFT) {
      snake.set_dir(Snake::LEFT);
    } else if (key == hw::KBM::VK_UP) {
      snake.set_dir(Snake::UP);
    } else if (key == hw::KBM::VK_DOWN) {
      snake.set_dir(Snake::DOWN);
    } else if (key == hw::KBM::VK_SPACE and snake.is_gameover()) {
      snake.reset();
    }
  });
}

void Service::start()
{
  // Redirect stdout to vga screen
  // ... even though we aren't really using it after the game starts
  OS::set_rsprint(
  [] (const char* data, size_t len) {
    vga.write(data, len);
  });

  // We have to start snake later to avoid late text output
  hw::PIT::on_timeout(0.25, [] { begin_snake(); });

  // Stack with network interface (eth0) driven by VirtioNet
  // DNS address defaults to 8.8.8.8
  auto inet = net::new_ipv4_stack<>(0.15, [](bool timeout) {
    if (timeout) {
      printf("%s\n", "DHCP negotiation timed out\n");
    } else {
      printf("%s\n", "DHCP negotiation completed successfully\n");
    }
  });

  // Static IP configuration, until we (possibly) get DHCP
  inet->network_config({ 10,0,0,42 },      // IP
                       { 255,255,255,0 },  // Netmask
                       { 10,0,0,1 },       // Gateway
                       { 8,8,8,8 });       // DNS

  printf("*** TEST SERVICE STARTED ***\n");
}
<|endoftext|>


<commit_before>#include "webcam.hpp"

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

void morphFast(Mat inout, int smallsize = 100, int factor = 25, int eq = 1, int diler = 0) {
 int width, height;
 width = inout.size().width;
 height = inout.size().height;
 Mat downsample;
 resize(inout, downsample, Size(smallsize,smallsize));
 Mat kernel = ellipticKernel(factor);
 if (diler) {
  erode(downsample, downsample, kernel);
 } else {
  dilate(downsample, downsample, kernel);
 }
 if (eq) {
  equalizeHist(downsample, downsample);
 }
 resize(downsample, inout, Size(width, height));
}

int main (int argc, char** argv) {

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

 Mat background = cvQueryFrame(capture);
 background = background.clone();
 blur(background, background, Size(50,50));

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
// preprocess by rotating according to OVR roll
//  imshow("webcam", image);

// let's make multiple masks where 0=not mouth, 1=uncertain

// then multiply them together and multiply that with image
// and run haar classifier on image

  Mat gray, blurred_img;
  cvtColor(image, gray, CV_RGB2GRAY);
  blur(image, blurred_img, Size(50,50));

// this mask filters out areas with too many edges
// removed for now; it didn't generalize well
/*
  Mat canny;
  Canny(gray, canny, 50, 50, 3);
  blur(canny, canny, Size(width/20,height/20));
  bitwise_not(canny, canny);
  threshold(canny, canny, 200, 1, THRESH_BINARY);
  blur(canny*255, canny, Size(width/10, height/10));
  threshold(canny, canny, 220, 1, THRESH_BINARY);
  imshow("canny mask", gray.mul(canny));
*/

// this mask filters out areas which have not changed much
// background needs to be updated when person is not in frame
// use OVR SDK to do this later
  Mat flow;
  absdiff(blurred_img, background, flow);
  cvtColor(flow, flow, CV_RGB2GRAY);
  morphFast(flow);
  threshold(flow, flow, 60, 1, THRESH_BINARY);
//  imshow("flow mask", gray.mul(flow));

// this mask gets anything kind of dark (DK2) and dilates
  Mat kindofdark;
  equalizeHist(gray, kindofdark);
  threshold(kindofdark, kindofdark, 100, 1, THRESH_BINARY_INV);
  morphFast(kindofdark, 100, 17, 0);
//  imshow("dark mask", gray.mul(kindofdark));

// this mask gets rid of anything far away from red stuff
// lips have a lot of red
  Mat notlips;
  Mat channels[3];
  split(image, channels);
  channels[2].convertTo(notlips, CV_32FC1);
  divide(notlips, gray, notlips, 1, CV_32FC1);
  //equalistHist is horrible for a red background
  //equalizeHist(notlips, notlips);
  threshold(notlips, notlips, tracker3/30.0, 1, THRESH_BINARY);
  imshow("lip mask", notlips*255);
  Mat otherMorph = notlips.copy();
  int tx = tracker1+1-(tracker1%2);
  if (tx<3) tx=1;
  if (tx>90) tx=91;
  morphFast(notlips, 100, tx, 0, 0);
  int ty = tracker2+1-(tracker2%2);
  if (ty<3) ty=1;
  if (ty>90) ty=91;
  morphFast(notlips, 100, ty, 0, 1);
  imshow("lips2", notlips*255);
  morphFast(otherMorph, 100, tx, 0, 1);
  morphFast(otherMorph, 100, tx, 0, 0);
  imshow("lips3", otherMorph*255);
  waitKey(1);

  Mat mask = flow.mul(kindofdark);
// open the mask
  Mat smallMask0, smallMask1;
  resize(mask, smallMask0, Size(width/5,height/5));
  Mat erodeKernel = ellipticKernel(69,79);
  erode(smallMask0, smallMask1, erodeKernel);
  Mat dilateKernel = ellipticKernel(69,79);
  dilate(smallMask1, smallMask1, dilateKernel);
  bitwise_and(smallMask0, smallMask1, smallMask1);
  resize(smallMask1, mask, Size(width, height));
//  imshow("morph mask", gray.mul(mask));

// update background with new morph mask
// average what we know is background with prior background
// erode it first since we really want to be sure it's bg

//  Mat erodeKernel = ellipticKernel(21);
  Mat erodedMask;
  erode(mask, erodedMask, erodeKernel);
  Mat mask_;
  subtract(1,erodedMask,mask_);
  Mat mask3, mask3_;
  channel[0] = erodedMask;
  channel[1] = erodedMask;
  channel[2] = erodedMask;
  merge(channel, 3, mask3);
  channel[0] = mask_;
  channel[1] = mask_;
  channel[2] = mask_;
  merge(channel, 3, mask3_);

  background = background.mul(mask3) +
   (background.mul(mask3_) + blurred_img.mul(mask3_))/2;

  imshow("background", background);

/*
  Moments lol = moments(gray, 1);
  circle(image, Point(lol.m10/lol.m00,lol.m01/lol.m00),20,Scalar(128),30);
  imshow("leimage", image);
*/
/*
  CascadeClassifier mouth_cascade;
  mouth_cascade.load("Mouth.xml");
  vector<Rect> mouths;
  int scale = tracker1+1;
  Mat classifyThis = image.clone();
  equalizeHist(gray, gray);//ew; watch out not to use this later
  resize(gray.mul(mask), classifyThis, Size(width/scale,height/scale));
//  bilateralFilter(gray, classifyThis, 15, 10, 1);
  mouth_cascade.detectMultiScale(classifyThis, mouths, 1.1, tracker2, CV_HAAR_SCALE_IMAGE);
  for (size_t i=0; i<mouths.size(); i++) {
   Rect scaled(mouths[i].x*scale, mouths[i].y*scale, mouths[i].width*scale,mouths[i].height*scale);
   rectangle(image, scaled, Scalar(255,0,0));
  }
  imshow("MOUTH", image);
*/

  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<commit_msg>hacking<commit_after>#include "webcam.hpp"

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

void morphFast(Mat inout, int smallsize = 100, int factor = 25, int eq = 1, int diler = 0) {
 int width, height;
 width = inout.size().width;
 height = inout.size().height;
 Mat downsample;
 resize(inout, downsample, Size(smallsize,smallsize));
 Mat kernel = ellipticKernel(factor);
 if (diler) {
  erode(downsample, downsample, kernel);
 } else {
  dilate(downsample, downsample, kernel);
 }
 if (eq) {
  equalizeHist(downsample, downsample);
 }
 resize(downsample, inout, Size(width, height));
}

int main (int argc, char** argv) {

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

 Mat background = cvQueryFrame(capture);
 background = background.clone();
 blur(background, background, Size(50,50));

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
// preprocess by rotating according to OVR roll
//  imshow("webcam", image);

// let's make multiple masks where 0=not mouth, 1=uncertain

// then multiply them together and multiply that with image
// and run haar classifier on image

  Mat gray, blurred_img;
  cvtColor(image, gray, CV_RGB2GRAY);
  blur(image, blurred_img, Size(50,50));

// this mask filters out areas with too many edges
// removed for now; it didn't generalize well
/*
  Mat canny;
  Canny(gray, canny, 50, 50, 3);
  blur(canny, canny, Size(width/20,height/20));
  bitwise_not(canny, canny);
  threshold(canny, canny, 200, 1, THRESH_BINARY);
  blur(canny*255, canny, Size(width/10, height/10));
  threshold(canny, canny, 220, 1, THRESH_BINARY);
  imshow("canny mask", gray.mul(canny));
*/

// this mask filters out areas which have not changed much
// background needs to be updated when person is not in frame
// use OVR SDK to do this later
  Mat flow;
  absdiff(blurred_img, background, flow);
  cvtColor(flow, flow, CV_RGB2GRAY);
  morphFast(flow);
  threshold(flow, flow, 60, 1, THRESH_BINARY);
//  imshow("flow mask", gray.mul(flow));

// this mask gets anything kind of dark (DK2) and dilates
  Mat kindofdark;
  equalizeHist(gray, kindofdark);
  threshold(kindofdark, kindofdark, 100, 1, THRESH_BINARY_INV);
  morphFast(kindofdark, 100, 17, 0);
//  imshow("dark mask", gray.mul(kindofdark));

// this mask gets rid of anything far away from red stuff
// lips have a lot of red
  Mat notlips;
  Mat channels[3];
  split(image, channels);
  channels[2].convertTo(notlips, CV_32FC1);
  divide(notlips, gray, notlips, 1, CV_32FC1);
  //equalistHist is horrible for a red background
  //equalizeHist(notlips, notlips);
  threshold(notlips, notlips, tracker3/30.0, 1, THRESH_BINARY);
  imshow("lip mask", notlips*255);
  Mat otherMorph = notlips.clone();
  int tx = tracker1+1-(tracker1%2);
  if (tx<3) tx=1;
  if (tx>90) tx=91;
  morphFast(notlips, 100, tx, 0, 0);
  int ty = tracker2+1-(tracker2%2);
  if (ty<3) ty=1;
  if (ty>90) ty=91;
  morphFast(notlips, 100, ty, 0, 1);
  imshow("lips2", notlips*255);
  morphFast(otherMorph, 100, tx, 0, 1);
  morphFast(otherMorph, 100, tx, 0, 0);
  imshow("lips3", otherMorph*255);
  waitKey(1);

  Mat mask = flow.mul(kindofdark);
// open the mask
  Mat smallMask0, smallMask1;
  resize(mask, smallMask0, Size(width/5,height/5));
  Mat erodeKernel = ellipticKernel(69,79);
  erode(smallMask0, smallMask1, erodeKernel);
  Mat dilateKernel = ellipticKernel(69,79);
  dilate(smallMask1, smallMask1, dilateKernel);
  bitwise_and(smallMask0, smallMask1, smallMask1);
  resize(smallMask1, mask, Size(width, height));
//  imshow("morph mask", gray.mul(mask));

// update background with new morph mask
// average what we know is background with prior background
// erode it first since we really want to be sure it's bg

//  Mat erodeKernel = ellipticKernel(21);
  Mat erodedMask;
  erode(mask, erodedMask, erodeKernel);
  Mat mask_;
  subtract(1,erodedMask,mask_);
  Mat mask3, mask3_;
  channel[0] = erodedMask;
  channel[1] = erodedMask;
  channel[2] = erodedMask;
  merge(channel, 3, mask3);
  channel[0] = mask_;
  channel[1] = mask_;
  channel[2] = mask_;
  merge(channel, 3, mask3_);

  background = background.mul(mask3) +
   (background.mul(mask3_) + blurred_img.mul(mask3_))/2;

  imshow("background", background);

/*
  Moments lol = moments(gray, 1);
  circle(image, Point(lol.m10/lol.m00,lol.m01/lol.m00),20,Scalar(128),30);
  imshow("leimage", image);
*/
/*
  CascadeClassifier mouth_cascade;
  mouth_cascade.load("Mouth.xml");
  vector<Rect> mouths;
  int scale = tracker1+1;
  Mat classifyThis = image.clone();
  equalizeHist(gray, gray);//ew; watch out not to use this later
  resize(gray.mul(mask), classifyThis, Size(width/scale,height/scale));
//  bilateralFilter(gray, classifyThis, 15, 10, 1);
  mouth_cascade.detectMultiScale(classifyThis, mouths, 1.1, tracker2, CV_HAAR_SCALE_IMAGE);
  for (size_t i=0; i<mouths.size(); i++) {
   Rect scaled(mouths[i].x*scale, mouths[i].y*scale, mouths[i].width*scale,mouths[i].height*scale);
   rectangle(image, scaled, Scalar(255,0,0));
  }
  imshow("MOUTH", image);
*/

  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<|endoftext|>