<commit_before>/* -------------------------------------------------------------------------- *
 *                        OpenSim:  testInitState.cpp                         *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2016 Stanford University and the Authors                *
 * Author(s): Peter Eastman, Ajay Seth                                        *
 *                                                                            *
 * 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 <stdint.h>
#include <OpenSim/Simulation/Manager/Manager.h>
#include <OpenSim/Simulation/Control/ControlSetController.h>
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Common/LoadOpenSimLibrary.h>
#include <OpenSim/Auxiliary/auxiliaryTestFunctions.h>

using namespace OpenSim;
using namespace std;

//==============================================================================
// testInitState tests that a Model consistently generates the same default
// state from its initSystem() method. It also tests that when the properties
// are updated (after a simulation) that the defaults match the values in the
// new state.
//==============================================================================
void testStates(const string& modelFile);
//==============================================================================
// testMemoryUsage tests that repeated initialization of the state does not
// cause the memory footprint of the process to increase significantly.
//==============================================================================
void testMemoryUsage(const string& modelFile);

static const int MAX_N_TRIES = 100;

int main()
{
    try {
        LoadOpenSimLibrary("osimActuators");
        testStates("arm26.osim");
        testMemoryUsage("arm26.osim");
        testMemoryUsage("PushUpToesOnGroundWithMuscles.osim");
    }
    catch (const Exception& e) {
        cout << "testInitState failed: ";
        e.print(cout);
        return 1;
    }
    catch (const std::exception& e) {
        cout << "testInitState failed: " << e.what() << endl;
        return 1;
    }
    cout << "Done" << endl;
    return 0;
}

//==============================================================================
// Test Cases
//==============================================================================
void testStates(const string& modelFile)
{
    using namespace SimTK;

    //==========================================================================
    // Setup OpenSim model
    Model model(modelFile);
    ControlSetController* controller = new ControlSetController();
    controller->setControlSetFileName("arm26_StaticOptimization_controls.xml");

    model.addController( controller );
    // original default state
    State& state = model.initSystem();

    // hold on to original default continuous state variables
    Vector y1 = state.getY();
    y1 = state.getY();
    //y1.dump("y1: Initial state:");

    // update state to contain muscle states that yield muscle equilibrium
    model.equilibrateMuscles(state);
    state.getY().dump("y1: State after equilibrateMuscles:");
    //==========================================================================
    // Compute the force and torque at the specified times.

    RungeKuttaMersonIntegrator integrator(model.getMultibodySystem());
    Manager manager(model, integrator);
    manager.setInitialTime(0.0);
    manager.setFinalTime(0.05);

    // update state after a short simulation forward in time
    manager.integrate(state);

    // continuous state variables after simulation
    Vector y2 = state.getY();
    //y2.dump("y2: State after integration:");

    // reset model working state to default state
    State& state2 = model.initializeState();

    // another version of default continuous state variables
    // should be unaffected by simulation of the system
    Vector y3 = state2.getY();
    //y3.dump("y3: Model reset to Initial state:");

    // update state to contain muscle states that yield muscle equilibrium
    model.equilibrateMuscles(state2);
    state.getY().dump("y3: State after equilibrateMuscles:");
    //==========================================================================
    // Compute the force and torque at the specified times.

    RungeKuttaMersonIntegrator integrator2(model.getMultibodySystem());
    Manager manager2(model, integrator);
    manager2.setInitialTime(0.0);
    manager2.setFinalTime(0.05);

    // update state after a short simulation forward in time
    manager2.integrate(state2);

    // get the default continuous state variables updated
    // from the state after the simulation
    Vector y4 = state2.getY();

    //y4.dump("y4: Default State after second simulation:");

    for (int i = 0; i < y1.size(); i++)
    {
        cout << i <<" : y1[i] = " << y1[i] << " :: y3[i] = " << y3[i] << endl;
        ASSERT_EQUAL(y1[i], y3[i], 1e-5,__FILE__, __LINE__,
            "Model failed to maintain default state after simulation.");
        cout << i <<" : y2[i] = " << y2[i] << " :: y4[i] = " << y4[i] << endl;
        ASSERT_EQUAL(y2[i], y4[i], 1e-5,__FILE__, __LINE__,
            "Model failed to properly update default state after simulation.");
    }
    ASSERT(max(abs(y1-y2)) > 1e-4);
}

void testMemoryUsage(const string& modelFile)
{
    using namespace SimTK;

    if (isGetRSSValid) {
        //=========================================================================
        // Estimate the size of the model when loaded into memory
        const size_t model_size = estimateMemoryChangeForModelLoading(modelFile, 10);

        Model model(modelFile);
        State state = model.initSystem();

        // also time how long initializing the state takes
        clock_t startTime = clock();

        // determine the change in memory usage due to invoking model.initialiState
        auto command = [&model]() mutable { model.initializeState(); };
        const size_t leak = estimateMemoryChangeForCommand(command, MAX_N_TRIES);

        long double leak_percent = 100.0 * double(leak) / model_size;

        long double dT = (long double)(clock() - startTime) / CLOCKS_PER_SEC;
        long double meanT = 1.0e3 * dT / MAX_N_TRIES; // in ms

        cout << "Approximate leak size: " << leak / 1024.0 << "KB or " <<
            leak_percent << "% of model size." << endl;
        cout << "Average initialization time: " << meanT << "ms" << endl;

        // If we are leaking more than 0.5% of the model's footprint that is significant
        ASSERT((leak_percent) < 0.5, __FILE__, __LINE__,
            "testMemoryUsage: state initialization leak > 0.5% of model memory footprint.");
    }
}
<commit_msg>Invoke Model loading as a command for estimateMemoryChangeForCommand within testInitState. Also only perform memory usage related tests if getRSS is valid by calling isGetRSSValid().<commit_after>/* -------------------------------------------------------------------------- *
 *                        OpenSim:  testInitState.cpp                         *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2016 Stanford University and the Authors                *
 * Author(s): Peter Eastman, Ajay Seth                                        *
 *                                                                            *
 * 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 <stdint.h>
#include <OpenSim/Simulation/Manager/Manager.h>
#include <OpenSim/Simulation/Control/ControlSetController.h>
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Common/LoadOpenSimLibrary.h>
#include <OpenSim/Auxiliary/auxiliaryTestFunctions.h>

using namespace OpenSim;
using namespace std;

//==============================================================================
// testInitState tests that a Model consistently generates the same default
// state from its initSystem() method. It also tests that when the properties
// are updated (after a simulation) that the defaults match the values in the
// new state.
//==============================================================================
void testStates(const string& modelFile);
//==============================================================================
// testMemoryUsage tests that repeated initialization of the state does not
// cause the memory footprint of the process to increase significantly.
//==============================================================================
void testMemoryUsage(const string& modelFile);

static const int MAX_N_TRIES = 100;

int main()
{
    try {
        LoadOpenSimLibrary("osimActuators");
        testStates("arm26.osim");
        if (isGetRSSValid()) {
            testMemoryUsage("arm26.osim");
            testMemoryUsage("PushUpToesOnGroundWithMuscles.osim");
        }
    }
    catch (const Exception& e) {
        cout << "testInitState failed: ";
        e.print(cout);
        return 1;
    }
    catch (const std::exception& e) {
        cout << "testInitState failed: " << e.what() << endl;
        return 1;
    }
    cout << "Done" << endl;
    return 0;
}

//==============================================================================
// Test Cases
//==============================================================================
void testStates(const string& modelFile)
{
    using namespace SimTK;

    //==========================================================================
    // Setup OpenSim model
    Model model(modelFile);
    ControlSetController* controller = new ControlSetController();
    controller->setControlSetFileName("arm26_StaticOptimization_controls.xml");

    model.addController( controller );
    // original default state
    State& state = model.initSystem();

    // hold on to original default continuous state variables
    Vector y1 = state.getY();
    y1 = state.getY();
    //y1.dump("y1: Initial state:");

    // update state to contain muscle states that yield muscle equilibrium
    model.equilibrateMuscles(state);
    state.getY().dump("y1: State after equilibrateMuscles:");
    //==========================================================================
    // Compute the force and torque at the specified times.

    RungeKuttaMersonIntegrator integrator(model.getMultibodySystem());
    Manager manager(model, integrator);
    manager.setInitialTime(0.0);
    manager.setFinalTime(0.05);

    // update state after a short simulation forward in time
    manager.integrate(state);

    // continuous state variables after simulation
    Vector y2 = state.getY();
    //y2.dump("y2: State after integration:");

    // reset model working state to default state
    State& state2 = model.initializeState();

    // another version of default continuous state variables
    // should be unaffected by simulation of the system
    Vector y3 = state2.getY();
    //y3.dump("y3: Model reset to Initial state:");

    // update state to contain muscle states that yield muscle equilibrium
    model.equilibrateMuscles(state2);
    state.getY().dump("y3: State after equilibrateMuscles:");
    //==========================================================================
    // Compute the force and torque at the specified times.

    RungeKuttaMersonIntegrator integrator2(model.getMultibodySystem());
    Manager manager2(model, integrator);
    manager2.setInitialTime(0.0);
    manager2.setFinalTime(0.05);

    // update state after a short simulation forward in time
    manager2.integrate(state2);

    // get the default continuous state variables updated
    // from the state after the simulation
    Vector y4 = state2.getY();

    //y4.dump("y4: Default State after second simulation:");

    for (int i = 0; i < y1.size(); i++)
    {
        cout << i <<" : y1[i] = " << y1[i] << " :: y3[i] = " << y3[i] << endl;
        ASSERT_EQUAL(y1[i], y3[i], 1e-5,__FILE__, __LINE__,
            "Model failed to maintain default state after simulation.");
        cout << i <<" : y2[i] = " << y2[i] << " :: y4[i] = " << y4[i] << endl;
        ASSERT_EQUAL(y2[i], y4[i], 1e-5,__FILE__, __LINE__,
            "Model failed to properly update default state after simulation.");
    }
    ASSERT(max(abs(y1-y2)) > 1e-4);
}

void testMemoryUsage(const string& modelFile)
{
    using namespace SimTK;

    //=========================================================================
    // Estimate the size of the model when loaded into memory
    auto loader = [modelFile]() {
        OpenSim::Model model(modelFile);
        model.finalizeFromProperties();
    };
    size_t model_size = estimateMemoryChangeForCommand(loader, 10);

    Model model(modelFile);
    State state = model.initSystem();

    // also time how long initializing the state takes
    clock_t startTime = clock();

    // determine the change in memory usage due to invoking model.initialiState
    auto command = [&model]() mutable { model.initializeState(); };
    const size_t leak = estimateMemoryChangeForCommand(command, MAX_N_TRIES);

    long double leak_percent = 100.0 * double(leak) / model_size;

    long double dT = (long double)(clock() - startTime) / CLOCKS_PER_SEC;
    long double meanT = 1.0e3 * dT / MAX_N_TRIES; // in ms

    cout << "Approximate leak size: " << leak / 1024.0 << "KB or " <<
        leak_percent << "% of model size." << endl;
    cout << "Average initialization time: " << meanT << "ms" << endl;

    // If we are leaking more than 0.5% of the model's footprint that is significant
    ASSERT((leak_percent) < 0.5, __FILE__, __LINE__,
        "testMemoryUsage: state initialization leak > 0.5% of model memory footprint.");
}
<|endoftext|>


<commit_before>#ifndef PK_PALINDROMICSUBSTRINGSMANACHER_HPP
#define PK_PALINDROMICSUBSTRINGSMANACHER_HPP

#include <algorithm>

namespace pk
{

/**
 * Can be used to find longest palindromic substring.
 * WARNING: Add "guards" ath both ends of the input string before calling run()
 *          For example if your string is "abcd", modify it to "#abcd$" first.
 */
