<commit_before>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
    Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//!
//! @file   AuxiliarySimulationFunctions.cc
//! @author Robert Braun <robert.braun@liu.se>
//! @date   2010-06-30
//!
//! @brief Contiains a second order integrator utility with provision for some damping
//!
//$Id$

#include "ComponentUtilities/AuxiliarySimulationFunctions.h"
#include <cmath>
#include <limits>

using namespace hopsan;

//! @defgroup ComponentUtilities ComponentUtilities
//! @defgroup AuxiliarySimulationFunctions AuxiliarySimulationFunctions
//! @ingroup ComponentUtilities
//! @defgroup ComponentUtilityClasses ComponentUtilityClasses
//! @ingroup ComponentUtilities

//! @brief Limits a value so it is between min and max
//! @ingroup AuxiliarySimulationFunctions
//! @param &rValue Reference pointer to the value
//! @param min Lower limit of the value
//! @param max Upper limit of the value
void hopsan::limitValue(double &rValue, double min, double max)
{
    if(min>max)
    {
        double temp;
        temp = max;
        max = min;
        min = temp;
    }
    if(rValue > max)
    {
        rValue = max;
    }
    else if(rValue < min)
    {
        rValue = min;
    }
}

//! @brief checks if two double varaiables are equal with a tolerance
//! @ingroup AuxiliarySimulationFunctions
//! @param [in] x First value
//! @param [in] y Second value
//! @param [in] eps Allowed relative error
//! @note Based on http://floating-point-gui.de/errors/comparison (20130429)
bool hopsan::fuzzyEqual(const double x, const double y, const double epsilon)
{
    const double absX = fabs(x);
    const double absY = fabs(y);
    const double diff = fabs(x-y);

    // shortcut, handles infinities
    if (x == y)
    {
        return true;
    }
    // a or b is zero or both are extremely close to it
    // relative error is less meaningful here
    else if (x == 0 || y == 0 || diff < std::numeric_limits<double>::epsilon() )
    {

        return diff < (epsilon * std::numeric_limits<double>::epsilon() );
    }
    // use relative error
    else
    {
        return diff / (absX + absY) < epsilon;
    }
}

//! @ingroup AuxiliarySimulationFunctions
double hopsan::signedSquareL(const double x, const double x0)
{
    return (-sqrt(x0) + sqrt(x0 + fabs(x))) * sign(x);
}

//! @ingroup AuxiliarySimulationFunctions
double hopsan::dxSignedSquareL(const double x, const double x0)
{
    return (1.0 / (sqrt(x0 + fabs(x)) * 2.0));
}

//! @ingroup AuxiliarySimulationFunctions
double hopsan::squareAbsL(const double x, const double x0)
{
    return (-sqrt(x0) + sqrt(x0 + fabs(x)));
}

//! @ingroup AuxiliarySimulationFunctions
double hopsan::dxSquareAbsL(const double x, const double x0)
{
    return 1.0 / (sqrt(x0 + fabs(x)) * 2.0) * sign(x);
}

//! @brief Safe variant of atan2
//! @ingroup AuxiliarySimulationFunctions
double hopsan::Atan2L(const double y, const double x)
{
    if (x >0. || x<0.)
    { return atan2(y,x);}
        else
    {return 0.;}
}

//! @brief Returns 1.0 if input variables have same sign, else returns 0.0
//! @ingroup AuxiliarySimulationFunctions
double hopsan::equalSigns(const double x, const double y)
{
//    //! @warning This will NOT work (double != double)
//    if (hopsan::sign(x) != hopsan::sign(y)) {
//        return 0.0;
//    }
//    return 1.0;

    if ( ((x < 0.0) && ( y < 0.0)) || ((x >= 0.0) && (y >= 0.0)) )
    {
        return 1.0;
    }
    else
    {
        return 0.0;
    }
}

//! @brief Safe variant of asin
//! @ingroup AuxiliarySimulationFunctions
double hopsan::ArcSinL(const double x)
{
    return asin(limit(x,-0.999,0.999));
}

//! @brief derivative of AsinL
//! @ingroup AuxiliarySimulationFunctions
double hopsan::dxArcSinL(const double x)
{
    return 1.0/sqrt(1 - pow(limit(x,-0.999,0.999),2));
}

//! @brief difference between two angles, fi1-fi2
//! @ingroup AuxiliarySimulationFunctions
double hopsan::diffAngle(const double fi1, const double fi2)
{   double output;
    double output0 = fi1-fi2;
    double output1 = fi1-fi2 + 2.0*pi;//3.14159;
    double output2 = fi1-fi2 - 2.0*pi;//3.14159;
                                      output = output0;
    if (fabs(output0)> fabs(output1)){output = output1;}
    if (fabs(output0)> fabs(output2)){output = output2;}

    return output;
}

//! @brief Lift coefficient for aircraft model
//! @ingroup AuxiliarySimulationFunctions
double hopsan::CLift(const double alpha, const double CLalpha, const double ap, const double an, const double awp, const double awn)
{
    return (1 - 1/(1 + pow(2.71828,(-2*(-alpha - an))/awn)) - 1/(1 + pow(2.71828,(-2*(alpha - ap))/awp)))*alpha*
            CLalpha + 0.707107*(1/(1 + pow(2.71828,(-2*(-alpha - an))/awn)) +
              1/(1 + pow(2.71828,(-2*(alpha - ap))/awp)))*sin(2*alpha);
}

//! @brief Induced drag coefficient for aircraft model
//! @ingroup AuxiliarySimulationFunctions
double hopsan::CDragInd(const double alpha, const double AR, const double e, const double CLalpha, const double ap, const double an, const double awp, const double awn)
{
    return (0.31831*(1 - 1/(1 + pow(2.71828,(-2*(-alpha - an))/awn)) - 1/(1 + pow(2.71828,(-2*(alpha - ap))/awp)))*
             pow(alpha,2)*pow(CLalpha,2))/(AR*e) +
          (1/(1 + pow(2.71828,(-2*(-alpha - an))/awn)) + 1/(1 + pow(2.71828,(-2*(alpha - ap))/awp)))*
           pow(sin(alpha),2);
}

//! @brief Moment coefficient for aircraft model
//! @ingroup AuxiliarySimulationFunctions
double hopsan::CMoment(const double alpha, const double Cm0, const double Cmfs, const double /*ap*/, const double /*an*/, const double /*awp*/, const double /*awn*/)
{
    return (1 - 1/(1 + pow(2.71828,-20.*(-0.5 - alpha))) - 1/(1 + pow(2.71828,-20.*(-0.5 + alpha))))*Cm0 +
            (1/(1 + pow(2.71828,-20.*(-0.5 - alpha))) + 1/(1 + pow(2.71828,-20.*(-0.5 + alpha))))*Cmfs*sign(alpha);
}

//! @brief Overloads void hopsan::limitValue() with a return value.
//! @ingroup AuxiliarySimulationFunctions
//! @see void hopsan::limitValue(&value, min, max)
//! @param x Value to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
double hopsan::limit(const double x, const double xmin, const double xmax)
{
    double output = x;
    limitValue(output, xmin, xmax);
    return output;
}

//! @brief Sets the derivative of x to zero if x is outside of limits.
//! @ingroup AuxiliarySimulationFunctions
//! @details Returns 1.0 if x is within limits, else 0.0. Used to make the derivative of x zero if limit is reached.
//! @param x Value whos derivative is to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
//! @returns Limited derivative of x
double hopsan::dxLimit(const double x, const double xmin, const double xmax)
{
    if (x >= xmax) { return 0.000000001; }
    if (x <= xmin) { return 0.000000001; }
    return 1.0;
}

//! @brief Limits the derivative of x when x is outside of its limits.
//! @ingroup AuxiliarySimulationFunctions
//! Returns 1.0 if x is within borders, or if x is outside borders but derivative has opposite sign (so that x can only move back to the limited range).
//! @param x Value whos derivative is to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
//! @returns Limited derivative of x
double hopsan::dxLimit2(const double x, const double sx, const double xmin, const double xmax)
{
    if (x >= xmax && sx >= 0.0) { return 0.0000001; }
    if (x <= xmin && sx <= 0.0) { return 0.0000001; }
    return 1.0;
}

//! @brief Returns the algebraic quotient x/y with any fractional parts discarded
//! @ingroup AuxiliarySimlationFunctions
//! @ingroup ModelicaWrapperFunctions
//! @param x Numinator
//! @param y Denominator
//! @returns Algebraic quotient with any fracrional parts discarded
double div(const double x, const double y)
{
    if(x/y > 0)
    {
        return floor(x/y);
    }
    else
    {
        return ceil(x/y);
    }
}
<commit_msg>lowLimits added<commit_after>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
    Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//!
//! @file   AuxiliarySimulationFunctions.cc
//! @author Robert Braun <robert.braun@liu.se>
//! @date   2010-06-30
//!
//! @brief Contiains a second order integrator utility with provision for some damping
//!
//$Id$

#include "ComponentUtilities/AuxiliarySimulationFunctions.h"
#include <cmath>
#include <limits>

using namespace hopsan;

//! @defgroup ComponentUtilities ComponentUtilities
//! @defgroup AuxiliarySimulationFunctions AuxiliarySimulationFunctions
//! @ingroup ComponentUtilities
//! @defgroup ComponentUtilityClasses ComponentUtilityClasses
//! @ingroup ComponentUtilities

//! @brief Limits a value so it is between min and max
//! @ingroup AuxiliarySimulationFunctions
//! @param &rValue Reference pointer to the value
//! @param min Lower limit of the value
//! @param max Upper limit of the value
void hopsan::limitValue(double &rValue, double min, double max)
{
    if(min>max)
    {
        double temp;
        temp = max;
        max = min;
        min = temp;
    }
    if(rValue > max)
    {
        rValue = max;
    }
    else if(rValue < min)
    {
        rValue = min;
    }
}

//! @brief checks if two double varaiables are equal with a tolerance
//! @ingroup AuxiliarySimulationFunctions
//! @param [in] x First value
//! @param [in] y Second value
//! @param [in] eps Allowed relative error
//! @note Based on http://floating-point-gui.de/errors/comparison (20130429)
bool hopsan::fuzzyEqual(const double x, const double y, const double epsilon)
{
    const double absX = fabs(x);
    const double absY = fabs(y);
    const double diff = fabs(x-y);

    // shortcut, handles infinities
    if (x == y)
    {
        return true;
    }
    // a or b is zero or both are extremely close to it
    // relative error is less meaningful here
    else if (x == 0 || y == 0 || diff < std::numeric_limits<double>::epsilon() )
    {

        return diff < (epsilon * std::numeric_limits<double>::epsilon() );
    }
    // use relative error
    else
    {
        return diff / (absX + absY) < epsilon;
    }
}

//! @ingroup AuxiliarySimulationFunctions
double hopsan::signedSquareL(const double x, const double x0)
{
    return (-sqrt(x0) + sqrt(x0 + fabs(x))) * sign(x);
}

//! @ingroup AuxiliarySimulationFunctions
double hopsan::dxSignedSquareL(const double x, const double x0)
{
    return (1.0 / (sqrt(x0 + fabs(x)) * 2.0));
}

//! @ingroup AuxiliarySimulationFunctions
double hopsan::squareAbsL(const double x, const double x0)
{
    return (-sqrt(x0) + sqrt(x0 + fabs(x)));
}

//! @ingroup AuxiliarySimulationFunctions
double hopsan::dxSquareAbsL(const double x, const double x0)
{
    return 1.0 / (sqrt(x0 + fabs(x)) * 2.0) * sign(x);
}

//! @brief Safe variant of atan2
//! @ingroup AuxiliarySimulationFunctions
double hopsan::Atan2L(const double y, const double x)
{
    if (x >0. || x<0.)
    { return atan2(y,x);}
        else
    {return 0.;}
}

//! @brief Returns 1.0 if input variables have same sign, else returns 0.0
//! @ingroup AuxiliarySimulationFunctions
double hopsan::equalSigns(const double x, const double y)
{
//    //! @warning This will NOT work (double != double)
//    if (hopsan::sign(x) != hopsan::sign(y)) {
//        return 0.0;
//    }
//    return 1.0;

    if ( ((x < 0.0) && ( y < 0.0)) || ((x >= 0.0) && (y >= 0.0)) )
    {
        return 1.0;
    }
    else
    {
        return 0.0;
    }
}

