<commit_before>#include <omnicore/wallettxbuilder.h>

#include <omnicore/encoding.h>
#include <omnicore/errors.h>
#include <omnicore/log.h>
#include <omnicore/omnicore.h>
#include <omnicore/parsing.h>
#include <omnicore/script.h>
#include <omnicore/walletutils.h>

#include <amount.h>
#include <base58.h>
#include <coins.h>
#include <consensus/validation.h>
#include <core_io.h>
#include <interfaces/wallet.h>
#include <key_io.h>
#include <keystore.h>
#include <validation.h>
#include <net.h>
#include <node/transaction.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <script/sign.h>
#include <script/standard.h>
#include <sync.h>
#include <txmempool.h>
#include <uint256.h>
#ifdef ENABLE_WALLET
#include <wallet/coincontrol.h>
#include <wallet/wallet.h>
#endif

#include <stdint.h>
#include <string>
#include <utility>
#include <vector>

using mastercore::AddressToPubKey;
using mastercore::UseEncodingClassC;

/** Creates and sends a transaction. */
int WalletTxBuilder(
        const std::string& senderAddress,
        const std::string& receiverAddress,
        const std::string& redemptionAddress,
        int64_t referenceAmount,
        const std::vector<unsigned char>& payload,
        uint256& retTxid,
        std::string& retRawTx,
        bool commit,
        interfaces::Wallet* iWallet)
{
#ifdef ENABLE_WALLET
    if (!iWallet) return MP_ERR_WALLET_ACCESS;

    // Determine the class to send the transaction via - default is Class C
    int omniTxClass = OMNI_CLASS_C;
    if (!UseEncodingClassC(payload.size())) omniTxClass = OMNI_CLASS_B;

    // Prepare the transaction - first setup some vars
    CCoinControl coinControl;
    std::vector<std::pair<CScript, int64_t> > vecSend;

    // Next, we set the change address to the sender
    coinControl.destChange = DecodeDestination(senderAddress);

    // Select the inputs
    if (0 > mastercore::SelectCoins(*iWallet, senderAddress, coinControl, referenceAmount)) { return MP_INPUTS_INVALID; }

    // Encode the data outputs
    switch(omniTxClass) {
        case OMNI_CLASS_B: { // declaring vars in a switch here so use an expicit code block
            CPubKey redeemingPubKey;
            const std::string& sAddress = redemptionAddress.empty() ? senderAddress : redemptionAddress;
            if (!AddressToPubKey(iWallet, sAddress, redeemingPubKey)) {
                return MP_REDEMP_BAD_VALIDATION;
            }
            if (!OmniCore_Encode_ClassB(senderAddress,redeemingPubKey,payload,vecSend)) { return MP_ENCODING_ERROR; }
        break; }
        case OMNI_CLASS_C:
            if(!OmniCore_Encode_ClassC(payload,vecSend)) { return MP_ENCODING_ERROR; }
        break;
    }

    // Then add a paytopubkeyhash output for the recipient (if needed) - note we do this last as we want this to be the highest vout
    if (!receiverAddress.empty()) {
        CScript scriptPubKey = GetScriptForDestination(DecodeDestination(receiverAddress));
        vecSend.push_back(std::make_pair(scriptPubKey, 0 < referenceAmount ? referenceAmount : OmniGetDustThreshold(scriptPubKey)));
    }

    // Now we have what we need to pass to the wallet to create the transaction, perform some checks first

    if (!coinControl.HasSelected()) return MP_ERR_INPUTSELECT_FAIL;

    std::vector<CRecipient> vecRecipients;
    for (size_t i = 0; i < vecSend.size(); ++i) {
        const std::pair<CScript, int64_t>& vec = vecSend[i];
        CRecipient recipient = {vec.first, vec.second, false};
        vecRecipients.push_back(recipient);
    }

    // Ask the wallet to create the transaction (note mining fee determined by Bitcoin Core params)
    CAmount nFeeRet = 0;
    int nChangePosInOut = -1;
    std::string strFailReason;
    auto wtxNew = iWallet->createTransaction(vecRecipients, coinControl, true /* sign */, nChangePosInOut, nFeeRet, strFailReason, false);

    if (!wtxNew) {
        PrintToLog("%s: ERROR: wallet transaction creation failed: %s\n", __func__, strFailReason);
        return MP_ERR_CREATE_TX;
    }

    // If this request is only to create, but not commit the transaction then display it and exit
    if (!commit) {
        retRawTx = EncodeHexTx(wtxNew->get());
        return 0;
    } else {
        // Commit the transaction to the wallet and broadcast)
        PrintToLog("%s: %s; nFeeRet = %d\n", __func__, wtxNew->get().ToString(), nFeeRet);
        std::string rejectReason;
        if (!wtxNew->commit({}, {}, rejectReason)) return MP_ERR_COMMIT_TX;
        retTxid = wtxNew->get().GetHash();
        return 0;
    }
#else
    return MP_ERR_WALLET_ACCESS;
#endif

}

#ifdef ENABLE_WALLET
/** Locks all available coins that are not in the set of destinations. */
static void LockUnrelatedCoins(
        interfaces::Wallet* iWallet,
        const std::set<CTxDestination>& destinations,
        std::vector<COutPoint>& retLockedCoins)
{
    if (!iWallet) {
        return;
    }

    // NOTE: require: LOCK2(cs_main, pwallet->cs_wallet);

    // lock any other output
    std::vector<COutput> vCoins;
    iWallet->availableCoins(vCoins, false, nullptr, 0);

    for (COutput& output : vCoins) {
        CTxDestination address;
        const CScript& scriptPubKey = output.tx->tx->vout[output.i].scriptPubKey;
        bool fValidAddress = ExtractDestination(scriptPubKey, address);

        // don't lock specified coins, but any other
        if (fValidAddress && destinations.count(address)) {
            continue;
        }

        COutPoint outpointLocked(output.tx->GetHash(), output.i);
        iWallet->lockCoin(outpointLocked);
        retLockedCoins.push_back(outpointLocked);
    }
}

/** Unlocks all coins, which were previously locked. */
static void UnlockCoins(
        interfaces::Wallet* iWallet,
        const std::vector<COutPoint>& vToUnlock)
{
    // NOTE: require: LOCK2(cs_main, pwallet->cs_wallet);

    for (const COutPoint& output : vToUnlock) {
        iWallet->unlockCoin(output);
    }
}
#endif

/**
 * Creates and sends a raw transaction by selecting all coins from the sender
 * and enough coins from a fee source. Change is sent to the fee source!
 */
int CreateFundedTransaction(
        const std::string& senderAddress,
        const std::string& receiverAddress,
        const std::string& feeAddress,
        const std::vector<unsigned char>& payload,
        uint256& retTxid,
        interfaces::Wallet* iWallet)
{
#ifdef ENABLE_WALLET
    if (!iWallet) {
        return MP_ERR_WALLET_ACCESS;
    }

    if (!UseEncodingClassC(payload.size())) {
        return MP_ENCODING_ERROR;
    }

    // add payload output
    std::vector<std::pair<CScript, int64_t> > vecSend;
    if (!OmniCore_Encode_ClassC(payload, vecSend)) {
        return MP_ENCODING_ERROR;
    }

    // add reference output, if there is one
    if (!receiverAddress.empty() && receiverAddress != feeAddress) {
        CScript scriptPubKey = GetScriptForDestination(DecodeDestination(receiverAddress));
        vecSend.push_back(std::make_pair(scriptPubKey, OmniGetDustThreshold(scriptPubKey)));
    }

    // convert into recipients objects
    std::vector<CRecipient> vecRecipients;
    for (size_t i = 0; i < vecSend.size(); ++i) {
        const std::pair<CScript, int64_t>& vec = vecSend[i];
        CRecipient recipient = {vec.first, vec.second, false};
        vecRecipients.push_back(recipient);
    }

    bool fSuccess = false;
    CAmount nFeeRequired = 0;
    std::string strFailReason;
    int nChangePosRet = 0; // add change first

    // set change
    CCoinControl coinControl;
    coinControl.destChange = DecodeDestination(feeAddress);
    coinControl.fAllowOtherInputs = true;

    if (!mastercore::SelectAllCoins(*iWallet, senderAddress, coinControl)) {
        PrintToLog("%s: ERROR: sender %s has no coins\n", __func__, senderAddress);
        return MP_INPUTS_INVALID;
    }

    // prepare sources for fees
    std::set<CTxDestination> feeSources;
    feeSources.insert(DecodeDestination(feeAddress));

    std::vector<COutPoint> vLockedCoins;
    LockUnrelatedCoins(iWallet, feeSources, vLockedCoins);

    auto wtxNew = iWallet->createTransaction(vecRecipients, coinControl, false /* sign */, nChangePosRet, nFeeRequired, strFailReason, true);

    if (wtxNew) {
        fSuccess = true;
    }

    if (fSuccess && nChangePosRet == -1 && receiverAddress == feeAddress) {
        fSuccess = false;
        strFailReason = "send to self without change";
    }

    // to restore the original order of inputs, create a new transaction and add
    // inputs and outputs step by step
    CMutableTransaction tx;

    if (fSuccess)
    {
        std::vector<COutPoint> vSelectedInputs;
        coinControl.ListSelected(vSelectedInputs);

        // add previously selected coins
        for(const COutPoint& txIn : vSelectedInputs) {
            tx.vin.push_back(CTxIn(txIn));
        }

        // add other selected coins
        for(const CTxIn& txin : wtxNew->get().vin) {
            if (!coinControl.IsSelected(txin.prevout)) {
                tx.vin.push_back(txin);
            }
        }

        // add outputs
        for(const CTxOut& txOut : wtxNew->get().vout) {
            tx.vout.push_back(txOut);
        }
    }

    // restore original locking state
    UnlockCoins(iWallet, vLockedCoins);

    // lock selected outputs for this transaction // TODO: could be removed?
    if (fSuccess) {
        for(const CTxIn& txIn : tx.vin) {
            iWallet->lockCoin(txIn.prevout);
        }
    }

    if (!fSuccess) {
        PrintToLog("%s: ERROR: wallet transaction creation failed: %s\n", __func__, strFailReason);
        return MP_ERR_CREATE_TX;
    }

    // sign the transaction

    // fetch previous transactions (inputs):
    CCoinsView viewDummy;
    CCoinsViewCache view(&viewDummy);
    {
        LOCK(mempool.cs);
        CCoinsViewCache &viewChain = *pcoinsTip;
        CCoinsViewMemPool viewMempool(&viewChain, mempool);
        view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view

        for(const CTxIn& txin : tx.vin) {
            const auto& prevout = txin.prevout;
            view.AccessCoin(prevout); // this is certainly allowed to fail
        }

        view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
    }

    int nHashType = SIGHASH_ALL;

    for (unsigned int i = 0; i < tx.vin.size(); i++) {
        CTxIn& txin = tx.vin[i];
        const Coin& coin = view.AccessCoin(txin.prevout);
        if (coin.IsSpent()) {
            PrintToLog("%s: ERROR: wallet transaction signing failed: input not found or already spent\n", __func__);
            continue;
        }
        const CScript& prevPubKey = coin.out.scriptPubKey;
        const CAmount& amount = coin.out.nValue;

        SignatureData sigdata;
        if (!iWallet->produceSignature(MutableTransactionSignatureCreator(&tx, i, amount, nHashType), prevPubKey, sigdata)) {
            PrintToLog("%s: ERROR: wallet transaction signing failed\n", __func__);
            return MP_ERR_CREATE_TX;
        }

        UpdateInput(txin, sigdata);
    }

    // send the transaction

    CValidationState state;
    bool missing_inputs;
    CTransactionRef ctx(MakeTransactionRef(std::move(tx)));

    if (!AcceptToMemoryPool(mempool, state, ctx, &missing_inputs, nullptr, false, DEFAULT_TRANSACTION_MAXFEE)) {
        PrintToLog("%s: ERROR: failed to broadcast transaction: %s\n", __func__, state.GetRejectReason());
        return MP_ERR_COMMIT_TX;
    }

    uint256 txid;
    std::string err_string;
    const TransactionError err = BroadcastTransaction(ctx, txid, err_string, true);
    if (TransactionError::OK != err) {
        LogPrintf("%s: BroadcastTransaction failed error: %s\n", __func__, err_string);
    }

    retTxid = txid;

    return 0;
#else
    return MP_ERR_WALLET_ACCESS;
#endif

}
<commit_msg>Fail funded send TXs with more outputs than expected<commit_after>#include <omnicore/wallettxbuilder.h>