template<int MaxTextSize>
class palindromic_substrings_manacher
{
public:
    /**
     * WARNING: text_size parameter should count "guards" as well
     */
    void find_even(const char* text, const int text_size)
    {
        palindromic_substrings_table[0] = 0;
        int i = 1;
        int t = 0;
        while(i < text_size)
        {
           while(text[i-t] == text[i+t+1])
               ++t;

           palindromic_substrings_table[i] = t;

           int k = 1;
           while((k <= t) && (palindromic_substrings_table[i-k] != palindromic_substrings_table[i]-k))
           {
               palindromic_substrings_table[i+k] = std::min(palindromic_substrings_table[i-k], palindromic_substrings_table[i]-k);
              ++k;
           }

           t = std::max(0, t-k);
           i += k;
        }
    }

    /**
     * table[i] = k means that substring text[i-k+1,..,i+k] is a palindrome (of length 2*k)
     */
    const int* get_palindromic_substrings_table() const
    {
        return palindromic_substrings_table;
    }

private:
    int palindromic_substrings_table[MaxTextSize];
};

} // namespace pk

#endif // PK_PALINDROMICSUBSTRINGSMANACHER_HPP
<commit_msg>Manacher's algorithm for finding even palindromic substrings<commit_after>#ifndef PK_PALINDROMICSUBSTRINGSMANACHER_HPP
#define PK_PALINDROMICSUBSTRINGSMANACHER_HPP

#include <algorithm>

namespace pk
{

/**
 * Can be used to find longest palindromic substring.
 * WARNING: Add "guards" ath both ends of the input string before calling run()
 *          For example if your string is "abcd", modify it to "#abcd$" first.
 */
template<int MaxTextSize>
class palindromic_substrings_manacher
{
public:
    /**
     * WARNING: text_size parameter should count "guards" as well
     */
    void find_even(const char* text, const int text_size)
    {
        palindromic_substrings_table[0] = 0;
        int i = 1;
        int t = 0;
        while(i < text_size)
        {
           while(text[i-t] == text[i+t+1])
               ++t;

           palindromic_substrings_table[i] = t;

           int k = 1;
           while((k <= t) && (palindromic_substrings_table[i-k] != palindromic_substrings_table[i]-k))
           {
               palindromic_substrings_table[i+k] = std::min(palindromic_substrings_table[i-k], palindromic_substrings_table[i]-k);
              ++k;
           }

           t = std::max(0, t-k);
           i += k;
        }
    }
    /**
     * WARNING: text_size parameter should count "guards" as well
     */
    void find_odd(const char* text, const int text_size)
    {
        palindromic_substrings_table[0] = 0;
        int i = 1;
        int t = 1;
        while(i < text_size)
        {
           while(text[i-t] == text[i+t])
               ++t;

           palindromic_substrings_table[i] = t;

           int k = 1;
           while((k <= t) && (palindromic_substrings_table[i-k] != palindromic_substrings_table[i]-k))
           {
               palindromic_substrings_table[i+k] = std::min(palindromic_substrings_table[i-k], palindromic_substrings_table[i]-k);
              ++k;
           }

           t = std::max(1, t-k);
           i += k;
        }
    }

    /**
     * table[i] = k means that substring text[i-k+1,..,i+k] is a palindrome (of length 2*k)
     */
    const int* get_palindromic_substrings_table() const
    {
        return palindromic_substrings_table;
    }

private:
    int palindromic_substrings_table[MaxTextSize];
};

} // namespace pk

#endif // PK_PALINDROMICSUBSTRINGSMANACHER_HPP
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: filglob.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 15:23:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _FILGLOB_HXX_
#define _FILGLOB_HXX_

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif
#ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HPP_
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#endif

namespace fileaccess {

    class shell;
    class BaseContent;

    struct equalOUString
    {
        bool operator()( const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const
        {
            return !!( rKey1 == rKey2 );
        }
    };

    struct hashOUString
    {
        size_t operator()( const rtl::OUString& rName ) const
        {
            return rName.hashCode();
        }
    };

    /******************************************************************************/
    /*                                                                            */
    /*                         Helper functions                                   */
    /*                                                                            */
    /******************************************************************************/

    // Returns true if dstUnqPath is a child from srcUnqPath or both are equal

    extern sal_Bool isChild( const rtl::OUString& srcUnqPath,
                                      const rtl::OUString& dstUnqPath );

    // Changes the prefix in name
    extern rtl::OUString newName( const rtl::OUString& aNewPrefix,
                                           const rtl::OUString& aOldPrefix,
                                           const rtl::OUString& old_Name );

    // returns the last part of the given url as title
    extern rtl::OUString getTitle( const rtl::OUString& aPath );

    // returns the url without last part as parentname
    // In case aFileName is root ( file:/// ) root is returned

    extern rtl::OUString getParentName( const rtl::OUString& aFileName );

    /**
     *  special copy:
     *  On test = true, the implementation determines whether the
     *  destination exists and returns the appropriate errorcode E_EXIST.
     *  osl::File::copy copies unchecked.
     */

    extern osl::FileBase::RC osl_File_copy( const rtl::OUString& strPath,
                                            const rtl::OUString& strDestPath,
                                            sal_Bool test = false );

    /**
     *  special move:
     *  On test = true, the implementation determines whether the
     *  destination exists and returns the appropriate errorcode E_EXIST.
     *  osl::File::move moves unchecked
     */

    extern osl::FileBase::RC osl_File_move( const rtl::OUString& strPath,
                                            const rtl::OUString& strDestPath,
                                            sal_Bool test = false );

    extern oslFileError getResolvedURL( rtl_uString* ustrPath,
                                        rtl_uString** pustrResolvedURL);

    // Removes ellipses like .. and . from a file path
    // Needs rework; This seems to be the most time consuming function in
    // the whole file content provider

    extern sal_Bool SAL_CALL makeAbsolutePath( const rtl::OUString& aRelPath,
                                               rtl::OUString& aAbsPath );

    // This function implements the global exception handler of the file_ucp;
    // It never returns;

    extern void throw_handler( shell * pShell, // must not be null
                               sal_Int32 errorCode,
                               sal_Int32 minorCode,
                               const com::sun::star::uno::Reference<
                               com::sun::star::ucb::XCommandEnvironment >& xEnv,
                               const rtl::OUString& aUncPath,
                               BaseContent* pContent,
                               bool isHandled = false);
                                   // the physical URL of the object

} // end namespace fileaccess

#endif
<commit_msg>INTEGRATION: CWS warnings01 (1.9.10); FILE MERGED 2005/11/09 21:01:52 sb 1.9.10.1: #i53898# Made code warning-free.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: filglob.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 05:19:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _FILGLOB_HXX_
#define _FILGLOB_HXX_

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif
#ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HPP_
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#endif

namespace fileaccess {

    class BaseContent;

    struct equalOUString
    {
        bool operator()( const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const
        {
            return !!( rKey1 == rKey2 );
        }
    };

    struct hashOUString
    {
        size_t operator()( const rtl::OUString& rName ) const
        {
            return rName.hashCode();
        }
    };

    /******************************************************************************/
    /*                                                                            */
    /*                         Helper functions                                   */
    /*                                                                            */
    /******************************************************************************/

    // Returns true if dstUnqPath is a child from srcUnqPath or both are equal

    extern sal_Bool isChild( const rtl::OUString& srcUnqPath,
                                      const rtl::OUString& dstUnqPath );

    // Changes the prefix in name
    extern rtl::OUString newName( const rtl::OUString& aNewPrefix,
                                           const rtl::OUString& aOldPrefix,
                                           const rtl::OUString& old_Name );

    // returns the last part of the given url as title
    extern rtl::OUString getTitle( const rtl::OUString& aPath );

    // returns the url without last part as parentname
    // In case aFileName is root ( file:/// ) root is returned

    extern rtl::OUString getParentName( const rtl::OUString& aFileName );

    /**
     *  special copy:
     *  On test = true, the implementation determines whether the
     *  destination exists and returns the appropriate errorcode E_EXIST.
     *  osl::File::copy copies unchecked.
     */