//! @brief Safe variant of asin
//! @ingroup AuxiliarySimulationFunctions
double hopsan::ArcSinL(const double x)
{
    return asin(limit(x,-0.999,0.999));
}

//! @brief derivative of AsinL
//! @ingroup AuxiliarySimulationFunctions
double hopsan::dxArcSinL(const double x)
{
    return 1.0/sqrt(1 - pow(limit(x,-0.999,0.999),2));
}

//! @brief difference between two angles, fi1-fi2
//! @ingroup AuxiliarySimulationFunctions
double hopsan::diffAngle(const double fi1, const double fi2)
{   double output;
    double output0 = fi1-fi2;
    double output1 = fi1-fi2 + 2.0*pi;//3.14159;
    double output2 = fi1-fi2 - 2.0*pi;//3.14159;
                                      output = output0;
    if (fabs(output0)> fabs(output1)){output = output1;}
    if (fabs(output0)> fabs(output2)){output = output2;}

    return output;
}

//! @brief Lift coefficient for aircraft model
//! @ingroup AuxiliarySimulationFunctions
double hopsan::CLift(const double alpha, const double CLalpha, const double ap, const double an, const double awp, const double awn)
{
    return (1 - 1/(1 + pow(2.71828,(-2*(-alpha - an))/awn)) - 1/(1 + pow(2.71828,(-2*(alpha - ap))/awp)))*alpha*
            CLalpha + 0.707107*(1/(1 + pow(2.71828,(-2*(-alpha - an))/awn)) +
              1/(1 + pow(2.71828,(-2*(alpha - ap))/awp)))*sin(2*alpha);
}

//! @brief Induced drag coefficient for aircraft model
//! @ingroup AuxiliarySimulationFunctions
double hopsan::CDragInd(const double alpha, const double AR, const double e, const double CLalpha, const double ap, const double an, const double awp, const double awn)
{
    return (0.31831*(1 - 1/(1 + pow(2.71828,(-2*(-alpha - an))/awn)) - 1/(1 + pow(2.71828,(-2*(alpha - ap))/awp)))*
             pow(alpha,2)*pow(CLalpha,2))/(AR*e) +
          (1/(1 + pow(2.71828,(-2*(-alpha - an))/awn)) + 1/(1 + pow(2.71828,(-2*(alpha - ap))/awp)))*
           pow(sin(alpha),2);
}

//! @brief Moment coefficient for aircraft model
//! @ingroup AuxiliarySimulationFunctions
double hopsan::CMoment(const double alpha, const double Cm0, const double Cmfs, const double /*ap*/, const double /*an*/, const double /*awp*/, const double /*awn*/)
{
    return (1 - 1/(1 + pow(2.71828,-20.*(-0.5 - alpha))) - 1/(1 + pow(2.71828,-20.*(-0.5 + alpha))))*Cm0 +
            (1/(1 + pow(2.71828,-20.*(-0.5 - alpha))) + 1/(1 + pow(2.71828,-20.*(-0.5 + alpha))))*Cmfs*sign(alpha);
}

//! @brief Overloads void hopsan::limitValue() with a return value.
//! @ingroup AuxiliarySimulationFunctions
//! @see void hopsan::limitValue(&value, min, max)
//! @param x Value to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
double hopsan::limit(const double x, const double xmin, const double xmax)
{
    double output = x;
    limitValue(output, xmin, xmax);
    return output;
}

//! @brief Overloads void hopsan::limitValue() with a return value.
//! @ingroup AuxiliarySimulationFunctions
//! @see void hopsan::limitValue(&value, min, max)
//! @param x Value to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
double hopsan::lowLimit(const double x, const double xmin)
{
    double output = x;
    if(x < xmin)
    {
        output = xmin;
    }
    return output;
}

//! @brief Sets the derivative of x to zero if x is outside of limits.
//! @ingroup AuxiliarySimulationFunctions
//! @details Returns 1.0 if x is within limits, else 0.0. Used to make the derivative of x zero if limit is reached.
//! @param x Value whos derivative is to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
//! @returns Limited derivative of x
double hopsan::dxLimit(const double x, const double xmin, const double xmax)
{
    if (x >= xmax) { return 0.000000001; }
    if (x <= xmin) { return 0.000000001; }
    return 1.0;
}

//! @brief Sets the derivative of x to zero if x is outside of limits.
//! @ingroup AuxiliarySimulationFunctions
//! @details Returns 1.0 if x is within limits, else 0.0. Used to make the derivative of x zero if limit is reached.
//! @param x Value whos derivative is to be limited
//! @param xmin Minimum value of x
//! @returns Limited derivative of x
double hopsan::dxLowLimit(const double x,const double xmin)
{
    if (x <= xmin) { return 0.0000001; }
    return 1.0;
}
//! @brief Sets the derivative of x to zero if x is outside of limits.
//! @ingroup AuxiliarySimulationFunctions
//! @details Returns 1.0 if x is within limits, else 0.0. Used to make the derivative of x zero if limit is reached.
//! @param x Value whos derivative is to be limited
//! @param xmin Minimum value of x
//! @returns Limited derivative of x
double hopsan::dxLowLimit2(const double x, const double sx, const double xmin)
{
    if (x <= xmin && sx <= 0.0) { return 0.0000001; }
    return 1.0;
}

//! @brief Limits the derivative of x when x is outside of its limits.
//! @ingroup AuxiliarySimulationFunctions
//! Returns 1.0 if x is within borders, or if x is outside borders but derivative has opposite sign (so that x can only move back to the limited range).
//! @param x Value whos derivative is to be limited
//! @param xmin Minimum value of x
//! @param xmax Maximum value of x
//! @returns Limited derivative of x
double hopsan::dxLimit2(const double x, const double sx, const double xmin, const double xmax)
{
    if (x >= xmax && sx >= 0.0) { return 0.0000001; }
    if (x <= xmin && sx <= 0.0) { return 0.0000001; }
    return 1.0;
}

//! @brief Returns the algebraic quotient x/y with any fractional parts discarded
//! @ingroup AuxiliarySimlationFunctions
//! @ingroup ModelicaWrapperFunctions
//! @param x Numinator
//! @param y Denominator
//! @returns Algebraic quotient with any fracrional parts discarded
double div(const double x, const double y)
{
    if(x/y > 0)
    {
        return floor(x/y);
    }
    else
    {
        return ceil(x/y);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add 1 problem<commit_after>/*
Given a binary tree, determine if it is a valid binary search tree (BST).

Assume a BST is defined as follows:

The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.

OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal,
where '#' signifies a path terminator where no node exists below.

Here's an example:
   1
  / \
 2   3
    /
   4
    \
     5
The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}".
 */

#include <stdio.h>

// Definition for a binary tree node.
struct TreeNode
{
    int        val;
    TreeNode*  left;
    TreeNode*  right;

    TreeNode(int x)
        : val(x), left(NULL), right(NULL)
    {
    }
};

class Solution
{
public:
    bool isValidBST(TreeNode* root)
    {
        if (root == NULL)
        {
            return true;
        }
        TreeNode* prev = NULL;
        return doIsValidBst(root, prev);
    }

    bool doIsValidBst(TreeNode* node, TreeNode*& prev)
    {
        if (node == NULL)
        {
            return true;
        }
        if (!doIsValidBst(node->left, prev))
        {
            return false;
        }
        if (prev != NULL && prev->val >= node->val)
        {
            return false;
        }
        prev = node;
        return doIsValidBst(node->right, prev);
    }
};
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */
#include "../../StroikaPreComp.h"

#if qHasFeature_OpenSSL
#include <openssl/evp.h>
#if OPENSSL_VERSION_MAJOR >= 3
#include <openssl/provider.h>
#endif
#endif

#include "../../Debug/Assertions.h"
#include "../../Execution/Exceptions.h"

#include "LibraryContext.h"

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Cryptography;
using namespace Stroika::Foundation::Cryptography::OpenSSL;

#if qHasFeature_OpenSSL && defined(_MSC_VER)
// Use #pragma comment lib instead of explicit entry in the lib entry of the project file
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib")
#else
#pragma comment(lib, "libcrypto.lib")
#pragma comment(lib, "libssl.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "crypt32.lib")
#endif
#endif

#if qHasFeature_OpenSSL

namespace {
    optional<String> GetCiphrName_ (CipherAlgorithm a)
    {
        if (auto i = ::EVP_CIPHER_name (a)) {
            return String::FromASCII (i);
        }
        return nullopt;
    }
}

/*
 ********************************************************************************
 ******************* Cryptography::OpenSSL::LibraryContext **********************
 ********************************************************************************
 */
LibraryContext LibraryContext::sDefault;

LibraryContext::LibraryContext ()
    : pAvailableAlgorithms{
          [qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]] const auto* property) -> Set<CipherAlgorithm> {
              const LibraryContext*                               thisObj = qStroika_Foundation_Common_Property_OuterObjPtr (property, &LibraryContext::pAvailableAlgorithms);
              shared_lock<const AssertExternallySynchronizedLock> critSec{*thisObj};
              Set<String>                                         ciphers;
              ::EVP_CIPHER_do_all_provided (
                  nullptr,
                  [] (EVP_CIPHER* ciph, void* arg) {
                      Set<String>* ciphers = reinterpret_cast<Set<String>*> (arg);
                      if (ciph != nullptr) {
                          DbgTrace (L"cipher: %p (name: %s), provider: %p", ciph, CipherAlgorithm{ciph}.pName ().c_str (), ::EVP_CIPHER_provider (ciph));
                          Assert (GetCiphrName_ (ciph));
                          if (auto cipherName = GetCiphrName_ (ciph)) {

#if OPENSSL_VERSION_MAJOR >= 3
                              if (auto provider = ::EVP_CIPHER_provider (ciph)) {
                                  DbgTrace ("providername = %s", ::OSSL_PROVIDER_name (provider));
                              }
#endif
                              int flags = ::EVP_CIPHER_flags (ciph);
                              DbgTrace ("flags=%x", flags);

                              ciphers->Add (*cipherName);
                          }
                      }
                  },
                  &ciphers);
              DbgTrace (L"Found kAllLoadedCiphers=%s", Characters::ToString (ciphers).c_str ());

              auto fn = [] (const String& n) -> optional<CipherAlgorithm> { return OpenSSL::GetCipherByNameQuietly (n); };

              Traversal::Iterable<int> yyy{};
              Set<int>                 resultyyy{yyy};

              using namespace Configuration;
              static_assert (IsIterable_v<Traversal::Iterable<CipherAlgorithm>>);

              using ITERABLE_OF_T = Traversal::Iterable<CipherAlgorithm>;
    //Configuration::Private::  IsIterableOfT_Impl2_<set<int>, int> aa;

#if 1

              Set<CipherAlgorithm> result{ciphers.Select<CipherAlgorithm> ([] (const String& n) -> optional<CipherAlgorithm> { return OpenSSL::GetCipherByNameQuietly (n); })};
              WeakAssert (result.size () == ciphers.size ());
#endif
              return result;
          }}
{
    LoadProvider (kDefaultProvider);
}

LibraryContext ::~LibraryContext ()
{
    lock_guard<const AssertExternallySynchronizedLock> critSec{*this};
#if OPENSSL_VERSION_MAJOR >= 3
    for (auto i : fLoadedProviders_) {
        Verify (::OSSL_PROVIDER_unload (i.fValue.first) == 1);
    }
#endif
}

void LibraryContext::LoadProvider (const String& providerName)
{
    lock_guard<const AssertExternallySynchronizedLock> critSec{*this};
#if OPENSSL_VERSION_MAJOR >= 3
    OSSL_PROVIDER*                                p = ::OSSL_PROVIDER_load (NULL, providerName.AsNarrowSDKString ().c_str ());
    static const Execution::RuntimeErrorException kErr_{L"No such SSL provider"sv};
    Execution::ThrowIfNull (p, kErr_);
    if (auto l = fLoadedProviders_.Lookup (providerName)) {
        l->second++;
        fLoadedProviders_.Add (providerName, *l);
    }
    else {
        fLoadedProviders_.Add (providerName, {p, 1});
    }
#else
    Require (providerName == kDefaultProvider or providerName == kLegacyProvider);
#endif
}

