<commit_before>/*
 +----------------------------------------------------------------------+
 | Swoole                                                               |
 +----------------------------------------------------------------------+
 | Copyright (c) 2012-2018 The Swoole Group                             |
 +----------------------------------------------------------------------+
 | This source file is subject to version 2.0 of the Apache license,    |
 | that is bundled with this package in the file LICENSE, and is        |
 | available through the world-wide-web at the following url:           |
 | http://www.apache.org/licenses/LICENSE-2.0.html                      |
 | If you did not receive a copy of the Apache2.0 license and are unable|
 | to obtain it through the world-wide-web, please send a note to       |
 | license@swoole.com so we can mail you a copy immediately.            |
 +----------------------------------------------------------------------+
 | Author: Xinyu Zhu  <xyzhu1120@gmail.com>                             |
 |         Tianfeng Han <rango@swoole.com>                              |
 +----------------------------------------------------------------------+
 */

#include "php_swoole_cxx.h"

#include "coroutine_channel.h"

using swoole::coroutine::Channel;

static zend_class_entry *swoole_channel_coro_ce;
static zend_object_handlers swoole_channel_coro_handlers;

typedef struct
{
    Channel *chan;
    zend_object std;
} channel_coro;

static PHP_METHOD(swoole_channel_coro, __construct);
static PHP_METHOD(swoole_channel_coro, push);
static PHP_METHOD(swoole_channel_coro, pop);
static PHP_METHOD(swoole_channel_coro, close);
static PHP_METHOD(swoole_channel_coro, stats);
static PHP_METHOD(swoole_channel_coro, length);
static PHP_METHOD(swoole_channel_coro, isEmpty);
static PHP_METHOD(swoole_channel_coro, isFull);

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_channel_coro_construct, 0, 0, 0)
    ZEND_ARG_INFO(0, size)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_channel_coro_push, 0, 0, 1)
    ZEND_ARG_INFO(0, data)
    ZEND_ARG_INFO(0, timeout)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_channel_coro_pop, 0, 0, 0)
    ZEND_ARG_INFO(0, timeout)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0)
ZEND_END_ARG_INFO()

static const zend_function_entry swoole_channel_coro_methods[] =
{
    PHP_ME(swoole_channel_coro, __construct, arginfo_swoole_channel_coro_construct, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, push, arginfo_swoole_channel_coro_push, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, pop,  arginfo_swoole_channel_coro_pop,  ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, isEmpty, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, isFull, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, close, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, stats, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, length, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_FE_END
};

enum swChannelErrorCode
{
    SW_CHANNEL_OK = 0,
    SW_CHANNEL_TIMEOUT = -1,
    SW_CHANNEL_CLOSED = -2,
};

static sw_inline channel_coro* swoole_channel_coro_fetch_object(zend_object *obj)
{
    return (channel_coro *) ((char *) obj - swoole_channel_coro_handlers.offset);
}

static sw_inline Channel * swoole_get_channel(zval *zobject)
{
    Channel *chan = swoole_channel_coro_fetch_object(Z_OBJ_P(zobject))->chan;
    if (UNEXPECTED(!chan))
    {
        php_swoole_fatal_error(E_ERROR, "you must call Channel constructor first");
    }
    return chan;
}

static void swoole_channel_coro_free_object(zend_object *object)
{
    channel_coro *chan_t = swoole_channel_coro_fetch_object(object);
    Channel *chan = chan_t->chan;
    if (chan)
    {
        chan->close();
        zval *data;
        while ((data = (zval *) chan->pop_data()))
        {
            sw_zval_free(data);
        }
        delete chan;
    }
    zend_object_std_dtor(&chan_t->std);
}

static zend_object *swoole_channel_coro_create_object(zend_class_entry *ce)
{
    channel_coro *chan_t = (channel_coro *) ecalloc(1, sizeof(channel_coro) + zend_object_properties_size(ce));
    zend_object_std_init(&chan_t->std, ce);
    object_properties_init(&chan_t->std, ce);
    chan_t->std.handlers = &swoole_channel_coro_handlers;
    return &chan_t->std;
}

void php_swoole_channel_coro_minit(int module_number)
{
    SW_INIT_CLASS_ENTRY(swoole_channel_coro, "Swoole\\Coroutine\\Channel", NULL, "Co\\Channel", swoole_channel_coro_methods);
    SW_SET_CLASS_SERIALIZABLE(swoole_channel_coro, zend_class_serialize_deny, zend_class_unserialize_deny);
    SW_SET_CLASS_CLONEABLE(swoole_channel_coro, sw_zend_class_clone_deny);
    SW_SET_CLASS_UNSET_PROPERTY_HANDLER(swoole_channel_coro, sw_zend_class_unset_property_deny);
    SW_SET_CLASS_CUSTOM_OBJECT(swoole_channel_coro, swoole_channel_coro_create_object, swoole_channel_coro_free_object, channel_coro, std);
    if (SWOOLE_G(use_shortname))
    {
        SW_CLASS_ALIAS("Chan", swoole_channel_coro);
    }

    zend_declare_property_long(swoole_channel_coro_ce, ZEND_STRL("capacity"), 0, ZEND_ACC_PUBLIC);
    zend_declare_property_long(swoole_channel_coro_ce, ZEND_STRL("errCode"), 0, ZEND_ACC_PUBLIC);

    SW_REGISTER_LONG_CONSTANT("SWOOLE_CHANNEL_OK", SW_CHANNEL_OK);
    SW_REGISTER_LONG_CONSTANT("SWOOLE_CHANNEL_TIMEOUT", SW_CHANNEL_TIMEOUT);
    SW_REGISTER_LONG_CONSTANT("SWOOLE_CHANNEL_CLOSED", SW_CHANNEL_CLOSED);
}

static PHP_METHOD(swoole_channel_coro, __construct)
{
    zend_long capacity = 1;

    ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 0, 1)
        Z_PARAM_OPTIONAL
        Z_PARAM_LONG(capacity)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    if (capacity <= 0)
    {
        capacity = 1;
    }

    channel_coro *chan_t = swoole_channel_coro_fetch_object(Z_OBJ_P(ZEND_THIS));
    chan_t->chan = new Channel(capacity);
    zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("capacity"), capacity);
}

static PHP_METHOD(swoole_channel_coro, push)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    if (chan->is_closed())
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), SW_CHANNEL_CLOSED);
        RETURN_FALSE;
    }
    else
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), SW_CHANNEL_OK);
    }

    zval *zdata;
    double timeout = -1;

    ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 1, 2)
        Z_PARAM_ZVAL(zdata)
        Z_PARAM_OPTIONAL
        Z_PARAM_DOUBLE(timeout)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    Z_TRY_ADDREF_P(zdata);
    zdata = sw_zval_dup(zdata);
    if (chan->push(zdata, timeout))
    {
        RETURN_TRUE;
    }
    else
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), chan->is_closed() ? SW_CHANNEL_CLOSED : SW_CHANNEL_TIMEOUT);
        Z_TRY_DELREF_P(zdata);
        efree(zdata);
        RETURN_FALSE;
    }
}

static PHP_METHOD(swoole_channel_coro, pop)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    if (chan->is_closed())
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), SW_CHANNEL_CLOSED);
        RETURN_FALSE;
    }
    else
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), SW_CHANNEL_OK);
    }

    double timeout = -1;

    ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 0, 1)
        Z_PARAM_OPTIONAL
        Z_PARAM_DOUBLE(timeout)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    zval *zdata = (zval *) chan->pop(timeout);
    if (zdata)
    {
        RETVAL_ZVAL(zdata, 0, 0);
        efree(zdata);
    }
    else
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), chan->is_closed() ? SW_CHANNEL_CLOSED : SW_CHANNEL_TIMEOUT);
        RETURN_FALSE;
    }
}

static PHP_METHOD(swoole_channel_coro, close)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    RETURN_BOOL(chan->close());
}

static PHP_METHOD(swoole_channel_coro, length)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    RETURN_LONG(chan->length());
}

static PHP_METHOD(swoole_channel_coro, isEmpty)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    RETURN_BOOL(chan->is_empty());
}

static PHP_METHOD(swoole_channel_coro, isFull)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    RETURN_BOOL(chan->is_full());
}

static PHP_METHOD(swoole_channel_coro, stats)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    array_init(return_value);
    add_assoc_long_ex(return_value, ZEND_STRL("consumer_num"), chan->consumer_num());
    add_assoc_long_ex(return_value, ZEND_STRL("producer_num"), chan->producer_num());
    add_assoc_long_ex(return_value, ZEND_STRL("queue_num"), chan->length());
}

<commit_msg>Revert 6135e623<commit_after>/*
 +----------------------------------------------------------------------+
 | Swoole                                                               |
 +----------------------------------------------------------------------+
 | Copyright (c) 2012-2018 The Swoole Group                             |
 +----------------------------------------------------------------------+
 | This source file is subject to version 2.0 of the Apache license,    |
 | that is bundled with this package in the file LICENSE, and is        |
 | available through the world-wide-web at the following url:           |
 | http://www.apache.org/licenses/LICENSE-2.0.html                      |
 | If you did not receive a copy of the Apache2.0 license and are unable|
 | to obtain it through the world-wide-web, please send a note to       |
 | license@swoole.com so we can mail you a copy immediately.            |
 +----------------------------------------------------------------------+
 | Author: Xinyu Zhu  <xyzhu1120@gmail.com>                             |
 |         Tianfeng Han <rango@swoole.com>                              |
 +----------------------------------------------------------------------+
 */

#include "php_swoole_cxx.h"

#include "coroutine_channel.h"

using swoole::coroutine::Channel;

static zend_class_entry *swoole_channel_coro_ce;
static zend_object_handlers swoole_channel_coro_handlers;

typedef struct
{
    Channel *chan;
    zend_object std;
} channel_coro;

static PHP_METHOD(swoole_channel_coro, __construct);
static PHP_METHOD(swoole_channel_coro, push);
static PHP_METHOD(swoole_channel_coro, pop);
static PHP_METHOD(swoole_channel_coro, close);
static PHP_METHOD(swoole_channel_coro, stats);
static PHP_METHOD(swoole_channel_coro, length);
static PHP_METHOD(swoole_channel_coro, isEmpty);
static PHP_METHOD(swoole_channel_coro, isFull);

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_channel_coro_construct, 0, 0, 0)
    ZEND_ARG_INFO(0, size)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_channel_coro_push, 0, 0, 1)
    ZEND_ARG_INFO(0, data)
    ZEND_ARG_INFO(0, timeout)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_channel_coro_pop, 0, 0, 0)
    ZEND_ARG_INFO(0, timeout)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0)
ZEND_END_ARG_INFO()