    extern osl::FileBase::RC osl_File_copy( const rtl::OUString& strPath,
                                            const rtl::OUString& strDestPath,
                                            sal_Bool test = false );

    /**
     *  special move:
     *  On test = true, the implementation determines whether the
     *  destination exists and returns the appropriate errorcode E_EXIST.
     *  osl::File::move moves unchecked
     */

    extern osl::FileBase::RC osl_File_move( const rtl::OUString& strPath,
                                            const rtl::OUString& strDestPath,
                                            sal_Bool test = false );

    extern oslFileError getResolvedURL( rtl_uString* ustrPath,
                                        rtl_uString** pustrResolvedURL);

    // Removes ellipses like .. and . from a file path
    // Needs rework; This seems to be the most time consuming function in
    // the whole file content provider

    extern sal_Bool SAL_CALL makeAbsolutePath( const rtl::OUString& aRelPath,
                                               rtl::OUString& aAbsPath );

    // This function implements the global exception handler of the file_ucp;
    // It never returns;

    extern void throw_handler( sal_Int32 errorCode,
                               sal_Int32 minorCode,
                               const com::sun::star::uno::Reference<
                               com::sun::star::ucb::XCommandEnvironment >& xEnv,
                               const rtl::OUString& aUncPath,
                               BaseContent* pContent,
                               bool isHandled = false);
                                   // the physical URL of the object

} // end namespace fileaccess

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: content.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 05:27:02 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _GVFS_UCP_CONTENT_HXX
#define _GVFS_UCP_CONTENT_HXX

#include <memory>
#include <list>

#ifndef _RTL_REF_HXX_
#include <rtl/ref.hxx>
#endif

#ifndef _COM_SUN_STAR_UCB_CONTENTCREATIONEXCEPTION_HPP_
#include <com/sun/star/ucb/ContentCreationException.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTCREATOR_HPP_
#include <com/sun/star/ucb/XContentCreator.hpp>
#endif

#ifndef _UCBHELPER_CONTENTHELPER_HXX
#include <ucbhelper/contenthelper.hxx>
#endif

#include <glib/gthread.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomevfs/gnome-vfs-directory.h>

namespace com { namespace sun { namespace star { namespace beans {
    struct Property;
    struct PropertyValue;
} } } }

namespace com { namespace sun { namespace star { namespace io {
    class XInputStream;
    class XOutputStream;
} } } }

namespace com { namespace sun { namespace star { namespace sdbc {
    class XRow;
} } } }

namespace com { namespace sun { namespace star { namespace ucb {
    struct TransferInfo;
} } } }

namespace gvfs
{

class ContentProvider;
class ContentProperties;

// Random made up names - AFAICS
#define GVFS_FILE_TYPE   "application/vnd.sun.staroffice.gvfs-file"
#define GVFS_FOLDER_TYPE "application/vnd.sun.staroffice.gvfs-folder"

class Authentication
{
public:
    // Helper class to make exceptions pleasant
    Authentication( const com::sun::star::uno::Reference<
                com::sun::star::ucb::XCommandEnvironment > & xEnv );
    ~Authentication();
};

class Content : public ::ucb::ContentImplHelper,
        public com::sun::star::ucb::XContentCreator
{
//=========================================================================
//          Internals
//=========================================================================
private:
    typedef rtl::Reference< Content > ContentRef;
      typedef std::list< ContentRef > ContentRefList;

    // Instance data
    ContentProvider  *m_pProvider;  // No need for a ref, base class holds object
    sal_Bool          m_bTransient; // A non-existant (as yet) item
    GnomeVFSFileInfo  m_info;       // cached status information

    // Internal helpers
    void                       queryChildren   ( ContentRefList& rChildren );
    ::com::sun::star::uno::Any getBadArgExcept ();
    GnomeVFSResult             getInfo         ( const ::com::sun::star::uno::Reference<
                             ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
      sal_Bool                   isFolder        ( const ::com::sun::star::uno::Reference<
                             ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
    sal_Bool                   exchangeIdentity( const ::com::sun::star::uno::Reference<
                             ::com::sun::star::ucb::XContentIdentifier >&  xNewId);
    GnomeVFSResult             doSetFileInfo   ( const GnomeVFSFileInfo                       *newInfo,
                             GnomeVFSSetFileInfoMask                       setMask,
                             const ::com::sun::star::uno::Reference<
                             ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
    ::rtl::OUString            makeNewURL      ( const char *newName );
    // End Internal helpers

    // For ucbhelper
      virtual ::rtl::OUString getParentURL();
    // For ucbhelper
    virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
    getProperties( const com::sun::star::uno::Reference<
               com::sun::star::ucb::XCommandEnvironment > & xEnv );
    // For ucbhelper
    virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
    getCommands( const com::sun::star::uno::Reference<
             com::sun::star::ucb::XCommandEnvironment > & xEnv );

public:
    // Command "getPropertyValues"
      ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
      getPropertyValues( const ::com::sun::star::uno::Sequence<
               ::com::sun::star::beans::Property >& rProperties,
               const ::com::sun::star::uno::Reference<
               ::com::sun::star::ucb::XCommandEnvironment >& xEnv );

private:
    // Command "setPropertyValues"
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
    setPropertyValues( const ::com::sun::star::uno::Sequence<
               ::com::sun::star::beans::PropertyValue >& rValues,
               const ::com::sun::star::uno::Reference<
               ::com::sun::star::ucb::XCommandEnvironment >& xEnv );

      // Command "insert"
      void insert( const ::com::sun::star::uno::Reference<
                    ::com::sun::star::io::XInputStream > & xInputStream,
                   sal_Bool bReplaceExisting,
                   const com::sun::star::uno::Reference<
                      com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw( ::com::sun::star::uno::Exception );

    // Command "transfer"
    void transfer( const ::com::sun::star::ucb::TransferInfo & rArgs,
               const com::sun::star::uno::Reference<
                      com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw( ::com::sun::star::uno::Exception );

    // Command "delete"
      void destroy( sal_Bool bDeletePhysical )
        throw( ::com::sun::star::uno::Exception );

    // "open" helpers
    void    copyData( ::com::sun::star::uno::Reference<
                ::com::sun::star::io::XInputStream > xIn,
              ::com::sun::star::uno::Reference<
                    ::com::sun::star::io::XOutputStream > xOut );

    ::com::sun::star::uno::Reference<
        ::com::sun::star::io::XInputStream >
        createTempStream(  const ::com::sun::star::uno::Reference<
                    com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw( ::com::sun::star::uno::Exception );
    ::com::sun::star::uno::Reference<
        ::com::sun::star::io::XInputStream >
        createInputStream(  const ::com::sun::star::uno::Reference<
                    com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw( ::com::sun::star::uno::Exception );
           sal_Bool feedSink( ::com::sun::star::uno::Reference<
                ::com::sun::star::uno::XInterface> aSink,
               const ::com::sun::star::uno::Reference<
                com::sun::star::ucb::XCommandEnvironment >& xEnv );

      ::com::sun::star::uno::Any mapVFSException( const GnomeVFSResult result,
                            sal_Bool bWrite );

    void cancelCommandExecution(const GnomeVFSResult result,
                    const ::com::sun::star::uno::Reference<
                    com::sun::star::ucb::XCommandEnvironment > & xEnv,
                    sal_Bool bWrite = sal_False )
        throw( ::com::sun::star::uno::Exception );

public:
    // Non-interface bits
    char         *getURI ();
    rtl::OString  getOURI ();
    rtl::OUString getOUURI ();

//=========================================================================
//          Externals
//=========================================================================
public:

      Content( const ::com::sun::star::uno::Reference<
         ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
         ContentProvider                                *pProvider,
         const ::com::sun::star::uno::Reference<
         ::com::sun::star::ucb::XContentIdentifier >&    Identifier)
            throw ( ::com::sun::star::ucb::ContentCreationException );
      Content( const ::com::sun::star::uno::Reference<
         ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
         ContentProvider                                *pProvider,
         const ::com::sun::star::uno::Reference<
         ::com::sun::star::ucb::XContentIdentifier >&    Identifier,
         sal_Bool                                        isFolder)
            throw ( ::com::sun::star::ucb::ContentCreationException );
      virtual ~Content();

      // XInterface
      XINTERFACE_DECL()

    // XTypeProvider
    XTYPEPROVIDER_DECL()

        // XServiceInfo
        virtual ::rtl::OUString SAL_CALL getImplementationName()
        throw( ::com::sun::star::uno::RuntimeException );
      virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
      getSupportedServiceNames()
        throw( ::com::sun::star::uno::RuntimeException );

      // XContent
      virtual rtl::OUString SAL_CALL
      getContentType()
        throw( com::sun::star::uno::RuntimeException );

      // XCommandProcessor
      virtual com::sun::star::uno::Any SAL_CALL
      execute( const com::sun::star::ucb::Command& aCommand,
         sal_Int32 CommandId,
         const com::sun::star::uno::Reference<
         com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw( com::sun::star::uno::Exception,
               com::sun::star::ucb::CommandAbortedException,
               com::sun::star::uno::RuntimeException );
      virtual void SAL_CALL
      abort( sal_Int32 CommandId )
        throw( com::sun::star::uno::RuntimeException );

      //////////////////////////////////////////////////////////////////////
      // Additional interfaces
      //////////////////////////////////////////////////////////////////////

      // XContentCreator
    virtual com::sun::star::uno::Sequence<
        com::sun::star::ucb::ContentInfo > SAL_CALL
      queryCreatableContentsInfo()
        throw( com::sun::star::uno::RuntimeException );
      virtual com::sun::star::uno::Reference<
          com::sun::star::ucb::XContent > SAL_CALL
      createNewContent( const com::sun::star::ucb::ContentInfo& Info )
        throw( com::sun::star::uno::RuntimeException );
};

}

extern "C" {
    extern GPrivate *auth_queue;
    extern void auth_queue_destroy( gpointer data );
}

#endif
<commit_msg>INTEGRATION: CWS bgdlremove (1.4.62); FILE MERGED 2007/05/18 11:37:16 kso 1.4.62.1: #i77419# - cleanup of ucbhelper namespaces.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: content.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: ihi $ $Date: 2007-06-05 18:03:08 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _GVFS_UCP_CONTENT_HXX
#define _GVFS_UCP_CONTENT_HXX

#include <memory>
#include <list>

#ifndef _RTL_REF_HXX_
#include <rtl/ref.hxx>
#endif

#ifndef _COM_SUN_STAR_UCB_CONTENTCREATIONEXCEPTION_HPP_
#include <com/sun/star/ucb/ContentCreationException.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTCREATOR_HPP_
#include <com/sun/star/ucb/XContentCreator.hpp>
#endif

#ifndef _UCBHELPER_CONTENTHELPER_HXX
#include <ucbhelper/contenthelper.hxx>
#endif

#include <glib/gthread.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomevfs/gnome-vfs-directory.h>

namespace com { namespace sun { namespace star { namespace beans {
    struct Property;
    struct PropertyValue;
} } } }

namespace com { namespace sun { namespace star { namespace io {
    class XInputStream;
    class XOutputStream;
} } } }

namespace com { namespace sun { namespace star { namespace sdbc {
    class XRow;
} } } }

namespace com { namespace sun { namespace star { namespace ucb {
    struct TransferInfo;
} } } }

namespace gvfs
{

class ContentProvider;
class ContentProperties;

// Random made up names - AFAICS
#define GVFS_FILE_TYPE   "application/vnd.sun.staroffice.gvfs-file"
#define GVFS_FOLDER_TYPE "application/vnd.sun.staroffice.gvfs-folder"

class Authentication
{
public:
    // Helper class to make exceptions pleasant
    Authentication( const com::sun::star::uno::Reference<
                com::sun::star::ucb::XCommandEnvironment > & xEnv );
    ~Authentication();
};

class Content : public ::ucbhelper::ContentImplHelper,
        public com::sun::star::ucb::XContentCreator
{
//=========================================================================
//          Internals
//=========================================================================
private:
    typedef rtl::Reference< Content > ContentRef;
      typedef std::list< ContentRef > ContentRefList;

    // Instance data
    ContentProvider  *m_pProvider;  // No need for a ref, base class holds object
    sal_Bool          m_bTransient; // A non-existant (as yet) item
    GnomeVFSFileInfo  m_info;       // cached status information

    // Internal helpers
    void                       queryChildren   ( ContentRefList& rChildren );
    ::com::sun::star::uno::Any getBadArgExcept ();
    GnomeVFSResult             getInfo         ( const ::com::sun::star::uno::Reference<
                             ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
      sal_Bool                   isFolder        ( const ::com::sun::star::uno::Reference<
                             ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
    sal_Bool                   exchangeIdentity( const ::com::sun::star::uno::Reference<
                             ::com::sun::star::ucb::XContentIdentifier >&  xNewId);
    GnomeVFSResult             doSetFileInfo   ( const GnomeVFSFileInfo                       *newInfo,
                             GnomeVFSSetFileInfoMask                       setMask,
                             const ::com::sun::star::uno::Reference<
                             ::com::sun::star::ucb::XCommandEnvironment >& xEnv );
    ::rtl::OUString            makeNewURL      ( const char *newName );
    // End Internal helpers

    // For ucbhelper
      virtual ::rtl::OUString getParentURL();
    // For ucbhelper
    virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
    getProperties( const com::sun::star::uno::Reference<
               com::sun::star::ucb::XCommandEnvironment > & xEnv );
    // For ucbhelper
    virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
    getCommands( const com::sun::star::uno::Reference<
             com::sun::star::ucb::XCommandEnvironment > & xEnv );

public:
    // Command "getPropertyValues"
      ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
      getPropertyValues( const ::com::sun::star::uno::Sequence<
               ::com::sun::star::beans::Property >& rProperties,
               const ::com::sun::star::uno::Reference<
               ::com::sun::star::ucb::XCommandEnvironment >& xEnv );

private:
    // Command "setPropertyValues"
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
    setPropertyValues( const ::com::sun::star::uno::Sequence<
               ::com::sun::star::beans::PropertyValue >& rValues,
               const ::com::sun::star::uno::Reference<
               ::com::sun::star::ucb::XCommandEnvironment >& xEnv );

      // Command "insert"
      void insert( const ::com::sun::star::uno::Reference<
                    ::com::sun::star::io::XInputStream > & xInputStream,
                   sal_Bool bReplaceExisting,
                   const com::sun::star::uno::Reference<
                      com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw( ::com::sun::star::uno::Exception );

    // Command "transfer"
    void transfer( const ::com::sun::star::ucb::TransferInfo & rArgs,
               const com::sun::star::uno::Reference<
                      com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw( ::com::sun::star::uno::Exception );

    // Command "delete"
      void destroy( sal_Bool bDeletePhysical )
        throw( ::com::sun::star::uno::Exception );

    // "open" helpers
    void    copyData( ::com::sun::star::uno::Reference<
                ::com::sun::star::io::XInputStream > xIn,
              ::com::sun::star::uno::Reference<
                    ::com::sun::star::io::XOutputStream > xOut );

    ::com::sun::star::uno::Reference<
        ::com::sun::star::io::XInputStream >
        createTempStream(  const ::com::sun::star::uno::Reference<
                    com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw( ::com::sun::star::uno::Exception );
    ::com::sun::star::uno::Reference<
        ::com::sun::star::io::XInputStream >
        createInputStream(  const ::com::sun::star::uno::Reference<
                    com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw( ::com::sun::star::uno::Exception );
           sal_Bool feedSink( ::com::sun::star::uno::Reference<
                ::com::sun::star::uno::XInterface> aSink,
               const ::com::sun::star::uno::Reference<
                com::sun::star::ucb::XCommandEnvironment >& xEnv );

      ::com::sun::star::uno::Any mapVFSException( const GnomeVFSResult result,
                            sal_Bool bWrite );

    void cancelCommandExecution(const GnomeVFSResult result,
                    const ::com::sun::star::uno::Reference<
                    com::sun::star::ucb::XCommandEnvironment > & xEnv,
                    sal_Bool bWrite = sal_False )
        throw( ::com::sun::star::uno::Exception );

public:
    // Non-interface bits
    char         *getURI ();
    rtl::OString  getOURI ();
    rtl::OUString getOUURI ();

//=========================================================================
//          Externals
//=========================================================================
public:

      Content( const ::com::sun::star::uno::Reference<
         ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
         ContentProvider                                *pProvider,
         const ::com::sun::star::uno::Reference<
         ::com::sun::star::ucb::XContentIdentifier >&    Identifier)
            throw ( ::com::sun::star::ucb::ContentCreationException );
      Content( const ::com::sun::star::uno::Reference<
         ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
         ContentProvider                                *pProvider,
         const ::com::sun::star::uno::Reference<
         ::com::sun::star::ucb::XContentIdentifier >&    Identifier,
         sal_Bool                                        isFolder)
            throw ( ::com::sun::star::ucb::ContentCreationException );
      virtual ~Content();

      // XInterface
      XINTERFACE_DECL()

    // XTypeProvider
    XTYPEPROVIDER_DECL()

        // XServiceInfo
        virtual ::rtl::OUString SAL_CALL getImplementationName()
        throw( ::com::sun::star::uno::RuntimeException );
      virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
      getSupportedServiceNames()
        throw( ::com::sun::star::uno::RuntimeException );

      // XContent
      virtual rtl::OUString SAL_CALL
      getContentType()
        throw( com::sun::star::uno::RuntimeException );

      // XCommandProcessor
      virtual com::sun::star::uno::Any SAL_CALL
      execute( const com::sun::star::ucb::Command& aCommand,
         sal_Int32 CommandId,
         const com::sun::star::uno::Reference<
         com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw( com::sun::star::uno::Exception,
               com::sun::star::ucb::CommandAbortedException,
               com::sun::star::uno::RuntimeException );
      virtual void SAL_CALL
      abort( sal_Int32 CommandId )
        throw( com::sun::star::uno::RuntimeException );

      //////////////////////////////////////////////////////////////////////
      // Additional interfaces
      //////////////////////////////////////////////////////////////////////

      // XContentCreator
    virtual com::sun::star::uno::Sequence<
        com::sun::star::ucb::ContentInfo > SAL_CALL
      queryCreatableContentsInfo()
        throw( com::sun::star::uno::RuntimeException );
      virtual com::sun::star::uno::Reference<
          com::sun::star::ucb::XContent > SAL_CALL
      createNewContent( const com::sun::star::ucb::ContentInfo& Info )
        throw( com::sun::star::uno::RuntimeException );
};

}

extern "C" {
    extern GPrivate *auth_queue;
    extern void auth_queue_destroy( gpointer data );
}

#endif
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/util.h"
namespace {

#if CONFIG_VP8_ENCODER

// lookahead range: [kLookAheadMin, kLookAheadMax).
const int kLookAheadMin = 5;
const int kLookAheadMax = 26;

class AltRefTest : public ::libvpx_test::EncoderTest,
    public ::libvpx_test::CodecTestWithParam<int> {
 protected:
  AltRefTest() : EncoderTest(GET_PARAM(0)), altref_count_(0) {}
  virtual ~AltRefTest() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(libvpx_test::kTwoPassGood);
  }

  virtual void BeginPassHook(unsigned int pass) {
    altref_count_ = 0;
  }

  virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
                                  libvpx_test::Encoder *encoder) {
    if (video->frame() == 1) {
      encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
      encoder->Control(VP8E_SET_CPUUSED, 3);
    }
  }

  virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
    if (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) ++altref_count_;
  }

  int altref_count() const { return altref_count_; }

 private:
  int altref_count_;
};

TEST_P(AltRefTest, MonotonicTimestamps) {
  const vpx_rational timebase = { 33333333, 1000000000 };
  cfg_.g_timebase = timebase;
  cfg_.rc_target_bitrate = 1000;
  cfg_.g_lag_in_frames = GET_PARAM(1);

  libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
                                     timebase.den, timebase.num, 0, 30);
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  EXPECT_GE(altref_count(), 1);
}

VP8_INSTANTIATE_TEST_CASE(AltRefTest,
                          ::testing::Range(kLookAheadMin, kLookAheadMax));

#endif  // CONFIG_VP8_ENCODER

class AltRefForcedKeyTest
    : public ::libvpx_test::EncoderTest,
      public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
 protected:
  AltRefForcedKeyTest()
      : EncoderTest(GET_PARAM(0)),
        encoding_mode_(GET_PARAM(1)),
        cpu_used_(GET_PARAM(2)),
        forced_kf_frame_num_(1),
        frame_num_(0) {}
  virtual ~AltRefForcedKeyTest() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(encoding_mode_);
    cfg_.rc_end_usage = VPX_VBR;
    cfg_.g_threads = 0;
  }

  virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
                                  ::libvpx_test::Encoder *encoder) {
    if (video->frame() == 0) {
      encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
      encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
      // override test default for tile columns if necessary.
#if CONFIG_VP9_ENCODER
      if (GET_PARAM(0) == &libvpx_test::kVP9) {
        encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
      }
#endif
#if CONFIG_VP10_ENCODER
      if (GET_PARAM(0) == &libvpx_test::kVP10) {
        encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
      }
#endif
    }
    frame_flags_ =
        (video->frame() == forced_kf_frame_num_) ? VPX_EFLAG_FORCE_KF : 0;
  }

  virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
    if (frame_num_ == forced_kf_frame_num_) {
      ASSERT_TRUE(!!(pkt->data.frame.flags & VPX_FRAME_IS_KEY))
          << "Frame #" << frame_num_ << " isn't a keyframe!";
    }
    ++frame_num_;
  }

  ::libvpx_test::TestMode encoding_mode_;
  int cpu_used_;
  unsigned int forced_kf_frame_num_;
  unsigned int frame_num_;
};

TEST_P(AltRefForcedKeyTest, Frame1IsKey) {
  const vpx_rational timebase = { 1, 30 };
  const int lag_values[] = { 3, 15, 25, -1 };

  forced_kf_frame_num_ = 1;
  for (int i = 0; lag_values[i] != -1; ++i) {
    frame_num_ = 0;
    cfg_.g_lag_in_frames = lag_values[i];
    libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
                                       timebase.den, timebase.num, 0, 30);
    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }
}

TEST_P(AltRefForcedKeyTest, ForcedFrameIsKey) {
  const vpx_rational timebase = { 1, 30 };
  const int lag_values[] = { 3, 15, 25, -1 };

  for (int i = 0; lag_values[i] != -1; ++i) {
    frame_num_ = 0;
    forced_kf_frame_num_ = lag_values[i] - 1;
    cfg_.g_lag_in_frames = lag_values[i];
    libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
                                       timebase.den, timebase.num, 0, 30);
    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }
}

VP8_INSTANTIATE_TEST_CASE(
    AltRefForcedKeyTest,
    ::testing::Values(::libvpx_test::kOnePassGood),
    ::testing::Range(0, 9));

VP9_INSTANTIATE_TEST_CASE(
    AltRefForcedKeyTest,
    ::testing::Values(::libvpx_test::kOnePassGood),
    ::testing::Range(0, 9));

VP10_INSTANTIATE_TEST_CASE(
    AltRefForcedKeyTest,
    ::testing::Values(::libvpx_test::kOnePassGood),
    ::testing::Range(0, 9));

}  // namespace
<commit_msg>altref_test: mark AltRefForcedKeyTest as large<commit_after>/*
 *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/util.h"
namespace {

#if CONFIG_VP8_ENCODER

// lookahead range: [kLookAheadMin, kLookAheadMax).
const int kLookAheadMin = 5;
const int kLookAheadMax = 26;

class AltRefTest : public ::libvpx_test::EncoderTest,
    public ::libvpx_test::CodecTestWithParam<int> {
 protected:
  AltRefTest() : EncoderTest(GET_PARAM(0)), altref_count_(0) {}
  virtual ~AltRefTest() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(libvpx_test::kTwoPassGood);
  }

  virtual void BeginPassHook(unsigned int pass) {
    altref_count_ = 0;
  }

  virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
                                  libvpx_test::Encoder *encoder) {
    if (video->frame() == 1) {
      encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
      encoder->Control(VP8E_SET_CPUUSED, 3);
    }
  }

  virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
    if (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) ++altref_count_;
  }

  int altref_count() const { return altref_count_; }

 private:
  int altref_count_;
};

TEST_P(AltRefTest, MonotonicTimestamps) {
  const vpx_rational timebase = { 33333333, 1000000000 };
  cfg_.g_timebase = timebase;
  cfg_.rc_target_bitrate = 1000;
  cfg_.g_lag_in_frames = GET_PARAM(1);

  libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
                                     timebase.den, timebase.num, 0, 30);
  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  EXPECT_GE(altref_count(), 1);
}

VP8_INSTANTIATE_TEST_CASE(AltRefTest,
                          ::testing::Range(kLookAheadMin, kLookAheadMax));

#endif  // CONFIG_VP8_ENCODER

class AltRefForcedKeyTestLarge
    : public ::libvpx_test::EncoderTest,
      public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
 protected:
  AltRefForcedKeyTestLarge()
      : EncoderTest(GET_PARAM(0)),
        encoding_mode_(GET_PARAM(1)),
        cpu_used_(GET_PARAM(2)),
        forced_kf_frame_num_(1),
        frame_num_(0) {}
  virtual ~AltRefForcedKeyTestLarge() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(encoding_mode_);
    cfg_.rc_end_usage = VPX_VBR;
    cfg_.g_threads = 0;
  }

  virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
                                  ::libvpx_test::Encoder *encoder) {
    if (video->frame() == 0) {
      encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
      encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
      // override test default for tile columns if necessary.
#if CONFIG_VP9_ENCODER
      if (GET_PARAM(0) == &libvpx_test::kVP9) {
        encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
      }
#endif
#if CONFIG_VP10_ENCODER
      if (GET_PARAM(0) == &libvpx_test::kVP10) {
        encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
      }
#endif
    }
    frame_flags_ =
        (video->frame() == forced_kf_frame_num_) ? VPX_EFLAG_FORCE_KF : 0;
  }

  virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
    if (frame_num_ == forced_kf_frame_num_) {
      ASSERT_TRUE(!!(pkt->data.frame.flags & VPX_FRAME_IS_KEY))
          << "Frame #" << frame_num_ << " isn't a keyframe!";
    }
    ++frame_num_;
  }

  ::libvpx_test::TestMode encoding_mode_;
  int cpu_used_;
  unsigned int forced_kf_frame_num_;
  unsigned int frame_num_;
};

TEST_P(AltRefForcedKeyTestLarge, Frame1IsKey) {
  const vpx_rational timebase = { 1, 30 };
  const int lag_values[] = { 3, 15, 25, -1 };

  forced_kf_frame_num_ = 1;
  for (int i = 0; lag_values[i] != -1; ++i) {
    frame_num_ = 0;
    cfg_.g_lag_in_frames = lag_values[i];
    libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
                                       timebase.den, timebase.num, 0, 30);
    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }
}

TEST_P(AltRefForcedKeyTestLarge, ForcedFrameIsKey) {
  const vpx_rational timebase = { 1, 30 };
  const int lag_values[] = { 3, 15, 25, -1 };

  for (int i = 0; lag_values[i] != -1; ++i) {
    frame_num_ = 0;
    forced_kf_frame_num_ = lag_values[i] - 1;
    cfg_.g_lag_in_frames = lag_values[i];
    libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
                                       timebase.den, timebase.num, 0, 30);
    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }
}

VP8_INSTANTIATE_TEST_CASE(
    AltRefForcedKeyTestLarge,
    ::testing::Values(::libvpx_test::kOnePassGood),
    ::testing::Range(0, 9));

VP9_INSTANTIATE_TEST_CASE(
    AltRefForcedKeyTestLarge,
    ::testing::Values(::libvpx_test::kOnePassGood),
    ::testing::Range(0, 9));

VP10_INSTANTIATE_TEST_CASE(
    AltRefForcedKeyTestLarge,
    ::testing::Values(::libvpx_test::kOnePassGood),
    ::testing::Range(0, 9));

}  // namespace
<|endoftext|>


<commit_before>/*
    Copyright (C) 2009-2011 qiuu
    Copyright (C) 2016 Clownacy

    This library 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.

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

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

#include <cstdio>
#include <cstdint>
#include <SDL2/SDL.h>

#include "Screen.h"
#ifdef _WIN32
#include "WinAPI.h"
#endif

#ifdef _WIN32
#define WINDOW_HEIGHT SCREEN_HEIGHT+20	// Windows menu bar adds 20 pixels
#else
#define WINDOW_HEIGHT SCREEN_HEIGHT
#endif

Screen::Screen(void)
{
	if (SDL_Init(SDL_INIT_VIDEO)<0)
		this->ShowInternalError("Unable to init SDL video\n\n", SDL_GetError());

	atexit(SDL_Quit);

	this->window = SDL_CreateWindow("Captain PlaneEd v1.0.1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
	if (this->window == NULL)
		this->ShowInternalError("Unable to init SDL Window\n\n", SDL_GetError());

	this->renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_ACCELERATED);
	if (this->renderer == NULL)
		this->ShowInternalError("Unable to init SDL Renderer\n\n", SDL_GetError());

	SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);

	this->surface = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0, 0, 0, 0);	// Implicitly ARGB8888, compatible with the below texture
	if (this->surface==NULL)
		this->ShowInternalError("Unable to init screen SDL Surface\n\n", SDL_GetError());

	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
	this->base_texture = SDL_CreateTexture(this->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT);
	if (this->base_texture==NULL)
		this->ShowInternalError("Unable to init screen SDL Texture\n\n", SDL_GetError());

	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
	this->final_texture = SDL_CreateTexture(this->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH*3, SCREEN_HEIGHT*3);
	if (this->final_texture==NULL)
		this->ShowInternalError("Unable to init screen SDL Texture\n\n", SDL_GetError());

	this->background_colour = {.r = 0, .g = 0, .b = 0};

#ifdef _WIN32
	// Windows-only crap to generate a menu bar
	WinAPI::SaveHWND(this->window);
	WinAPI::CreateMenuBar();
#endif
}

void Screen::ProcessDisplay(void)
{
	void* pixels;
	int pitch;
	SDL_LockTexture(this->base_texture, NULL, &pixels, &pitch);
	memcpy(pixels, this->surface->pixels, pitch*this->surface->h);
	SDL_UnlockTexture(this->base_texture);

	// SDL2's 'linear' filter is ugly with pixel art, and the
	// 'nearest' one gets pretty bad with non-integer scaling.
	// Instead, we're going to emulate a type of upscale that
	// preserves the quality of the image, while smoothing pixels
	// that 'bleed'.
	SDL_SetRenderTarget(this->renderer, this->final_texture);		// Render to texture...
	SDL_RenderCopy(this->renderer, this->base_texture, NULL, NULL);		// ...and upscale using 'nearest'
	SDL_SetRenderTarget(this->renderer, NULL);				// Render to screen...
	SDL_RenderCopy(this->renderer, this->final_texture, NULL, NULL);	// ...and upscale/downscale using 'linear'
	SDL_RenderPresent(this->renderer);
}

void Screen::Clear(void)
{
	SDL_FillRect(this->surface, NULL, SDL_MapRGB(this->surface->format, this->background_colour.r, this->background_colour.g, this->background_colour.b));
}

void Screen::ShowInformation(const char* const message)
{
	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Information", message, this->window);
}

void Screen::ShowInformation(const char* const message_part1, const char* const message_part2)
{
	char* const whole_message = new char[strlen(message_part1)+strlen(message_part2)+1];
	sprintf(whole_message, "%s%s", message_part1, message_part2);
	this->ShowInformation(whole_message);
	delete[] whole_message;
}

void Screen::ShowWarning(const char* const message)
{
	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Warning", message, this->window);
}

void Screen::ShowError(const char* const message)
{
	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", message, this->window);
	exit(1);
}

void Screen::ShowInternalError(const char* const message)
{
	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Internal Error", message, this->window);
	exit(1);
}

void Screen::ShowInternalError(const char* const message_part1, const char* const message_part2)
{
	char* const whole_message = new char[strlen(message_part1)+strlen(message_part2)+1];
	sprintf(whole_message, "%s%s", message_part1, message_part2);
	this->ShowInternalError(whole_message);
	delete[] whole_message;
}

<commit_msg>Made upscale factor a constant<commit_after>/*
    Copyright (C) 2009-2011 qiuu
    Copyright (C) 2016 Clownacy

    This library 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.

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

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

#include <cstdio>
#include <cstdint>
#include <SDL2/SDL.h>

#include "Screen.h"
#ifdef _WIN32
#include "WinAPI.h"
#endif

#ifdef _WIN32
#define WINDOW_HEIGHT SCREEN_HEIGHT+20	// Windows menu bar adds 20 pixels
#else
#define WINDOW_HEIGHT SCREEN_HEIGHT
#endif

#define INTERNAL_UPSCALE_FACTOR 3

Screen::Screen(void)
{
	if (SDL_Init(SDL_INIT_VIDEO)<0)
		this->ShowInternalError("Unable to init SDL video\n\n", SDL_GetError());

	atexit(SDL_Quit);

	this->window = SDL_CreateWindow("Captain PlaneEd v1.0.1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
	if (this->window == NULL)
		this->ShowInternalError("Unable to init SDL Window\n\n", SDL_GetError());

	this->renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_ACCELERATED);
	if (this->renderer == NULL)
		this->ShowInternalError("Unable to init SDL Renderer\n\n", SDL_GetError());

	SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);

	this->surface = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0, 0, 0, 0);	// Implicitly ARGB8888, compatible with the below texture
	if (this->surface==NULL)
		this->ShowInternalError("Unable to init screen SDL Surface\n\n", SDL_GetError());

	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
	this->base_texture = SDL_CreateTexture(this->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT);
	if (this->base_texture==NULL)
		this->ShowInternalError("Unable to init screen SDL Texture\n\n", SDL_GetError());

	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
	this->final_texture = SDL_CreateTexture(this->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH*INTERNAL_UPSCALE_FACTOR, SCREEN_HEIGHT*INTERNAL_UPSCALE_FACTOR);
	if (this->final_texture==NULL)
		this->ShowInternalError("Unable to init screen SDL Texture\n\n", SDL_GetError());

	this->background_colour = {.r = 0, .g = 0, .b = 0};

#ifdef _WIN32
	// Windows-only crap to generate a menu bar
	WinAPI::SaveHWND(this->window);
	WinAPI::CreateMenuBar();
#endif
}

void Screen::ProcessDisplay(void)
{
	void* pixels;
	int pitch;
	SDL_LockTexture(this->base_texture, NULL, &pixels, &pitch);
	memcpy(pixels, this->surface->pixels, pitch*this->surface->h);
	SDL_UnlockTexture(this->base_texture);

	// SDL2's 'linear' filter is ugly with pixel art, and the
	// 'nearest' one gets pretty bad with non-integer scaling.
	// Instead, we're going to emulate a type of upscale that
	// preserves the quality of the image, while smoothing pixels
	// that 'bleed'.
	SDL_SetRenderTarget(this->renderer, this->final_texture);		// Render to texture...
	SDL_RenderCopy(this->renderer, this->base_texture, NULL, NULL);		// ...and upscale using 'nearest'
	SDL_SetRenderTarget(this->renderer, NULL);				// Render to screen...
	SDL_RenderCopy(this->renderer, this->final_texture, NULL, NULL);	// ...and upscale/downscale using 'linear'
	SDL_RenderPresent(this->renderer);
}

void Screen::Clear(void)
{
	SDL_FillRect(this->surface, NULL, SDL_MapRGB(this->surface->format, this->background_colour.r, this->background_colour.g, this->background_colour.b));
}

void Screen::ShowInformation(const char* const message)
{
	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Information", message, this->window);
}

void Screen::ShowInformation(const char* const message_part1, const char* const message_part2)
{
	char* const whole_message = new char[strlen(message_part1)+strlen(message_part2)+1];
	sprintf(whole_message, "%s%s", message_part1, message_part2);
	this->ShowInformation(whole_message);
	delete[] whole_message;
}

void Screen::ShowWarning(const char* const message)
{
	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Warning", message, this->window);
}

void Screen::ShowError(const char* const message)
{
	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", message, this->window);
	exit(1);
}

void Screen::ShowInternalError(const char* const message)
{
	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Internal Error", message, this->window);
	exit(1);
}

void Screen::ShowInternalError(const char* const message_part1, const char* const message_part2)
{
	char* const whole_message = new char[strlen(message_part1)+strlen(message_part2)+1];
	sprintf(whole_message, "%s%s", message_part1, message_part2);
	this->ShowInternalError(whole_message);
	delete[] whole_message;
}

<|endoftext|>


<commit_before>/*
 *  Copyright 2012 Anders Wallin (anders.e.e.wallin "at" gmail.com)
 *
 *  This file is part of OpenVoronoi.
 *
 *  OpenVoronoi 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.
 *
 *  OpenVoronoi 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 OpenVoronoi.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <string>
#include <iostream>

#include <boost/python.hpp>

#include "graph.hpp"
#include "site.hpp"

namespace ovd
{

// (approximate) medial-axis filter
// marks the valid-property true for edges belonging to the medial axis
// and false for other edges.
struct medial_filter {
    medial_filter(HEGraph& gi, double thr=0.8) : g(gi) , _dot_product_threshold(thr) { }
    bool operator()(const HEEdge& e) const {
        if (g[e].type == LINESITE || g[e].type == NULLEDGE)
            return true; // we keep linesites and nulledges
        if (g[e].type == SEPARATOR)
            return false; // separators are allways removed

        if (both_endpoints_positive(e)) // these are interior edges which we keep.
            return true;

        // this leaves us with edges where one end connects to the polygon (dist==0)
        // and the other end does not.
        // figure out the angle between the adjacent line-segments and decide based on the angle.
        if (segments_parallel(e))
            return false;

        return true; // otherwise we keep the edge
    }
    // return true if this is an internal edge, i.e. both endpoints have a nonzero clearance-disk radius
    bool both_endpoints_positive(HEEdge e) const {
        HEVertex src = g.source(e);
        HEVertex trg = g.target(e);
        return (g[src].dist()>0) && (g[trg].dist()>0);
    }
    // return true if the segments that connect to the given Edge are nearly parallel
    bool segments_parallel( HEEdge e ) const {
        HEVertex endp1 = find_endpoint(e);
        HEVertex endp2 = find_endpoint( g[e].twin );
        // find the segments
        HEEdge e1 = find_segment(endp1);
        HEEdge e2 = find_segment(endp2);
        e2 = g[e2].twin; // this makes the edges oriented in the same direction
        double dotprod = edge_dotprod(e1,e2);
        return fabs(dotprod)>_dot_product_threshold;
    }

    // calculate the dot-product between unit vectors aligned along edges e1->e2
    // since e1 and e2 are both line-sites the direction is easy to find
    // FIXME: more code needed here for tangent calculation if we have arc-sites
    double edge_dotprod(HEEdge e1, HEEdge e2) const {
        HEVertex src1 = g.source(e1);
        HEVertex trg1 = g.target(e1);
        HEVertex src2 = g.source(e2);
        HEVertex trg2 = g.target(e2);
        Point sp1 = g[src1].position;
        Point tp1 = g[trg1].position;
        Point sp2 = g[src2].position;
        Point tp2 = g[trg2].position;

        Point dir1 = tp1-sp1;
        Point dir2 = tp2-sp2;
        dir1.normalize();
        dir2.normalize();
        return dir1.dot(dir2);
    }

    // find the linesite edge that connects to v.
    HEEdge find_segment(HEVertex v) const {
        BOOST_FOREACH(HEEdge e, g.out_edges(v)) {
            if ( g[e].type == LINESITE )
                return e;
        }
        assert(0);
        exit(-1);
        return HEEdge();
    }

    // find an ENDPOINT vertex that connects to Edge e through a NULLEDGE at either the source or target of e.
    HEVertex find_endpoint(HEEdge e) const {
        HEEdge next = g[e].next;
        HEEdge prev = g.previous_edge(e);
        HEVertex endp;
        if ( g[next].type == NULLEDGE ) {
            endp = g.target(next);
            assert( g[endp].type == ENDPOINT );

        } else if ( g[prev].type == NULLEDGE ) {
            endp = g.source(prev);
            assert( g[endp].type == ENDPOINT );
        } else {
            assert(0);
            exit(-1);
        }
        return endp;
    }

private:
    HEGraph& g;
    double _dot_product_threshold;
};

/// \brief From a voronoi-diagram, generate offset curve(s).
class MedialAxis {
public:
    MedialAxis(HEGraph& gi): g(gi) {
        medial_filter f(g);
        medial_filter flt(g);
        g.filter_graph(flt);
    }
private:
    MedialAxis(); // don't use.
    HEGraph& g; // original graph
};

// when we want a toolpath along the medial axis we use this class
// walk along the "valid" edges which are left in the diagram
// first find one valid edge that has a degree-1 vertex (i.e. a suitable start point for the path)
// -- if there's only one choice for the next edge, go there
// -- if there are two choices, take one of the choices
// when done, find another valid start-edge
// FIXME: this could probably be optimized to minimize rapid-traverses
class MedialAxisWalk {
public:
    MedialAxisWalk(HEGraph& gi): g(gi) {}

    boost::python::list walk() {
        out = boost::python::list();
        HEEdge start;
        while( find_start_edge(start) ) { // find a suitable start-edge
            medial_axis_walk(start); // from the start-edge, walk as far as possible
        }
        return out;
    }

    // start at source of Edge start, and walk as far as possible
    void medial_axis_walk(HEEdge start) {
        // begin chain with start.
        HEEdge next = start; // why does = HEEdge() cause Wuninitialized ?
        boost::python::list chain;
        append_edge(chain, start);
        set_invalid(start);
        while (next_edge(start, next)  ) {
            assert( g.target( start ) == g.source( next ) );
            append_edge(chain, next);
            start=next;
            set_invalid(start);
        }
        // end chain
        out.append( chain );
    }

    // add the given edge to the current list of edges.
    // for line-edges we add only two endpoints
    // for parabolic edges we add many points
    void append_edge(boost::python::list& list, HEEdge edge)  {
        boost::python::list point_list; // the endpoints of each edge
        HEVertex v1 = g.source( edge );
        HEVertex v2 = g.target( edge );
        // these edge-types are drawn as a single line from source to target.
        if (  (g[edge].type == LINE) || (g[edge].type == LINELINE)  || (g[edge].type == PARA_LINELINE)) {
            boost::python::list pt1;
            pt1.append( g[v1].position ); pt1.append( g[v1].dist() );
            point_list.append(pt1);
            boost::python::list pt2;
            pt2.append( g[v2].position ); pt2.append( g[v2].dist() );
            point_list.append(pt2);
        } else if ( g[edge].type == PARABOLA ) { // these edge-types are drawn as polylines with edge_points number of points
            double t_src = g[v1].dist();
            double t_trg = g[v2].dist();
            double t_min = std::min(t_src,t_trg);
            double t_max = std::max(t_src,t_trg);
            int _edge_points= 20; // number of points to subdivide parabolas. FIXME: make this adjustable

            for (int n=0;n< _edge_points;n++) {
                double t;
                if (t_src<=t_trg) // increasing t-value
                    t = t_min + ((t_max-t_min)/sq(_edge_points-1))*sq(n); // NOTE: quadratic t-dependece. More points at smaller t.
                else if (t_trg<t_src) { // decreasing t-value
                    int m = _edge_points-1-n; // m goes from (N-1)...0   as n goes from 0...(N-1)
                    t = t_min + ((t_max-t_min)/sq(_edge_points-1))*sq(m);
                }
                Point p = g[edge].point(t);
                boost::python::list pt;
                pt.append( p ); pt.append( t );
                point_list.append(pt);
            }
        }
        list.append( point_list );
    }
    // we are at target(e). find the next suitable edge.
    // return true if a next-edge was found, false otherwise.
    bool next_edge(HEEdge e, HEEdge& next) {
        HEVertex trg = g.target(e);
        EdgeVector out_edges = g.out_edges(trg);
        std::vector<HEEdge> valid_edges;
        BOOST_FOREACH( HEEdge oe, out_edges) {
            if ( valid_next_edge(oe) ) {
                valid_edges.push_back(oe);
            }
        }
        if (!valid_edges.empty() ) {
            next = valid_edges[0]; // return the first valid one
            return true;
        }
        return false;
    }

    void set_invalid(HEEdge e) {
        g[e].valid = false;
        g[ g[e].twin ].valid = false;
    }
    // loop through all edges and find an edge where we can start
    // valid edges have a source-vertex with exactly one valid out-edge.
    bool find_start_edge(HEEdge& start) {
        BOOST_FOREACH(HEEdge e, g.edges() ) {
            if ( valid_next_edge(e) ) {
                if (degree_one_source(e)) {
                    start = e;
                    return true;
                }
            }
        }
        return false;
    }
    // we can follow an edge if it is valid, and not a LINESITE or NULLEDGE
    bool valid_next_edge(HEEdge e) {
        return ( (g[e].type != LINESITE) && (g[e].type !=NULLEDGE) && (g[e].valid) );
    }
    // check if the source of the edge is a valid starting-point for a path
    bool degree_one_source(HEEdge e) {
        HEVertex src = g.source(e);
        EdgeVector out_edges = g.out_edges(src);
        int count(0);
        BOOST_FOREACH( HEEdge oe, out_edges) {
            if ( valid_next_edge(oe) ) {
                count++;
            }
        }
        return (count==1);
    }
private:
    boost::python::list out;
    MedialAxisWalk(); // don't use.
    HEGraph& g; // original graph

};

} // end namespace

// end file medial_axis.hpp
<commit_msg>LINE edges should be output as many points!<commit_after>/*
 *  Copyright 2012 Anders Wallin (anders.e.e.wallin "at" gmail.com)
 *
 *  This file is part of OpenVoronoi.
 *
 *  OpenVoronoi 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.
 *
 *  OpenVoronoi 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 OpenVoronoi.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <string>
#include <iostream>

#include <boost/python.hpp>

#include "graph.hpp"
#include "site.hpp"

namespace ovd
{

// (approximate) medial-axis filter
// marks the valid-property true for edges belonging to the medial axis
// and false for other edges.
struct medial_filter {
    medial_filter(HEGraph& gi, double thr=0.8) : g(gi) , _dot_product_threshold(thr) { }
    bool operator()(const HEEdge& e) const {
        if (g[e].type == LINESITE || g[e].type == NULLEDGE)
            return true; // we keep linesites and nulledges
        if (g[e].type == SEPARATOR)
            return false; // separators are allways removed

        if (both_endpoints_positive(e)) // these are interior edges which we keep.
            return true;

        // this leaves us with edges where one end connects to the polygon (dist==0)
        // and the other end does not.
        // figure out the angle between the adjacent line-segments and decide based on the angle.
        if (segments_parallel(e))
            return false;

        return true; // otherwise we keep the edge
    }
    // return true if this is an internal edge, i.e. both endpoints have a nonzero clearance-disk radius
    bool both_endpoints_positive(HEEdge e) const {
        HEVertex src = g.source(e);
        HEVertex trg = g.target(e);
        return (g[src].dist()>0) && (g[trg].dist()>0);
    }
    // return true if the segments that connect to the given Edge are nearly parallel
    bool segments_parallel( HEEdge e ) const {
        HEVertex endp1 = find_endpoint(e);
        HEVertex endp2 = find_endpoint( g[e].twin );
        // find the segments
        HEEdge e1 = find_segment(endp1);
        HEEdge e2 = find_segment(endp2);
        e2 = g[e2].twin; // this makes the edges oriented in the same direction
        double dotprod = edge_dotprod(e1,e2);
        return fabs(dotprod)>_dot_product_threshold;
    }

    // calculate the dot-product between unit vectors aligned along edges e1->e2
    // since e1 and e2 are both line-sites the direction is easy to find
    // FIXME: more code needed here for tangent calculation if we have arc-sites
    double edge_dotprod(HEEdge e1, HEEdge e2) const {
        HEVertex src1 = g.source(e1);
        HEVertex trg1 = g.target(e1);
        HEVertex src2 = g.source(e2);
        HEVertex trg2 = g.target(e2);
        Point sp1 = g[src1].position;
        Point tp1 = g[trg1].position;
        Point sp2 = g[src2].position;
        Point tp2 = g[trg2].position;

        Point dir1 = tp1-sp1;
        Point dir2 = tp2-sp2;
        dir1.normalize();
        dir2.normalize();
        return dir1.dot(dir2);
    }

    // find the linesite edge that connects to v.
    HEEdge find_segment(HEVertex v) const {
        BOOST_FOREACH(HEEdge e, g.out_edges(v)) {
            if ( g[e].type == LINESITE )
                return e;
        }
        assert(0);
        exit(-1);
        return HEEdge();
    }

    // find an ENDPOINT vertex that connects to Edge e through a NULLEDGE at either the source or target of e.
    HEVertex find_endpoint(HEEdge e) const {
        HEEdge next = g[e].next;
        HEEdge prev = g.previous_edge(e);
        HEVertex endp;
        if ( g[next].type == NULLEDGE ) {
            endp = g.target(next);
            assert( g[endp].type == ENDPOINT );

        } else if ( g[prev].type == NULLEDGE ) {
            endp = g.source(prev);
            assert( g[endp].type == ENDPOINT );
        } else {
            assert(0);
            exit(-1);
        }
        return endp;
    }

private:
    HEGraph& g;
    double _dot_product_threshold;
};

/// \brief From a voronoi-diagram, generate offset curve(s).
class MedialAxis {
public:
    MedialAxis(HEGraph& gi): g(gi) {
        medial_filter f(g);
        medial_filter flt(g);
        g.filter_graph(flt);
    }
private:
    MedialAxis(); // don't use.
    HEGraph& g; // original graph
};

// when we want a toolpath along the medial axis we use this class
// walk along the "valid" edges which are left in the diagram
// first find one valid edge that has a degree-1 vertex (i.e. a suitable start point for the path)
// -- if there's only one choice for the next edge, go there
// -- if there are two choices, take one of the choices
// when done, find another valid start-edge
// FIXME: this could probably be optimized to minimize rapid-traverses
class MedialAxisWalk {
public:
    MedialAxisWalk(HEGraph& gi): g(gi) {}

    boost::python::list walk() {
        out = boost::python::list();
        HEEdge start;
        while( find_start_edge(start) ) { // find a suitable start-edge
            medial_axis_walk(start); // from the start-edge, walk as far as possible
        }
        return out;
    }

    // start at source of Edge start, and walk as far as possible
    void medial_axis_walk(HEEdge start) {
        // begin chain with start.
        HEEdge next = start; // why does = HEEdge() cause Wuninitialized ?
        boost::python::list chain;
        append_edge(chain, start);
        set_invalid(start);
        while (next_edge(start, next)  ) {
            assert( g.target( start ) == g.source( next ) );
            append_edge(chain, next);
            start=next;
            set_invalid(start);
        }
        // end chain
        out.append( chain );
    }

    // add the given edge to the current list of edges.
    // for line-edges we add only two endpoints
    // for parabolic edges we add many points
    void append_edge(boost::python::list& list, HEEdge edge)  {
        boost::python::list point_list; // the endpoints of each edge
        HEVertex v1 = g.source( edge );
        HEVertex v2 = g.target( edge );
        // these edge-types are drawn as a single line from source to target.
        if (   (g[edge].type == LINELINE)  || (g[edge].type == PARA_LINELINE)) {
            boost::python::list pt1;
            pt1.append( g[v1].position ); pt1.append( g[v1].dist() );
            point_list.append(pt1);
            boost::python::list pt2;
            pt2.append( g[v2].position ); pt2.append( g[v2].dist() );
            point_list.append(pt2);
        } else if ( (g[edge].type == PARABOLA) || (g[edge].type == LINE) ) { // these edge-types are drawn as polylines with edge_points number of points
            double t_src = g[v1].dist();
            double t_trg = g[v2].dist();
            double t_min = std::min(t_src,t_trg);
            double t_max = std::max(t_src,t_trg);
            int _edge_points= 20; // number of points to subdivide parabolas. FIXME: make this adjustable

            for (int n=0;n< _edge_points;n++) {
                double t;
                if (t_src<=t_trg) // increasing t-value
                    t = t_min + ((t_max-t_min)/sq(_edge_points-1))*sq(n); // NOTE: quadratic t-dependece. More points at smaller t.
                else if (t_trg<t_src) { // decreasing t-value
                    int m = _edge_points-1-n; // m goes from (N-1)...0   as n goes from 0...(N-1)
                    t = t_min + ((t_max-t_min)/sq(_edge_points-1))*sq(m);
                }
                Point p = g[edge].point(t);
                boost::python::list pt;
                pt.append( p ); pt.append( t );
                point_list.append(pt);
            }
        }
        list.append( point_list );
    }
    // we are at target(e). find the next suitable edge.
    // return true if a next-edge was found, false otherwise.
    bool next_edge(HEEdge e, HEEdge& next) {
        HEVertex trg = g.target(e);
        EdgeVector out_edges = g.out_edges(trg);
        std::vector<HEEdge> valid_edges;
        BOOST_FOREACH( HEEdge oe, out_edges) {
            if ( valid_next_edge(oe) ) {
                valid_edges.push_back(oe);
            }
        }
        if (!valid_edges.empty() ) {
            next = valid_edges[0]; // return the first valid one
            return true;
        }
        return false;
    }

    void set_invalid(HEEdge e) {
        g[e].valid = false;
        g[ g[e].twin ].valid = false;
    }
    // loop through all edges and find an edge where we can start
    // valid edges have a source-vertex with exactly one valid out-edge.
    bool find_start_edge(HEEdge& start) {
        BOOST_FOREACH(HEEdge e, g.edges() ) {
            if ( valid_next_edge(e) ) {
                if (degree_one_source(e)) {
                    start = e;
                    return true;
                }
            }
        }
        return false;
    }
    // we can follow an edge if it is valid, and not a LINESITE or NULLEDGE
    bool valid_next_edge(HEEdge e) {
        return ( (g[e].type != LINESITE) && (g[e].type !=NULLEDGE) && (g[e].valid) );
    }
    // check if the source of the edge is a valid starting-point for a path
    bool degree_one_source(HEEdge e) {
        HEVertex src = g.source(e);
        EdgeVector out_edges = g.out_edges(src);
        int count(0);
        BOOST_FOREACH( HEEdge oe, out_edges) {
            if ( valid_next_edge(oe) ) {
                count++;
            }
        }
        return (count==1);
    }
private:
    boost::python::list out;
    MedialAxisWalk(); // don't use.
    HEGraph& g; // original graph

};

} // end namespace

// end file medial_axis.hpp
<|endoftext|>


<commit_before>
#include "../src/AtomicStack.h"
#include <thread>

using namespace peloton;
using namespace index;

void BasicTest() {
  dbg_printf("========== Basic Test ==========\n");

  AtomicStack<uint64_t> as{};

  for(uint64_t i = 0;i < 100;i++) {
    as.Push(i);
  }

  for(uint64_t i = 0;i < 100;i++) {
    uint64_t top;
    uint64_t expected = 99 - i;
    bool ret = as.Pop(top);

    assert(ret == true);

    assert(top == expected);
  }

  return;
}

void ThreadTest(int thread_num, int op_num) {
  dbg_printf("========== Thread Test ==========\n");

  AtomicStack<int> as{};

  auto push_func = [&as, thread_num, op_num](uint64_t id) {
                     for(int i = static_cast<int>(id);i < thread_num * op_num;i += thread_num) {
                       as.Push(i);
                     }
                   };

  // We use this to count what we have fetched from the stack
  std::atomic<int> sum;
  sum.store(0);

  auto pop_func = [&as, &sum, thread_num, op_num](uint64_t id) {
                    for(int i = 0;i < op_num;i++) {
                      int data;
                      bool ret = as.Pop(data);

                      // The data must be valid
                      assert(ret == true);

                      // Atomically adding the poped value onto the atomic
                      sum.fetch_add(data);
                    }
                  };

  StartThreads(thread_num, push_func);
  StartThreads(thread_num, pop_func);

  int expected = (op_num * thread_num) * (op_num * thread_num - 1) / 2;

  dbg_printf("Sum = %d; Expected = %d\n", sum.load(), expected);
  assert(sum.load() == expected);

  return;
}

int main() {
  BasicTest();
  ThreadTest(16, 2);

  return 0;
}
<commit_msg>Use more comprehensive tests<commit_after>
#include "../src/AtomicStack.h"

using namespace peloton;
using namespace index;

void BasicTest() {
  dbg_printf("========== Basic Test ==========\n");

  AtomicStack<uint64_t> as{};

  for(uint64_t i = 0;i < 100;i++) {
    as.Push(i);
  }

  for(uint64_t i = 0;i < 100;i++) {
    uint64_t top;
    uint64_t expected = 99 - i;
    bool ret = as.Pop(top);

    assert(ret == true);

    assert(top == expected);
  }

  return;
}

void ThreadTest(uint64_t thread_num, uint64_t op_num) {
  dbg_printf("========== Thread Test ==========\n");

  AtomicStack<uint64_t> as{};

  // This counts the number of push operation we have performed
  std::atomic<uint64_t> counter;
  counter.store(0);

  auto push_func = [&as, &counter, thread_num, op_num](uint64_t id) {
                     for(uint64_t i = id;i < thread_num * op_num;i += thread_num) {
                       as.Push(i);

                       // Increase the counter atomically
                       counter.fetch_add(1);
                     }
                   };

  // We use this to count what we have fetched from the stack
  std::atomic<uint64_t> sum;
  sum.store(0);
  counter.store(0);

  auto pop_func = [&as, &sum, &counter, thread_num, op_num](uint64_t id) {
                    for(uint64_t i = 0;i < op_num;i++) {
                      uint64_t data;
                      bool ret = as.Pop(data);

                      // The operation must success
                      assert(ret == true);

                      // Atomically adding the poped value onto the atomic
                      sum.fetch_add(data);
                    }
                  };

  // Let threads start
  StartThreads(thread_num, push_func);

  // We must have performed exactly this number of operations
  assert(counter.load() == thread_num * op_num);

  StartThreads(thread_num, pop_func);

  uint64_t expected = (op_num * thread_num) * (op_num * thread_num - 1) / 2;

  dbg_printf("Sum = %lu; Expected = %lu\n", sum.load(), expected);
  assert(sum.load() == expected);

  return;
}

int main() {
  BasicTest();
  ThreadTest(4, 2000000);

  return 0;
}
<|endoftext|>