void LibraryContext ::UnLoadProvider (const String& providerName)
{
    lock_guard<const AssertExternallySynchronizedLock> critSec{*this};
#if OPENSSL_VERSION_MAJOR >= 3
    Require (fLoadedProviders_.ContainsKey (providerName));
    auto l = fLoadedProviders_.Lookup (providerName);
    Assert (l);
    l->second--;
    if (l->second == 0) {
        fLoadedProviders_.Remove (providerName);
        Verify (::OSSL_PROVIDER_unload (l->first) == 1);
    }
    else {
        fLoadedProviders_.Add (providerName, *l);
    }
#endif
}
#endif
<commit_msg>call EVP_CIPHER_do_all_provided in openssl 3 and EVP_CIPHER_do_all_sorted in openssl 1 (to avoid failures - not fully clear why)<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */
#include "../../StroikaPreComp.h"

#if qHasFeature_OpenSSL
#include <openssl/evp.h>
#if OPENSSL_VERSION_MAJOR >= 3
#include <openssl/provider.h>
#endif
#endif

#include "../../Debug/Assertions.h"
#include "../../Execution/Exceptions.h"

#include "LibraryContext.h"

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Cryptography;
using namespace Stroika::Foundation::Cryptography::OpenSSL;

#if qHasFeature_OpenSSL && defined(_MSC_VER)
// Use #pragma comment lib instead of explicit entry in the lib entry of the project file
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib")
#else
#pragma comment(lib, "libcrypto.lib")
#pragma comment(lib, "libssl.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "crypt32.lib")
#endif
#endif

#if qHasFeature_OpenSSL

namespace {
    optional<String> GetCiphrName_ (CipherAlgorithm a)
    {
        if (auto i = ::EVP_CIPHER_name (a)) {
            return String::FromASCII (i);
        }
        return nullopt;
    }
}

/*
 ********************************************************************************
 ******************* Cryptography::OpenSSL::LibraryContext **********************
 ********************************************************************************
 */
LibraryContext LibraryContext::sDefault;
namespace {
    void f (const EVP_CIPHER* ciph, void* arg) {
        Set<String>* ciphers = reinterpret_cast<Set<String>*> (arg);
        if (ciph != nullptr) {
#if OPENSSL_VERSION_MAJOR >= 3
            DbgTrace (L"cipher: %p (name: %s), provider: %p", ciph, CipherAlgorithm{ciph}.pName ().c_str (), ::EVP_CIPHER_provider (ciph));
#else
                          DbgTrace (L"cipher: %p (name: %s), ciph, CipherAlgorithm{ciph}.pName ().c_str ());
#endif
            Assert (GetCiphrName_ (ciph));
            if (auto cipherName = GetCiphrName_ (ciph)) {

#if OPENSSL_VERSION_MAJOR >= 3
                if (auto provider = ::EVP_CIPHER_provider (ciph)) {
                    DbgTrace ("providername = %s", ::OSSL_PROVIDER_name (provider));
                }
#endif
                int flags = ::EVP_CIPHER_flags (ciph);
                DbgTrace ("flags=%x", flags);

                ciphers->Add (*cipherName);
            }
        }
    };
}
LibraryContext::LibraryContext ()
    : pAvailableAlgorithms{
          [qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]] const auto* property) -> Set<CipherAlgorithm> {
              const LibraryContext*                               thisObj = qStroika_Foundation_Common_Property_OuterObjPtr (property, &LibraryContext::pAvailableAlgorithms);
              shared_lock<const AssertExternallySynchronizedLock> critSec{*thisObj};
              Set<String>                                         ciphers;

#if OPENSSL_VERSION_MAJOR >= 3
              ::EVP_CIPHER_do_all_provided (
                  nullptr,
                  [] (EVP_CIPHER* ciph, void* arg) { f (ciph, arg); },
                  &ciphers);
#else
              ::EVP_CIPHER_do_all_sorted (
                  [] (const EVP_CIPHER* ciph, [[maybe_unused]] const char* from, [[maybe_unused]] const char* to, void* arg) { f (ciph, arg); },
                  &ciphers);
#endif
              DbgTrace (L"Found kAllLoadedCiphers=%s", Characters::ToString (ciphers).c_str ());

              auto fn = [] (const String& n) -> optional<CipherAlgorithm> { return OpenSSL::GetCipherByNameQuietly (n); };

              Traversal::Iterable<int> yyy{};
              Set<int>                 resultyyy{yyy};

              using namespace Configuration;
              static_assert (IsIterable_v<Traversal::Iterable<CipherAlgorithm>>);

              using ITERABLE_OF_T = Traversal::Iterable<CipherAlgorithm>;
    //Configuration::Private::  IsIterableOfT_Impl2_<set<int>, int> aa;

#if 1

              Set<CipherAlgorithm> result{ciphers.Select<CipherAlgorithm> ([] (const String& n) -> optional<CipherAlgorithm> { return OpenSSL::GetCipherByNameQuietly (n); })};
              WeakAssert (result.size () == ciphers.size ());
#endif
              return result;
          }}
{
    LoadProvider (kDefaultProvider);
}

LibraryContext ::~LibraryContext ()
{
    lock_guard<const AssertExternallySynchronizedLock> critSec{*this};
#if OPENSSL_VERSION_MAJOR >= 3
    for (auto i : fLoadedProviders_) {
        Verify (::OSSL_PROVIDER_unload (i.fValue.first) == 1);
    }
#endif
}

void LibraryContext::LoadProvider (const String& providerName)
{
    lock_guard<const AssertExternallySynchronizedLock> critSec{*this};
#if OPENSSL_VERSION_MAJOR >= 3
    OSSL_PROVIDER*                                p = ::OSSL_PROVIDER_load (NULL, providerName.AsNarrowSDKString ().c_str ());
    static const Execution::RuntimeErrorException kErr_{L"No such SSL provider"sv};
    Execution::ThrowIfNull (p, kErr_);
    if (auto l = fLoadedProviders_.Lookup (providerName)) {
        l->second++;
        fLoadedProviders_.Add (providerName, *l);
    }
    else {
        fLoadedProviders_.Add (providerName, {p, 1});
    }
#else
    Require (providerName == kDefaultProvider or providerName == kLegacyProvider);
#endif
}

void LibraryContext ::UnLoadProvider (const String& providerName)
{
    lock_guard<const AssertExternallySynchronizedLock> critSec{*this};
#if OPENSSL_VERSION_MAJOR >= 3
    Require (fLoadedProviders_.ContainsKey (providerName));
    auto l = fLoadedProviders_.Lookup (providerName);
    Assert (l);
    l->second--;
    if (l->second == 0) {
        fLoadedProviders_.Remove (providerName);
        Verify (::OSSL_PROVIDER_unload (l->first) == 1);
    }
    else {
        fLoadedProviders_.Add (providerName, *l);
    }
#endif
}
#endif
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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 "itkBSplineControlPointImageFilter.h"
#include "itkConstantPadImageFilter.h"
#include "itkExpImageFilter.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImageRegionIterator.h"
#include "itkN4MRIBiasFieldCorrectionImageFilter.h"
#include "itkOtsuThresholdImageFilter.h"
#include "itkShrinkImageFilter.h"

template<class TFilter>
class CommandIterationUpdate : public itk::Command
{
public:
  typedef CommandIterationUpdate  Self;
  typedef itk::Command            Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  itkNewMacro( Self );
protected:
  CommandIterationUpdate() {}
public:

  void Execute(itk::Object *caller, const itk::EventObject & event)
    {
    Execute( (const itk::Object *) caller, event);
    }

  void Execute(const itk::Object * object, const itk::EventObject & event)
    {
    const TFilter * filter =
      dynamic_cast< const TFilter * >( object );

    if( typeid( event ) != typeid( itk::IterationEvent ) )
                                        { return; }
    if( filter->GetElapsedIterations() == 1 )
      {
      std::cout << "Current level = " << filter->GetCurrentLevel() + 1
                << std::endl;
      }
    std::cout << "  Iteration " << filter->GetElapsedIterations()
              << " (of "
              << filter->GetMaximumNumberOfIterations()[
      filter->GetCurrentLevel()]
              << ").  ";
    std::cout << " Current convergence value = "
              << filter->GetCurrentConvergenceMeasurement()
              << " (threshold = " << filter->GetConvergenceThreshold()
              << ")" << std::endl;
    }

};

#include <string>
#include <vector>

template<class TValue>
TValue Convert( std::string optionString )
{
  TValue             value;
  std::istringstream iss( optionString );

  iss >> value;
  return value;
}

template<class TValue>
std::vector<TValue> ConvertVector( std::string optionString )
{
  std::vector<TValue>    values;
  std::string::size_type crosspos = optionString.find( 'x', 0 );

  if ( crosspos == std::string::npos )
    {
    values.push_back( Convert<TValue>( optionString ) );
    }
  else
    {
    std::string        element = optionString.substr( 0, crosspos );
    TValue             value;
    std::istringstream iss( element );
    iss >> value;
    values.push_back( value );
    while ( crosspos != std::string::npos )
      {
      std::string::size_type crossposfrom = crosspos;
      crosspos = optionString.find( 'x', crossposfrom + 1 );
      if ( crosspos == std::string::npos )
        {
        element = optionString.substr( crossposfrom + 1, optionString.length() );
        }
      else
        {
        element = optionString.substr( crossposfrom + 1, crosspos );
        }
      std::istringstream iss2( element );
      iss2 >> value;
      values.push_back( value );
      }
    }
  return values;
}