static const zend_function_entry swoole_channel_coro_methods[] =
{
    PHP_ME(swoole_channel_coro, __construct, arginfo_swoole_channel_coro_construct, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, push, arginfo_swoole_channel_coro_push, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, pop,  arginfo_swoole_channel_coro_pop,  ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, isEmpty, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, isFull, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, close, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, stats, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_channel_coro, length, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_FE_END
};

enum swChannelErrorCode
{
    SW_CHANNEL_OK = 0,
    SW_CHANNEL_TIMEOUT = -1,
    SW_CHANNEL_CLOSED = -2,
};

static sw_inline channel_coro* swoole_channel_coro_fetch_object(zend_object *obj)
{
    return (channel_coro *) ((char *) obj - swoole_channel_coro_handlers.offset);
}

static sw_inline Channel * swoole_get_channel(zval *zobject)
{
    Channel *chan = swoole_channel_coro_fetch_object(Z_OBJ_P(zobject))->chan;
    if (UNEXPECTED(!chan))
    {
        php_swoole_fatal_error(E_ERROR, "you must call Channel constructor first");
    }
    return chan;
}

static void swoole_channel_coro_free_object(zend_object *object)
{
    channel_coro *chan_t = swoole_channel_coro_fetch_object(object);
    Channel *chan = chan_t->chan;
    if (chan)
    {
        zval *data;
        while ((data = (zval *) chan->pop_data()))
        {
            sw_zval_free(data);
        }
        delete chan;
    }
    zend_object_std_dtor(&chan_t->std);
}

static zend_object *swoole_channel_coro_create_object(zend_class_entry *ce)
{
    channel_coro *chan_t = (channel_coro *) ecalloc(1, sizeof(channel_coro) + zend_object_properties_size(ce));
    zend_object_std_init(&chan_t->std, ce);
    object_properties_init(&chan_t->std, ce);
    chan_t->std.handlers = &swoole_channel_coro_handlers;
    return &chan_t->std;
}

void php_swoole_channel_coro_minit(int module_number)
{
    SW_INIT_CLASS_ENTRY(swoole_channel_coro, "Swoole\\Coroutine\\Channel", NULL, "Co\\Channel", swoole_channel_coro_methods);
    SW_SET_CLASS_SERIALIZABLE(swoole_channel_coro, zend_class_serialize_deny, zend_class_unserialize_deny);
    SW_SET_CLASS_CLONEABLE(swoole_channel_coro, sw_zend_class_clone_deny);
    SW_SET_CLASS_UNSET_PROPERTY_HANDLER(swoole_channel_coro, sw_zend_class_unset_property_deny);
    SW_SET_CLASS_CUSTOM_OBJECT(swoole_channel_coro, swoole_channel_coro_create_object, swoole_channel_coro_free_object, channel_coro, std);
    if (SWOOLE_G(use_shortname))
    {
        SW_CLASS_ALIAS("Chan", swoole_channel_coro);
    }

    zend_declare_property_long(swoole_channel_coro_ce, ZEND_STRL("capacity"), 0, ZEND_ACC_PUBLIC);
    zend_declare_property_long(swoole_channel_coro_ce, ZEND_STRL("errCode"), 0, ZEND_ACC_PUBLIC);

    SW_REGISTER_LONG_CONSTANT("SWOOLE_CHANNEL_OK", SW_CHANNEL_OK);
    SW_REGISTER_LONG_CONSTANT("SWOOLE_CHANNEL_TIMEOUT", SW_CHANNEL_TIMEOUT);
    SW_REGISTER_LONG_CONSTANT("SWOOLE_CHANNEL_CLOSED", SW_CHANNEL_CLOSED);
}

static PHP_METHOD(swoole_channel_coro, __construct)
{
    zend_long capacity = 1;

    ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 0, 1)
        Z_PARAM_OPTIONAL
        Z_PARAM_LONG(capacity)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    if (capacity <= 0)
    {
        capacity = 1;
    }

    channel_coro *chan_t = swoole_channel_coro_fetch_object(Z_OBJ_P(ZEND_THIS));
    chan_t->chan = new Channel(capacity);
    zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("capacity"), capacity);
}

static PHP_METHOD(swoole_channel_coro, push)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    if (chan->is_closed())
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), SW_CHANNEL_CLOSED);
        RETURN_FALSE;
    }
    else
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), SW_CHANNEL_OK);
    }

    zval *zdata;
    double timeout = -1;

    ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 1, 2)
        Z_PARAM_ZVAL(zdata)
        Z_PARAM_OPTIONAL
        Z_PARAM_DOUBLE(timeout)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    Z_TRY_ADDREF_P(zdata);
    zdata = sw_zval_dup(zdata);
    if (chan->push(zdata, timeout))
    {
        RETURN_TRUE;
    }
    else
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), chan->is_closed() ? SW_CHANNEL_CLOSED : SW_CHANNEL_TIMEOUT);
        Z_TRY_DELREF_P(zdata);
        efree(zdata);
        RETURN_FALSE;
    }
}

static PHP_METHOD(swoole_channel_coro, pop)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    if (chan->is_closed())
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), SW_CHANNEL_CLOSED);
        RETURN_FALSE;
    }
    else
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), SW_CHANNEL_OK);
    }

    double timeout = -1;

    ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 0, 1)
        Z_PARAM_OPTIONAL
        Z_PARAM_DOUBLE(timeout)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    zval *zdata = (zval *) chan->pop(timeout);
    if (zdata)
    {
        RETVAL_ZVAL(zdata, 0, 0);
        efree(zdata);
    }
    else
    {
        zend_update_property_long(swoole_channel_coro_ce, ZEND_THIS, ZEND_STRL("errCode"), chan->is_closed() ? SW_CHANNEL_CLOSED : SW_CHANNEL_TIMEOUT);
        RETURN_FALSE;
    }
}

static PHP_METHOD(swoole_channel_coro, close)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    RETURN_BOOL(chan->close());
}

static PHP_METHOD(swoole_channel_coro, length)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    RETURN_LONG(chan->length());
}

static PHP_METHOD(swoole_channel_coro, isEmpty)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    RETURN_BOOL(chan->is_empty());
}

static PHP_METHOD(swoole_channel_coro, isFull)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    RETURN_BOOL(chan->is_full());
}

static PHP_METHOD(swoole_channel_coro, stats)
{
    Channel *chan = swoole_get_channel(ZEND_THIS);
    array_init(return_value);
    add_assoc_long_ex(return_value, ZEND_STRL("consumer_num"), chan->consumer_num());
    add_assoc_long_ex(return_value, ZEND_STRL("producer_num"), chan->producer_num());
    add_assoc_long_ex(return_value, ZEND_STRL("queue_num"), chan->length());
}

<|endoftext|>


<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file JPetTaskChainExecutorUtilsTest.cpp
 */

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE JPetTaskChainExecutorUtilsTest
#include <boost/test/unit_test.hpp>
#include "../JPetTaskChainExecutor/JPetTaskChainExecutorUtils.h"

BOOST_AUTO_TEST_SUITE(JPetTaskChainExecutorTestSuite)

BOOST_AUTO_TEST_CASE(tryToUnzipSomethingNotExistingFile)
{
  BOOST_REQUIRE(!JPetTaskChainExecutorUtils::unzipFile("kiko.gz"));
  std::string initialPath = boost::filesystem::path(boost::filesystem::current_path()).string();
  initialPath = initialPath.substr(0, initialPath.find("build") );
  std::string wrongZipPath = initialPath + "unitTestData/JPetTaskChainExecutorUtilsTest/wrongZip.gz";
  BOOST_REQUIRE(!JPetTaskChainExecutorUtils::unzipFile( wrongZipPath.c_str() ));

}
BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Added tests for new unzipping format, and fixed old ones. Now three checks are done: successfull unzipping, failure due to wrong path and failure due to bad format<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file JPetTaskChainExecutorUtilsTest.cpp
 */

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE JPetTaskChainExecutorUtilsTest
#include <boost/test/unit_test.hpp>
#include "../JPetTaskChainExecutor/JPetTaskChainExecutorUtils.h"

BOOST_AUTO_TEST_SUITE(JPetTaskChainExecutorTestSuite)

BOOST_AUTO_TEST_CASE(tryToUnzipSomethingNotExistingFile)
{
  BOOST_REQUIRE(JPetTaskChainExecutorUtils::unzipFile("unitTestData/JPetTaskChainExecutorUtilsTest/goodZip.gz"));
  std::string initialPath = boost::filesystem::path(boost::filesystem::current_path()).string();
  initialPath = initialPath.substr(0, initialPath.find("build") );
  std::string wrongZipPath = initialPath + "wrongZip.gz";
  BOOST_REQUIRE(!JPetTaskChainExecutorUtils::unzipFile( wrongZipPath.c_str() ));
  BOOST_REQUIRE(!JPetTaskChainExecutorUtils::unzipFile( "unitTestData/JPetTaskChainExecutorUtilsTest/wrongZip.gz" ));
}