#include <omnicore/encoding.h>
#include <omnicore/errors.h>
#include <omnicore/log.h>
#include <omnicore/omnicore.h>
#include <omnicore/parsing.h>
#include <omnicore/script.h>
#include <omnicore/walletutils.h>

#include <amount.h>
#include <base58.h>
#include <coins.h>
#include <consensus/validation.h>
#include <core_io.h>
#include <interfaces/wallet.h>
#include <key_io.h>
#include <keystore.h>
#include <validation.h>
#include <net.h>
#include <node/transaction.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <script/sign.h>
#include <script/standard.h>
#include <sync.h>
#include <txmempool.h>
#include <uint256.h>
#ifdef ENABLE_WALLET
#include <wallet/coincontrol.h>
#include <wallet/wallet.h>
#endif

#include <stdint.h>
#include <string>
#include <utility>
#include <vector>

using mastercore::AddressToPubKey;
using mastercore::UseEncodingClassC;

/** Creates and sends a transaction. */
int WalletTxBuilder(
        const std::string& senderAddress,
        const std::string& receiverAddress,
        const std::string& redemptionAddress,
        int64_t referenceAmount,
        const std::vector<unsigned char>& payload,
        uint256& retTxid,
        std::string& retRawTx,
        bool commit,
        interfaces::Wallet* iWallet)
{
#ifdef ENABLE_WALLET
    if (!iWallet) return MP_ERR_WALLET_ACCESS;

    // Determine the class to send the transaction via - default is Class C
    int omniTxClass = OMNI_CLASS_C;
    if (!UseEncodingClassC(payload.size())) omniTxClass = OMNI_CLASS_B;

    // Prepare the transaction - first setup some vars
    CCoinControl coinControl;
    std::vector<std::pair<CScript, int64_t> > vecSend;

    // Next, we set the change address to the sender
    coinControl.destChange = DecodeDestination(senderAddress);

    // Select the inputs
    if (0 > mastercore::SelectCoins(*iWallet, senderAddress, coinControl, referenceAmount)) { return MP_INPUTS_INVALID; }

    // Encode the data outputs
    switch(omniTxClass) {
        case OMNI_CLASS_B: { // declaring vars in a switch here so use an expicit code block
            CPubKey redeemingPubKey;
            const std::string& sAddress = redemptionAddress.empty() ? senderAddress : redemptionAddress;
            if (!AddressToPubKey(iWallet, sAddress, redeemingPubKey)) {
                return MP_REDEMP_BAD_VALIDATION;
            }
            if (!OmniCore_Encode_ClassB(senderAddress,redeemingPubKey,payload,vecSend)) { return MP_ENCODING_ERROR; }
        break; }
        case OMNI_CLASS_C:
            if(!OmniCore_Encode_ClassC(payload,vecSend)) { return MP_ENCODING_ERROR; }
        break;
    }

    // Then add a paytopubkeyhash output for the recipient (if needed) - note we do this last as we want this to be the highest vout
    if (!receiverAddress.empty()) {
        CScript scriptPubKey = GetScriptForDestination(DecodeDestination(receiverAddress));
        vecSend.push_back(std::make_pair(scriptPubKey, 0 < referenceAmount ? referenceAmount : OmniGetDustThreshold(scriptPubKey)));
    }

    // Now we have what we need to pass to the wallet to create the transaction, perform some checks first

    if (!coinControl.HasSelected()) return MP_ERR_INPUTSELECT_FAIL;

    std::vector<CRecipient> vecRecipients;
    for (size_t i = 0; i < vecSend.size(); ++i) {
        const std::pair<CScript, int64_t>& vec = vecSend[i];
        CRecipient recipient = {vec.first, vec.second, false};
        vecRecipients.push_back(recipient);
    }

    // Ask the wallet to create the transaction (note mining fee determined by Bitcoin Core params)
    CAmount nFeeRet = 0;
    int nChangePosInOut = -1;
    std::string strFailReason;
    auto wtxNew = iWallet->createTransaction(vecRecipients, coinControl, true /* sign */, nChangePosInOut, nFeeRet, strFailReason, false);

    if (!wtxNew) {
        PrintToLog("%s: ERROR: wallet transaction creation failed: %s\n", __func__, strFailReason);
        return MP_ERR_CREATE_TX;
    }

    // If this request is only to create, but not commit the transaction then display it and exit
    if (!commit) {
        retRawTx = EncodeHexTx(wtxNew->get());
        return 0;
    } else {
        // Commit the transaction to the wallet and broadcast)
        PrintToLog("%s: %s; nFeeRet = %d\n", __func__, wtxNew->get().ToString(), nFeeRet);
        std::string rejectReason;
        if (!wtxNew->commit({}, {}, rejectReason)) return MP_ERR_COMMIT_TX;
        retTxid = wtxNew->get().GetHash();
        return 0;
    }
#else
    return MP_ERR_WALLET_ACCESS;
#endif

}

#ifdef ENABLE_WALLET
/** Locks all available coins that are not in the set of destinations. */
static void LockUnrelatedCoins(
        interfaces::Wallet* iWallet,
        const std::set<CTxDestination>& destinations,
        std::vector<COutPoint>& retLockedCoins)
{
    if (!iWallet) {
        return;
    }

    // NOTE: require: LOCK2(cs_main, pwallet->cs_wallet);

    // lock any other output
    std::vector<COutput> vCoins;
    iWallet->availableCoins(vCoins, false, nullptr, 0);

    for (COutput& output : vCoins) {
        CTxDestination address;
        const CScript& scriptPubKey = output.tx->tx->vout[output.i].scriptPubKey;
        bool fValidAddress = ExtractDestination(scriptPubKey, address);

        // don't lock specified coins, but any other
        if (fValidAddress && destinations.count(address)) {
            continue;
        }

        COutPoint outpointLocked(output.tx->GetHash(), output.i);
        iWallet->lockCoin(outpointLocked);
        retLockedCoins.push_back(outpointLocked);
    }
}

/** Unlocks all coins, which were previously locked. */
static void UnlockCoins(
        interfaces::Wallet* iWallet,
        const std::vector<COutPoint>& vToUnlock)
{
    // NOTE: require: LOCK2(cs_main, pwallet->cs_wallet);

    for (const COutPoint& output : vToUnlock) {
        iWallet->unlockCoin(output);
    }
}
#endif

/**
 * Creates and sends a raw transaction by selecting all coins from the sender
 * and enough coins from a fee source. Change is sent to the fee source!
 */