template<unsigned int ImageDimension>
int N4( int argc, char *argv[] )
{
  typedef float RealType;

  typedef itk::Image<RealType, ImageDimension>  ImageType;
  typedef typename ImageType::Pointer           ImagePointer;

  typedef itk::ImageFileReader<ImageType> ReaderType;
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[2] );
  reader->Update();

  ImagePointer inputImage = reader->GetOutput();
  inputImage->DisconnectPipeline();

  // handle the mask image
  typedef itk::Image<unsigned char, ImageDimension> MaskImageType;
  typename MaskImageType::Pointer maskImage = NULL;

  if( argc > 6 )
    {
    typedef itk::ImageFileReader<MaskImageType> MaskReaderType;
    typename MaskReaderType::Pointer maskreader = MaskReaderType::New();
    maskreader->SetFileName( argv[6] );
    try
      {
      maskreader->Update();
      maskImage = maskreader->GetOutput();
      maskImage->DisconnectPipeline();
      }
    catch( ... )
      {
      maskImage = NULL;
      }
    }

  if( !maskImage )
    {
    std::cout << "Mask not read.  Creating Otsu mask." << std::endl;
    typedef itk::OtsuThresholdImageFilter<ImageType, MaskImageType>
    ThresholderType;
    typename ThresholderType::Pointer otsu = ThresholderType::New();
    otsu->SetInput( inputImage );
    otsu->SetNumberOfHistogramBins( 200 );
    otsu->SetInsideValue( 0 );
    otsu->SetOutsideValue( 1 );

    otsu->Update();
    maskImage = otsu->GetOutput();
    maskImage->DisconnectPipeline();
    }

  // instantiate N4 and assign variables not exposed to the user in this test.
  typedef itk::N4MRIBiasFieldCorrectionImageFilter<ImageType, MaskImageType,
                                                   ImageType> CorrecterType;
  typename CorrecterType::Pointer correcter = CorrecterType::New();
  correcter->SetMaskLabel( 1 );
  correcter->SetSplineOrder( 3 );
  correcter->SetWienerFilterNoise( 0.01 );
  correcter->SetBiasFieldFullWidthAtHalfMaximum( 0.15 );
  correcter->SetConvergenceThreshold( 0.0000001 );

  // handle the number of iterations
  std::vector<unsigned int> numIters = ConvertVector<unsigned int>(
      std::string( "100x50x50" ) );
  if( argc > 5 )
    {
    numIters = ConvertVector<unsigned int>( argv[5] );
    }
  typename CorrecterType::VariableSizeArrayType
  maximumNumberOfIterations( numIters.size() );
  for( unsigned int d = 0; d < numIters.size(); d++ )
    {
    maximumNumberOfIterations[d] = numIters[d];
    }
  correcter->SetMaximumNumberOfIterations( maximumNumberOfIterations );

  typename CorrecterType::ArrayType numberOfFittingLevels;
  numberOfFittingLevels.Fill( numIters.size() );
  correcter->SetNumberOfFittingLevels( numberOfFittingLevels );

  /* B-spline options -- we place this here to take care of the case where
   * the user wants to specify things in terms of the spline distance.
   *  1. need to pad the images to get as close to possible to the
   *     requested domain size.
   */
  typename ImageType::PointType newOrigin = inputImage->GetOrigin();

  typename CorrecterType::ArrayType numberOfControlPoints;

  float splineDistance = 200;
  if( argc > 7 )
    {
    splineDistance = atof( argv[7] );
    }

  itk::SizeValueType lowerBound[ImageDimension];
  itk::SizeValueType upperBound[ImageDimension];

  for( unsigned int d = 0; d < ImageDimension; d++ )
    {
    float domain = static_cast<RealType>( inputImage->
      GetLargestPossibleRegion().GetSize()[d] - 1 ) *
      inputImage->GetSpacing()[d];
    unsigned int numberOfSpans = static_cast<unsigned int>(
      vcl_ceil( domain / splineDistance ) );
    unsigned long extraPadding = static_cast<unsigned long>( ( numberOfSpans *
      splineDistance - domain ) / inputImage->GetSpacing()[d] + 0.5 );
    lowerBound[d] = static_cast<unsigned long>( 0.5 * extraPadding );
    upperBound[d] = extraPadding - lowerBound[d];
    newOrigin[d] -= ( static_cast<RealType>( lowerBound[d] ) *
                      inputImage->GetSpacing()[d] );
    numberOfControlPoints[d] = numberOfSpans + correcter->GetSplineOrder();
    }

  typedef itk::ConstantPadImageFilter<ImageType, ImageType> PadderType;
  typename PadderType::Pointer padder = PadderType::New();
  padder->SetInput( inputImage );
  padder->SetPadLowerBound( lowerBound );
  padder->SetPadUpperBound( upperBound );
  padder->SetConstant( 0 );
  padder->Update();

  inputImage = padder->GetOutput();
  inputImage->DisconnectPipeline();

  typedef itk::ConstantPadImageFilter<MaskImageType, MaskImageType>
  MaskPadderType;
  typename MaskPadderType::Pointer maskPadder = MaskPadderType::New();
  maskPadder->SetInput( maskImage );
  maskPadder->SetPadLowerBound( lowerBound );
  maskPadder->SetPadUpperBound( upperBound );
  maskPadder->SetConstant( 0 );
  maskPadder->Update();

  maskImage = maskPadder->GetOutput();
  maskImage->DisconnectPipeline();

  correcter->SetNumberOfControlPoints( numberOfControlPoints );

  // handle the shrink factor
  typedef itk::ShrinkImageFilter<ImageType, ImageType> ShrinkerType;
  typename ShrinkerType::Pointer shrinker = ShrinkerType::New();
  shrinker->SetInput( reader->GetOutput() );
  shrinker->SetShrinkFactors( 1 );

  typedef itk::ShrinkImageFilter<MaskImageType, MaskImageType>
  MaskShrinkerType;
  typename MaskShrinkerType::Pointer maskshrinker = MaskShrinkerType::New();
  maskshrinker->SetInput( maskImage );
  maskshrinker->SetShrinkFactors( 1 );

  if( argc > 4 )
    {
    shrinker->SetShrinkFactors( atoi( argv[4] ) );
    maskshrinker->SetShrinkFactors( atoi( argv[4] ) );
    }
  shrinker->Update();
  inputImage = shrinker->GetOutput();
  inputImage->DisconnectPipeline();

  maskshrinker->Update();
  maskImage = maskshrinker->GetOutput();
  maskImage->DisconnectPipeline();

  // set the input image and mask image
  correcter->SetInput( inputImage );
  correcter->SetMaskImage( maskImage );

  typedef CommandIterationUpdate<CorrecterType> CommandType;
  typename CommandType::Pointer observer = CommandType::New();
  correcter->AddObserver( itk::IterationEvent(), observer );

  try
    {
    correcter->Update();
    }
  catch( itk::ExceptionObject &excep )
    {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << excep << std::endl;
    return EXIT_FAILURE;
    }

  correcter->Print( std::cout, 3 );

  // Test the reconstruction of the log bias field
  ImagePointer originalInputImage = reader->GetOutput();
  typedef itk::BSplineControlPointImageFilter
  <typename CorrecterType::BiasFieldControlPointLatticeType, typename
   CorrecterType::ScalarImageType> BSplinerType;
  typename BSplinerType::Pointer bspliner = BSplinerType::New();
  bspliner->SetInput( correcter->GetLogBiasFieldControlPointLattice() );
  bspliner->SetSplineOrder( correcter->GetSplineOrder() );
  bspliner->SetSize(
    originalInputImage->GetLargestPossibleRegion().GetSize() );
  bspliner->SetOrigin( originalInputImage->GetOrigin() );
  bspliner->SetDirection( originalInputImage->GetDirection() );
  bspliner->SetSpacing( originalInputImage->GetSpacing() );
  bspliner->Update();

  // output the log bias field control point lattice
  typedef itk::ImageFileWriter<
    typename CorrecterType::BiasFieldControlPointLatticeType> WriterType;
  typename WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( argv[3] );
  writer->SetInput( correcter->GetLogBiasFieldControlPointLattice() );
  writer->Update();

  return EXIT_SUCCESS;
}

int itkN4MRIBiasFieldCorrectionImageFilterTest( int argc, char *argv[] )
{
  if ( argc < 4 )
    {
    std::cerr << "Usage: " << argv[0] << " imageDimension inputImage "
              << "outputLogControlPointLattice [shrinkFactor,default=1] "
              << "[numberOfIterations,default=100x50x50] "
              << " [maskImageWithLabelEqualTo1] [splineDistance,default=200]"
              << std::endl;
    exit( EXIT_FAILURE );
    }

  switch( atoi( argv[1] ) )
    {
    case 2:
      N4<2>( argc, argv );
      break;
    case 3:
      N4<3>( argc, argv );
      break;
    default:
      std::cerr << "Unsupported dimension" << std::endl;
      exit( EXIT_FAILURE );
    }
  return EXIT_SUCCESS;
}
<commit_msg>BUG: return value not propagated, incorrect image in sequence<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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 "itkBSplineControlPointImageFilter.h"
#include "itkConstantPadImageFilter.h"
#include "itkExpImageFilter.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImageRegionIterator.h"
#include "itkN4MRIBiasFieldCorrectionImageFilter.h"
#include "itkOtsuThresholdImageFilter.h"
#include "itkShrinkImageFilter.h"

template<class TFilter>
class CommandIterationUpdate : public itk::Command
{
public:
  typedef CommandIterationUpdate  Self;
  typedef itk::Command            Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  itkNewMacro( Self );
protected:
  CommandIterationUpdate() {}
public:

  void Execute(itk::Object *caller, const itk::EventObject & event)
    {
    Execute( (const itk::Object *) caller, event);
    }

  void Execute(const itk::Object * object, const itk::EventObject & event)
    {
    const TFilter * filter =
      dynamic_cast< const TFilter * >( object );

    if( typeid( event ) != typeid( itk::IterationEvent ) )
                                        { return; }
    if( filter->GetElapsedIterations() == 1 )
      {
      std::cout << "Current level = " << filter->GetCurrentLevel() + 1
                << std::endl;
      }
    std::cout << "  Iteration " << filter->GetElapsedIterations()
              << " (of "
              << filter->GetMaximumNumberOfIterations()[
      filter->GetCurrentLevel()]
              << ").  ";
    std::cout << " Current convergence value = "
              << filter->GetCurrentConvergenceMeasurement()
              << " (threshold = " << filter->GetConvergenceThreshold()
              << ")" << std::endl;
    }

};

#include <string>
#include <vector>

template<class TValue>
TValue Convert( std::string optionString )
{
  TValue             value;
  std::istringstream iss( optionString );

  iss >> value;
  return value;
}

template<class TValue>
std::vector<TValue> ConvertVector( std::string optionString )
{
  std::vector<TValue>    values;
  std::string::size_type crosspos = optionString.find( 'x', 0 );

  if ( crosspos == std::string::npos )
    {
    values.push_back( Convert<TValue>( optionString ) );
    }
  else
    {
    std::string        element = optionString.substr( 0, crosspos );
    TValue             value;
    std::istringstream iss( element );
    iss >> value;
    values.push_back( value );
    while ( crosspos != std::string::npos )
      {
      std::string::size_type crossposfrom = crosspos;
      crosspos = optionString.find( 'x', crossposfrom + 1 );
      if ( crosspos == std::string::npos )
        {
        element = optionString.substr( crossposfrom + 1, optionString.length() );
        }
      else
        {
        element = optionString.substr( crossposfrom + 1, crosspos );
        }
      std::istringstream iss2( element );
      iss2 >> value;
      values.push_back( value );
      }
    }
  return values;
}