BOOST_AUTO_TEST_CASE(tryToUnzipSomethingNotExistingFileWithXz)
{
  BOOST_REQUIRE(JPetTaskChainExecutorUtils::unzipFile("unitTestData/JPetTaskChainExecutorUtilsTest/goodXZ.xz"));
  std::string initialPath = boost::filesystem::path(boost::filesystem::current_path()).string();
  initialPath = initialPath.substr(0, initialPath.find("build") );
  std::string wrongZipPath = initialPath + "unitTestData/JPetTaskChainExecutorUtilsTest/wrongZip.Xz";
  BOOST_REQUIRE(!JPetTaskChainExecutorUtils::unzipFile( wrongZipPath.c_str() ));
  BOOST_REQUIRE(!JPetTaskChainExecutorUtils::unzipFile( "unitTestData/JPetTaskChainExecutorUtilsTest/wrongXZ.xz" ));
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/*
    First, we do some algebraic manipulations.

        n = x^2 - y^2 - z^2
          = x^2 - z^2 - y^2
          = (x + z)(x - z) - y^2
          = (2y)(2(x - y)) - y^2
          = 4xy - 5y^2
          = y(4x - 5y)

    We can search through valid pairs of (x, y) and add one to the counter for
    every corresponding n. Afterwards, we count the number of n whose counter
    reads 10.

    Now, we need to specify bounds for our iteration of (x, y). We will pick y
    first and then loop through x for every value of y. Since y | n, we need y <=
    n.

    For every y, we need n to be positive. We can start with x > 5y / 4, or x >=
    ceil(5y / 4). Since z must be positive and z = 2y - x, we have an upper
    bound x < 2y. Furthermore, for fixed y, n = y(4x - 5y) increases as x
    increases. This gives us the second upper bound that n = y(4x - 5y) <=
    n_max, which is 999999 in this case.
*/

#include <iostream>
#include <unordered_map>

int main()
{
    int n_max = 1000000;
    std::unordered_map<int, int> solution_counts;
    for (int y = 0; y < n_max; y++)
    {
        int x = y * 5 / 4 + 1;
        int n = y * (4 * x - 5 * y);
        while (n < n_max && x < 2 * y)
        {
            solution_counts[n]++;
            x++;
            n += 4 * y; // Because 4(x + 1)y - 5y^2 = (4xy - 5y^2) + 4y
        }
    }

    int count = 0;
    for (auto &pair : solution_counts)
        if (pair.second == 10)
            count++;

    std::cout << count;
}
<commit_msg>Changed unordered_map to vector.<commit_after>/*
    First, we do some algebraic manipulations.

        n = x^2 - y^2 - z^2
          = x^2 - z^2 - y^2
          = (x + z)(x - z) - y^2
          = (2y)(2(x - y)) - y^2
          = 4xy - 5y^2
          = y(4x - 5y)

    We can search through valid pairs of (x, y) and add one to the counter for
    every corresponding n. Afterwards, we count the number of n whose counter
    reads 10.

    Now, we need to specify bounds for our iteration of (x, y). We will pick y
    first and then loop through x for every value of y. Since y | n, we need y <=
    n.

    For every y, we need n to be positive. We can start with x > 5y / 4, or x >=
    ceil(5y / 4). Since z must be positive and z = 2y - x, we have an upper
    bound x < 2y. Furthermore, for fixed y, n = y(4x - 5y) increases as x
    increases. This gives us the second upper bound that n = y(4x - 5y) <=
    n_max, which is 999999 in this case.
*/

#include <iostream>
#include <vector>

int main()
{
    int n_max = 1000000;
    std::vector<int> solution_counts(n_max);
    for (int y = 0; y < n_max; y++)
    {
        int x = y * 5 / 4 + 1;
        int n = y * (4 * x - 5 * y);
        while (n < n_max && x < 2 * y)
        {
            solution_counts[n]++;
            x++;
            n += 4 * y; // Because 4(x + 1)y - 5y^2 = (4xy - 5y^2) + 4y
        }
    }

    int count = 0;
    for (int c : solution_counts)
        if (c == 10)
            count++;

    std::cout << count;
}
<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPaintbrushTool.h"

#include "mitkToolManager.h"
#include "mitkOverwriteSliceImageFilter.h"
#include "mitkBaseRenderer.h"
#include "mitkImageDataItem.h"
#include "ipSegmentation.h"

#include "mitkLevelWindowProperty.h"

#define ROUND(a)     ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a)))

int mitk::PaintbrushTool::m_Size = 1;

mitk::PaintbrushTool::PaintbrushTool(int paintingPixelValue)
:FeedbackContourTool("PressMoveReleaseWithCTRLInversionAllMouseMoves"),
 m_PaintingPixelValue(paintingPixelValue),
 m_LastContourSize(0) // other than initial mitk::PaintbrushTool::m_Size (around l. 28)
{
  m_MasterContour = Contour::New();
  m_MasterContour->Initialize();
  m_CurrentPlane = NULL;

  m_WorkingNode = DataNode::New();
  m_WorkingNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(0, 1) ) );
  m_WorkingNode->SetProperty( "binary", mitk::BoolProperty::New(true) );
}

mitk::PaintbrushTool::~PaintbrushTool()
{
}

void mitk::PaintbrushTool::Activated()
{
  Superclass::Activated();
  FeedbackContourTool::SetFeedbackContourVisible(true);
  SizeChanged.Send(m_Size);
}

void mitk::PaintbrushTool::Deactivated()
{
  FeedbackContourTool::SetFeedbackContourVisible(false);
  if (m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
      m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
  Superclass::Deactivated();
}

void mitk::PaintbrushTool::SetSize(int value)
{
  m_Size = value;
}

void mitk::PaintbrushTool::UpdateContour(const StateEvent* stateEvent)
{
    //MITK_INFO<<"Update...";
  // examine stateEvent and create a contour that matches the pixel mask that we are going to draw
  const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
  if (!positionEvent) return;

  // create a copy of this slice (at least match the pixel sizes/spacings),
  // then draw the desired mask on it and create a contour from it

  // Convert to ipMITKSegmentationTYPE (because getting pixels relys on that data type)
  itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
  CastToItkImage(m_WorkingSlice/*dynamic_cast<mitk::Image*>(m_WorkingNode->GetData())*/, correctPixelTypeImage );
  assert (correctPixelTypeImage.IsNotNull() );

  itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
  imageDirection.SetIdentity();
  correctPixelTypeImage->SetDirection(imageDirection);

  Image::Pointer temporarySlice = Image::New();
  CastToMitkImage( correctPixelTypeImage, temporarySlice );

  //mitkIpPicDescriptor* stupidClone = mitkIpPicClone( temporarySlice->GetSliceData()->GetPicDescriptor() );
  mitkIpPicDescriptor* stupidClone = mitkIpPicNew();
  CastToIpPicDescriptor( temporarySlice->GetSliceData(), stupidClone );
  unsigned int pixelWidth  = m_Size + 1;
  unsigned int pixelHeight = m_Size + 1;

  if ( stupidClone->n[0] <= pixelWidth || stupidClone->n[1] <= pixelHeight )
  {
    MITK_INFO << "Brush size is bigger than your working image. Reconsider this...\n"
                "(Or tell your progammer until (s)he fixes this message.)" << std::endl;
    mitkIpPicFree( stupidClone );
    return;
  }

  unsigned int lineLength( stupidClone->n[0] );
  unsigned int oneContourOffset(0);
  float circleCenterX = (float)m_Size / 2.0;
  float circleCenterY = (float)m_Size / 2.0;
  for (unsigned int x = 0; x <= pixelWidth; ++x)
  {
    for (unsigned int y = 0; y <= pixelHeight; ++y)
    {
      unsigned int offset = lineLength * y + x;
      ipMITKSegmentationTYPE* current = (ipMITKSegmentationTYPE*)stupidClone->data + offset;

      float pixelCenterX = x + 0.5;
      float pixelCenterY = y + 0.5;

      float xoff = pixelCenterX - circleCenterX;
      float yoff = pixelCenterY - circleCenterY;

      bool inside = xoff * xoff + yoff * yoff < (m_Size * m_Size) / 4.0; // no idea, if this would work for ellipses
      if (inside)
      {
        *current = 1;
        oneContourOffset = offset;
      }
      else
      {
        *current = 0;
      }
    }
  }

  int numberOfContourPoints( 0 );
  int newBufferSize( 0 );
  float* contourPoints = ipMITKSegmentationGetContour8N( stupidClone, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc
  if (!contourPoints)
  {
    mitkIpPicFree( stupidClone );
    return;
  }

  // copy point from float* to mitk::Contour
  Contour::Pointer contourInImageIndexCoordinates = Contour::New();
  contourInImageIndexCoordinates->Initialize();
  Point3D newPoint;
  //ipMITKSegmentationGetContour8N returns all points, which causes vtk warnings, since the first and the last points are coincident.
  //leaving the last point out, the contour is still drawn correctly
  for (int index = 0; index < numberOfContourPoints-1; ++index)
  {
    newPoint[0] = contourPoints[ 2 * index + 0 ] - circleCenterX; // master contour should be centered around (0,0)
    newPoint[1] = contourPoints[ 2 * index + 1] - circleCenterY;
    newPoint[2] = 0.0;
    MITK_DEBUG << "Point [" << index << "] (" << newPoint[0] << ", " << newPoint[1] << ")" << std::endl;

    contourInImageIndexCoordinates->AddVertex( newPoint );
  }

  free(contourPoints);

  m_MasterContour = contourInImageIndexCoordinates;

  // The PicDescriptor is only REFERENCING(!) the data, the temporarySlice takes care of deleting the data also the descriptor is pointing on
  // because they got allocated by the ImageDataItem, not the descriptor.
  stupidClone->data = NULL;
  mitkIpPicFree( stupidClone );
}

/**
  Just show the contour, get one point as the central point and add surrounding points to the contour.
  */
bool mitk::PaintbrushTool::OnMousePressed (Action* action, const StateEvent* stateEvent)
{
  return this->OnMouseMoved(action, stateEvent);
}

/**
  Insert the point to the feedback contour,finish to build the contour and at the same time the painting function
  */
bool mitk::PaintbrushTool::OnMouseMoved   (Action* itkNotUsed(action), const StateEvent* stateEvent)
{
    const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
    if (!positionEvent) return false;

    CheckIfCurrentSliceHasChanged(positionEvent);

    if ( m_LastContourSize != m_Size )
    {
      UpdateContour( stateEvent );
      m_LastContourSize = m_Size;
    }

  bool leftMouseButtonPressed(
          stateEvent->GetId() == 530
       || stateEvent->GetId() == 534
       || stateEvent->GetId() == 1
       || stateEvent->GetId() == 5
                             );

  Point3D worldCoordinates = positionEvent->GetWorldPosition();
  Point3D indexCoordinates;

  m_WorkingSlice->GetGeometry()->WorldToIndex( worldCoordinates, indexCoordinates );

  MITK_DEBUG << "Mouse at W " << worldCoordinates << std::endl;
  MITK_DEBUG << "Mouse at I " << indexCoordinates << std::endl;

  // round to nearest voxel center (abort if this hasn't changed)
  if ( m_Size % 2 == 0 ) // even
  {
    indexCoordinates[0] = ROUND( indexCoordinates[0] /*+ 0.5*/) + 0.5;
    indexCoordinates[1] = ROUND( indexCoordinates[1] /*+ 0.5*/ ) + 0.5;
  }
  else // odd
  {
    indexCoordinates[0] = ROUND( indexCoordinates[0]  ) ;
    indexCoordinates[1] = ROUND( indexCoordinates[1] ) ;
  }

  static Point3D lastPos; // uninitialized: if somebody finds out how this can be initialized in a one-liner, tell me
  static bool lastLeftMouseButtonPressed(false);
  if ( fabs(indexCoordinates[0] - lastPos[0]) > mitk::eps ||
       fabs(indexCoordinates[1] - lastPos[1]) > mitk::eps ||
       fabs(indexCoordinates[2] - lastPos[2]) > mitk::eps ||
       leftMouseButtonPressed != lastLeftMouseButtonPressed
     )
  {
    lastPos = indexCoordinates;
    lastLeftMouseButtonPressed = leftMouseButtonPressed;
  }
  else
  {
    MITK_DEBUG << "." << std::flush;
    return false;
  }

  MITK_DEBUG << "Mouse at C " << indexCoordinates;

  Contour::Pointer contour = Contour::New();
  contour->Initialize();
  for (unsigned int index = 0; index < m_MasterContour->GetNumberOfPoints(); ++index)
  {
    Point3D point = m_MasterContour->GetPoints()->ElementAt(index);
    point[0] += indexCoordinates[ 0 ];
    point[1] += indexCoordinates[ 1 ];

    MITK_DEBUG << "Contour point [" << index << "] :" << point;
    contour->AddVertex( point );
  }

  if (leftMouseButtonPressed)
  {
    FeedbackContourTool::FillContourInSlice( contour, m_WorkingSlice, m_PaintingPixelValue );
    m_WorkingNode->SetData(m_WorkingSlice);
    m_WorkingNode->Modified();
  }

  // visualize contour
  Contour::Pointer displayContour = Contour::New();
  displayContour->Initialize();

  //for (unsigned int index = 0; index < contour->GetNumberOfPoints(); ++index)
  //{
  //  Point3D point = contour->GetPoints()->ElementAt(index);
  //  if ( m_Size % 2 == 0 ) // even
  //  {
  //    point[0] += 0.5;
  //    point[1] += 0.5;
  //  }
  //  displayContour->AddVertex( point );
  //}

  displayContour = FeedbackContourTool::BackProjectContourFrom2DSlice( m_WorkingSlice->GetGeometry(), /*displayContour*/contour );
  SetFeedbackContour( *displayContour );
  assert( positionEvent->GetSender()->GetRenderWindow() );

  RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );

  return true;
}

bool mitk::PaintbrushTool::OnMouseReleased(Action* /*action*/, const StateEvent* stateEvent)
{
    //When mouse is released write segmentationresult back into image
    const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
    if (!positionEvent) return false;
    this->WriteBackSegmentationResult(positionEvent, m_WorkingSlice);
//  FeedbackContourTool::SetFeedbackContourVisible(false);

  return true;
}

/**
  Called when the CTRL key is pressed. Will change the painting pixel value from 0 to 1 or from 1 to 0.
  */
bool mitk::PaintbrushTool::OnInvertLogic(Action* action, const StateEvent* stateEvent)
{
  if (!FeedbackContourTool::OnInvertLogic(action, stateEvent)) return false;

  // Inversion only for 0 and 1 as painting values
  if (m_PaintingPixelValue == 1)
  {
    m_PaintingPixelValue = 0;
    FeedbackContourTool::SetFeedbackContourColor( 1.0, 0.0, 0.0 );
  }
  else if (m_PaintingPixelValue == 0)
  {
    m_PaintingPixelValue = 1;
    FeedbackContourTool::SetFeedbackContourColorDefault();
  }

  return true;
}

void mitk::PaintbrushTool::CheckIfCurrentSliceHasChanged(const PositionEvent *event)
{
    const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (event->GetSender()->GetCurrentWorldGeometry2D() ) );
    DataNode* workingNode( m_ToolManager->GetWorkingData(0) );

    if (!workingNode)
        return;

    Image::Pointer image = dynamic_cast<Image*>(workingNode->GetData());

    if ( !image || !planeGeometry )
        return;

    if(m_CurrentPlane.IsNull())
    {
        m_CurrentPlane = const_cast<PlaneGeometry*>(planeGeometry);
        m_WorkingSlice = SegTool2D::GetAffectedImageSliceAs2DImage(event, image)->Clone();

        m_WorkingNode->ReplaceProperty( "color", workingNode->GetProperty("color") );
        m_WorkingNode->SetData(m_WorkingSlice);
    }
    else
    {
        bool isSameSlice (false);
        isSameSlice = mitk::MatrixEqualElementWise(planeGeometry->GetIndexToWorldTransform()->GetMatrix(),m_CurrentPlane->GetIndexToWorldTransform()->GetMatrix());
        isSameSlice = mitk::Equal(planeGeometry->GetIndexToWorldTransform()->GetOffset(),m_CurrentPlane->GetIndexToWorldTransform()->GetOffset());
        if (!isSameSlice)
        {
            m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
            m_CurrentPlane = NULL;
            m_WorkingSlice = NULL;
            m_WorkingNode = NULL;
            m_CurrentPlane = const_cast<PlaneGeometry*>(planeGeometry);
            m_WorkingSlice = SegTool2D::GetAffectedImageSliceAs2DImage(event, image)->Clone();

            m_WorkingNode = mitk::DataNode::New();
            m_WorkingNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(0, 1) ) );
            m_WorkingNode->SetProperty( "binary", mitk::BoolProperty::New(true) );

            m_WorkingNode->SetData(m_WorkingSlice);
        }

    }

    if(!m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
    {

        m_WorkingNode->SetProperty( "outline binary", mitk::BoolProperty::New(true) );
        m_WorkingNode->SetProperty( "color", workingNode->GetProperty("color") );
        m_WorkingNode->SetProperty( "name", mitk::StringProperty::New("Paintbrush_Node") );
        m_WorkingNode->SetProperty( "helper object", mitk::BoolProperty::New(true) );
        m_WorkingNode->SetProperty( "opacity", mitk::FloatProperty::New(0.8) );
        m_WorkingNode->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(false));

        m_ToolManager->GetDataStorage()->Add(m_WorkingNode);
    }
}
<commit_msg>Fixed bug which caused painttool not to react on mouse click<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPaintbrushTool.h"