int CreateFundedTransaction(
        const std::string& senderAddress,
        const std::string& receiverAddress,
        const std::string& feeAddress,
        const std::vector<unsigned char>& payload,
        uint256& retTxid,
        interfaces::Wallet* iWallet)
{
#ifdef ENABLE_WALLET
    if (!iWallet) {
        return MP_ERR_WALLET_ACCESS;
    }

    if (!UseEncodingClassC(payload.size())) {
        return MP_ENCODING_ERROR;
    }

    // add payload output
    std::vector<std::pair<CScript, int64_t> > vecSend;
    if (!OmniCore_Encode_ClassC(payload, vecSend)) {
        return MP_ENCODING_ERROR;
    }

    // Maximum number of expected outputs
    std::vector<CTxOut>::size_type max_outputs = 2;

    // add reference output, if there is one
    if (!receiverAddress.empty() && receiverAddress != feeAddress) {
        max_outputs = 3;
        CScript scriptPubKey = GetScriptForDestination(DecodeDestination(receiverAddress));
        vecSend.push_back(std::make_pair(scriptPubKey, OmniGetDustThreshold(scriptPubKey)));
    }

    // convert into recipients objects
    std::vector<CRecipient> vecRecipients;
    for (size_t i = 0; i < vecSend.size(); ++i) {
        const std::pair<CScript, int64_t>& vec = vecSend[i];
        CRecipient recipient = {vec.first, vec.second, false};
        vecRecipients.push_back(recipient);
    }

    bool fSuccess = false;
    CAmount nFeeRequired = 0;
    std::string strFailReason;
    int nChangePosRet = 0; // add change first

    // set change
    CCoinControl coinControl;
    coinControl.destChange = DecodeDestination(feeAddress);
    coinControl.fAllowOtherInputs = true;

    if (!mastercore::SelectAllCoins(*iWallet, senderAddress, coinControl)) {
        PrintToLog("%s: ERROR: sender %s has no coins\n", __func__, senderAddress);
        return MP_INPUTS_INVALID;
    }

    // prepare sources for fees
    std::set<CTxDestination> feeSources;
    feeSources.insert(DecodeDestination(feeAddress));

    std::vector<COutPoint> vLockedCoins;
    LockUnrelatedCoins(iWallet, feeSources, vLockedCoins);

    auto wtxNew = iWallet->createTransaction(vecRecipients, coinControl, false /* sign */, nChangePosRet, nFeeRequired, strFailReason, true);

    if (wtxNew) {
        fSuccess = true;
    }

    if (fSuccess && nChangePosRet == -1 && receiverAddress == feeAddress) {
        fSuccess = false;
        strFailReason = "send to self without change";
    }

    if (wtxNew->get().vout.size() > max_outputs)
    {
        strFailReason = "more outputs than expected";
        PrintToLog("%s: ERROR: more outputs than expected (Max expected %d, actual %d)\n Failed transaction: %s\n",
                   __func__, max_outputs, wtxNew->get().vout.size(), wtxNew->get().ToString());
    }

    // to restore the original order of inputs, create a new transaction and add
    // inputs and outputs step by step
    CMutableTransaction tx;

    if (fSuccess)
    {
        std::vector<COutPoint> vSelectedInputs;
        coinControl.ListSelected(vSelectedInputs);

        // add previously selected coins
        for(const COutPoint& txIn : vSelectedInputs) {
            tx.vin.push_back(CTxIn(txIn));
        }

        // add other selected coins
        for(const CTxIn& txin : wtxNew->get().vin) {
            if (!coinControl.IsSelected(txin.prevout)) {
                tx.vin.push_back(txin);
            }
        }

        // add outputs
        for(const CTxOut& txOut : wtxNew->get().vout) {
            tx.vout.push_back(txOut);
        }
    }

    // restore original locking state
    UnlockCoins(iWallet, vLockedCoins);

    // lock selected outputs for this transaction // TODO: could be removed?
    if (fSuccess) {
        for(const CTxIn& txIn : tx.vin) {
            iWallet->lockCoin(txIn.prevout);
        }
    }

    if (!fSuccess) {
        PrintToLog("%s: ERROR: wallet transaction creation failed: %s\n", __func__, strFailReason);
        return MP_ERR_CREATE_TX;
    }

    // sign the transaction

    // fetch previous transactions (inputs):
    CCoinsView viewDummy;
    CCoinsViewCache view(&viewDummy);
    {
        LOCK(mempool.cs);
        CCoinsViewCache &viewChain = *pcoinsTip;
        CCoinsViewMemPool viewMempool(&viewChain, mempool);
        view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view

        for(const CTxIn& txin : tx.vin) {
            const auto& prevout = txin.prevout;
            view.AccessCoin(prevout); // this is certainly allowed to fail
        }

        view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
    }

    int nHashType = SIGHASH_ALL;

    for (unsigned int i = 0; i < tx.vin.size(); i++) {
        CTxIn& txin = tx.vin[i];
        const Coin& coin = view.AccessCoin(txin.prevout);
        if (coin.IsSpent()) {
            PrintToLog("%s: ERROR: wallet transaction signing failed: input not found or already spent\n", __func__);
            continue;
        }
        const CScript& prevPubKey = coin.out.scriptPubKey;
        const CAmount& amount = coin.out.nValue;

        SignatureData sigdata;
        if (!iWallet->produceSignature(MutableTransactionSignatureCreator(&tx, i, amount, nHashType), prevPubKey, sigdata)) {
            PrintToLog("%s: ERROR: wallet transaction signing failed\n", __func__);
            return MP_ERR_CREATE_TX;
        }

        UpdateInput(txin, sigdata);
    }

    // send the transaction

    CValidationState state;
    bool missing_inputs;
    CTransactionRef ctx(MakeTransactionRef(std::move(tx)));

    if (!AcceptToMemoryPool(mempool, state, ctx, &missing_inputs, nullptr, false, DEFAULT_TRANSACTION_MAXFEE)) {
        PrintToLog("%s: ERROR: failed to broadcast transaction: %s\n", __func__, state.GetRejectReason());
        return MP_ERR_COMMIT_TX;
    }

    uint256 txid;
    std::string err_string;
    const TransactionError err = BroadcastTransaction(ctx, txid, err_string, true);
    if (TransactionError::OK != err) {
        LogPrintf("%s: BroadcastTransaction failed error: %s\n", __func__, err_string);
    }

    retTxid = txid;

    return 0;
#else
    return MP_ERR_WALLET_ACCESS;
#endif

}
<|endoftext|>


<commit_before>#include "collinswordtomemo.h"
#include <QFileInfo>
#include <assert.h>
#include "shanbay.hxx"

QString EnExampleToEnJieshi::highlightWord(const QString &sentence, const QString &word)
{
    //    if (cs == Qt::CaseInsensitive) {
    //    }
    QString tempSentence = sentence;
    if (tempSentence.contains(word))
        tempSentence = tempSentence.replace(word,""+word+"");
    if (word.size() > 0) {
        QString bigWord = word.at(0).toUpper() + word.mid(1);
        if (tempSentence.contains(bigWord))
            tempSentence = tempSentence.replace(bigWord,""+bigWord+"");
    }
    //            QString tempSentence = collinsInfo.sentences;
    //            if (tempSentence.contains(word))
    //                tempSentence = tempSentence.replace(word,""+word+"");
    //            if (word.size() > 0) {
    //                QString bigWord = word.at(0).toUpper() + word.mid(1);
    //                if (tempSentence.contains(bigWord))
    //                    tempSentence = tempSentence.replace(bigWord,""+bigWord+"");
    //            }
    return tempSentence;
}

QString EnExampleToEnJieshi::pronToHtml(const QString &pron)
{
    const ushort * utf16 = pron.utf16();
    QString utf16pron;
    for (int j = 0; j < pron.size(); ++j){
        ushort ch = *(utf16+j);
        QString temp = "&#";
        temp += QString::number(ch);
        temp += ";";
        utf16pron += temp;
    }
    return utf16pron;
}

MemoUnit EnExampleToEnJieshi::covertToMemoUnit(const CollinsInfo &collinsInfo)
{

    MemoUnit unit;

    QString br = "
";
    QString word = collinsInfo.word;
    QMap<QString,QString> exampleEnZh = collinsInfo.example; //<en,zh> pair
    QStringList enList = exampleEnZh.keys();
    QString exampleEn = enList.join(br);
    QString question = highlightWord(exampleEn, word);

    QString highlightSentence = highlightWord(collinsInfo.sentences, word);

    ShanbayWordInfo wordInfo = Shanbay::instance()->getWordInfo(word);

    QString utf16pron = pronToHtml(wordInfo.pron);
    qDebug() << utf16pron;
    QString pron = " [ " +utf16pron + " ] ";

    // TODO: copy mp3 from zip
#if 0
    QFileInfo fileInfo(outFile);
    QString mp3path = fileInfo.baseName()+"_files/Elements";

    Util::downloadFile(wordInfo.audio, mp3path); // down mp3
#endif
//    QTextCodec *gbk = QTextCodec::codecForName("GB18030");
//    QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
//    QString g2u = gbk->toUnicode(gbk->fromUnicode(wordInfo.pron));
//    qDebug()<< wordInfo.pron<<"    GBK -> UTF-8     " << g2u<<endl;
//    QString cn = wordInfo.cn;
//    QStringList cnList = cn.split("\n");

    QString answer;

//    QString answer_pron = answer_head +pron+ br;
//    answer.append(answer_pron + "\r\n");
//    foreach (QString onecn, cnList) {
//        QString oneAnswer = answer_head + onecn + br;
//        answer.append(oneAnswer + "\r\n");
//    }
#if 0
    answer = highlightSentence+br       //  If you describe something as immoderate, you disapprove of it because it is too extreme.
            +collinsInfo.cn+br          // 极端的;不合理的
            +collinsInfo.st+br          // ADJ-GRADED	能被表示程度的副词或介词词组修饰的形容词
            +pron+br                    // [immoderate]
            +collinsInfo.grammer+br     // 【搭配模式】：usu ADJ n【语用信息】：disapproval【语域标签】：FORMAL 正式
            +collinsInfo.explain+br     // in BRIT, also use 英国英语亦用 characterise
            +collinsInfo.usagenote;     // Usage Note :In British English, a person's weight is normally measured in stones and pounds.
                                        //A stone is equivalent to 14 pounds, or 6.35 kilograms...
#else
    answer = highlightSentence;
#endif
    unit.setQuestion(Question(question));
    unit.setAnswer(Answer(answer));

    //            QString pron;
//            ShanbayWordInfo wordInfo = Shanbay::instance()->getWordInfo(word);

//            QString utf16pron = pronToHtml(wordInfo.pron);
//            qDebug() << utf16pron;
//            QString pron = " [ " +utf16pron + " ] ";

//            // TODO: copy mp3 from zip

//            QFileInfo fileInfo(outFile);
//            QString mp3path = fileInfo.baseName()+"_files/Elements";
//            Util::downloadFile(wordInfo.audio, mp3path); // down mp3
//            QString name = wordInfo.word;
//            QString audio = wordInfo.audio;
//            int audioIndex = audio.lastIndexOf("/");
//            audio = audio.mid(audioIndex + 1);
//            QString url = "[SecondaryStorage]\\"+ audio;
//            qDebug() << "mp3name"<<url;
    Sound sound;
    QString audio = wordInfo.audio;
    int audioIndex = audio.lastIndexOf("/");
    audio = audio.mid(audioIndex + 1);
    QString url = "[SecondaryStorage]\\"+ audio;

    sound.setUrl(url);
    sound.setName(word);
    sound.setText(pron);
    QUrl sourceUrl = wordInfo.audio;
    QFileInfo fileinfo("./shanbaymp3/" + audio );
    if (fileinfo.exists()) {
        sourceUrl = QUrl::fromLocalFile("./shanbaymp3/" + audio );
    }
    sound.setSource(sourceUrl);
    unit.setSound(sound);
    return unit;
}

CollinsWordToMemo::CollinsWordToMemo(CovertStrategy *strategy) : covertStrategy_(strategy)
{
    assert(covertStrategy_);
}

void CollinsWordToMemo::addWord(const QString &word)
{
    wordList_.append(word);
}

void CollinsWordToMemo::addWordList(const QStringList &list)
{
    wordList_.append(list);
}

void CollinsWordToMemo::setCovertStrategy(CovertStrategy *strategy)
{
    covertStrategy_ = strategy;
}

QSharedPointer<MemoCollection> CollinsWordToMemo::makeCollection()
{
    QSharedPointer<MemoCollection> collection(new MemoCollection);
    Q_FOREACH(const QString& word, wordList_) {
        QList<CollinsInfo> infoList = COLLINS->zhCollins(word);
        Q_FOREACH(const CollinsInfo& info, infoList) {
            MemoUnit unit = covertStrategy_->covertToMemoUnit(info);
            collection->addMemoUnit(unit);
        }
    }
    return collection;
}

<commit_msg>add pron to answer<commit_after>#include "collinswordtomemo.h"
#include <QFileInfo>
#include <assert.h>
#include "shanbay.hxx"

QString EnExampleToEnJieshi::highlightWord(const QString &sentence, const QString &word)
{
    //    if (cs == Qt::CaseInsensitive) {
    //    }
    QString tempSentence = sentence;
    if (tempSentence.contains(word))
        tempSentence = tempSentence.replace(word,""+word+"");
    if (word.size() > 0) {
        QString bigWord = word.at(0).toUpper() + word.mid(1);
        if (tempSentence.contains(bigWord))
            tempSentence = tempSentence.replace(bigWord,""+bigWord+"");
    }
    //            QString tempSentence = collinsInfo.sentences;
    //            if (tempSentence.contains(word))
    //                tempSentence = tempSentence.replace(word,""+word+"");
    //            if (word.size() > 0) {
    //                QString bigWord = word.at(0).toUpper() + word.mid(1);
    //                if (tempSentence.contains(bigWord))
    //                    tempSentence = tempSentence.replace(bigWord,""+bigWord+"");
    //            }
    return tempSentence;
}