template<unsigned int ImageDimension>
int N4( int argc, char *argv[] )
{
  typedef float RealType;

  typedef itk::Image<RealType, ImageDimension>  ImageType;
  typedef typename ImageType::Pointer           ImagePointer;

  typedef itk::ImageFileReader<ImageType> ReaderType;
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[2] );
  reader->Update();

  ImagePointer inputImage = reader->GetOutput();
  inputImage->DisconnectPipeline();

  // handle the mask image
  typedef itk::Image<unsigned char, ImageDimension> MaskImageType;
  typename MaskImageType::Pointer maskImage = NULL;

  if( argc > 6 )
    {
    typedef itk::ImageFileReader<MaskImageType> MaskReaderType;
    typename MaskReaderType::Pointer maskreader = MaskReaderType::New();
    maskreader->SetFileName( argv[6] );
    try
      {
      maskreader->Update();
      maskImage = maskreader->GetOutput();
      maskImage->DisconnectPipeline();
      }
    catch( ... )
      {
      maskImage = NULL;
      }
    }

  if( !maskImage )
    {
    std::cout << "Mask not read.  Creating Otsu mask." << std::endl;
    typedef itk::OtsuThresholdImageFilter<ImageType, MaskImageType>
    ThresholderType;
    typename ThresholderType::Pointer otsu = ThresholderType::New();
    otsu->SetInput( inputImage );
    otsu->SetNumberOfHistogramBins( 200 );
    otsu->SetInsideValue( 0 );
    otsu->SetOutsideValue( 1 );

    otsu->Update();
    maskImage = otsu->GetOutput();
    maskImage->DisconnectPipeline();
    }

  // instantiate N4 and assign variables not exposed to the user in this test.
  typedef itk::N4MRIBiasFieldCorrectionImageFilter<ImageType, MaskImageType,
                                                   ImageType> CorrecterType;
  typename CorrecterType::Pointer correcter = CorrecterType::New();
  correcter->SetMaskLabel( 1 );
  correcter->SetSplineOrder( 3 );
  correcter->SetWienerFilterNoise( 0.01 );
  correcter->SetBiasFieldFullWidthAtHalfMaximum( 0.15 );
  correcter->SetConvergenceThreshold( 0.0000001 );

  // handle the number of iterations
  std::vector<unsigned int> numIters = ConvertVector<unsigned int>(
      std::string( "100x50x50" ) );
  if( argc > 5 )
    {
    numIters = ConvertVector<unsigned int>( argv[5] );
    }
  typename CorrecterType::VariableSizeArrayType
  maximumNumberOfIterations( numIters.size() );
  for( unsigned int d = 0; d < numIters.size(); d++ )
    {
    maximumNumberOfIterations[d] = numIters[d];
    }
  correcter->SetMaximumNumberOfIterations( maximumNumberOfIterations );

  typename CorrecterType::ArrayType numberOfFittingLevels;
  numberOfFittingLevels.Fill( numIters.size() );
  correcter->SetNumberOfFittingLevels( numberOfFittingLevels );

  /* B-spline options -- we place this here to take care of the case where
   * the user wants to specify things in terms of the spline distance.
   *  1. need to pad the images to get as close to possible to the
   *     requested domain size.
   */
  typename ImageType::PointType newOrigin = inputImage->GetOrigin();

  typename CorrecterType::ArrayType numberOfControlPoints;

  float splineDistance = 200;
  if( argc > 7 )
    {
    splineDistance = atof( argv[7] );
    }

  itk::SizeValueType lowerBound[ImageDimension];
  itk::SizeValueType upperBound[ImageDimension];

  for( unsigned int d = 0; d < ImageDimension; d++ )
    {
    float domain = static_cast<RealType>( inputImage->
      GetLargestPossibleRegion().GetSize()[d] - 1 ) *
      inputImage->GetSpacing()[d];
    unsigned int numberOfSpans = static_cast<unsigned int>(
      vcl_ceil( domain / splineDistance ) );
    unsigned long extraPadding = static_cast<unsigned long>( ( numberOfSpans *
      splineDistance - domain ) / inputImage->GetSpacing()[d] + 0.5 );
    lowerBound[d] = static_cast<unsigned long>( 0.5 * extraPadding );
    upperBound[d] = extraPadding - lowerBound[d];
    newOrigin[d] -= ( static_cast<RealType>( lowerBound[d] ) *
                      inputImage->GetSpacing()[d] );
    numberOfControlPoints[d] = numberOfSpans + correcter->GetSplineOrder();
    }

  typedef itk::ConstantPadImageFilter<ImageType, ImageType> PadderType;
  typename PadderType::Pointer padder = PadderType::New();
  padder->SetInput( inputImage );
  padder->SetPadLowerBound( lowerBound );
  padder->SetPadUpperBound( upperBound );
  padder->SetConstant( 0 );
  padder->Update();

  inputImage = padder->GetOutput();
  inputImage->DisconnectPipeline();

  typedef itk::ConstantPadImageFilter<MaskImageType, MaskImageType>
  MaskPadderType;
  typename MaskPadderType::Pointer maskPadder = MaskPadderType::New();
  maskPadder->SetInput( maskImage );
  maskPadder->SetPadLowerBound( lowerBound );
  maskPadder->SetPadUpperBound( upperBound );
  maskPadder->SetConstant( 0 );
  maskPadder->Update();

  maskImage = maskPadder->GetOutput();
  maskImage->DisconnectPipeline();

  correcter->SetNumberOfControlPoints( numberOfControlPoints );

  // handle the shrink factor
  typedef itk::ShrinkImageFilter<ImageType, ImageType> ShrinkerType;
  typename ShrinkerType::Pointer shrinker = ShrinkerType::New();
  shrinker->SetInput( inputImage );
  shrinker->SetShrinkFactors( 1 );

  typedef itk::ShrinkImageFilter<MaskImageType, MaskImageType>
  MaskShrinkerType;
  typename MaskShrinkerType::Pointer maskshrinker = MaskShrinkerType::New();
  maskshrinker->SetInput( maskImage );
  maskshrinker->SetShrinkFactors( 1 );

  if( argc > 4 )
    {
    shrinker->SetShrinkFactors( atoi( argv[4] ) );
    maskshrinker->SetShrinkFactors( atoi( argv[4] ) );
    }
  shrinker->Update();
  inputImage = shrinker->GetOutput();
  inputImage->DisconnectPipeline();

  maskshrinker->Update();
  maskImage = maskshrinker->GetOutput();
  maskImage->DisconnectPipeline();

  // set the input image and mask image
  correcter->SetInput( inputImage );
  correcter->SetMaskImage( maskImage );

  typedef CommandIterationUpdate<CorrecterType> CommandType;
  typename CommandType::Pointer observer = CommandType::New();
  correcter->AddObserver( itk::IterationEvent(), observer );

  try
    {
    correcter->Update();
    }
  catch( itk::ExceptionObject &excep )
    {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << excep << std::endl;
    return EXIT_FAILURE;
    }

  correcter->Print( std::cout, 3 );

  // Test the reconstruction of the log bias field
  ImagePointer originalInputImage = reader->GetOutput();
  reader->UpdateOutputInformation();
  typedef itk::BSplineControlPointImageFilter
  <typename CorrecterType::BiasFieldControlPointLatticeType, typename
   CorrecterType::ScalarImageType> BSplinerType;
  typename BSplinerType::Pointer bspliner = BSplinerType::New();
  bspliner->SetInput( correcter->GetLogBiasFieldControlPointLattice() );
  bspliner->SetSplineOrder( correcter->GetSplineOrder() );
  bspliner->SetSize(
    originalInputImage->GetLargestPossibleRegion().GetSize() );
  bspliner->SetOrigin( originalInputImage->GetOrigin() );
  bspliner->SetDirection( originalInputImage->GetDirection() );
  bspliner->SetSpacing( originalInputImage->GetSpacing() );
  bspliner->Update();

  // output the log bias field control point lattice
  typedef itk::ImageFileWriter<
    typename CorrecterType::BiasFieldControlPointLatticeType> WriterType;
  typename WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( argv[3] );
  writer->SetInput( correcter->GetLogBiasFieldControlPointLattice() );
  writer->Update();

  return EXIT_SUCCESS;
}

int itkN4MRIBiasFieldCorrectionImageFilterTest( int argc, char *argv[] )
{
  if ( argc < 4 )
    {
    std::cerr << "Usage: " << argv[0] << " imageDimension inputImage "
              << "outputLogControlPointLattice [shrinkFactor,default=1] "
              << "[numberOfIterations,default=100x50x50] "
              << " [maskImageWithLabelEqualTo1] [splineDistance,default=200]"
              << std::endl;
    exit( EXIT_FAILURE );
    }

  switch( atoi( argv[1] ) )
    {
    case 2:
      return N4<2>( argc, argv );
      break;
    case 3:
      return N4<3>( argc, argv );
      break;
    default:
      std::cerr << "Unsupported dimension" << std::endl;
      exit( EXIT_FAILURE );
    }
  return EXIT_SUCCESS;
}
<|endoftext|>


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

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

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

#include "otbWrapperCommandLineLauncher.h"

int main(int argc, char* argv[])
{
  if (argc < 2)
    {
    std::cerr << "Usage : " << argv[0] << " module_name module_path [arguments]" << std::endl;
    return EXIT_FAILURE;
    }

  // Construct the string expression
  std::string exp;
  for( unsigned int i=1; i<argc; i++)
    {
      if( i!= argc-1)
        {
          exp.append(argv[i]);
          exp.append(" ");
        }
      else
        {
          exp.append(argv[i]);
        }

    }

  typedef otb::Wrapper::CommandLineLauncher LauncherType;
  LauncherType::Pointer launcher = LauncherType::New();

  if (launcher->Load( exp ) == true )
    {
      if (launcher->ExecuteAndWriteOutput() == false)
        {
          return EXIT_FAILURE;
        }
    }
  else
    {
      return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<commit_msg>WRG: comparison signed/unsigned<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

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

#include "otbWrapperCommandLineLauncher.h"

int main(int argc, char* argv[])
{
  if (argc < 2)
    {
    std::cerr << "Usage : " << argv[0] << " module_name module_path [arguments]" << std::endl;
    return EXIT_FAILURE;
    }

  // Construct the string expression
  std::string exp;
  for (int i = 1; i < argc; i++)
    {
    if (i != argc - 1)
      {
      exp.append(argv[i]);
      exp.append(" ");
      }
    else
      {
      exp.append(argv[i]);
      }
    }

  typedef otb::Wrapper::CommandLineLauncher LauncherType;
  LauncherType::Pointer launcher = LauncherType::New();

  if (launcher->Load(exp) == true)
    {
    if (launcher->ExecuteAndWriteOutput() == false)
      {
      return EXIT_FAILURE;
      }
    }
  else
    {
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<|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 "mitkUSImageToIGTLMessageFilter.h"
#include "igtlImageMessage.h"

mitk::USImageToIGTLMessageFilter::USImageToIGTLMessageFilter()
{
  mitk::IGTLMessage::Pointer output = mitk::IGTLMessage::New();
  this->SetNumberOfRequiredOutputs(1);
  this->SetNthOutput(0, output.GetPointer());
  this->SetNumberOfRequiredInputs(1);

  m_CurrentTimeStep = 0;
}

mitk::USImageToIGTLMessageFilter::~USImageToIGTLMessageFilter() {}

void mitk::USImageToIGTLMessageFilter::GenerateData()
{
  for (size_t i = 0; i < this->GetNumberOfIndexedOutputs(); ++i)
  {
    mitk::IGTLMessage* output = this->GetOutput(i);
    assert(output);
    const mitk::USImage* input = this->GetInput(i);
    assert(input);

    int dim = input->GetDimension();

    if (dim > 3)
    {
      mitkThrow() << "Too many dimensions";
    }

    igtl::ImageMessage::Pointer imgMsg = igtl::ImageMessage::New();
    // TODO: Find out, if MITK uses RAS or LPS or something else entirely and we
    // need to convert
    imgMsg->SetCoordinateSystem(igtl::ImageMessage::COORDINATE_RAS);

    mitk::USImageMetadata::Pointer md = input->GetMetadata();
    imgMsg->SetDeviceName(md->GetProbeName().c_str());

    const mitk::PixelType pt = input->GetPixelType(0);
    switch (pt.GetComponentType())
    {
      case itk::ImageIOBase::UCHAR:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_UINT8);
      case itk::ImageIOBase::CHAR:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_INT8);
      case itk::ImageIOBase::USHORT:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_UINT16);
      case itk::ImageIOBase::SHORT:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_INT16);
      case itk::ImageIOBase::UINT:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_UINT32);
      case itk::ImageIOBase::INT:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_INT32);
      case itk::ImageIOBase::FLOAT:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_FLOAT32);
      case itk::ImageIOBase::DOUBLE:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_FLOAT64);
      default:
        mitkThrow() << "Incompatible PixelType " << pt.GetPixelTypeAsString();
    }

    imgMsg->SetNumComponents(pt.GetNumberOfComponents());

    // TODO: Endian

    switch (dim)
    {
      case 2:
        imgMsg->SetDimensions(input->GetDimension(0), input->GetDimension(1),
                              1);
      case 3:
        imgMsg->SetDimensions((int*)input->GetDimensions());
      default:
        mitkThrow() << "Too few dimensions";
    }

    // TODO: Origin, Geometry, spacing…
    mitk::SlicedGeometry3D* geometry = input->GetSlicedGeometry();

    Vector3D x = geometry->GetAxisVector(0);
    Vector3D y = geometry->GetAxisVector(1);
    Vector3D z = geometry->GetAxisVector(2);

    float t[3] = {(float)x[0], (float)x[1], (float)x[2]};
    float s[3] = {(float)y[0], (float)y[1], (float)y[2]};
    float n[3] = {(float)z[0], (float)z[1], (float)z[2]};

    imgMsg->SetNormals(t, s, n);

    mitk::Vector3D spacing = geometry->GetSpacing();
    imgMsg->SetSpacing(spacing[0], spacing[1], spacing[2]);

    Point3D origin = geometry->GetOrigin();
    float forigin[3] = {(float)origin[0], (float)origin[1], (float)origin[2]};
    imgMsg->SetOrigin(forigin);
  }
}

void mitk::USImageToIGTLMessageFilter::SetInput(const USImage* im)
{
  this->ProcessObject::SetNthInput(0, const_cast<USImage*>(im));
  this->CreateOutputsForAllInputs();
}

void mitk::USImageToIGTLMessageFilter::SetInput(unsigned int idx, const USImage* im)
{
  this->ProcessObject::SetNthInput(idx, const_cast<USImage*>(im));
  this->CreateOutputsForAllInputs();
}

const mitk::USImage* mitk::USImageToIGTLMessageFilter::GetInput(void)
{
  if (this->GetNumberOfInputs() < 1)
  {
    return NULL;
  }
  return static_cast<const USImage*>(this->ProcessObject::GetInput(0));
}

const mitk::USImage* mitk::USImageToIGTLMessageFilter::GetInput(unsigned int idx)
{
  if (this->GetNumberOfInputs() < idx + 1)
  {
    return NULL;
  }
  return static_cast<const USImage*>(this->ProcessObject::GetInput(idx));
}