#include "mitkToolManager.h"
#include "mitkOverwriteSliceImageFilter.h"
#include "mitkBaseRenderer.h"
#include "mitkImageDataItem.h"
#include "ipSegmentation.h"

#include "mitkLevelWindowProperty.h"

#define ROUND(a)     ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a)))

int mitk::PaintbrushTool::m_Size = 1;

mitk::PaintbrushTool::PaintbrushTool(int paintingPixelValue)
:FeedbackContourTool("PressMoveReleaseWithCTRLInversionAllMouseMoves"),
 m_PaintingPixelValue(paintingPixelValue),
 m_LastContourSize(0) // other than initial mitk::PaintbrushTool::m_Size (around l. 28)
{
  m_MasterContour = Contour::New();
  m_MasterContour->Initialize();
  m_CurrentPlane = NULL;

  m_WorkingNode = DataNode::New();
  m_WorkingNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(0, 1) ) );
  m_WorkingNode->SetProperty( "binary", mitk::BoolProperty::New(true) );
}

mitk::PaintbrushTool::~PaintbrushTool()
{
}

void mitk::PaintbrushTool::Activated()
{
  Superclass::Activated();
  FeedbackContourTool::SetFeedbackContourVisible(true);
  SizeChanged.Send(m_Size);
}

void mitk::PaintbrushTool::Deactivated()
{
  FeedbackContourTool::SetFeedbackContourVisible(false);
  if (m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
      m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
  Superclass::Deactivated();
}

void mitk::PaintbrushTool::SetSize(int value)
{
  m_Size = value;
}

void mitk::PaintbrushTool::UpdateContour(const StateEvent* stateEvent)
{
    //MITK_INFO<<"Update...";
  // examine stateEvent and create a contour that matches the pixel mask that we are going to draw
  const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
  if (!positionEvent) return;

  // create a copy of this slice (at least match the pixel sizes/spacings),
  // then draw the desired mask on it and create a contour from it

  // Convert to ipMITKSegmentationTYPE (because getting pixels relys on that data type)
  itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
  CastToItkImage(m_WorkingSlice/*dynamic_cast<mitk::Image*>(m_WorkingNode->GetData())*/, correctPixelTypeImage );
  assert (correctPixelTypeImage.IsNotNull() );

  itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
  imageDirection.SetIdentity();
  correctPixelTypeImage->SetDirection(imageDirection);

  Image::Pointer temporarySlice = Image::New();
  CastToMitkImage( correctPixelTypeImage, temporarySlice );

  //mitkIpPicDescriptor* stupidClone = mitkIpPicClone( temporarySlice->GetSliceData()->GetPicDescriptor() );
  mitkIpPicDescriptor* stupidClone = mitkIpPicNew();
  CastToIpPicDescriptor( temporarySlice->GetSliceData(), stupidClone );
  unsigned int pixelWidth  = m_Size + 1;
  unsigned int pixelHeight = m_Size + 1;

  if ( stupidClone->n[0] <= pixelWidth || stupidClone->n[1] <= pixelHeight )
  {
    MITK_INFO << "Brush size is bigger than your working image. Reconsider this...\n"
                "(Or tell your progammer until (s)he fixes this message.)" << std::endl;
    mitkIpPicFree( stupidClone );
    return;
  }

  unsigned int lineLength( stupidClone->n[0] );
  unsigned int oneContourOffset(0);
  float circleCenterX = (float)m_Size / 2.0;
  float circleCenterY = (float)m_Size / 2.0;
  for (unsigned int x = 0; x <= pixelWidth; ++x)
  {
    for (unsigned int y = 0; y <= pixelHeight; ++y)
    {
      unsigned int offset = lineLength * y + x;
      ipMITKSegmentationTYPE* current = (ipMITKSegmentationTYPE*)stupidClone->data + offset;

      float pixelCenterX = x + 0.5;
      float pixelCenterY = y + 0.5;

      float xoff = pixelCenterX - circleCenterX;
      float yoff = pixelCenterY - circleCenterY;

      bool inside = xoff * xoff + yoff * yoff < (m_Size * m_Size) / 4.0; // no idea, if this would work for ellipses
      if (inside)
      {
        *current = 1;
        oneContourOffset = offset;
      }
      else
      {
        *current = 0;
      }
    }
  }

  int numberOfContourPoints( 0 );
  int newBufferSize( 0 );
  float* contourPoints = ipMITKSegmentationGetContour8N( stupidClone, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc
  if (!contourPoints)
  {
    mitkIpPicFree( stupidClone );
    return;
  }

  // copy point from float* to mitk::Contour
  Contour::Pointer contourInImageIndexCoordinates = Contour::New();
  contourInImageIndexCoordinates->Initialize();
  Point3D newPoint;
  //ipMITKSegmentationGetContour8N returns all points, which causes vtk warnings, since the first and the last points are coincident.
  //leaving the last point out, the contour is still drawn correctly
  for (int index = 0; index < numberOfContourPoints-1; ++index)
  {
    newPoint[0] = contourPoints[ 2 * index + 0 ] - circleCenterX; // master contour should be centered around (0,0)
    newPoint[1] = contourPoints[ 2 * index + 1] - circleCenterY;
    newPoint[2] = 0.0;
    MITK_DEBUG << "Point [" << index << "] (" << newPoint[0] << ", " << newPoint[1] << ")" << std::endl;

    contourInImageIndexCoordinates->AddVertex( newPoint );
  }

  free(contourPoints);

  m_MasterContour = contourInImageIndexCoordinates;

  // The PicDescriptor is only REFERENCING(!) the data, the temporarySlice takes care of deleting the data also the descriptor is pointing on
  // because they got allocated by the ImageDataItem, not the descriptor.
  stupidClone->data = NULL;
  mitkIpPicFree( stupidClone );
}

/**
  Just show the contour, get one point as the central point and add surrounding points to the contour.
  */
bool mitk::PaintbrushTool::OnMousePressed (Action* action, const StateEvent* stateEvent)
{
  return this->OnMouseMoved(action, stateEvent);
}

/**
  Insert the point to the feedback contour,finish to build the contour and at the same time the painting function
  */
bool mitk::PaintbrushTool::OnMouseMoved   (Action* itkNotUsed(action), const StateEvent* stateEvent)
{
    const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
    if (!positionEvent) return false;

    CheckIfCurrentSliceHasChanged(positionEvent);

    if ( m_LastContourSize != m_Size )
    {
      UpdateContour( stateEvent );
      m_LastContourSize = m_Size;
    }

  bool leftMouseButtonPressed(
          stateEvent->GetId() == 530
       || stateEvent->GetId() == 534
       || stateEvent->GetId() == 1
       || stateEvent->GetId() == 5
                             );

  Point3D worldCoordinates = positionEvent->GetWorldPosition();
  Point3D indexCoordinates;

  m_WorkingSlice->GetGeometry()->WorldToIndex( worldCoordinates, indexCoordinates );

  MITK_DEBUG << "Mouse at W " << worldCoordinates << std::endl;
  MITK_DEBUG << "Mouse at I " << indexCoordinates << std::endl;

  // round to nearest voxel center (abort if this hasn't changed)
  if ( m_Size % 2 == 0 ) // even
  {
    indexCoordinates[0] = ROUND( indexCoordinates[0] /*+ 0.5*/) + 0.5;
    indexCoordinates[1] = ROUND( indexCoordinates[1] /*+ 0.5*/ ) + 0.5;
  }
  else // odd
  {
    indexCoordinates[0] = ROUND( indexCoordinates[0]  ) ;
    indexCoordinates[1] = ROUND( indexCoordinates[1] ) ;
  }

  static Point3D lastPos; // uninitialized: if somebody finds out how this can be initialized in a one-liner, tell me
  if ( fabs(indexCoordinates[0] - lastPos[0]) > mitk::eps ||
       fabs(indexCoordinates[1] - lastPos[1]) > mitk::eps ||
       fabs(indexCoordinates[2] - lastPos[2]) > mitk::eps ||
       leftMouseButtonPressed
     )
  {
    lastPos = indexCoordinates;
  }
  else
  {
    MITK_DEBUG << "." << std::flush;
    return false;
  }

  MITK_DEBUG << "Mouse at C " << indexCoordinates;

  Contour::Pointer contour = Contour::New();
  contour->Initialize();

  for (unsigned int index = 0; index < m_MasterContour->GetNumberOfPoints(); ++index)
  {
    Point3D point = m_MasterContour->GetPoints()->ElementAt(index);
    point[0] += indexCoordinates[ 0 ];
    point[1] += indexCoordinates[ 1 ];

    contour->AddVertex( point );
  }

  if (leftMouseButtonPressed)
  {
    FeedbackContourTool::FillContourInSlice( contour, m_WorkingSlice, m_PaintingPixelValue );
    m_WorkingNode->SetData(m_WorkingSlice);
    m_WorkingNode->Modified();
  }

  // visualize contour
  Contour::Pointer displayContour = Contour::New();
  displayContour->Initialize();

  //for (unsigned int index = 0; index < contour->GetNumberOfPoints(); ++index)
  //{
  //  Point3D point = contour->GetPoints()->ElementAt(index);
  //  if ( m_Size % 2 == 0 ) // even
  //  {
  //    point[0] += 0.5;
  //    point[1] += 0.5;
  //  }
  //  displayContour->AddVertex( point );
  //}

  displayContour = FeedbackContourTool::BackProjectContourFrom2DSlice( m_WorkingSlice->GetGeometry(), /*displayContour*/contour );
  SetFeedbackContour( *displayContour );
  assert( positionEvent->GetSender()->GetRenderWindow() );

  RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );

  return true;
}

bool mitk::PaintbrushTool::OnMouseReleased(Action* /*action*/, const StateEvent* stateEvent)
{
    //When mouse is released write segmentationresult back into image
    const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
    if (!positionEvent) return false;
    this->WriteBackSegmentationResult(positionEvent, m_WorkingSlice);
//  FeedbackContourTool::SetFeedbackContourVisible(false);

  return true;
}

/**
  Called when the CTRL key is pressed. Will change the painting pixel value from 0 to 1 or from 1 to 0.
  */
bool mitk::PaintbrushTool::OnInvertLogic(Action* action, const StateEvent* stateEvent)
{
  if (!FeedbackContourTool::OnInvertLogic(action, stateEvent)) return false;

  // Inversion only for 0 and 1 as painting values
  if (m_PaintingPixelValue == 1)
  {
    m_PaintingPixelValue = 0;
    FeedbackContourTool::SetFeedbackContourColor( 1.0, 0.0, 0.0 );
  }
  else if (m_PaintingPixelValue == 0)
  {
    m_PaintingPixelValue = 1;
    FeedbackContourTool::SetFeedbackContourColorDefault();
  }

  return true;
}

void mitk::PaintbrushTool::CheckIfCurrentSliceHasChanged(const PositionEvent *event)
{
    const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (event->GetSender()->GetCurrentWorldGeometry2D() ) );
    DataNode* workingNode( m_ToolManager->GetWorkingData(0) );

    if (!workingNode)
        return;

    Image::Pointer image = dynamic_cast<Image*>(workingNode->GetData());

    if ( !image || !planeGeometry )
        return;

    if(m_CurrentPlane.IsNull())
    {
        m_CurrentPlane = const_cast<PlaneGeometry*>(planeGeometry);
        m_WorkingSlice = SegTool2D::GetAffectedImageSliceAs2DImage(event, image)->Clone();

        m_WorkingNode->ReplaceProperty( "color", workingNode->GetProperty("color") );
        m_WorkingNode->SetData(m_WorkingSlice);
    }
    else
    {
        bool isSameSlice (false);
        isSameSlice = mitk::MatrixEqualElementWise(planeGeometry->GetIndexToWorldTransform()->GetMatrix(),m_CurrentPlane->GetIndexToWorldTransform()->GetMatrix());
        isSameSlice = mitk::Equal(planeGeometry->GetIndexToWorldTransform()->GetOffset(),m_CurrentPlane->GetIndexToWorldTransform()->GetOffset());
        if (!isSameSlice)
        {
            m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
            m_CurrentPlane = NULL;
            m_WorkingSlice = NULL;
            m_WorkingNode = NULL;
            m_CurrentPlane = const_cast<PlaneGeometry*>(planeGeometry);
            m_WorkingSlice = SegTool2D::GetAffectedImageSliceAs2DImage(event, image)->Clone();

            m_WorkingNode = mitk::DataNode::New();
            m_WorkingNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(0, 1) ) );
            m_WorkingNode->SetProperty( "binary", mitk::BoolProperty::New(true) );

            m_WorkingNode->SetData(m_WorkingSlice);
        }

    }

    if(!m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
    {

        m_WorkingNode->SetProperty( "outline binary", mitk::BoolProperty::New(true) );
        m_WorkingNode->SetProperty( "color", workingNode->GetProperty("color") );
        m_WorkingNode->SetProperty( "name", mitk::StringProperty::New("Paintbrush_Node") );
        m_WorkingNode->SetProperty( "helper object", mitk::BoolProperty::New(true) );
        m_WorkingNode->SetProperty( "opacity", mitk::FloatProperty::New(0.8) );
        m_WorkingNode->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(false));

        m_ToolManager->GetDataStorage()->Add(m_WorkingNode);
    }
}
<|endoftext|>