QString EnExampleToEnJieshi::pronToHtml(const QString &pron)
{
    const ushort * utf16 = pron.utf16();
    QString utf16pron;
    for (int j = 0; j < pron.size(); ++j){
        ushort ch = *(utf16+j);
        QString temp = "&#";
        temp += QString::number(ch);
        temp += ";";
        utf16pron += temp;
    }
    return utf16pron;
}

MemoUnit EnExampleToEnJieshi::covertToMemoUnit(const CollinsInfo &collinsInfo)
{

    MemoUnit unit;

    QString br = "
";
    QString word = collinsInfo.word;
    QMap<QString,QString> exampleEnZh = collinsInfo.example; //<en,zh> pair
    QStringList enList = exampleEnZh.keys();
    QString exampleEn = enList.join(br);
    QString question = highlightWord(exampleEn, word);

    QString highlightSentence = highlightWord(collinsInfo.sentences, word);

    ShanbayWordInfo wordInfo = Shanbay::instance()->getWordInfo(word);

    QString utf16pron = pronToHtml(wordInfo.pron);
    qDebug() << utf16pron;
    QString pron = " [ " +utf16pron + " ] ";

    // TODO: copy mp3 from zip
#if 0
    QFileInfo fileInfo(outFile);
    QString mp3path = fileInfo.baseName()+"_files/Elements";

    Util::downloadFile(wordInfo.audio, mp3path); // down mp3
#endif
//    QTextCodec *gbk = QTextCodec::codecForName("GB18030");
//    QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
//    QString g2u = gbk->toUnicode(gbk->fromUnicode(wordInfo.pron));
//    qDebug()<< wordInfo.pron<<"    GBK -> UTF-8     " << g2u<<endl;
//    QString cn = wordInfo.cn;
//    QStringList cnList = cn.split("\n");

    QString answer;

//    QString answer_pron = answer_head +pron+ br;
//    answer.append(answer_pron + "\r\n");
//    foreach (QString onecn, cnList) {
//        QString oneAnswer = answer_head + onecn + br;
//        answer.append(oneAnswer + "\r\n");
//    }
#if 0
    answer = highlightSentence+br       //  If you describe something as immoderate, you disapprove of it because it is too extreme.
            +collinsInfo.cn+br          // 极端的;不合理的
            +collinsInfo.st+br          // ADJ-GRADED	能被表示程度的副词或介词词组修饰的形容词
            +pron+br                    // [immoderate]
            +collinsInfo.grammer+br     // 【搭配模式】：usu ADJ n【语用信息】：disapproval【语域标签】：FORMAL 正式
            +collinsInfo.explain+br     // in BRIT, also use 英国英语亦用 characterise
            +collinsInfo.usagenote;     // Usage Note :In British English, a person's weight is normally measured in stones and pounds.
                                        //A stone is equivalent to 14 pounds, or 6.35 kilograms...
#else
    answer = highlightSentence + br
            + pron;
#endif
    unit.setQuestion(Question(question));
    unit.setAnswer(Answer(answer));

    //            QString pron;
//            ShanbayWordInfo wordInfo = Shanbay::instance()->getWordInfo(word);

//            QString utf16pron = pronToHtml(wordInfo.pron);
//            qDebug() << utf16pron;
//            QString pron = " [ " +utf16pron + " ] ";

//            // TODO: copy mp3 from zip

//            QFileInfo fileInfo(outFile);
//            QString mp3path = fileInfo.baseName()+"_files/Elements";
//            Util::downloadFile(wordInfo.audio, mp3path); // down mp3
//            QString name = wordInfo.word;
//            QString audio = wordInfo.audio;
//            int audioIndex = audio.lastIndexOf("/");
//            audio = audio.mid(audioIndex + 1);
//            QString url = "[SecondaryStorage]\\"+ audio;
//            qDebug() << "mp3name"<<url;
    Sound sound;
    QString audio = wordInfo.audio;
    int audioIndex = audio.lastIndexOf("/");
    audio = audio.mid(audioIndex + 1);
    QString url = "[SecondaryStorage]\\"+ audio;

    sound.setUrl(url);
    sound.setName(word);
    sound.setText(pron);
    QUrl sourceUrl = wordInfo.audio;
    QFileInfo fileinfo("./shanbaymp3/" + audio );
    if (fileinfo.exists()) {
        sourceUrl = QUrl::fromLocalFile("./shanbaymp3/" + audio );
    }
    sound.setSource(sourceUrl);
    unit.setSound(sound);
    return unit;
}

CollinsWordToMemo::CollinsWordToMemo(CovertStrategy *strategy) : covertStrategy_(strategy)
{
    assert(covertStrategy_);
}

void CollinsWordToMemo::addWord(const QString &word)
{
    wordList_.append(word);
}

void CollinsWordToMemo::addWordList(const QStringList &list)
{
    wordList_.append(list);
}

void CollinsWordToMemo::setCovertStrategy(CovertStrategy *strategy)
{
    covertStrategy_ = strategy;
}

QSharedPointer<MemoCollection> CollinsWordToMemo::makeCollection()
{
    QSharedPointer<MemoCollection> collection(new MemoCollection);
    Q_FOREACH(const QString& word, wordList_) {
        QList<CollinsInfo> infoList = COLLINS->zhCollins(word);
        Q_FOREACH(const CollinsInfo& info, infoList) {
            MemoUnit unit = covertStrategy_->covertToMemoUnit(info);
            collection->addMemoUnit(unit);
        }
    }
    return collection;
}

<|endoftext|>


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

/* $Id:$ */

#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <dastrie.h>
#include <optparse.h>

class option : public optparse
{
public:
    bool compact;
    std::string db;
    bool help;

public:
    option() : compact(false), help(false)
    {
    }

    BEGIN_OPTION_MAP_INLINE()
        ON_OPTION(SHORTOPT('c') || LONGOPT("compact"))
            compact = true;

        ON_OPTION_WITH_ARG(SHORTOPT('d') || LONGOPT("db"))
            db = arg;

        ON_OPTION(SHORTOPT('h') || LONGOPT("help"))
            help = true;

    END_OPTION_MAP()
};

static void usage(std::ostream& os, const char *argv0)
{
    os << "USAGE: " << argv0 << " [OPTIONS] INPUT" << std::endl;
    os << "This utility builds a double-array trie from an input file (INPUT)." << std::endl;
    os << std::endl;
    os << "  INPUT   an input file in which each line represents a record; a record (line)" << std::endl;
    os << "          consists of a key string and its value (optional) separated by a TAB" << std::endl;
    os << "          character; the records must be sorted by dictionary order of keys." << std::endl;
    os << std::endl;
    os << "OPTIONS:" << std::endl;
    os << "  -c, --compact      make a double array trie compact by storing a double-array" << std::endl;
    os << "                     element in 4 bytes; this compaction is available only when" << std::endl;
    os << "                     the number of records are small" << std::endl;
    os << "  -d, --db           specify a database file to which the double array trie will" << std::endl;
    os << "                     be stored; by default, this utility write no database" << std::endl;
    os << "  -h, --help         show this help message and exit" << std::endl;
}

static char* read_text(const char *filename, std::streamoff& size)
{
    // Open the input file.
    std::ifstream ifs(filename);
    if (ifs.fail()) {
        return NULL;
    }

    // Get the size of the input file.
    ifs.seekg(0, std::ios::end);
    size = (std::streamoff)ifs.tellg();
    ifs.seekg(0, std::ios::beg);

    // Read the entire data of the input file.
    char *block = new char[size+1];
    std::memset(block, 0, sizeof(char) * (size+1));
    ifs.read(block, size);
    return block;
}

template <class value_type, class traits_type>
int test(char *text, size_t size, const option& opt)
{
    typedef dastrie::trie<char*, traits_type> trie_type;
    trie_type trie;
    char *p = text, *key = NULL;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    if (opt.db.empty()) {
        es << "ERROR: No database file specified." << std::endl;
        return 1;
    }

    std::ifstream ifs(opt.db.c_str(), std::ios::binary);
    if (ifs.fail()) {
        es << "ERROR: Database file not found." << std::endl;
        return 1;
    }

    if (trie.read(ifs) == 0) {
        es << "ERROR: Failed to read the database." << std::endl;
        return 1;
    }

    key = p;
    while (*p) {
        if (*p == '\n' || *p == 0) {
            *p = 0;
            if (!trie.in(key)) {
                es << "ERROR: The key not found, " << key << std::endl;
            }
            key = p+1;
        }
        if (*p == 0) {
            break;
        }
        ++p;
    }

    return 0;
}