void mitk::USImageToIGTLMessageFilter::CreateOutputsForAllInputs()
{
  // create one message output for all image inputs
  this->SetNumberOfIndexedOutputs(this->GetNumberOfIndexedInputs());

  for (size_t idx = 0; idx < this->GetNumberOfIndexedOutputs(); ++idx)
  {
    if (this->GetOutput(idx) == NULL)
    {
      this->SetNthOutput(idx, this->MakeOutput(idx));
    }
    this->Modified();
  }
}

void mitk::USImageToIGTLMessageFilter::ConnectTo(mitk::USImageSource* upstream)
{
  this->SetInput(static_cast<USImage*>(upstream->GetNextImage().GetPointer()));
}
<commit_msg>Just send something<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 "mitkUSImageToIGTLMessageFilter.h"
#include "igtlImageMessage.h"

mitk::USImageToIGTLMessageFilter::USImageToIGTLMessageFilter()
{
  mitk::IGTLMessage::Pointer output = mitk::IGTLMessage::New();
  this->SetNumberOfRequiredOutputs(1);
  this->SetNthOutput(0, output.GetPointer());
  this->SetNumberOfRequiredInputs(1);

  m_CurrentTimeStep = 0;
}

mitk::USImageToIGTLMessageFilter::~USImageToIGTLMessageFilter() {}

void mitk::USImageToIGTLMessageFilter::GenerateData()
{
    for (size_t i = 0; i < this->GetNumberOfIndexedInputs(); ++i) {
    mitk::IGTLMessage* output = this->GetOutput(i);

    igtl::ImageMessage::Pointer imgMsg = igtl::ImageMessage::New();
    imgMsg->SetDimensions(1, 1, 1);
    imgMsg->SetCoordinateSystem(igtl::ImageMessage::COORDINATE_LPS);
    imgMsg->SetEndian(igtl::ImageMessage::ENDIAN_LITTLE);
    igtl::Matrix4x4 atm;
    memset(atm, '\0', sizeof(atm));
    atm[0][0] = 1;
    atm[1][1] = -1;
    atm[2][2] = 1;
    atm[3][3] = 1;
    imgMsg->SetMatrix(atm);
    imgMsg->SetNumComponents(1);
    imgMsg->SetScalarTypeToUint8();

    output->SetMessage((igtl::MessageBase::Pointer)imgMsg);
    }
    return;

  for (size_t i = 0; i < this->GetNumberOfIndexedOutputs(); ++i)
  {
    mitk::IGTLMessage* output = this->GetOutput(i);
    assert(output);
    const mitk::USImage* input = this->GetInput(i);
    assert(input);

    int dim = input->GetDimension();

    if (dim > 3)
    {
      mitkThrow() << "Too many dimensions";
    }

    igtl::ImageMessage::Pointer imgMsg = igtl::ImageMessage::New();
    // TODO: Find out, if MITK uses RAS or LPS or something else entirely and we
    // need to convert
    imgMsg->SetCoordinateSystem(igtl::ImageMessage::COORDINATE_RAS);

    mitk::USImageMetadata::Pointer md = input->GetMetadata();
    imgMsg->SetDeviceName(md->GetProbeName().c_str());

    const mitk::PixelType pt = input->GetPixelType(0);
    switch (pt.GetComponentType())
    {
      case itk::ImageIOBase::UCHAR:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_UINT8);
      case itk::ImageIOBase::CHAR:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_INT8);
      case itk::ImageIOBase::USHORT:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_UINT16);
      case itk::ImageIOBase::SHORT:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_INT16);
      case itk::ImageIOBase::UINT:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_UINT32);
      case itk::ImageIOBase::INT:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_INT32);
      case itk::ImageIOBase::FLOAT:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_FLOAT32);
      case itk::ImageIOBase::DOUBLE:
        imgMsg->SetScalarType(igtl::ImageMessage::TYPE_FLOAT64);
      default:
        mitkThrow() << "Incompatible PixelType " << pt.GetPixelTypeAsString();
    }

    imgMsg->SetNumComponents(pt.GetNumberOfComponents());

    // TODO: Endian

    switch (dim)
    {
      case 2:
        imgMsg->SetDimensions(input->GetDimension(0), input->GetDimension(1),
                              1);
      case 3:
        imgMsg->SetDimensions((int*)input->GetDimensions());
      default:
        mitkThrow() << "Too few dimensions";
    }

    // TODO: Origin, Geometry, spacing…
    mitk::SlicedGeometry3D* geometry = input->GetSlicedGeometry();

    Vector3D x = geometry->GetAxisVector(0);
    Vector3D y = geometry->GetAxisVector(1);
    Vector3D z = geometry->GetAxisVector(2);

    float t[3] = {(float)x[0], (float)x[1], (float)x[2]};
    float s[3] = {(float)y[0], (float)y[1], (float)y[2]};
    float n[3] = {(float)z[0], (float)z[1], (float)z[2]};

    imgMsg->SetNormals(t, s, n);

    mitk::Vector3D spacing = geometry->GetSpacing();
    imgMsg->SetSpacing(spacing[0], spacing[1], spacing[2]);

    Point3D origin = geometry->GetOrigin();
    float forigin[3] = {(float)origin[0], (float)origin[1], (float)origin[2]};
    imgMsg->SetOrigin(forigin);
  }
}

void mitk::USImageToIGTLMessageFilter::SetInput(const USImage* im)
{
  this->ProcessObject::SetNthInput(0, const_cast<USImage*>(im));
  this->CreateOutputsForAllInputs();
}

void mitk::USImageToIGTLMessageFilter::SetInput(unsigned int idx, const USImage* im)
{
  this->ProcessObject::SetNthInput(idx, const_cast<USImage*>(im));
  this->CreateOutputsForAllInputs();
}

const mitk::USImage* mitk::USImageToIGTLMessageFilter::GetInput(void)
{
  if (this->GetNumberOfInputs() < 1)
  {
    return NULL;
  }
  return static_cast<const USImage*>(this->ProcessObject::GetInput(0));
}

const mitk::USImage* mitk::USImageToIGTLMessageFilter::GetInput(unsigned int idx)
{
  if (this->GetNumberOfInputs() < idx + 1)
  {
    return NULL;
  }
  return static_cast<const USImage*>(this->ProcessObject::GetInput(idx));
}

void mitk::USImageToIGTLMessageFilter::CreateOutputsForAllInputs()
{
  // create one message output for all image inputs
  this->SetNumberOfIndexedOutputs(this->GetNumberOfIndexedInputs());

  for (size_t idx = 0; idx < this->GetNumberOfIndexedOutputs(); ++idx)
  {
    if (this->GetOutput(idx) == NULL)
    {
      this->SetNthOutput(idx, this->MakeOutput(idx));
    }
    this->Modified();
  }
}

void mitk::USImageToIGTLMessageFilter::ConnectTo(mitk::USImageSource* upstream)
{
  this->SetInput(static_cast<USImage*>(upstream->GetNextImage().GetPointer()));
}
<|endoftext|>


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

#include "chrome/browser/chromeos/preferences.h"

#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/input_method_library.h"
#include "chrome/browser/chromeos/cros/synaptics_library.h"
#include "chrome/browser/pref_member.h"
#include "chrome/browser/pref_service.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "unicode/timezone.h"

namespace chromeos {

// static
void Preferences::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterBooleanPref(prefs::kTapToClickEnabled, false);
  prefs->RegisterBooleanPref(prefs::kAccessibilityEnabled, false);
  prefs->RegisterBooleanPref(prefs::kVertEdgeScrollEnabled, false);
  prefs->RegisterIntegerPref(prefs::kTouchpadSpeedFactor, 9);
  prefs->RegisterIntegerPref(prefs::kTouchpadSensitivity, 5);
  prefs->RegisterStringPref(prefs::kLanguageCurrentInputMethod, "");
  prefs->RegisterStringPref(prefs::kLanguagePreviousInputMethod, "");
  prefs->RegisterStringPref(prefs::kLanguageHotkeyNextEngineInMenu,
                            kHotkeyNextEngineInMenu);
  prefs->RegisterStringPref(prefs::kLanguageHotkeyPreviousEngine,
                            kHotkeyPreviousEngine);
  prefs->RegisterStringPref(prefs::kLanguagePreloadEngines,
                            kFallbackInputMethodId);  // EN layout
  for (size_t i = 0; i < kNumChewingBooleanPrefs; ++i) {
    prefs->RegisterBooleanPref(kChewingBooleanPrefs[i].pref_name,
                               kChewingBooleanPrefs[i].default_pref_value);
  }
  for (size_t i = 0; i < kNumChewingMultipleChoicePrefs; ++i) {
    prefs->RegisterStringPref(
        kChewingMultipleChoicePrefs[i].pref_name,
        kChewingMultipleChoicePrefs[i].default_pref_value);
  }
  prefs->RegisterIntegerPref(kChewingHsuSelKeyType.pref_name,
                             kChewingHsuSelKeyType.default_pref_value);

  for (size_t i = 0; i < kNumChewingIntegerPrefs; ++i) {
    prefs->RegisterIntegerPref(kChewingIntegerPrefs[i].pref_name,
                               kChewingIntegerPrefs[i].default_pref_value);
  }
  prefs->RegisterStringPref(
      prefs::kLanguageHangulKeyboard,
      kHangulKeyboardNameIDPairs[0].keyboard_id);
  for (size_t i = 0; i < kNumPinyinBooleanPrefs; ++i) {
    prefs->RegisterBooleanPref(kPinyinBooleanPrefs[i].pref_name,
                               kPinyinBooleanPrefs[i].default_pref_value);
  }
  for (size_t i = 0; i < kNumPinyinIntegerPrefs; ++i) {
    prefs->RegisterIntegerPref(kPinyinIntegerPrefs[i].pref_name,
                               kPinyinIntegerPrefs[i].default_pref_value);
  }
  prefs->RegisterIntegerPref(kPinyinDoublePinyinSchema.pref_name,
                             kPinyinDoublePinyinSchema.default_pref_value);

  for (size_t i = 0; i < kNumMozcBooleanPrefs; ++i) {
    prefs->RegisterBooleanPref(kMozcBooleanPrefs[i].pref_name,
                               kMozcBooleanPrefs[i].default_pref_value);
  }
  for (size_t i = 0; i < kNumMozcMultipleChoicePrefs; ++i) {
    prefs->RegisterStringPref(
        kMozcMultipleChoicePrefs[i].pref_name,
        kMozcMultipleChoicePrefs[i].default_pref_value);
  }
  for (size_t i = 0; i < kNumMozcIntegerPrefs; ++i) {
    prefs->RegisterIntegerPref(kMozcIntegerPrefs[i].pref_name,
                               kMozcIntegerPrefs[i].default_pref_value);
  }
}