<commit_before>/** \brief Utility for removing unreferenced authority records
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2017 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <stdexcept>
#include <unordered_set>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include "FileUtil.h"
#include "Leader.h"
#include "MarcReader.h"
#include "MarcRecord.h"
#include "MarcWriter.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "util.h"

namespace {

void Usage() __attribute__((noreturn));

void Usage() {
    std::cerr << "Usage: " << ::progname << " title_data authority_data filtered_authority_data\n";
    std::exit(EXIT_FAILURE);
}

void CollectGNDReferences(MarcReader * const marc_reader, std::unordered_set<std::string> * const gnd_numbers) {
    std::string err_msg;
    RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory("\x1F""0\\(DE-588\\)([^\x1F]+).*\x1F""2gnd",
                                                                   &err_msg));
    if (matcher == nullptr)
        logger->error("failed to compile a regex in CollectGNDReferences: " + err_msg);

    unsigned record_count(0);
    while (const MarcRecord record = marc_reader->read()) {
        ++record_count;

        for (const auto field_contents : record) {
            if (matcher->matched(field_contents))
                gnd_numbers->emplace((*matcher)[1]);
        }
    }

    std::cout << "Extracted " << gnd_numbers->size() << " GND number(s) from " <<  record_count
              << " title record(s).\n";
}

std::string GetGNDNumber(const MarcRecord &record) {
    std::vector<size_t> _035_indices;
    record.getFieldIndices("035", &_035_indices);

    for (const auto index : _035_indices) {
        const Subfields _035_subfields(record.getFieldData(index));
        const std::string _035a_contents(_035_subfields.getFirstSubfieldValue('a'));
        if (StringUtil::StartsWith(_035a_contents, "(DE-588)"))
            return _035a_contents.substr(__builtin_strlen("(DE-588)"));
    }

    return "";
}

const std::string DROPPED_GND_LIST_FILE("/usr/local/var/log/tufind/dropped_gnd_numbers.list");

void FilterAuthorityData(MarcReader * const marc_reader, MarcWriter * const marc_writer,
                         const std::unordered_set<std::string> &gnd_numbers)
{
    std::unique_ptr<File> gnd_list_file(FileUtil::OpenOutputFileOrDie(DROPPED_GND_LIST_FILE));
    unsigned record_count(0), dropped_count(0), authority_records_without_gnd_numbers_count(0);
    while (const MarcRecord record = marc_reader->read()) {
        ++record_count;

        const std::string gnd_number(GetGNDNumber(record));
        if (gnd_numbers.find(gnd_number) == gnd_numbers.cend()) {
            gnd_list_file->write(gnd_number + "\n");
            ++dropped_count;
            continue;
        }

        if (gnd_number.empty())
            ++authority_records_without_gnd_numbers_count;
        marc_writer->write(record);
    }

    std::cerr << "Read " << record_count << " authority record(s) of which " << dropped_count << " were dropped.\n";
    std::cerr << "Found and kept " << authority_records_without_gnd_numbers_count
              << " authority records w/o a GND number.\n";
}

} // unnamed namespace

int main(int argc, char *argv[]) {
    ::progname = argv[0];

    if (argc != 4)
        Usage();

    try {
        std::unique_ptr<MarcReader> marc_title_reader(MarcReader::Factory(argv[1]));
        std::unique_ptr<MarcReader> marc_authority_reader(MarcReader::Factory(argv[2]));
        std::unique_ptr<MarcWriter> marc_authority_writer(MarcWriter::Factory(argv[3]));

        std::unordered_set<std::string> gnd_numbers;
        CollectGNDReferences(marc_title_reader.get(), &gnd_numbers);
        FilterAuthorityData(marc_authority_reader.get(), marc_authority_writer.get(), gnd_numbers);
    } catch (const std::exception &e) {
        logger->error("Caught exception: " + std::string(e.what()));
    }
}
<commit_msg>If at first you don't succeed, try, try again!<commit_after>/** \brief Utility for removing unreferenced authority records
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2017 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <stdexcept>
#include <unordered_set>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include "FileUtil.h"
#include "Leader.h"
#include "MarcReader.h"
#include "MarcRecord.h"
#include "MarcWriter.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "util.h"

namespace {

void Usage() __attribute__((noreturn));

void Usage() {
    std::cerr << "Usage: " << ::progname << " title_data authority_data filtered_authority_data\n";
    std::exit(EXIT_FAILURE);
}

void CollectGNDReferences(MarcReader * const marc_reader, std::unordered_set<std::string> * const gnd_numbers) {
    std::string err_msg;
    RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory("\x1F""0\\(DE-588\\)([^\x1F]+).*\x1F""2gnd",
                                                                   &err_msg));
    if (matcher == nullptr)
        logger->error("failed to compile a regex in CollectGNDReferences: " + err_msg);

    unsigned record_count(0);
    while (const MarcRecord record = marc_reader->read()) {
        ++record_count;

        for (const auto field_contents : record) {
            if (matcher->matched(field_contents))
                gnd_numbers->emplace((*matcher)[1]);
        }
    }

    std::cout << "Extracted " << gnd_numbers->size() << " GND number(s) from " <<  record_count
              << " title record(s).\n";
}

std::string GetGNDNumber(const MarcRecord &record) {
    std::vector<size_t> _035_indices;
    record.getFieldIndices("035", &_035_indices);

    for (const auto index : _035_indices) {
        const Subfields _035_subfields(record.getFieldData(index));
        const std::string _035a_contents(_035_subfields.getFirstSubfieldValue('a'));
        if (StringUtil::StartsWith(_035a_contents, "(DE-588)"))
            return _035a_contents.substr(__builtin_strlen("(DE-588)"));
    }

    return "";
}

const std::string DROPPED_GND_LIST_FILE("/usr/local/var/log/tufind/dropped_gnd_numbers.list");

void FilterAuthorityData(MarcReader * const marc_reader, MarcWriter * const marc_writer,
                         const std::unordered_set<std::string> &gnd_numbers)
{
    std::unique_ptr<File> gnd_list_file(FileUtil::OpenOutputFileOrDie(DROPPED_GND_LIST_FILE));
    unsigned record_count(0), dropped_count(0), authority_records_without_gnd_numbers_count(0);
    while (const MarcRecord record = marc_reader->read()) {
        ++record_count;

        const std::string gnd_number(GetGNDNumber(record));
        if (not gnd_number.empty() and gnd_numbers.find(gnd_number) == gnd_numbers.cend()) {
            gnd_list_file->write(gnd_number + "\n");
            ++dropped_count;
            continue;
        }

        if (gnd_number.empty())
            ++authority_records_without_gnd_numbers_count;
        marc_writer->write(record);
    }

    std::cerr << "Read " << record_count << " authority record(s) of which " << dropped_count << " were dropped.\n";
    std::cerr << "Found and kept " << authority_records_without_gnd_numbers_count
              << " authority records w/o a GND number.\n";
}

} // unnamed namespace

int main(int argc, char *argv[]) {
    ::progname = argv[0];

    if (argc != 4)
        Usage();

    try {
        std::unique_ptr<MarcReader> marc_title_reader(MarcReader::Factory(argv[1]));
        std::unique_ptr<MarcReader> marc_authority_reader(MarcReader::Factory(argv[2]));
        std::unique_ptr<MarcWriter> marc_authority_writer(MarcWriter::Factory(argv[3]));

        std::unordered_set<std::string> gnd_numbers;
        CollectGNDReferences(marc_title_reader.get(), &gnd_numbers);
        FilterAuthorityData(marc_authority_reader.get(), marc_authority_writer.get(), gnd_numbers);
    } catch (const std::exception &e) {
        logger->error("Caught exception: " + std::string(e.what()));
    }
}
<|endoftext|>


<commit_before>// ------------------------------------------------------------------------
// Copyright (C) 2009 Kai Vehmanen
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
// ------------------------------------------------------------------------

#include <cstdio>
#include <cstring>
#include <cstdlib>

#include "eca-version.h"
#include "samplebuffer.h"
#include "audiofx_amplitude.h"

#include "kvu_procedure_timer.h"
#include "ecatestsuite.h"

int test_sbuf_make_silent(void);
int test_sbuf_copy_ops(void);
int test_sbuf_constructor(void);
int test_sbuf_mix(void);
int test_sbuf_iter(void);

int main(int argc, char *argv[])
{
  int res = 0;

  std::printf("--------------------------------------------------------\n"
	      "Testing with libecasound *** v%s *** (%s).\n",
	      ecasound_library_version, __FILE__);

  res += test_sbuf_copy_ops();
  res += test_sbuf_constructor();
  res += test_sbuf_make_silent();
  res += test_sbuf_mix();
  res += test_sbuf_iter();

  return res;
}

void helper_print_one_result(const char *casename, const PROCEDURE_TIMER& t1, int loops, int bsize)
{
  double per_loop = t1.last_duration_seconds() / loops;

  std::printf("\t%-20.20s:\t%.03fms (%.03fus/loop, %.04f%% CPU@48kHz)\n",
	      casename,
	      t1.last_duration_seconds() * 1000.0,
	      per_loop * 1000000.0,
	      (per_loop / (((double)bsize) / 48000.0)));
}

int test_sbuf_make_silent(void)
{
  const int loops = 10000;
  const int bufsize = 1024;
  const int channels = 12;

  std::printf("sbuf_make_silent with %d loops (bufsize=%d, ch=%d):\n",
	      loops, bufsize, channels);

  PROCEDURE_TIMER t1;
  SAMPLE_BUFFER sbuf (bufsize, channels);

  /* note: make sure code is paged in */
  sbuf.make_silent();

  t1.start();
  for(int n = 0; n < loops; n++) {
    sbuf.make_silent_range(0, bufsize);
  }
  t1.stop();

  helper_print_one_result("make_silent_range", t1, loops, bufsize);

  /* note: make sure code is paged in */
  sbuf.make_silent_range(0, bufsize);
  t1.reset();

  t1.start();
  for(int n = 0; n < loops; n++) {
    sbuf.make_silent();
  }
  t1.stop();

  helper_print_one_result("make_silent", t1, loops, bufsize);
}