int main(int argc, char *argv[])
{
    option opt;
    int ret = 0;
    int arg_used = 0;
    std::ostream& es = std::cerr;
    std::ostream& os = std::cout;

    // Show the copyright information.
    es << "DASTrie tester ";
    es << DASTRIE_MAJOR_VERSION << "." << DASTRIE_MINOR_VERSION << " ";
    es << DASTRIE_COPYRIGHT << std::endl;
    es << std::endl;

    // Parse the command-line options.
    try {
        arg_used = opt.parse(argv, argc);
    } catch (const optparse::unrecognized_option& e) {
        es << "ERROR: unrecognized option: " << e.what() << std::endl;
        return 1;
    } catch (const optparse::invalid_value& e) {
        es << "ERROR: " << e.what() << std::endl;
        return 1;
    }

    // Show the help message and exit.
    if (opt.help) {
        usage(os, argv[0]);
        return ret;
    }

    // Make sure that an input file is specified.
    if (argc <= arg_used) {
        es << "ERROR: No input file specified." << std::endl;
        return 1;
    }

    // Read the source data.
    std::streamoff textsize;
    char *text = read_text(argv[arg_used], textsize);
    if (text == NULL) {
        es << "ERROR: Failed to read the input data." << std::endl;
        return 1;
    }

    // Dispatch.
    if (opt.compact) {
        return test<
            dastrie::empty_type,
            dastrie::doublearray4_traits
        >(text, (size_t)textsize, opt);
    } else {
        return test<
            dastrie::empty_type,
            dastrie::doublearray5_traits
        >(text, (size_t)textsize, opt);
    }

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

/* $Id$ */

#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <dastrie.h>
#include <optparse.h>

#include <time.h>

class option : public optparse
{
public:
    bool compact;
    std::string db;
    bool help;

public:
    option() : compact(false), help(false)
    {
    }

    BEGIN_OPTION_MAP_INLINE()
        ON_OPTION(SHORTOPT('c') || LONGOPT("compact"))
            compact = true;

        ON_OPTION_WITH_ARG(SHORTOPT('d') || LONGOPT("db"))
            db = arg;

        ON_OPTION(SHORTOPT('h') || LONGOPT("help"))
            help = true;

    END_OPTION_MAP()
};

static void usage(std::ostream& os, const char *argv0)
{
    os << "USAGE: " << argv0 << " [OPTIONS] INPUT" << std::endl;
    os << "This utility builds a double-array trie from an input file (INPUT)." << std::endl;
    os << std::endl;
    os << "  INPUT   an input file in which each line represents a record; a record (line)" << std::endl;
    os << "          consists of a key string and its value (optional) separated by a TAB" << std::endl;
    os << "          character; the records must be sorted by dictionary order of keys." << std::endl;
    os << std::endl;
    os << "OPTIONS:" << std::endl;
    os << "  -c, --compact      make a double array trie compact by storing a double-array" << std::endl;
    os << "                     element in 4 bytes; this compaction is available only when" << std::endl;
    os << "                     the number of records are small" << std::endl;
    os << "  -d, --db           specify a database file to which the double array trie will" << std::endl;
    os << "                     be stored; by default, this utility write no database" << std::endl;
    os << "  -h, --help         show this help message and exit" << std::endl;
}

static char* read_text(const char *filename, std::streamoff& size)
{
    // Open the input file.
    std::ifstream ifs(filename);
    if (ifs.fail()) {
        return NULL;
    }

    // Get the size of the input file.
    ifs.seekg(0, std::ios::end);
    size = (std::streamoff)ifs.tellg();
    ifs.seekg(0, std::ios::beg);

    // Read the entire data of the input file.
    char *block = new char[size+1];
    std::memset(block, 0, sizeof(char) * (size+1));
    ifs.read(block, size);
    return block;
}

template <class value_type, class traits_type>
int test(char *text, size_t size, const option& opt)
{
    typedef dastrie::trie<char*, traits_type> trie_type;
    trie_type trie;
    char *p = text, *key = NULL;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    if (opt.db.empty()) {
        es << "ERROR: No database file specified." << std::endl;
        return 1;
    }

    std::ifstream ifs(opt.db.c_str(), std::ios::binary);
    if (ifs.fail()) {
        es << "ERROR: Database file not found." << std::endl;
        return 1;
    }

    if (trie.read(ifs) == 0) {
        es << "ERROR: Failed to read the database." << std::endl;
        return 1;
    }

    size_t n = 0;
    clock_t start = clock();

    key = p;
    while (*p) {
        bool exit = (*p == 0);

        if (*p == '\n' || *p == 0) {
            *p = 0;
            ++n;
            if (!trie.in(key)) {
                es << "ERROR: The key not found, " << key << std::endl;
            }
            key = p+1;
        }

        if (exit) {
            break;
        }
        ++p;
    }
    clock_t end = clock();

    os << "Number of keys: " << n << std::endl;
    os << "Elapsed time: " <<
        (end - start) / (double)CLOCKS_PER_SEC << std::endl;

    return 0;
}

int main(int argc, char *argv[])
{
    option opt;
    int ret = 0;
    int arg_used = 0;
    std::ostream& es = std::cerr;
    std::ostream& os = std::cout;

    // Show the copyright information.
    es << "DASTrie tester ";
    es << DASTRIE_MAJOR_VERSION << "." << DASTRIE_MINOR_VERSION << " ";
    es << DASTRIE_COPYRIGHT << std::endl;
    es << std::endl;

    // Parse the command-line options.
    try {
        arg_used = opt.parse(argv, argc);
    } catch (const optparse::unrecognized_option& e) {
        es << "ERROR: unrecognized option: " << e.what() << std::endl;
        return 1;
    } catch (const optparse::invalid_value& e) {
        es << "ERROR: " << e.what() << std::endl;
        return 1;
    }

    // Show the help message and exit.
    if (opt.help) {
        usage(os, argv[0]);
        return ret;
    }

    // Make sure that an input file is specified.
    if (argc <= arg_used) {
        es << "ERROR: No input file specified." << std::endl;
        return 1;
    }

    // Read the source data.
    std::streamoff textsize;
    char *text = read_text(argv[arg_used], textsize);
    if (text == NULL) {
        es << "ERROR: Failed to read the input data." << std::endl;
        return 1;
    }

    // Dispatch.
    if (opt.compact) {
        return test<
            dastrie::empty_type,
            dastrie::doublearray4_traits
        >(text, (size_t)textsize, opt);
    } else {
        return test<
            dastrie::empty_type,
            dastrie::doublearray5_traits
        >(text, (size_t)textsize, opt);
    }

    return 0;
}
<|endoftext|>


<commit_before>#include "ddPythonManager.h"

#include "ddPythonQtWrapperFactory.h"
#include "ddPythonQtDecorators.h"

#include <ctkPythonConsole.h>

#include <QApplication>
#include <QDir>
#include <QShortcut>

//-----------------------------------------------------------------------------
class ddPythonManager::ddInternal
{
public:

  QPointer<ctkPythonConsole> Console;
};

//-----------------------------------------------------------------------------
ddPythonManager::ddPythonManager(QObject* parent) : ctkAbstractPythonManager(parent)
{
  this->Internal = new ddInternal;

  ctkPythonConsole* console = new ctkPythonConsole;
  console->setWindowFlags(Qt::Dialog | Qt::WindowStaysOnTopHint);
  console->initialize(this);
  console->setAttribute(Qt::WA_QuitOnClose, true);
  console->resize(800, 400);
  console->setProperty("isInteractive", true);
  this->Internal->Console = console;
  this->setupConsoleShortcuts();
  this->addObjectToPythonMain("_pythonManager", this);
  this->addObjectToPythonMain("_console", console);
}

//-----------------------------------------------------------------------------
ddPythonManager::~ddPythonManager()
{
  delete this->Internal->Console;
  delete this->Internal;
}

//-----------------------------------------------------------------------------
void ddPythonManager::handleCommandLineArgs()
{
  QStringList args = QApplication::instance()->arguments();
  args.removeFirst();
  foreach (QString arg, args)
  {
    this->executeFile(arg);
  }
}

//-----------------------------------------------------------------------------
void ddPythonManager::preInitialization()
{
  this->addWrapperFactory(new ddPythonQtWrapperFactory);
  this->registerPythonQtDecorator(new ddPythonQtDecorators);

  // when running from a cmake build directory (not an install tree)
  // then automatically prepend the python sys.path
  if (QFileInfo(QCoreApplication::applicationDirPath()  + "/../CMakeCache.txt").exists())
  {
    PythonQt::self()->addSysPath(this->appSitePackagesDir());
  }

  PythonQtObjectPtr mod = PythonQt::self()->importModule("PythonQt.dd");
  mod.addObject("_pythonManager", this);
}

//-----------------------------------------------------------------------------
QString ddPythonManager::appSitePackagesDir()
{
  return QFileInfo(QCoreApplication::applicationDirPath()  + "/../lib/python2.7/dist-packages").canonicalFilePath();
}

//-----------------------------------------------------------------------------
QStringList ddPythonManager::pythonPaths()
{
  QStringList searchDirs;
  searchDirs << this->appSitePackagesDir();

  QStringList paths;
  foreach (const QString& dirname, searchDirs)
  {
    if (QDir(dirname).exists())
    {
      paths.append(dirname);
    }
  }
  return paths;
}

//-----------------------------------------------------------------------------
void ddPythonManager::executeInitializationScripts()
{

}

//-----------------------------------------------------------------------------
ctkPythonConsole* ddPythonManager::consoleWidget() const
{
  return this->Internal->Console;
}

//-----------------------------------------------------------------------------
void ddPythonManager::showConsole()
{
  this->Internal->Console->show();
}

//-----------------------------------------------------------------------------
void ddPythonManager::onExecuteFile(const QString& filename)
{
  this->executeFile(filename);
}

//-----------------------------------------------------------------------------
void ddPythonManager::setupConsole(QWidget* parent)
{
  this->Internal->Console->setParent(parent);
#ifdef Q_OS_MAC
    this->Internal->Console->setWindowFlags(Qt::Dialog | Qt::WindowStaysOnTopHint);
#else
    this->Internal->Console->setWindowFlags(Qt::Dialog);
#endif
}

//-----------------------------------------------------------------------------
void ddPythonManager::setupConsoleShortcuts()
{
  ctkPythonConsole* console = this->Internal->Console;
  this->connect(new QShortcut(QKeySequence("Ctrl+W"), console), SIGNAL(activated()), console, SLOT(close()));

  QString closeShortcut = "Ctrl+D";
  #ifdef Q_OS_DARWIN
  closeShortcut = "Meta+D";
  #endif
  this->connect(new QShortcut(QKeySequence(closeShortcut), console), SIGNAL(activated()), console, SLOT(close()));
}
<commit_msg>add local site-packages to list of search dirs for python sys.path<commit_after>#include "ddPythonManager.h"

#include "ddPythonQtWrapperFactory.h"
#include "ddPythonQtDecorators.h"

#include <ctkPythonConsole.h>

#include <QApplication>
#include <QDir>
#include <QShortcut>

//-----------------------------------------------------------------------------
class ddPythonManager::ddInternal
{
public:

  QPointer<ctkPythonConsole> Console;
};

//-----------------------------------------------------------------------------
ddPythonManager::ddPythonManager(QObject* parent) : ctkAbstractPythonManager(parent)
{
  this->Internal = new ddInternal;

  ctkPythonConsole* console = new ctkPythonConsole;
  console->setWindowFlags(Qt::Dialog | Qt::WindowStaysOnTopHint);
  console->initialize(this);
  console->setAttribute(Qt::WA_QuitOnClose, true);
  console->resize(800, 400);
  console->setProperty("isInteractive", true);
  this->Internal->Console = console;
  this->setupConsoleShortcuts();
  this->addObjectToPythonMain("_pythonManager", this);
  this->addObjectToPythonMain("_console", console);
}

//-----------------------------------------------------------------------------
ddPythonManager::~ddPythonManager()
{
  delete this->Internal->Console;
  delete this->Internal;
}

//-----------------------------------------------------------------------------
void ddPythonManager::handleCommandLineArgs()
{
  QStringList args = QApplication::instance()->arguments();
  args.removeFirst();
  foreach (QString arg, args)
  {
    this->executeFile(arg);
  }
}

//-----------------------------------------------------------------------------
void ddPythonManager::preInitialization()
{
  this->addWrapperFactory(new ddPythonQtWrapperFactory);
  this->registerPythonQtDecorator(new ddPythonQtDecorators);

  // when running from a cmake build directory (not an install tree)
  // then automatically prepend the python sys.path
  if (QFileInfo(QCoreApplication::applicationDirPath()  + "/../CMakeCache.txt").exists())
  {
    PythonQt::self()->addSysPath(this->appSitePackagesDir());
  }

  PythonQtObjectPtr mod = PythonQt::self()->importModule("PythonQt.dd");
  mod.addObject("_pythonManager", this);
}

//-----------------------------------------------------------------------------
QString ddPythonManager::appSitePackagesDir()
{
  return QFileInfo(QCoreApplication::applicationDirPath()  + "/../lib/python2.7/dist-packages").canonicalFilePath();
}

//-----------------------------------------------------------------------------
QStringList ddPythonManager::pythonPaths()
{
  QStringList searchDirs;
  searchDirs << this->appSitePackagesDir();
  searchDirs << this->appSitePackagesDir().replace("dist-packages", "site-packages");

  QStringList paths;
  foreach (const QString& dirname, searchDirs)
  {
    if (QDir(dirname).exists())
    {
      paths.append(dirname);
    }
  }
  return paths;
}

//-----------------------------------------------------------------------------
void ddPythonManager::executeInitializationScripts()
{

}

//-----------------------------------------------------------------------------
ctkPythonConsole* ddPythonManager::consoleWidget() const
{
  return this->Internal->Console;
}

//-----------------------------------------------------------------------------
void ddPythonManager::showConsole()
{
  this->Internal->Console->show();
}

//-----------------------------------------------------------------------------
void ddPythonManager::onExecuteFile(const QString& filename)
{
  this->executeFile(filename);
}

//-----------------------------------------------------------------------------
void ddPythonManager::setupConsole(QWidget* parent)
{
  this->Internal->Console->setParent(parent);
#ifdef Q_OS_MAC
    this->Internal->Console->setWindowFlags(Qt::Dialog | Qt::WindowStaysOnTopHint);
#else
    this->Internal->Console->setWindowFlags(Qt::Dialog);
#endif
}

//-----------------------------------------------------------------------------
void ddPythonManager::setupConsoleShortcuts()
{
  ctkPythonConsole* console = this->Internal->Console;
  this->connect(new QShortcut(QKeySequence("Ctrl+W"), console), SIGNAL(activated()), console, SLOT(close()));

  QString closeShortcut = "Ctrl+D";
  #ifdef Q_OS_DARWIN
  closeShortcut = "Meta+D";
  #endif
  this->connect(new QShortcut(QKeySequence(closeShortcut), console), SIGNAL(activated()), console, SLOT(close()));
}
<|endoftext|>


<commit_before>#include <RGBLed.h>
#include <Backlight.h>
#include <AdapterBoard.h>
#include <Arduino.h>
#include "usb_commands.h"

bool isUsb = false;
unsigned long lastPowerChange = 0;

AdapterBoard::AdapterBoard()
{
}

void AdapterBoard::init()
{
  //Initialize the led, set to 'standby'
  led.init(LED_R, LED_G, LED_B);
  led.set(STANDBY_COLOUR);

  //Setup backlight, restore previous brightness, but don't enable
  backlight.init(BACKLIGHT_PIN, SUPPLY_EN);
  backlight.off();

  //Initialize the switches on board
  initSwitches();
}

void AdapterBoard::poll()
{
  //Check the switches, execute action if necessary
  pollSwitches();

  //Handle any USB commands waiting
  handleUSB();
}

void AdapterBoard::initSwitches()
{
  pinMode(SW_ON, INPUT);
  pinMode(SW_UP, INPUT);
  pinMode(SW_DOWN, INPUT);

  prev_swOn1 = HIGH;
  prev_swUp1 = HIGH;
  prev_swDown1 = HIGH;
  prev_swOn2 = HIGH;
  prev_swUp2 = HIGH;
  prev_swDown2 = HIGH;
  switchDelay = 0;
}

void AdapterBoard::pollSwitches()
{
  //Ignore a few polls
  if(switchDelay++ < 40000)
    return;

  int swOn = digitalRead(SW_ON);
  int swUp = digitalRead(SW_UP);
  int swDown = digitalRead(SW_DOWN);

  if(swOn == LOW && prev_swOn1 == LOW && prev_swOn2 == HIGH)
    togglePower();

  //When both pressed, backlight up button has priority
  if(swUp == LOW && prev_swUp1 == LOW && prev_swUp2 == HIGH)
    backlight.up();
  if(swDown == LOW && prev_swDown1 == LOW && prev_swDown2 == HIGH)
    backlight.down();

  prev_swOn2 = prev_swOn1;
  prev_swUp2 = prev_swUp1;
  prev_swDown2 = prev_swDown1;

  prev_swOn1 = swOn;
  prev_swUp1 = swUp;
  prev_swDown1 = swDown;
}

void AdapterBoard::togglePower()
{
  if((millis() - lastPowerChange) < 300)
    return;
  lastPowerChange = millis();

  if(backlight.isOn())
  {
    led.set(STANDBY_COLOUR);
    backlight.off();
  }
  else
  {
    if(isUsb)
      led.set(ONUSB_COLOUR);
    else
      led.set(ON_COLOUR);

    backlight.on();
  }
}

char buf[EP_LEN];

void AdapterBoard::handleUSB()
{
  if(usb.isEnumerated())
  {
    isUsb = true;
    if(backlight.isOn())
      led.set(ONUSB_COLOUR);

    if(usb.hasData())
    {
      char resp[EP_LEN];
      bool unknown = false;
      bool needsAck = true;
      usb.read(buf, EP_LEN);

      //Command type specifier stored in byte 0
      switch(buf[0])
      {
        case CMD_BL_ON:
          led.set(ONUSB_COLOUR);
          backlight.on();
          break;
        case CMD_BL_OFF:
          led.set(STANDBY_COLOUR);
          backlight.off();
          break;
        case CMD_BL_LEVEL:
          backlight.set(buf[1]);
          break;
        case CMD_BL_UP:
          backlight.up();
          break;
        case CMD_BL_DOWN:
          backlight.down();
          break;
        case CMD_BL_GET_STATE:
          needsAck = false;
          //Send state response
          resp[0] = CMD_RESP;
          resp[1] = CMD_BL_GET_STATE;
          resp[2] = backlight.isOn();
          resp[3] = backlight.get();
          while(!usb.canSend());
          usb.write(resp, EP_LEN);
          break;

        case CMD_RGB_SET:
          led.set(buf[1], buf[2], buf[3]);
          break;
        case CMD_RGB_GET:
          needsAck = false;
          //Send response
          resp[0] = CMD_RESP;
          resp[1] = CMD_RGB_GET;
          resp[2] = led.r;
          resp[2] = led.g;
          resp[3] = led.b;
          while(!usb.canSend());
          usb.write(resp, EP_LEN);
          break;

        default:
          unknown = true;
          break;
      }

      if(!unknown && needsAck)
      {
        //Send ACK back to PC
        resp[0] = CMD_ACK;
        resp[1] = buf[0];
        while(!usb.canSend());
        usb.write(resp, EP_LEN);
      }
    }
  }
  else
  {
    isUsb = false;
    if(backlight.isOn())
      led.set(ON_COLOUR);
  }
}
<commit_msg>Only care about up/down switches if backlight is on<commit_after>#include <RGBLed.h>
#include <Backlight.h>
#include <AdapterBoard.h>
#include <Arduino.h>
#include "usb_commands.h"

bool isUsb = false;
unsigned long lastPowerChange = 0;

AdapterBoard::AdapterBoard()
{
}

void AdapterBoard::init()
{
  //Initialize the led, set to 'standby'
  led.init(LED_R, LED_G, LED_B);
  led.set(STANDBY_COLOUR);

  //Setup backlight, restore previous brightness, but don't enable
  backlight.init(BACKLIGHT_PIN, SUPPLY_EN);
  backlight.off();

  //Initialize the switches on board
  initSwitches();
}

void AdapterBoard::poll()
{
  //Check the switches, execute action if necessary
  pollSwitches();

  //Handle any USB commands waiting
  handleUSB();
}

void AdapterBoard::initSwitches()
{
  pinMode(SW_ON, INPUT);
  pinMode(SW_UP, INPUT);
  pinMode(SW_DOWN, INPUT);

  prev_swOn1 = HIGH;
  prev_swUp1 = HIGH;
  prev_swDown1 = HIGH;
  prev_swOn2 = HIGH;
  prev_swUp2 = HIGH;
  prev_swDown2 = HIGH;
  switchDelay = 0;
}

void AdapterBoard::pollSwitches()
{
  //Ignore a few polls
  if(switchDelay++ < 40000)
    return;

  int swOn = digitalRead(SW_ON);
  int swUp = digitalRead(SW_UP);
  int swDown = digitalRead(SW_DOWN);

  if(swOn == LOW && prev_swOn1 == LOW && prev_swOn2 == HIGH)
    togglePower();

  //When both pressed, backlight up button has priority
  if(backlight.isOn())
  {
    if(swUp == LOW && prev_swUp1 == LOW && prev_swUp2 == HIGH)
      backlight.up();
    if(swDown == LOW && prev_swDown1 == LOW && prev_swDown2 == HIGH)
      backlight.down();
  }

  prev_swOn2 = prev_swOn1;
  prev_swUp2 = prev_swUp1;
  prev_swDown2 = prev_swDown1;

  prev_swOn1 = swOn;
  prev_swUp1 = swUp;
  prev_swDown1 = swDown;
}

void AdapterBoard::togglePower()
{
  if((millis() - lastPowerChange) < 300)
    return;
  lastPowerChange = millis();

  if(backlight.isOn())
  {
    led.set(STANDBY_COLOUR);
    backlight.off();
  }
  else
  {
    if(isUsb)
      led.set(ONUSB_COLOUR);
    else
      led.set(ON_COLOUR);

    backlight.on();
  }
}

char buf[EP_LEN];

void AdapterBoard::handleUSB()
{
  if(usb.isEnumerated())
  {
    isUsb = true;
    if(backlight.isOn())
      led.set(ONUSB_COLOUR);

    if(usb.hasData())
    {
      char resp[EP_LEN];
      bool unknown = false;
      bool needsAck = true;
      usb.read(buf, EP_LEN);

      //Command type specifier stored in byte 0
      switch(buf[0])
      {
        case CMD_BL_ON:
          led.set(ONUSB_COLOUR);
          backlight.on();
          break;
        case CMD_BL_OFF:
          led.set(STANDBY_COLOUR);
          backlight.off();
          break;
        case CMD_BL_LEVEL:
          backlight.set(buf[1]);
          break;
        case CMD_BL_UP:
          backlight.up();
          break;
        case CMD_BL_DOWN:
          backlight.down();
          break;
        case CMD_BL_GET_STATE:
          needsAck = false;
          //Send state response
          resp[0] = CMD_RESP;
          resp[1] = CMD_BL_GET_STATE;
          resp[2] = backlight.isOn();
          resp[3] = backlight.get();
          while(!usb.canSend());
          usb.write(resp, EP_LEN);
          break;

        case CMD_RGB_SET:
          led.set(buf[1], buf[2], buf[3]);
          break;
        case CMD_RGB_GET:
          needsAck = false;
          //Send response
          resp[0] = CMD_RESP;
          resp[1] = CMD_RGB_GET;
          resp[2] = led.r;
          resp[2] = led.g;
          resp[3] = led.b;
          while(!usb.canSend());
          usb.write(resp, EP_LEN);
          break;

        default:
          unknown = true;
          break;
      }

      if(!unknown && needsAck)
      {
        //Send ACK back to PC
        resp[0] = CMD_ACK;
        resp[1] = buf[0];
        while(!usb.canSend());
        usb.write(resp, EP_LEN);
      }
    }
  }
  else
  {
    isUsb = false;
    if(backlight.isOn())
      led.set(ON_COLOUR);
  }
}
<|endoftext|>


<commit_before>inline
grass_points::grass_points( const std::string in_path,
			    const std::string in_actionNames,
			    const int in_scale_factor,
			    const int in_shift,
			    const int in_scene, //only for kth
			    const int in_segment_length,
			    const int in_p
)
:path(in_path), actionNames(in_actionNames), scale_factor(in_scale_factor), shift(in_shift), total_scenes(in_scene), segment_length(in_segment_length), p(in_p)
{
  actions.load( actionNames );
}

inline
void
grass_points::calculate( field<string> in_all_people, int  in_dim  )
{
  all_people = in_all_people;
  dim = in_dim;
  int n_actions = actions.n_rows;
  int n_peo =  all_people.n_rows;
  //all_people.print("people");

  field <std::string> parallel_names(n_peo*n_actions,4);
  int sc = total_scenes; //Solo estoy usando 1
  int k =0;

  for (int pe = 0; pe< n_peo; ++pe)
  {
    for (int act=0; act<n_actions; ++act)
    {

      std::stringstream load_folder;
      std::stringstream load_feat_video_i;
      std::stringstream load_labels_video_i;

      load_folder << path <<"kth-features_dim" << dim <<  "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;
      load_feat_video_i << load_folder.str() << "/" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
      load_labels_video_i << load_folder.str() << "/lab_" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";

      std::ostringstream ss1;
      std::ostringstream ss2;
      ss1 << pe;
      ss2 << act;

      parallel_names(k,0) = load_feat_video_i.str();
      parallel_names(k,1) = load_labels_video_i.str();
      parallel_names(k,2) = ss1.str();
      parallel_names(k,3) = ss2.str();
      k++;

    }
  }

  //Aca podria hacer el paparelo

  #pragma omp parallel for
  for (int k = 0; k< parallel_names.n_rows; ++k)
  {
    std::string load_feat_video_i   = parallel_names(k,0);
    std::string load_labels_video_i = parallel_names(k,1);

    int pe   = atoi( parallel_names(k,2).c_str() );
    int act  = atoi( parallel_names(k,3).c_str() );

    one_video(load_feat_video_i, load_labels_video_i, sc, pe, act );
  }

}

inline
void
grass_points::one_video( std::string load_feat_video_i,	std::string load_labels_video_i, int sc, int pe, int act )
{
  //cout << load_feat_video_i << endl;
  mat mat_features_video_i;
  vec lab_video_i;

  mat_features_video_i.load( load_feat_video_i, hdf5_binary );
  lab_video_i.load( load_labels_video_i, hdf5_binary );
  int n_vec = lab_video_i.n_elem;
  int last = lab_video_i( n_vec - 1 );
  //cout << last << endl;

  int seg = 0;

  std::stringstream save_folder;
  save_folder << "./kth-grass-point-dim"<< dim << "-L" << segment_length << "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;

  for (int l=2; l<last-segment_length; l = l+4 )
  {
    std::vector<vec> feat_seg;

    for (int j=l; j< l + segment_length; ++j)
    {
      //k++;
      //cout << " " << j;
      uvec indices = find(lab_video_i == j);
      mat feat_fr = mat_features_video_i.cols(indices);

      for (int v=0; v < feat_fr.n_cols; ++v)
      {
	vec sample = feat_fr.col(v);
	feat_seg.push_back(sample);
      }

    }
    //cout << feat_seg.size() << endl;
    if (feat_seg.size()>100) // Cuando en el segmento hay mas de 100 vectores
    {
      mat mat_feat_seg(dim,feat_seg.size());

      for (uword i = 0; i < feat_seg.size(); ++i)
      {
	mat_feat_seg.col(i) = feat_seg.at(i);

      }

      mat U; vec s;   mat V;
      svd(U,s,V,mat_feat_seg);
      mat Gnp = U.cols(0,p-1);

      std::stringstream save_Gnp;
      //cout << save_folder.str() << endl;
      save_Gnp << save_folder.str() << "/grass_pt" << seg << "_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
      //cout << save_Gnp.str() << endl;
      #pragma omp critical
      Gnp.save( save_Gnp.str(), hdf5_binary );
      seg++;
    }
    else {
      //cout << " " << stat_seg.count();
      //getchar();

    }

  }

  std::stringstream save_seg;
  vec total_seg;
  total_seg.zeros(1);
  total_seg( 0 ) = seg;
  save_seg << save_folder.str() << "/num_seg_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".dat";
  #pragma omp critical
  {
    total_seg.save( save_seg.str(), raw_ascii );
    cout <<  all_people (pe) << "_" << actions(act) << ". Total # of segments " << seg << endl;
  }
  //cout << "press a key " ;
  //getchar();

}

<commit_msg>Run Grass in Parallel<commit_after>inline
grass_points::grass_points( const std::string in_path,
			    const std::string in_actionNames,
			    const int in_scale_factor,
			    const int in_shift,
			    const int in_scene, //only for kth
			    const int in_segment_length,
			    const int in_p
)
:path(in_path), actionNames(in_actionNames), scale_factor(in_scale_factor), shift(in_shift), total_scenes(in_scene), segment_length(in_segment_length), p(in_p)
{
  actions.load( actionNames );
}

inline
void
grass_points::calculate( field<string> in_all_people, int  in_dim  )
{
  all_people = in_all_people;
  dim = in_dim;
  int n_actions = actions.n_rows;
  int n_peo =  all_people.n_rows;
  //all_people.print("people");

  field <std::string> parallel_names(n_peo*n_actions,4);
  int sc = total_scenes; //Solo estoy usando 1
  int k =0;

  for (int pe = 0; pe< n_peo; ++pe)
  {
    for (int act=0; act<n_actions; ++act)
    {

      std::stringstream load_folder;
      std::stringstream load_feat_video_i;
      std::stringstream load_labels_video_i;

      load_folder << path <<"kth-features_dim" << dim <<  "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;
      load_feat_video_i << load_folder.str() << "/" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
      load_labels_video_i << load_folder.str() << "/lab_" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";

      std::ostringstream ss1;
      std::ostringstream ss2;
      ss1 << pe;
      ss2 << act;

      parallel_names(k,0) = load_feat_video_i.str();
      parallel_names(k,1) = load_labels_video_i.str();
      parallel_names(k,2) = ss1.str();
      parallel_names(k,3) = ss2.str();
      k++;

    }
  }

  //Aca podria hacer el paparelo

  #pragma omp parallel for
  for (int k = 0; k< parallel_names.n_rows; ++k)
  {
    std::string load_feat_video_i   = parallel_names(k,0);
    std::string load_labels_video_i = parallel_names(k,1);

    int pe   = atoi( parallel_names(k,2).c_str() );
    int act  = atoi( parallel_names(k,3).c_str() );

    cout <<  all_people (pe) << "_" << actions(act) << endl;

    #pragma omp critical
    one_video(load_feat_video_i, load_labels_video_i, sc, pe, act );
  }

}

inline
void
grass_points::one_video( std::string load_feat_video_i,	std::string load_labels_video_i, int sc, int pe, int act )
{
  //cout << load_feat_video_i << endl;
  mat mat_features_video_i;
  vec lab_video_i;

  mat_features_video_i.load( load_feat_video_i, hdf5_binary );
  lab_video_i.load( load_labels_video_i, hdf5_binary );
  int n_vec = lab_video_i.n_elem;
  int last = lab_video_i( n_vec - 1 );
  //cout << last << endl;

  int seg = 0;

  std::stringstream save_folder;
  save_folder << "./kth-grass-point-dim"<< dim << "-L" << segment_length << "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;

  for (int l=2; l<last-segment_length; l = l+4 )
  {
    std::vector<vec> feat_seg;

    for (int j=l; j< l + segment_length; ++j)
    {
      //k++;
      //cout << " " << j;
      uvec indices = find(lab_video_i == j);
      mat feat_fr = mat_features_video_i.cols(indices);

      for (int v=0; v < feat_fr.n_cols; ++v)
      {
	vec sample = feat_fr.col(v);
	feat_seg.push_back(sample);
      }

    }
    //cout << feat_seg.size() << endl;
    if (feat_seg.size()>100) // Cuando en el segmento hay mas de 100 vectores
    {
      mat mat_feat_seg(dim,feat_seg.size());

      for (uword i = 0; i < feat_seg.size(); ++i)
      {
	mat_feat_seg.col(i) = feat_seg.at(i);

      }

      mat U; vec s;   mat V;
      svd(U,s,V,mat_feat_seg);
      mat Gnp = U.cols(0,p-1);

      std::stringstream save_Gnp;
      //cout << save_folder.str() << endl;
      save_Gnp << save_folder.str() << "/grass_pt" << seg << "_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
      //cout << save_Gnp.str() << endl;
      #pragma omp critical
      Gnp.save( save_Gnp.str(), hdf5_binary );
      seg++;
    }
    else {
      //cout << " " << stat_seg.count();
      //getchar();

    }

  }

  std::stringstream save_seg;
  vec total_seg;
  total_seg.zeros(1);
  total_seg( 0 ) = seg;
  save_seg << save_folder.str() << "/num_seg_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".dat";
  #pragma omp critical
  {
    total_seg.save( save_seg.str(), raw_ascii );
    //cout <<  all_people (pe) << "_" << actions(act) << ". Total # of segments " << seg << endl;
  }
  //cout << "press a key " ;
  //getchar();

}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ignoreMinusSign_ja_JP.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2003-04-08 16:03:16 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

// prevent internal compiler error with MSVC6SP3
#include <stl/utility>

#define TRANSLITERATION_MinusSign_ja_JP
#include <transliteration_Ignore.hxx>

namespace com { namespace sun { namespace star { namespace i18n {

sal_Unicode
ignoreMinusSign_ja_JP_translator (const sal_Unicode c)
{
    switch (c) {
        case 0x2212: // MINUS SIGN
        case 0x002d: // HYPHEN-MINUS
        return 0x30fc; // KATAKANA-HIRAGANA PROLONGED SOUND MARK
    }
    return c;
}

ignoreMinusSign_ja_JP::ignoreMinusSign_ja_JP()
{
        func = ignoreMinusSign_ja_JP_translator;
        table = 0;
        map = 0;
        transliterationName = "ignoreMinusSign_ja_JP";
        implementationName = "com.sun.star.i18n.Transliteration.ignoreMinusSign_ja_JP";
}

} } } }
<commit_msg>INTEGRATION: CWS ooo20030412 (1.2.44); FILE MERGED 2003/04/12 22:30:40 mh 1.2.44.2: RESYNC: (1.2-1.5); FILE MERGED 2003/04/11 11:38:39 mh 1.2.44.1: join: from ooo11beta<commit_after>/*************************************************************************
 *
 *  $RCSfile: ignoreMinusSign_ja_JP.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2003-04-28 16:51:39 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

// prevent internal compiler error with MSVC6SP3
#include <utility>

#define TRANSLITERATION_MinusSign_ja_JP
#include <transliteration_Ignore.hxx>

namespace com { namespace sun { namespace star { namespace i18n {

sal_Unicode
ignoreMinusSign_ja_JP_translator (const sal_Unicode c)
{
    switch (c) {
        case 0x2212: // MINUS SIGN
        case 0x002d: // HYPHEN-MINUS
        return 0x30fc; // KATAKANA-HIRAGANA PROLONGED SOUND MARK
    }
    return c;
}

ignoreMinusSign_ja_JP::ignoreMinusSign_ja_JP()
{
        func = ignoreMinusSign_ja_JP_translator;
        table = 0;
        map = 0;
        transliterationName = "ignoreMinusSign_ja_JP";
        implementationName = "com.sun.star.i18n.Transliteration.ignoreMinusSign_ja_JP";
}

} } } }
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP
#define MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP

// mapnik
#include <mapnik/warp.hpp>
#include <mapnik/raster.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/raster_colorizer.hpp>
#include <mapnik/proj_transform.hpp>
#include <mapnik/feature.hpp>

// agg
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
#include "agg_pixfmt_gray.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"

namespace mapnik {

template <typename F>
void render_raster_symbolizer(raster_symbolizer const &sym,
                              mapnik::feature_impl &feature,
                              proj_transform const &prj_trans,
                              renderer_common &common,
                              F composite)
{
    raster_ptr const& source = feature.get_raster();
    if (source)
    {
        box2d<double> target_ext = box2d<double>(source->ext_);
        prj_trans.backward(target_ext, PROJ_ENVELOPE_POINTS);
        box2d<double> ext = common.t_.forward(target_ext);
        int start_x = static_cast<int>(std::floor(ext.minx()+.5));
        int start_y = static_cast<int>(std::floor(ext.miny()+.5));
        int end_x = static_cast<int>(std::floor(ext.maxx()+.5));
        int end_y = static_cast<int>(std::floor(ext.maxy()+.5));
        int raster_width = end_x - start_x;
        int raster_height = end_y - start_y;
        if (raster_width > 0 && raster_height > 0)
        {
            scaling_method_e scaling_method = get<scaling_method_e>(sym, keys::scaling, feature, common.vars_, SCALING_NEAR);
            composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common.vars_, src_over);
            double opacity = get<double>(sym,keys::opacity,feature, common.vars_, 1.0);
            bool premultiply_source = !source->premultiplied_alpha_;
            auto is_premultiplied = get_optional<bool>(sym, keys::premultiplied, feature, common.vars_);
            if (is_premultiplied)
            {
                if (*is_premultiplied) premultiply_source = false;
                else premultiply_source = true;
            }
            // only premuiltiply rgba8 images
            if (premultiply_source && source->data_.is<image_data_32>())
            {
                agg::rendering_buffer buffer(source->data_.getBytes(),
                                             source->data_.width(),
                                             source->data_.height(),
                                             source->data_.width() * 4);
                agg::pixfmt_rgba32 pixf(buffer);
                pixf.premultiply();
            }
            if (!prj_trans.equal())
            {
                double offset_x = ext.minx() - start_x;
                double offset_y = ext.miny() - start_y;
                image_data_32 data(raster_width, raster_height);
                raster target(target_ext, data, source->get_filter_factor());
                unsigned mesh_size = static_cast<unsigned>(get<value_integer>(sym,keys::mesh_size,feature, common.vars_, 16));
                reproject_and_scale_raster(target,
                                           *source,
                                           prj_trans,
                                           offset_x,
                                           offset_y,
                                           mesh_size,
                                           scaling_method);
                if (target.data_.is<image_data_32>())
                {
                    composite(util::get<image_data_32>(target.data_), comp_op, opacity, start_x, start_y);
                }
                else
                {
                    std::cerr << "#1 source->data float32" << std::endl;
                }
            }
            else
            {
                double image_ratio_x = ext.width() / source->data_.width();
                double image_ratio_y = ext.height() / source->data_.height();
                double eps = 1e-5;
                if ( (std::fabs(image_ratio_x - 1.0) <= eps) &&
                     (std::fabs(image_ratio_y - 1.0) <= eps) &&
                     (std::abs(start_x) <= eps) &&
                     (std::abs(start_y) <= eps) )
                {
                    if (source->data_.is<image_data_32>())
                    {
                        composite(util::get<image_data_32>(source->data_), comp_op, opacity, start_x, start_y);
                    }
                    else
                    {
                        std::cerr << "#2 source->data float32" << std::endl;
                    }
                }
                else
                {
                    if (source->data_.is<image_data_32>())
                    {
                        image_data_32 data(raster_width, raster_height);
                        scale_image_agg<image_data_32>(data,
                                                       util::get<image_data_32>(source->data_),
                                                       scaling_method,
                                                       image_ratio_x,
                                                       image_ratio_y,
                                                       0.0,
                                                       0.0,
                                                       source->get_filter_factor());
                        composite(data, comp_op, opacity, start_x, start_y);
                    }
                    else if (source->data_.is<image_data_float32>())
                    {
                        std::cerr << "#3 source->data float32" << std::endl;
                    }
                    else if (source->data_.is<image_data_16>())
                    {
                        std::cerr << "#3 source->data int16" << std::endl;
                        raster target(target_ext, image_data_16(raster_width, raster_height), source->get_filter_factor());
                        scale_image_agg<image_data_16>(util::get<image_data_16>(target.data_),
                                                       util::get<image_data_16>(source->data_),
                                                       scaling_method,
                                                       image_ratio_x,
                                                       image_ratio_y,
                                                       0.0,
                                                       0.0,
                                                       source->get_filter_factor());
                        image_data_16 & data = util::get<image_data_16>(target.data_);
                        image_data_32 dst(raster_width, raster_height);
                        raster_colorizer_ptr colorizer = get<raster_colorizer_ptr>(sym, keys::colorizer);
                        if (colorizer) colorizer->colorize(dst, data,source->nodata(),feature);
                        composite(dst, comp_op, opacity, start_x, start_y);

                    }
                }
            }
        }
    }
}

} // namespace mapnik

#endif // MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP
<commit_msg>further simplify raster rendering code<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP
#define MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP

// mapnik
#include <mapnik/warp.hpp>
#include <mapnik/raster.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/raster_colorizer.hpp>
#include <mapnik/proj_transform.hpp>
#include <mapnik/feature.hpp>

// agg
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
#include "agg_pixfmt_gray.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"

namespace mapnik {

template <typename F>
void render_raster_symbolizer(raster_symbolizer const &sym,
                              mapnik::feature_impl &feature,
                              proj_transform const &prj_trans,
                              renderer_common &common,
                              F composite)
{
    raster_ptr const& source = feature.get_raster();
    if (source)
    {
        box2d<double> target_ext = box2d<double>(source->ext_);
        prj_trans.backward(target_ext, PROJ_ENVELOPE_POINTS);
        box2d<double> ext = common.t_.forward(target_ext);
        int start_x = static_cast<int>(std::floor(ext.minx()+.5));
        int start_y = static_cast<int>(std::floor(ext.miny()+.5));
        int end_x = static_cast<int>(std::floor(ext.maxx()+.5));
        int end_y = static_cast<int>(std::floor(ext.maxy()+.5));
        int raster_width = end_x - start_x;
        int raster_height = end_y - start_y;
        if (raster_width > 0 && raster_height > 0)
        {
            scaling_method_e scaling_method = get<scaling_method_e>(sym, keys::scaling, feature, common.vars_, SCALING_NEAR);
            composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common.vars_, src_over);
            double opacity = get<double>(sym,keys::opacity,feature, common.vars_, 1.0);
            bool premultiply_source = !source->premultiplied_alpha_;
            auto is_premultiplied = get_optional<bool>(sym, keys::premultiplied, feature, common.vars_);
            if (is_premultiplied)
            {
                if (*is_premultiplied) premultiply_source = false;
                else premultiply_source = true;
            }
            // only premuiltiply rgba8 images
            if (premultiply_source && source->data_.is<image_data_32>())
            {
                agg::rendering_buffer buffer(source->data_.getBytes(),
                                             source->data_.width(),
                                             source->data_.height(),
                                             source->data_.width() * 4);
                agg::pixfmt_rgba32 pixf(buffer);
                pixf.premultiply();
            }
            if (!prj_trans.equal())
            {
                double offset_x = ext.minx() - start_x;
                double offset_y = ext.miny() - start_y;
                image_data_32 data(raster_width, raster_height);
                raster target(target_ext, data, source->get_filter_factor());
                unsigned mesh_size = static_cast<unsigned>(get<value_integer>(sym,keys::mesh_size,feature, common.vars_, 16));
                reproject_and_scale_raster(target,
                                           *source,
                                           prj_trans,
                                           offset_x,
                                           offset_y,
                                           mesh_size,
                                           scaling_method);
                if (target.data_.is<image_data_32>())
                {
                    composite(util::get<image_data_32>(target.data_), comp_op, opacity, start_x, start_y);
                }
                else
                {
                    std::cerr << "#1 source->data float32" << std::endl;
                }
            }
            else
            {
                double image_ratio_x = ext.width() / source->data_.width();
                double image_ratio_y = ext.height() / source->data_.height();
                double eps = 1e-5;
                if ( (std::fabs(image_ratio_x - 1.0) <= eps) &&
                     (std::fabs(image_ratio_y - 1.0) <= eps) &&
                     (std::abs(start_x) <= eps) &&
                     (std::abs(start_y) <= eps) )
                {
                    if (source->data_.is<image_data_32>())
                    {
                        composite(util::get<image_data_32>(source->data_), comp_op, opacity, start_x, start_y);
                    }
                    else
                    {
                        std::cerr << "#2 source->data float32" << std::endl;
                    }
                }
                else
                {
                    if (source->data_.is<image_data_32>())
                    {
                        image_data_32 data(raster_width, raster_height);
                        scale_image_agg<image_data_32>(data,
                                                       util::get<image_data_32>(source->data_),
                                                       scaling_method,
                                                       image_ratio_x,
                                                       image_ratio_y,
                                                       0.0,
                                                       0.0,
                                                       source->get_filter_factor());
                        composite(data, comp_op, opacity, start_x, start_y);
                    }
                    else if (source->data_.is<image_data_float32>())
                    {
                        std::cerr << "#3 source->data float32" << std::endl;
                    }
                    else if (source->data_.is<image_data_16>())
                    {
                        image_data_16 scaled(raster_width, raster_height);
                        scale_image_agg<image_data_16>(scaled,
                                                       util::get<image_data_16>(source->data_),
                                                       scaling_method,
                                                       image_ratio_x,
                                                       image_ratio_y,
                                                       0.0,
                                                       0.0,
                                                       source->get_filter_factor());
                        image_data_32 dst(raster_width, raster_height);
                        raster_colorizer_ptr colorizer = get<raster_colorizer_ptr>(sym, keys::colorizer);
                        if (colorizer) colorizer->colorize(dst, scaled, source->nodata(), feature);
                        composite(dst, comp_op, opacity, start_x, start_y);

                    }
                }
            }
        }
    }
}

} // namespace mapnik

#endif // MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP
<|endoftext|>