void Preferences::Init(PrefService* prefs) {
  tap_to_click_enabled_.Init(prefs::kTapToClickEnabled, prefs, this);
  accessibility_enabled_.Init(prefs::kAccessibilityEnabled, prefs, this);
  vert_edge_scroll_enabled_.Init(prefs::kVertEdgeScrollEnabled, prefs, this);
  speed_factor_.Init(prefs::kTouchpadSpeedFactor, prefs, this);
  sensitivity_.Init(prefs::kTouchpadSensitivity, prefs, this);
  language_hotkey_next_engine_in_menu_.Init(
      prefs::kLanguageHotkeyNextEngineInMenu, prefs, this);
  language_hotkey_previous_engine_.Init(
      prefs::kLanguageHotkeyPreviousEngine, prefs, this);
  language_preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs, this);
  for (size_t i = 0; i < kNumChewingBooleanPrefs; ++i) {
    language_chewing_boolean_prefs_[i].Init(
        kChewingBooleanPrefs[i].pref_name, prefs, this);
  }
  for (size_t i = 0; i < kNumChewingMultipleChoicePrefs; ++i) {
    language_chewing_multiple_choice_prefs_[i].Init(
        kChewingMultipleChoicePrefs[i].pref_name, prefs, this);
  }
  language_chewing_hsu_sel_key_type_.Init(
      kChewingHsuSelKeyType.pref_name, prefs, this);
  for (size_t i = 0; i < kNumChewingIntegerPrefs; ++i) {
    language_chewing_integer_prefs_[i].Init(
        kChewingIntegerPrefs[i].pref_name, prefs, this);
  }
  language_hangul_keyboard_.Init(prefs::kLanguageHangulKeyboard, prefs, this);
  for (size_t i = 0; i < kNumPinyinBooleanPrefs; ++i) {
    language_pinyin_boolean_prefs_[i].Init(
        kPinyinBooleanPrefs[i].pref_name, prefs, this);
  }
  for (size_t i = 0; i < kNumPinyinIntegerPrefs; ++i) {
    language_pinyin_int_prefs_[i].Init(
        kPinyinIntegerPrefs[i].pref_name, prefs, this);
  }
  language_pinyin_double_pinyin_schema_.Init(
      kPinyinDoublePinyinSchema.pref_name, prefs, this);
  for (size_t i = 0; i < kNumMozcBooleanPrefs; ++i) {
    language_mozc_boolean_prefs_[i].Init(
        kMozcBooleanPrefs[i].pref_name, prefs, this);
  }
  for (size_t i = 0; i < kNumMozcMultipleChoicePrefs; ++i) {
    language_mozc_multiple_choice_prefs_[i].Init(
        kMozcMultipleChoicePrefs[i].pref_name, prefs, this);
  }
  for (size_t i = 0; i < kNumMozcIntegerPrefs; ++i) {
    language_mozc_integer_prefs_[i].Init(
        kMozcIntegerPrefs[i].pref_name, prefs, this);
  }

  // Initialize touchpad settings to what's saved in user preferences.
  NotifyPrefChanged(NULL);
}

void Preferences::Observe(NotificationType type,
                          const NotificationSource& source,
                          const NotificationDetails& details) {
  if (type == NotificationType::PREF_CHANGED)
    NotifyPrefChanged(Details<std::wstring>(details).ptr());
}

void Preferences::NotifyPrefChanged(const std::wstring* pref_name) {
  if (!pref_name || *pref_name == prefs::kTapToClickEnabled) {
    CrosLibrary::Get()->GetSynapticsLibrary()->SetBoolParameter(
        PARAM_BOOL_TAP_TO_CLICK,
        tap_to_click_enabled_.GetValue());
  }
  if (!pref_name || *pref_name == prefs::kVertEdgeScrollEnabled) {
    CrosLibrary::Get()->GetSynapticsLibrary()->SetBoolParameter(
        PARAM_BOOL_VERTICAL_EDGE_SCROLLING,
        vert_edge_scroll_enabled_.GetValue());
  }
  if (!pref_name || *pref_name == prefs::kTouchpadSpeedFactor) {
    CrosLibrary::Get()->GetSynapticsLibrary()->SetRangeParameter(
        PARAM_RANGE_SPEED_SENSITIVITY,
        speed_factor_.GetValue());
  }
  if (!pref_name || *pref_name == prefs::kTouchpadSensitivity) {
    CrosLibrary::Get()->GetSynapticsLibrary()->SetRangeParameter(
          PARAM_RANGE_TOUCH_SENSITIVITY,
          sensitivity_.GetValue());
  }

  // We don't handle prefs::kLanguageCurrentInputMethod and PreviousInputMethod
  // here.

  if (!pref_name || *pref_name == prefs::kLanguageHotkeyNextEngineInMenu) {
    SetLanguageConfigStringListAsCSV(
        kHotKeySectionName,
        kNextEngineInMenuConfigName,
        language_hotkey_next_engine_in_menu_.GetValue());
  }
  if (!pref_name || *pref_name == prefs::kLanguageHotkeyPreviousEngine) {
    SetLanguageConfigStringListAsCSV(
        kHotKeySectionName,
        kPreviousEngineConfigName,
        language_hotkey_previous_engine_.GetValue());
  }
  if (!pref_name || *pref_name == prefs::kLanguagePreloadEngines) {
    SetLanguageConfigStringListAsCSV(kGeneralSectionName,
                                     kPreloadEnginesConfigName,
                                     language_preload_engines_.GetValue());
  }
  for (size_t i = 0; i < kNumChewingBooleanPrefs; ++i) {
    if (!pref_name || *pref_name == kChewingBooleanPrefs[i].pref_name) {
      SetLanguageConfigBoolean(kChewingSectionName,
                               kChewingBooleanPrefs[i].ibus_config_name,
                               language_chewing_boolean_prefs_[i].GetValue());
    }
  }
  for (size_t i = 0; i < kNumChewingMultipleChoicePrefs; ++i) {
    if (!pref_name || *pref_name == kChewingMultipleChoicePrefs[i].pref_name) {
      SetLanguageConfigString(
          kChewingSectionName,
          kChewingMultipleChoicePrefs[i].ibus_config_name,
          language_chewing_multiple_choice_prefs_[i].GetValue());
    }
  }
  if (!pref_name || *pref_name == kChewingHsuSelKeyType.pref_name) {
    SetLanguageConfigInteger(
        kChewingSectionName,
        kChewingHsuSelKeyType.ibus_config_name,
        language_chewing_hsu_sel_key_type_.GetValue());
  }
  for (size_t i = 0; i < kNumChewingIntegerPrefs; ++i) {
    if (!pref_name || *pref_name == kChewingIntegerPrefs[i].pref_name) {
      SetLanguageConfigInteger(kChewingSectionName,
                               kChewingIntegerPrefs[i].ibus_config_name,
                               language_chewing_integer_prefs_[i].GetValue());
    }
  }
  if (!pref_name || *pref_name == prefs::kLanguageHangulKeyboard) {
    SetLanguageConfigString(kHangulSectionName, kHangulKeyboardConfigName,
                            language_hangul_keyboard_.GetValue());
  }
  for (size_t i = 0; i < kNumPinyinBooleanPrefs; ++i) {
    if (!pref_name || *pref_name == kPinyinBooleanPrefs[i].pref_name) {
      SetLanguageConfigBoolean(kPinyinSectionName,
                               kPinyinBooleanPrefs[i].ibus_config_name,
                               language_pinyin_boolean_prefs_[i].GetValue());
    }
  }
  for (size_t i = 0; i < kNumPinyinIntegerPrefs; ++i) {
    if (!pref_name || *pref_name == kPinyinIntegerPrefs[i].pref_name) {
      SetLanguageConfigInteger(kPinyinSectionName,
                               kPinyinIntegerPrefs[i].ibus_config_name,
                               language_pinyin_int_prefs_[i].GetValue());
    }
  }
  if (!pref_name || *pref_name == kPinyinDoublePinyinSchema.pref_name) {
    SetLanguageConfigInteger(
        kPinyinSectionName,
        kPinyinDoublePinyinSchema.ibus_config_name,
        language_pinyin_double_pinyin_schema_.GetValue());
  }
  for (size_t i = 0; i < kNumMozcBooleanPrefs; ++i) {
    if (!pref_name || *pref_name == kMozcBooleanPrefs[i].pref_name) {
      SetLanguageConfigBoolean(kMozcSectionName,
                               kMozcBooleanPrefs[i].ibus_config_name,
                               language_mozc_boolean_prefs_[i].GetValue());
    }
  }
  for (size_t i = 0; i < kNumMozcMultipleChoicePrefs; ++i) {
    if (!pref_name || *pref_name == kMozcMultipleChoicePrefs[i].pref_name) {
      SetLanguageConfigString(
          kMozcSectionName,
          kMozcMultipleChoicePrefs[i].ibus_config_name,
          language_mozc_multiple_choice_prefs_[i].GetValue());
    }
  }
  for (size_t i = 0; i < kNumMozcIntegerPrefs; ++i) {
    if (!pref_name || *pref_name == kMozcIntegerPrefs[i].pref_name) {
      SetLanguageConfigInteger(kMozcSectionName,
                               kMozcIntegerPrefs[i].ibus_config_name,
                               language_mozc_integer_prefs_[i].GetValue());
    }
  }
}

void Preferences::SetLanguageConfigBoolean(const char* section,
                                           const char* name,
                                           bool value) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeBool;
  config.bool_value = value;
  CrosLibrary::Get()->GetInputMethodLibrary()->
      SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigInteger(const char* section,
                                           const char* name,
                                           int value) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeInt;
  config.int_value = value;
  CrosLibrary::Get()->GetInputMethodLibrary()->
      SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigString(const char* section,
                                          const char* name,
                                          const std::string& value) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeString;
  config.string_value = value;
  CrosLibrary::Get()->GetInputMethodLibrary()->
      SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigStringList(
    const char* section,
    const char* name,
    const std::vector<std::string>& values) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeStringList;
  for (size_t i = 0; i < values.size(); ++i)
    config.string_list_value.push_back(values[i]);

  CrosLibrary::Get()->GetInputMethodLibrary()->
      SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigStringListAsCSV(const char* section,
                                                   const char* name,
                                                   const std::string& value) {
  LOG(INFO) << "Setting " << name << " to '" << value << "'";

  std::vector<std::string> split_values;
  if (!value.empty())
    SplitString(value, ',', &split_values);

  // We should call the cros API even when |value| is empty, to disable default
  // config.
  SetLanguageConfigStringList(section, name, split_values);
}

}  // namespace chromeos
<commit_msg>Preload all IMEs/Layouts for the UI Language on login, if the value has not yet been set.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/preferences.h"

#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/input_method_library.h"
#include "chrome/browser/chromeos/cros/synaptics_library.h"
#include "chrome/browser/chromeos/input_method/input_method_util.h"
#include "chrome/browser/pref_member.h"
#include "chrome/browser/pref_service.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "unicode/timezone.h"

namespace chromeos {

static const char kFallbackInputMethodLocale[] = "en-US";

// static
void Preferences::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterBooleanPref(prefs::kTapToClickEnabled, false);
  prefs->RegisterBooleanPref(prefs::kAccessibilityEnabled, false);
  prefs->RegisterBooleanPref(prefs::kVertEdgeScrollEnabled, false);
  prefs->RegisterIntegerPref(prefs::kTouchpadSpeedFactor, 9);
  prefs->RegisterIntegerPref(prefs::kTouchpadSensitivity, 5);
  prefs->RegisterStringPref(prefs::kLanguageCurrentInputMethod, "");
  prefs->RegisterStringPref(prefs::kLanguagePreviousInputMethod, "");
  prefs->RegisterStringPref(prefs::kLanguageHotkeyNextEngineInMenu,
                            kHotkeyNextEngineInMenu);
  prefs->RegisterStringPref(prefs::kLanguageHotkeyPreviousEngine,
                            kHotkeyPreviousEngine);
  prefs->RegisterStringPref(prefs::kLanguagePreloadEngines,
                            kFallbackInputMethodId);  // EN layout
  for (size_t i = 0; i < kNumChewingBooleanPrefs; ++i) {
    prefs->RegisterBooleanPref(kChewingBooleanPrefs[i].pref_name,
                               kChewingBooleanPrefs[i].default_pref_value);
  }
  for (size_t i = 0; i < kNumChewingMultipleChoicePrefs; ++i) {
    prefs->RegisterStringPref(
        kChewingMultipleChoicePrefs[i].pref_name,
        kChewingMultipleChoicePrefs[i].default_pref_value);
  }
  prefs->RegisterIntegerPref(kChewingHsuSelKeyType.pref_name,
                             kChewingHsuSelKeyType.default_pref_value);

  for (size_t i = 0; i < kNumChewingIntegerPrefs; ++i) {
    prefs->RegisterIntegerPref(kChewingIntegerPrefs[i].pref_name,
                               kChewingIntegerPrefs[i].default_pref_value);
  }
  prefs->RegisterStringPref(
      prefs::kLanguageHangulKeyboard,
      kHangulKeyboardNameIDPairs[0].keyboard_id);
  for (size_t i = 0; i < kNumPinyinBooleanPrefs; ++i) {
    prefs->RegisterBooleanPref(kPinyinBooleanPrefs[i].pref_name,
                               kPinyinBooleanPrefs[i].default_pref_value);
  }
  for (size_t i = 0; i < kNumPinyinIntegerPrefs; ++i) {
    prefs->RegisterIntegerPref(kPinyinIntegerPrefs[i].pref_name,
                               kPinyinIntegerPrefs[i].default_pref_value);
  }
  prefs->RegisterIntegerPref(kPinyinDoublePinyinSchema.pref_name,
                             kPinyinDoublePinyinSchema.default_pref_value);