int test_sbuf_copy_ops(void)
{
  const int loops = 10000;
  const int bufsize = 1024;
  const int channels = 12;

  PROCEDURE_TIMER t1;
  SAMPLE_BUFFER sbuf_a (bufsize, channels);
  SAMPLE_BUFFER sbuf_b (bufsize, channels);

  std::printf("sbuf_copy_ops with %d loops (bufsize=%d, ch=%d):\n",
	      loops, bufsize, channels);

#if LIBECASOUND_VERSION >= 22
 {
   /* note: make sure code is paged in */
   sbuf_a.copy_all_content(sbuf_b);

   t1.start();
   for(int n = 0; n < loops; n++) {
     sbuf_a.copy_all_content(sbuf_b);
   }
   t1.stop();
   helper_print_one_result("copy_all_content", t1, loops, bufsize);
 }
 {
   /* note: make sure code is paged in */
   sbuf_a.copy_matching_channels(sbuf_b);
   t1.reset();

   t1.start();
   for(int n = 0; n < loops; n++) {
     sbuf_a.copy_matching_channels(sbuf_b);
   }
   t1.stop();
   helper_print_one_result("copy_matching_channels", t1, loops, bufsize);
 }
#else
 {
   /* note: make sure code is paged in */
   sbuf_a.copy(sbuf_b);

   t1.reset();
   t1.start();
   for(int n = 0; n < loops; n++) {
     sbuf_a.copy(sbuf_b);
   }
   t1.stop();

   helper_print_one_result("copy (v21-lib)", t1, loops, bufsize);
 }
#endif
 {
   size_t rawsize = sizeof(SAMPLE_BUFFER::sample_t) * bufsize * channels;
   void *rawbuf1 = std::malloc(rawsize);
   void *rawbuf2 = std::malloc(rawsize);

   std::memcpy(rawbuf1, rawbuf2, rawsize);
   t1.reset();
   t1.start();
   for(int n = 0; n < loops; n++) {
     std::memcpy(rawbuf1, rawbuf2, rawsize);
   }
   t1.stop();
   helper_print_one_result("copy_raw_memcpy", t1, loops, bufsize);
   std::free(rawbuf1);
   std::free(rawbuf2);
 }
}

int test_sbuf_constructor(void)
{
  const int loops = 10000;
  const int bufsize = 1024;
  const int channels = 12;

  PROCEDURE_TIMER t1;
  SAMPLE_BUFFER sbuf_a (bufsize, channels);

  std::printf("sbuf constructor with %d loops (bufsize=%d, ch=%d):\n",
	      loops, bufsize, channels);

  /* note: make sure code is paged in */

  t1.start();
  for(int n = 0; n < loops; n++) {
    SAMPLE_BUFFER sbuf_b (bufsize, channels);
  }
  t1.stop();

  helper_print_one_result("constructor", t1, loops, bufsize);
}

int test_sbuf_mix(void)
{
  const int loops = 10000;
  const int bufsize = 1024;
  const int channels = 12;

  std::printf("sbuf_mix with %d loops (bufsize=%d, ch=%d):\n",
	      loops, bufsize, channels);

  PROCEDURE_TIMER t1;
  SAMPLE_BUFFER sbuf_a (bufsize, channels);
  SAMPLE_BUFFER sbuf_b (bufsize, channels);

  /* case 1 */
  {
    sbuf_a.divide_by(1.23456789);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.divide_by(1.23456789);
    }
    t1.stop();

    helper_print_one_result("divide_by", t1, loops, bufsize);
  }

  /* case 1b */
  {
#if LIBECASOUND_VERSION >= 22
    sbuf_a.divide_by_ref(1.23456789);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.divide_by_ref(1.23456789);
    }
    t1.stop();

    helper_print_one_result("divide_by_ref", t1, loops, bufsize);
#endif
  }

  /* case 2 */
  {
    sbuf_a.add_with_weight(sbuf_b, 2);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.add_with_weight(sbuf_b, 2);
    }
    t1.stop();

    helper_print_one_result("add_with_weight", t1, loops, bufsize);
  }

  /* case 3 */
  {
#if LIBECASOUND_VERSION >= 22
    sbuf_a.add_matching_channels(sbuf_b);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.add_matching_channels(sbuf_b);
    }
    t1.stop();

    helper_print_one_result("add_matching_channels", t1, loops, bufsize);

    /* case 3b */
    sbuf_a.add_matching_channels_ref(sbuf_b);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.add_matching_channels_ref(sbuf_b);
    }
    t1.stop();

    helper_print_one_result("add_matching_ch...ref", t1, loops, bufsize);

#else
    sbuf_a.add(sbuf_b);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.add(sbuf_b);
    }
    t1.stop();

    helper_print_one_result("add (v21-lib)", t1, loops, bufsize);
#endif
  }

  /* case 4 */
  {
    sbuf_a.limit_values();
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.limit_values();
    }
    t1.stop();

    helper_print_one_result("limit_values", t1, loops, bufsize);

    /* case 4b */
#if LIBECASOUND_VERSION >= 22
    sbuf_a.limit_values_ref();
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.limit_values_ref();
    }
    t1.stop();

    helper_print_one_result("limit_values_ref", t1, loops, bufsize);
#endif
  }
}