  for (size_t i = 0; i < kNumMozcBooleanPrefs; ++i) {
    prefs->RegisterBooleanPref(kMozcBooleanPrefs[i].pref_name,
                               kMozcBooleanPrefs[i].default_pref_value);
  }
  for (size_t i = 0; i < kNumMozcMultipleChoicePrefs; ++i) {
    prefs->RegisterStringPref(
        kMozcMultipleChoicePrefs[i].pref_name,
        kMozcMultipleChoicePrefs[i].default_pref_value);
  }
  for (size_t i = 0; i < kNumMozcIntegerPrefs; ++i) {
    prefs->RegisterIntegerPref(kMozcIntegerPrefs[i].pref_name,
                               kMozcIntegerPrefs[i].default_pref_value);
  }
}

void Preferences::Init(PrefService* prefs) {
  tap_to_click_enabled_.Init(prefs::kTapToClickEnabled, prefs, this);
  accessibility_enabled_.Init(prefs::kAccessibilityEnabled, prefs, this);
  vert_edge_scroll_enabled_.Init(prefs::kVertEdgeScrollEnabled, prefs, this);
  speed_factor_.Init(prefs::kTouchpadSpeedFactor, prefs, this);
  sensitivity_.Init(prefs::kTouchpadSensitivity, prefs, this);
  language_hotkey_next_engine_in_menu_.Init(
      prefs::kLanguageHotkeyNextEngineInMenu, prefs, this);
  language_hotkey_previous_engine_.Init(
      prefs::kLanguageHotkeyPreviousEngine, prefs, this);
  language_preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs, this);
  for (size_t i = 0; i < kNumChewingBooleanPrefs; ++i) {
    language_chewing_boolean_prefs_[i].Init(
        kChewingBooleanPrefs[i].pref_name, prefs, this);
  }
  for (size_t i = 0; i < kNumChewingMultipleChoicePrefs; ++i) {
    language_chewing_multiple_choice_prefs_[i].Init(
        kChewingMultipleChoicePrefs[i].pref_name, prefs, this);
  }
  language_chewing_hsu_sel_key_type_.Init(
      kChewingHsuSelKeyType.pref_name, prefs, this);
  for (size_t i = 0; i < kNumChewingIntegerPrefs; ++i) {
    language_chewing_integer_prefs_[i].Init(
        kChewingIntegerPrefs[i].pref_name, prefs, this);
  }
  language_hangul_keyboard_.Init(prefs::kLanguageHangulKeyboard, prefs, this);
  for (size_t i = 0; i < kNumPinyinBooleanPrefs; ++i) {
    language_pinyin_boolean_prefs_[i].Init(
        kPinyinBooleanPrefs[i].pref_name, prefs, this);
  }
  for (size_t i = 0; i < kNumPinyinIntegerPrefs; ++i) {
    language_pinyin_int_prefs_[i].Init(
        kPinyinIntegerPrefs[i].pref_name, prefs, this);
  }
  language_pinyin_double_pinyin_schema_.Init(
      kPinyinDoublePinyinSchema.pref_name, prefs, this);
  for (size_t i = 0; i < kNumMozcBooleanPrefs; ++i) {
    language_mozc_boolean_prefs_[i].Init(
        kMozcBooleanPrefs[i].pref_name, prefs, this);
  }
  for (size_t i = 0; i < kNumMozcMultipleChoicePrefs; ++i) {
    language_mozc_multiple_choice_prefs_[i].Init(
        kMozcMultipleChoicePrefs[i].pref_name, prefs, this);
  }
  for (size_t i = 0; i < kNumMozcIntegerPrefs; ++i) {
    language_mozc_integer_prefs_[i].Init(
        kMozcIntegerPrefs[i].pref_name, prefs, this);
  }

  std::string locale(g_browser_process->GetApplicationLocale());
  if (locale != kFallbackInputMethodLocale &&
      !prefs->HasPrefPath(prefs::kLanguagePreloadEngines)) {
    std::string preload_engines(language_preload_engines_.GetValue());
    std::vector<std::string> input_method_ids;
    input_method::GetInputMethodIdsFromLanguageCode(
        locale, input_method::kAllInputMethods, &input_method_ids);
    if (!input_method_ids.empty()) {
      if (!preload_engines.empty())
        preload_engines += ',';
      preload_engines += JoinString(input_method_ids, ',');
    }
    language_preload_engines_.SetValue(preload_engines);
  }

  // Initialize touchpad settings to what's saved in user preferences.
  NotifyPrefChanged(NULL);
}

void Preferences::Observe(NotificationType type,
                          const NotificationSource& source,
                          const NotificationDetails& details) {
  if (type == NotificationType::PREF_CHANGED)
    NotifyPrefChanged(Details<std::wstring>(details).ptr());
}

void Preferences::NotifyPrefChanged(const std::wstring* pref_name) {
  if (!pref_name || *pref_name == prefs::kTapToClickEnabled) {
    CrosLibrary::Get()->GetSynapticsLibrary()->SetBoolParameter(
        PARAM_BOOL_TAP_TO_CLICK,
        tap_to_click_enabled_.GetValue());
  }
  if (!pref_name || *pref_name == prefs::kVertEdgeScrollEnabled) {
    CrosLibrary::Get()->GetSynapticsLibrary()->SetBoolParameter(
        PARAM_BOOL_VERTICAL_EDGE_SCROLLING,
        vert_edge_scroll_enabled_.GetValue());
  }
  if (!pref_name || *pref_name == prefs::kTouchpadSpeedFactor) {
    CrosLibrary::Get()->GetSynapticsLibrary()->SetRangeParameter(
        PARAM_RANGE_SPEED_SENSITIVITY,
        speed_factor_.GetValue());
  }
  if (!pref_name || *pref_name == prefs::kTouchpadSensitivity) {
    CrosLibrary::Get()->GetSynapticsLibrary()->SetRangeParameter(
          PARAM_RANGE_TOUCH_SENSITIVITY,
          sensitivity_.GetValue());
  }

  // We don't handle prefs::kLanguageCurrentInputMethod and PreviousInputMethod
  // here.

  if (!pref_name || *pref_name == prefs::kLanguageHotkeyNextEngineInMenu) {
    SetLanguageConfigStringListAsCSV(
        kHotKeySectionName,
        kNextEngineInMenuConfigName,
        language_hotkey_next_engine_in_menu_.GetValue());
  }
  if (!pref_name || *pref_name == prefs::kLanguageHotkeyPreviousEngine) {
    SetLanguageConfigStringListAsCSV(
        kHotKeySectionName,
        kPreviousEngineConfigName,
        language_hotkey_previous_engine_.GetValue());
  }
  if (!pref_name || *pref_name == prefs::kLanguagePreloadEngines) {
    SetLanguageConfigStringListAsCSV(kGeneralSectionName,
                                     kPreloadEnginesConfigName,
                                     language_preload_engines_.GetValue());
  }
  for (size_t i = 0; i < kNumChewingBooleanPrefs; ++i) {
    if (!pref_name || *pref_name == kChewingBooleanPrefs[i].pref_name) {
      SetLanguageConfigBoolean(kChewingSectionName,
                               kChewingBooleanPrefs[i].ibus_config_name,
                               language_chewing_boolean_prefs_[i].GetValue());
    }
  }
  for (size_t i = 0; i < kNumChewingMultipleChoicePrefs; ++i) {
    if (!pref_name || *pref_name == kChewingMultipleChoicePrefs[i].pref_name) {
      SetLanguageConfigString(
          kChewingSectionName,
          kChewingMultipleChoicePrefs[i].ibus_config_name,
          language_chewing_multiple_choice_prefs_[i].GetValue());
    }
  }
  if (!pref_name || *pref_name == kChewingHsuSelKeyType.pref_name) {
    SetLanguageConfigInteger(
        kChewingSectionName,
        kChewingHsuSelKeyType.ibus_config_name,
        language_chewing_hsu_sel_key_type_.GetValue());
  }
  for (size_t i = 0; i < kNumChewingIntegerPrefs; ++i) {
    if (!pref_name || *pref_name == kChewingIntegerPrefs[i].pref_name) {
      SetLanguageConfigInteger(kChewingSectionName,
                               kChewingIntegerPrefs[i].ibus_config_name,
                               language_chewing_integer_prefs_[i].GetValue());
    }
  }
  if (!pref_name || *pref_name == prefs::kLanguageHangulKeyboard) {
    SetLanguageConfigString(kHangulSectionName, kHangulKeyboardConfigName,
                            language_hangul_keyboard_.GetValue());
  }
  for (size_t i = 0; i < kNumPinyinBooleanPrefs; ++i) {
    if (!pref_name || *pref_name == kPinyinBooleanPrefs[i].pref_name) {
      SetLanguageConfigBoolean(kPinyinSectionName,
                               kPinyinBooleanPrefs[i].ibus_config_name,
                               language_pinyin_boolean_prefs_[i].GetValue());
    }
  }
  for (size_t i = 0; i < kNumPinyinIntegerPrefs; ++i) {
    if (!pref_name || *pref_name == kPinyinIntegerPrefs[i].pref_name) {
      SetLanguageConfigInteger(kPinyinSectionName,
                               kPinyinIntegerPrefs[i].ibus_config_name,
                               language_pinyin_int_prefs_[i].GetValue());
    }
  }
  if (!pref_name || *pref_name == kPinyinDoublePinyinSchema.pref_name) {
    SetLanguageConfigInteger(
        kPinyinSectionName,
        kPinyinDoublePinyinSchema.ibus_config_name,
        language_pinyin_double_pinyin_schema_.GetValue());
  }
  for (size_t i = 0; i < kNumMozcBooleanPrefs; ++i) {
    if (!pref_name || *pref_name == kMozcBooleanPrefs[i].pref_name) {
      SetLanguageConfigBoolean(kMozcSectionName,
                               kMozcBooleanPrefs[i].ibus_config_name,
                               language_mozc_boolean_prefs_[i].GetValue());
    }
  }
  for (size_t i = 0; i < kNumMozcMultipleChoicePrefs; ++i) {
    if (!pref_name || *pref_name == kMozcMultipleChoicePrefs[i].pref_name) {
      SetLanguageConfigString(
          kMozcSectionName,
          kMozcMultipleChoicePrefs[i].ibus_config_name,
          language_mozc_multiple_choice_prefs_[i].GetValue());
    }
  }
  for (size_t i = 0; i < kNumMozcIntegerPrefs; ++i) {
    if (!pref_name || *pref_name == kMozcIntegerPrefs[i].pref_name) {
      SetLanguageConfigInteger(kMozcSectionName,
                               kMozcIntegerPrefs[i].ibus_config_name,
                               language_mozc_integer_prefs_[i].GetValue());
    }
  }
}

void Preferences::SetLanguageConfigBoolean(const char* section,
                                           const char* name,
                                           bool value) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeBool;
  config.bool_value = value;
  CrosLibrary::Get()->GetInputMethodLibrary()->
      SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigInteger(const char* section,
                                           const char* name,
                                           int value) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeInt;
  config.int_value = value;
  CrosLibrary::Get()->GetInputMethodLibrary()->
      SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigString(const char* section,
                                          const char* name,
                                          const std::string& value) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeString;
  config.string_value = value;
  CrosLibrary::Get()->GetInputMethodLibrary()->
      SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigStringList(
    const char* section,
    const char* name,
    const std::vector<std::string>& values) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeStringList;
  for (size_t i = 0; i < values.size(); ++i)
    config.string_list_value.push_back(values[i]);

  CrosLibrary::Get()->GetInputMethodLibrary()->
      SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigStringListAsCSV(const char* section,
                                                   const char* name,
                                                   const std::string& value) {
  LOG(INFO) << "Setting " << name << " to '" << value << "'";

  std::vector<std::string> split_values;
  if (!value.empty())
    SplitString(value, ',', &split_values);

  // We should call the cros API even when |value| is empty, to disable default
  // config.
  SetLanguageConfigStringList(section, name, split_values);
}

}  // namespace chromeos
<|endoftext|>