int test_sbuf_iter(void)
{
  const int loops = 10000;
  const int bufsize = 1024;
  const int channels = 12;
  const SAMPLE_BUFFER::sample_t multiplier = 100.1f;

  std::printf("sbuf_iter with %d loops (bufsize=%d, ch=%d):\n",
	      loops, bufsize, channels);

  PROCEDURE_TIMER t1;
  SAMPLE_BUFFER sbuf_a (bufsize, channels);
  EFFECT_AMPLIFY amplify (multiplier);

  /* case 1 */
  {
    amplify.init(&sbuf_a);
    amplify.process();

    t1.reset();
    t1.start();
    for(int n = 0; n < loops; n++) {
      amplify.process();
    }
    t1.stop();

    helper_print_one_result("effect_amplify", t1, loops, bufsize);
  }

  /* case 2 */
  {
    int ch_count = sbuf_a.number_of_channels();
    int i_count = sbuf_a.length_in_samples();
    t1.reset();
    t1.start();
    for(int n = 0; n < loops; n++) {
      for (int ch = 0; ch < ch_count; ch++) {
	SAMPLE_BUFFER::sample_t *buf = sbuf_a.buffer[ch];
	for (int i = 0; i < i_count; i++) {
	  buf[i] *= multiplier;
	}
      }
    }
    t1.stop();

    helper_print_one_result("amplify_plainc", t1, loops, bufsize);
  }

  /* case 3+4 */
  {
#if LIBECASOUND_VERSION >= 22
    sbuf_a.multiply_by(multiplier);
    t1.reset();
    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.multiply_by(multiplier);
    }
    t1.stop();
    helper_print_one_result("amplify_sbuf", t1, loops, bufsize);

    sbuf_a.multiply_by_ref(multiplier);
    t1.reset();
    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.multiply_by_ref(multiplier);
    }
    t1.stop();
    helper_print_one_result("amplify_sbuf_ref", t1, loops, bufsize);

#endif
  }

}
<commit_msg>Added loop performance test case for EFFECT_AMPLIFY<commit_after>// ------------------------------------------------------------------------
// Copyright (C) 2009 Kai Vehmanen
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
// ------------------------------------------------------------------------

#include <cstdio>
#include <cstring>
#include <cstdlib>

#include "eca-version.h"
#include "samplebuffer.h"
#include "audiofx_amplitude.h"

#include "kvu_procedure_timer.h"
#include "ecatestsuite.h"

int test_sbuf_make_silent(void);
int test_sbuf_copy_ops(void);
int test_sbuf_constructor(void);
int test_sbuf_mix(void);
int test_sbuf_iter(void);

int main(int argc, char *argv[])
{
  int res = 0;

  std::printf("--------------------------------------------------------\n"
	      "Testing with libecasound *** v%s *** (%s).\n",
	      ecasound_library_version, __FILE__);

  res += test_sbuf_copy_ops();
  res += test_sbuf_constructor();
  res += test_sbuf_make_silent();
  res += test_sbuf_mix();
  res += test_sbuf_iter();

  return res;
}

void helper_print_one_result(const char *casename, const PROCEDURE_TIMER& t1, int loops, int bsize)
{
  double per_loop = t1.last_duration_seconds() / loops;

  std::printf("\t%-20.20s:\t%.03fms (%.03fus/loop, %.04f%% CPU@48kHz)\n",
	      casename,
	      t1.last_duration_seconds() * 1000.0,
	      per_loop * 1000000.0,
	      (per_loop / (((double)bsize) / 48000.0)));
}

int test_sbuf_make_silent(void)
{
  const int loops = 10000;
  const int bufsize = 1024;
  const int channels = 12;

  std::printf("sbuf_make_silent with %d loops (bufsize=%d, ch=%d):\n",
	      loops, bufsize, channels);

  PROCEDURE_TIMER t1;
  SAMPLE_BUFFER sbuf (bufsize, channels);

  /* note: make sure code is paged in */
  sbuf.make_silent();

  t1.start();
  for(int n = 0; n < loops; n++) {
    sbuf.make_silent_range(0, bufsize);
  }
  t1.stop();

  helper_print_one_result("make_silent_range", t1, loops, bufsize);

  /* note: make sure code is paged in */
  sbuf.make_silent_range(0, bufsize);
  t1.reset();

  t1.start();
  for(int n = 0; n < loops; n++) {
    sbuf.make_silent();
  }
  t1.stop();

  helper_print_one_result("make_silent", t1, loops, bufsize);
}

int test_sbuf_copy_ops(void)
{
  const int loops = 10000;
  const int bufsize = 1024;
  const int channels = 12;

  PROCEDURE_TIMER t1;
  SAMPLE_BUFFER sbuf_a (bufsize, channels);
  SAMPLE_BUFFER sbuf_b (bufsize, channels);

  std::printf("sbuf_copy_ops with %d loops (bufsize=%d, ch=%d):\n",
	      loops, bufsize, channels);

#if LIBECASOUND_VERSION >= 22
 {
   /* note: make sure code is paged in */
   sbuf_a.copy_all_content(sbuf_b);

   t1.start();
   for(int n = 0; n < loops; n++) {
     sbuf_a.copy_all_content(sbuf_b);
   }
   t1.stop();
   helper_print_one_result("copy_all_content", t1, loops, bufsize);
 }
 {
   /* note: make sure code is paged in */
   sbuf_a.copy_matching_channels(sbuf_b);
   t1.reset();

   t1.start();
   for(int n = 0; n < loops; n++) {
     sbuf_a.copy_matching_channels(sbuf_b);
   }
   t1.stop();
   helper_print_one_result("copy_matching_channels", t1, loops, bufsize);
 }
#else
 {
   /* note: make sure code is paged in */
   sbuf_a.copy(sbuf_b);

   t1.reset();
   t1.start();
   for(int n = 0; n < loops; n++) {
     sbuf_a.copy(sbuf_b);
   }
   t1.stop();

   helper_print_one_result("copy (v21-lib)", t1, loops, bufsize);
 }
#endif
 {
   size_t rawsize = sizeof(SAMPLE_BUFFER::sample_t) * bufsize * channels;
   void *rawbuf1 = std::malloc(rawsize);
   void *rawbuf2 = std::malloc(rawsize);

   std::memcpy(rawbuf1, rawbuf2, rawsize);
   t1.reset();
   t1.start();
   for(int n = 0; n < loops; n++) {
     std::memcpy(rawbuf1, rawbuf2, rawsize);
   }
   t1.stop();
   helper_print_one_result("copy_raw_memcpy", t1, loops, bufsize);
   std::free(rawbuf1);
   std::free(rawbuf2);
 }
}

int test_sbuf_constructor(void)
{
  const int loops = 10000;
  const int bufsize = 1024;
  const int channels = 12;

  PROCEDURE_TIMER t1;
  SAMPLE_BUFFER sbuf_a (bufsize, channels);

  std::printf("sbuf constructor with %d loops (bufsize=%d, ch=%d):\n",
	      loops, bufsize, channels);

  /* note: make sure code is paged in */

  t1.start();
  for(int n = 0; n < loops; n++) {
    SAMPLE_BUFFER sbuf_b (bufsize, channels);
  }
  t1.stop();

  helper_print_one_result("constructor", t1, loops, bufsize);
}

int test_sbuf_mix(void)
{
  const int loops = 10000;
  const int bufsize = 1024;
  const int channels = 12;

  std::printf("sbuf_mix with %d loops (bufsize=%d, ch=%d):\n",
	      loops, bufsize, channels);

  PROCEDURE_TIMER t1;
  SAMPLE_BUFFER sbuf_a (bufsize, channels);
  SAMPLE_BUFFER sbuf_b (bufsize, channels);

  /* case 1 */
  {
    sbuf_a.divide_by(1.23456789);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.divide_by(1.23456789);
    }
    t1.stop();

    helper_print_one_result("divide_by", t1, loops, bufsize);
  }

  /* case 1b */
  {
#if LIBECASOUND_VERSION >= 22
    sbuf_a.divide_by_ref(1.23456789);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.divide_by_ref(1.23456789);
    }
    t1.stop();

    helper_print_one_result("divide_by_ref", t1, loops, bufsize);
#endif
  }

  /* case 2 */
  {
    sbuf_a.add_with_weight(sbuf_b, 2);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.add_with_weight(sbuf_b, 2);
    }
    t1.stop();

    helper_print_one_result("add_with_weight", t1, loops, bufsize);
  }

  /* case 3 */
  {
#if LIBECASOUND_VERSION >= 22
    sbuf_a.add_matching_channels(sbuf_b);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.add_matching_channels(sbuf_b);
    }
    t1.stop();

    helper_print_one_result("add_matching_channels", t1, loops, bufsize);

    /* case 3b */
    sbuf_a.add_matching_channels_ref(sbuf_b);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.add_matching_channels_ref(sbuf_b);
    }
    t1.stop();

    helper_print_one_result("add_matching_ch...ref", t1, loops, bufsize);

#else
    sbuf_a.add(sbuf_b);
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.add(sbuf_b);
    }
    t1.stop();

    helper_print_one_result("add (v21-lib)", t1, loops, bufsize);
#endif
  }

  /* case 4 */
  {
    sbuf_a.limit_values();
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.limit_values();
    }
    t1.stop();

    helper_print_one_result("limit_values", t1, loops, bufsize);

    /* case 4b */
#if LIBECASOUND_VERSION >= 22
    sbuf_a.limit_values_ref();
    t1.reset();

    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.limit_values_ref();
    }
    t1.stop();

    helper_print_one_result("limit_values_ref", t1, loops, bufsize);
#endif
  }
}

int test_sbuf_iter(void)
{
  const int loops = 10000;
  const int bufsize = 1024;
  const int channels = 12;
  const SAMPLE_BUFFER::sample_t multiplier = 100.1f;

  std::printf("sbuf_iter with %d loops (bufsize=%d, ch=%d):\n",
	      loops, bufsize, channels);

  PROCEDURE_TIMER t1;
  SAMPLE_BUFFER sbuf_a (bufsize, channels);
  EFFECT_AMPLIFY amplify (multiplier);

  /* case 1a */
  {
    amplify.init(&sbuf_a);
    amplify.process();

    t1.reset();
    t1.start();
    for(int n = 0; n < loops; n++) {
      amplify.process();
    }
    t1.stop();

    helper_print_one_result("effect_amplify", t1, loops, bufsize);
  }

  /* case 1b */
  {
    amplify.init(&sbuf_a);
    amplify.process_ref();

    t1.reset();
    t1.start();
    for(int n = 0; n < loops; n++) {
      amplify.process_ref();
    }
    t1.stop();

    helper_print_one_result("effect_amplify_ref", t1, loops, bufsize);
  }

  /* case 2 */
  {
    int ch_count = sbuf_a.number_of_channels();
    int i_count = sbuf_a.length_in_samples();
    t1.reset();
    t1.start();
    for(int n = 0; n < loops; n++) {
      for (int ch = 0; ch < ch_count; ch++) {
	SAMPLE_BUFFER::sample_t *buf = sbuf_a.buffer[ch];
	for (int i = 0; i < i_count; i++) {
	  buf[i] *= multiplier;
	}
      }
    }
    t1.stop();

    helper_print_one_result("amplify_plainc", t1, loops, bufsize);
  }

  /* case 3+4 */
  {
#if LIBECASOUND_VERSION >= 22
    sbuf_a.multiply_by(multiplier);
    t1.reset();
    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.multiply_by(multiplier);
    }
    t1.stop();
    helper_print_one_result("amplify_sbuf", t1, loops, bufsize);

    sbuf_a.multiply_by_ref(multiplier);
    t1.reset();
    t1.start();
    for(int n = 0; n < loops; n++) {
      sbuf_a.multiply_by_ref(multiplier);
    }
    t1.stop();
    helper_print_one_result("amplify_sbuf_ref", t1, loops, bufsize);

#endif
  }

}
<|endoftext|>


<commit_before><commit_msg>modular<commit_after><|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkToFImageDownsamplingFilter.h"
#include <itkResampleImageFilter.h>
#include <mitkImageCast.h>
#include <mitkImageAccessByItk.h>
#include <itkImageFileWriter.h>
#include <itkIdentityTransform.h>
#include <itkLinearInterpolateImageFunction.h>
#include <itkNearestNeighborInterpolateImageFunction.h>

mitk::ToFImageDownsamplingFilter::ToFImageDownsamplingFilter():
m_ResampledX(100), m_ResampledY(100),m_ResampledZ(1)
{
}

mitk::ToFImageDownsamplingFilter::~ToFImageDownsamplingFilter()
{
}

void mitk::ToFImageDownsamplingFilter::GenerateData()
{
  // set input image

  mitk::Image::ConstPointer inputImage = this->GetInput(0) ;
  if ( (inputImage->GetDimension() > 3) || (inputImage->GetDimension() < 2) )
  {
    MITK_ERROR << "mitk::TofImageDownsamplingFilter:GenerateData works only with 2D and 3D images, sorry." << std::endl;
    itkExceptionMacro("mitk::TofImageDownsamplingFilter:GenerateData works only with 2D and 3D images, sorry.");
    return;
  }

  if ( (inputImage->GetDimension(0)<m_ResampledX) || (inputImage->GetDimension(1)<m_ResampledY) || (inputImage->GetDimension(2)<m_ResampledZ) )
  {
    MITK_ERROR << "mitk::TofImageDownsamplingFilter:GenerateData only downsamples. Your requested dimensions exceed the original image dimensions." << std::endl;
    itkExceptionMacro("mitk::TofImageDownsamplingFilter:GenerateData only downsamples. Your requested dimensions exceed the original image dimensions.");
    return;
  }

  if ( (m_ResampledX < 1) || (m_ResampledY < 1)|| (m_ResampledZ < 1) )
  {
    MITK_ERROR << "mitk::TofImageDownsamplingFilter:GenerateData works only for positive input dimensions " << std::endl;
    itkExceptionMacro("mitk::TofImageDownsamplingFilter:GenerateData works only for positive input dimensions");
    return;
  }

  switch(inputImage->GetDimension())
  {
  case 2:
    {
      AccessFixedDimensionByItk( inputImage.GetPointer(), ItkImageResampling, 2 ); break;
    }
  case 3:
    {
      AccessFixedDimensionByItk( inputImage.GetPointer(), ItkImageResampling, 3 ); break;
    }

  default: break;
  }

}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ToFImageDownsamplingFilter::ItkImageResampling( itk::Image<TPixel,VImageDimension>* itkImage )
{
  // declare typdef for itk image from input mitk image
 typedef itk::Image< TPixel, VImageDimension >   ItkImageType;

  //declare itk filter related typedefs (transform type, interpolater, and size type)
  typedef itk::ResampleImageFilter<ItkImageType,ItkImageType>    ResamplerFilterType;
  typedef itk::IdentityTransform<double, VImageDimension> TransformType;
  typedef itk::NearestNeighborInterpolateImageFunction<ItkImageType, double > InterpolatorType;
  typedef typename ItkImageType::SizeType::SizeValueType SizeValueType;

  //instantiate filter related parameters
  typename ResamplerFilterType::Pointer resampler = ResamplerFilterType::New();
  typename TransformType::Pointer transform = TransformType::New();
  typename InterpolatorType::Pointer interpolator = InterpolatorType::New();

  // establish size for downsampled image ( the result of this filter)
  typename ItkImageType::SizeType inputSize = itkImage->GetLargestPossibleRegion().GetSize();
  typename ItkImageType::SizeType size;

  size[0] = static_cast< SizeValueType >( m_ResampledX );
  size[1] = static_cast< SizeValueType >( m_ResampledY );
  size[2] = static_cast< SizeValueType >( m_ResampledZ );

  //establish spacing for new downsampled image ( resulting image)
  const typename ItkImageType::SpacingType& inputSpacing = itkImage->GetSpacing();
  typename ItkImageType::SpacingType spacing;

  spacing[0] = inputSpacing[0] * ( inputSize[0]/ m_ResampledX );
  spacing[1] = inputSpacing[1] * ( inputSize[1]/ m_ResampledY );
  spacing[2] = inputSpacing[2] * ( inputSize[2]/ m_ResampledZ );

  // set filter parameters and update
  transform->SetIdentity();
  resampler->SetTransform(transform);
  resampler->SetInterpolator(interpolator);
  resampler->SetOutputSpacing(spacing);
  resampler->SetOutputOrigin(itkImage->GetOrigin());
  resampler->SetSize(size);
  resampler->SetInput(itkImage);
  resampler->UpdateLargestPossibleRegion();

  // Create mitk container for resulting image
  mitk::Image::Pointer resultImage = ImageToImageFilter::GetOutput();

  // Cast itk image to mitk image
  mitk::CastToMitkImage(resampler->GetOutput(), resultImage);
}
<commit_msg>Fixed a minor bug where the downsampling filter would not pass origin and spacing to its result iamge.<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkToFImageDownsamplingFilter.h"
#include <itkResampleImageFilter.h>
#include <mitkImageCast.h>
#include <mitkImageAccessByItk.h>
#include <itkImageFileWriter.h>
#include <itkIdentityTransform.h>
#include <itkLinearInterpolateImageFunction.h>
#include <itkNearestNeighborInterpolateImageFunction.h>

mitk::ToFImageDownsamplingFilter::ToFImageDownsamplingFilter():
m_ResampledX(100), m_ResampledY(100),m_ResampledZ(1)
{
}

mitk::ToFImageDownsamplingFilter::~ToFImageDownsamplingFilter()
{
}

void mitk::ToFImageDownsamplingFilter::GenerateData()
{
  // set input image

  mitk::Image::ConstPointer inputImage = this->GetInput(0) ;
  if ( (inputImage->GetDimension() > 3) || (inputImage->GetDimension() < 2) )
  {
    MITK_ERROR << "mitk::TofImageDownsamplingFilter:GenerateData works only with 2D and 3D images, sorry." << std::endl;
    itkExceptionMacro("mitk::TofImageDownsamplingFilter:GenerateData works only with 2D and 3D images, sorry.");
    return;
  }

  if ( (inputImage->GetDimension(0)<m_ResampledX) || (inputImage->GetDimension(1)<m_ResampledY) || (inputImage->GetDimension(2)<m_ResampledZ) )
  {
    MITK_ERROR << "mitk::TofImageDownsamplingFilter:GenerateData only downsamples. Your requested dimensions exceed the original image dimensions." << std::endl;
    itkExceptionMacro("mitk::TofImageDownsamplingFilter:GenerateData only downsamples. Your requested dimensions exceed the original image dimensions.");
    return;
  }

  if ( (m_ResampledX < 1) || (m_ResampledY < 1)|| (m_ResampledZ < 1) )
  {
    MITK_ERROR << "mitk::TofImageDownsamplingFilter:GenerateData works only for positive input dimensions " << std::endl;
    itkExceptionMacro("mitk::TofImageDownsamplingFilter:GenerateData works only for positive input dimensions");
    return;
  }

  switch(inputImage->GetDimension())
  {
  case 2:
    {
      AccessFixedDimensionByItk( inputImage.GetPointer(), ItkImageResampling, 2 ); break;
    }
  case 3:
    {
      AccessFixedDimensionByItk( inputImage.GetPointer(), ItkImageResampling, 3 ); break;
    }

  default: break;
  }

}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ToFImageDownsamplingFilter::ItkImageResampling( itk::Image<TPixel,VImageDimension>* itkImage )
{
  // declare typdef for itk image from input mitk image
 typedef itk::Image< TPixel, VImageDimension >   ItkImageType;

  //declare itk filter related typedefs (transform type, interpolater, and size type)
  typedef itk::ResampleImageFilter<ItkImageType,ItkImageType>    ResamplerFilterType;
  typedef itk::IdentityTransform<double, VImageDimension> TransformType;
  typedef itk::NearestNeighborInterpolateImageFunction<ItkImageType, double > InterpolatorType;
  typedef typename ItkImageType::SizeType::SizeValueType SizeValueType;

  //instantiate filter related parameters
  typename ResamplerFilterType::Pointer resampler = ResamplerFilterType::New();
  typename TransformType::Pointer transform = TransformType::New();
  typename InterpolatorType::Pointer interpolator = InterpolatorType::New();

  // establish size for downsampled image ( the result of this filter)
  typename ItkImageType::SizeType inputSize = itkImage->GetLargestPossibleRegion().GetSize();
  typename ItkImageType::SizeType size;

  size[0] = static_cast< SizeValueType >( m_ResampledX );
  size[1] = static_cast< SizeValueType >( m_ResampledY );
  size[2] = static_cast< SizeValueType >( m_ResampledZ );

  //establish spacing for new downsampled image ( resulting image)
  const typename ItkImageType::SpacingType& inputSpacing = itkImage->GetSpacing();
  typename ItkImageType::SpacingType outputSpacing;

  outputSpacing[0] = inputSpacing[0] * ( inputSize[0]/ m_ResampledX );
  outputSpacing[1] = inputSpacing[1] * ( inputSize[1]/ m_ResampledY );
  outputSpacing[2] = inputSpacing[2] * ( inputSize[2]/ m_ResampledZ );

  // set filter parameters and update
  transform->SetIdentity();
  resampler->SetTransform(transform);
  resampler->SetInterpolator(interpolator);
  resampler->SetOutputSpacing(outputSpacing);
  resampler->SetOutputOrigin(itkImage->GetOrigin());
  resampler->SetSize(size);
  resampler->SetInput(itkImage);
  resampler->UpdateLargestPossibleRegion();

  // Create mitk container for resulting image
  mitk::Image::Pointer resultImage = ImageToImageFilter::GetOutput();
  resultImage->SetSpacing(outputSpacing);
  resultImage->SetOrigin(itkImage->GetOrigin());

  // Cast itk image to mitk image
  mitk::CastToMitkImage(resampler->GetOutput(), resultImage);
}
<|endoftext|>