<commit_before>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * 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 copyright holders 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.
 *
 * Authors: Gabe Black
 */

#include "tracechild.hh"
#include "printer.hh"

using namespace std;

//Types of printers. If none is found, or there is an error in the input,
//there are psuedo types to return.
enum PrinterType {PRINTER_NONE, PRINTER_ERROR, PRINTER_NESTING, PRINTER_REG};

int findEndOfRegPrinter(string, int);
int findEndOfNestingPrinter(string, int);
PrinterType findSub(string, int &, int &);

//This is pretty easy. Just find the closing parenthesis.
int findEndOfRegPrinter(string config, int startPos)
{
    int pos = config.find(")", startPos);
    if(pos == string::npos)
    {
        cerr << "Couldn't find the closing parenthesis for a reg printer" << endl;
        return 0;
    }
    return pos;
}

//This is a little harder. We need to make sure we don't
//grab an ending parenthesis that belongs to the nesting printer.
int findEndOfNestingPrinter(string config, int startPos)
{
    int length = config.length();
    int pos = startPos;
    int endPos = length;
    int parenPos = config.find(")", pos);
    //If we didn't find an ending parenthesis at all, we're in trouble
    if(parenPos == string::npos)
    {
        cerr << "Couldn't find the closing parenthesis for a nesting printer on the first try" << endl;
        return 0;
    }
    //Keep pulling out embedded stuff until we can't any more
    //we need to make sure we aren't skipping over the parenthesis
    //that ends -this- printer.
    PrinterType type = findSub(config, pos, endPos);
    if(type == PRINTER_ERROR)
        return 0;
    while(type != PRINTER_NONE && endPos >= parenPos)
    {
        //Find the next closest ending parenthesis since we passed
        //up the last one
        parenPos = config.find(")", endPos + 1);
        //If we didn't find one, we're in trouble
        if(parenPos == string::npos)
        {
            cerr << "Couldn't find the closing parenthesis for a nested printer on later tries" << endl;
            return 0;
        }
        //Start looking for the end of this printer and embedded
        //stuff past the one we just found
        pos = endPos + 1;
        //Reset endPos so we search to the end of config
        endPos = length;
        type = findSub(config, pos, endPos);
        if(type == PRINTER_ERROR)
            return 0;
    }
    //We ran out of embedded items, and we didn't pass up our last
    //closing paren. This must be the end of this printer.
    return parenPos;
}

//Find a sub printer. This looks for things which have a type defining
//character and then an opening parenthesis. The type is returned, and
//startPos and endPos are set to the beginning and end of the sub printer
//On entry, the search starts at index startPos and ends at either index
//endPos or a closing parenthesis, whichever comes first
PrinterType findSub(string config, int & startPos, int & endPos)
{
    int length = config.length();
    //Figure out where the different types of sub printers may start
    int regPos = config.find("%(", startPos);
    int nestingPos = config.find("~(", startPos);
    //If a type of printer wasn't found, say it was found too far away.
    //This simplifies things later
    if(regPos == string::npos)
        regPos = endPos;
    if(nestingPos == string::npos)
        nestingPos = endPos;
    //If we find a closing paren, that marks the
    //end of the region we're searching.
    int closingPos = config.find(")", startPos);
    if(closingPos != string::npos &&
            closingPos < regPos &&
            closingPos < nestingPos)
        return PRINTER_NONE;
    //If we didn't find anything close enough, say so.
    if(regPos >= endPos && nestingPos >= endPos)
        return PRINTER_NONE;
    //At this point, we know that one of the options starts legally
    //We need to find which one is first and return that
    if(regPos < nestingPos)
    {
        int regEnd = findEndOfRegPrinter(config, regPos + 2);
        //If we couldn't find the end...
        if(!regEnd)
        {
            cerr << "Couldn't find the end of the reg printer" << endl;
            return PRINTER_ERROR;
        }
        //Report the sub printer's vitals.
        startPos = regPos;
        endPos = regEnd;
        return PRINTER_REG;
    }
    else
    {
        int nestingEnd = findEndOfNestingPrinter(config, nestingPos + 2);
        //If we couldn't find the end...
        if(!nestingEnd)
        {
            cerr << "Couldn't find the end of the nesting printer" << endl;
            return PRINTER_ERROR;
        }
        //Report the sub printer's vitals.
        startPos = nestingPos;
        endPos = nestingEnd;
        return PRINTER_NESTING;
    }
    return PRINTER_NONE;
}

//Set up a nesting printer. This printer can contain sub printers
bool NestingPrinter::configure(string config)
{
    //Clear out any old stuff
    constStrings.clear();
    numPrinters = 0;
    printers.clear();
    int length = config.length();
    int startPos = 0, endPos = length;
    int lastEndPos = -1;
    //Try to find a sub printer
    PrinterType type = findSub(config, startPos, endPos);
    if(type == PRINTER_ERROR)
    {
        cerr << "Problem finding first sub printer" << endl;
        return false;
    }
    while(type != PRINTER_NONE)
    {
        string prefix = config.substr(lastEndPos + 1, startPos - lastEndPos - 1);
        lastEndPos = endPos;
        constStrings.push_back(prefix);
        string subConfig, subString;
        int commaPos, lastCommaPos, childSwitchVar;
        switch(type)
        {
            //If we found a plain register printer
          case PRINTER_REG:
            numPrinters++;
            //Get the register name
            subConfig = config.substr(startPos + 2, endPos - startPos - 2);
            //Set up the register printer
            RegPrinter * regPrinter = new RegPrinter(child);
            if(!regPrinter->configure(subConfig))
            {
                delete regPrinter;
                cerr << "Error configuring reg printer" << endl;
                return false;
            }
            printers.push_back(regPrinter);
            break;
            //If we found an embedded nesting printer
          case PRINTER_NESTING:
            numPrinters++;
            //Punt on reading in all the parameters of the nesting printer
            NestingPrinter * nestingPrinter = new NestingPrinter(child);
            subConfig = config.substr(startPos + 2, endPos - startPos - 2);
            lastCommaPos = string::npos;
            commaPos = subConfig.find(",");
            if(commaPos == string::npos)
                return false;
            childSwitchVar = child->getRegNum(subConfig.substr(0, commaPos));
            if(childSwitchVar == -1)
            {
                cerr << "Couldn't configure switching variable!" << endl;
                return false;
            }
            //Eat up remaining arguments
            while(commaPos != string::npos)
            {
                lastCommaPos = commaPos;
                commaPos = subConfig.find(",", commaPos + 1);
            }
            if(lastCommaPos != string::npos)
            {
                subConfig = subConfig.substr(lastCommaPos + 1, subConfig.length() - lastCommaPos - 1);
            }
            if(!nestingPrinter->configure(subConfig))
            {
                delete nestingPrinter;
                cerr << "Error configuring nesting printer" << endl;
                return false;
            }
            nestingPrinter->switchVar = childSwitchVar;
            printers.push_back(nestingPrinter);
            break;
          default:
            cerr << "Unrecognized printer type" << endl;
            return false;
        }
        //Move down past what we just parsed
        startPos = endPos + 1;
        endPos = length;
        type = findSub(config, startPos, endPos);
        if(type == PRINTER_ERROR)
        {
            cerr << "Unable to find subprinters on later tries" << endl;
            return false;
        }
    }
    //Put in the trailing stuff
    string trailer = config.substr(startPos, length - startPos);
    constStrings.push_back(trailer);
    return true;
}

bool RegPrinter::configure(string config)
{
    //Figure out what our register number is based on the name we're given
    int num = child->getRegNum(config);
    if(num == -1)
    {
        cerr << "Couldn't find register " << config << endl;
        return false;
    }
    regNum(num);
    return true;
}

ostream & NestingPrinter::writeOut(ostream & os)
{
    if(switchVar == -1 || child->diffSinceUpdate(switchVar))
    {
        int x;
        for(x = 0; x < numPrinters; x++)
        {
            os << constStrings[x];
            os << printers[x];
        }
        os << constStrings[x];
    }
    return os;
}

ostream & RegPrinter::writeOut(ostream & os)
{
    os << child->printReg(intRegNum);
    return os;
}

<commit_msg>Statetrace: Fix compilation problem.<commit_after>/*
 * Copyright (c) 2006-2007 The Regents of The University of Michigan
 * 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 copyright holders 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.
 *
 * Authors: Gabe Black
 */

#include "tracechild.hh"
#include "printer.hh"

using namespace std;

//Types of printers. If none is found, or there is an error in the input,
//there are psuedo types to return.
enum PrinterType {PRINTER_NONE, PRINTER_ERROR, PRINTER_NESTING, PRINTER_REG};

int findEndOfRegPrinter(string, int);
int findEndOfNestingPrinter(string, int);
PrinterType findSub(string, int &, int &);

//This is pretty easy. Just find the closing parenthesis.
int findEndOfRegPrinter(string config, int startPos)
{
    int pos = config.find(")", startPos);
    if(pos == string::npos)
    {
        cerr << "Couldn't find the closing parenthesis for a reg printer" << endl;
        return 0;
    }
    return pos;
}

//This is a little harder. We need to make sure we don't
//grab an ending parenthesis that belongs to the nesting printer.
int findEndOfNestingPrinter(string config, int startPos)
{
    int length = config.length();
    int pos = startPos;
    int endPos = length;
    int parenPos = config.find(")", pos);
    //If we didn't find an ending parenthesis at all, we're in trouble
    if(parenPos == string::npos)
    {
        cerr << "Couldn't find the closing parenthesis for a nesting printer on the first try" << endl;
        return 0;
    }
    //Keep pulling out embedded stuff until we can't any more
    //we need to make sure we aren't skipping over the parenthesis
    //that ends -this- printer.
    PrinterType type = findSub(config, pos, endPos);
    if(type == PRINTER_ERROR)
        return 0;
    while(type != PRINTER_NONE && endPos >= parenPos)
    {
        //Find the next closest ending parenthesis since we passed
        //up the last one
        parenPos = config.find(")", endPos + 1);
        //If we didn't find one, we're in trouble
        if(parenPos == string::npos)
        {
            cerr << "Couldn't find the closing parenthesis for a nested printer on later tries" << endl;
            return 0;
        }
        //Start looking for the end of this printer and embedded
        //stuff past the one we just found
        pos = endPos + 1;
        //Reset endPos so we search to the end of config
        endPos = length;
        type = findSub(config, pos, endPos);
        if(type == PRINTER_ERROR)
            return 0;
    }
    //We ran out of embedded items, and we didn't pass up our last
    //closing paren. This must be the end of this printer.
    return parenPos;
}

//Find a sub printer. This looks for things which have a type defining
//character and then an opening parenthesis. The type is returned, and
//startPos and endPos are set to the beginning and end of the sub printer
//On entry, the search starts at index startPos and ends at either index
//endPos or a closing parenthesis, whichever comes first
PrinterType findSub(string config, int & startPos, int & endPos)
{
    int length = config.length();
    //Figure out where the different types of sub printers may start
    int regPos = config.find("%(", startPos);
    int nestingPos = config.find("~(", startPos);
    //If a type of printer wasn't found, say it was found too far away.
    //This simplifies things later
    if(regPos == string::npos)
        regPos = endPos;
    if(nestingPos == string::npos)
        nestingPos = endPos;
    //If we find a closing paren, that marks the
    //end of the region we're searching.
    int closingPos = config.find(")", startPos);
    if(closingPos != string::npos &&
            closingPos < regPos &&
            closingPos < nestingPos)
        return PRINTER_NONE;
    //If we didn't find anything close enough, say so.
    if(regPos >= endPos && nestingPos >= endPos)
        return PRINTER_NONE;
    //At this point, we know that one of the options starts legally
    //We need to find which one is first and return that
    if(regPos < nestingPos)
    {
        int regEnd = findEndOfRegPrinter(config, regPos + 2);
        //If we couldn't find the end...
        if(!regEnd)
        {
            cerr << "Couldn't find the end of the reg printer" << endl;
            return PRINTER_ERROR;
        }
        //Report the sub printer's vitals.
        startPos = regPos;
        endPos = regEnd;
        return PRINTER_REG;
    }
    else
    {
        int nestingEnd = findEndOfNestingPrinter(config, nestingPos + 2);
        //If we couldn't find the end...
        if(!nestingEnd)
        {
            cerr << "Couldn't find the end of the nesting printer" << endl;
            return PRINTER_ERROR;
        }
        //Report the sub printer's vitals.
        startPos = nestingPos;
        endPos = nestingEnd;
        return PRINTER_NESTING;
    }
    return PRINTER_NONE;
}

//Set up a nesting printer. This printer can contain sub printers
bool NestingPrinter::configure(string config)
{
    //Clear out any old stuff
    constStrings.clear();
    numPrinters = 0;
    printers.clear();
    int length = config.length();
    int startPos = 0, endPos = length;
    int lastEndPos = -1;
    //Try to find a sub printer
    PrinterType type = findSub(config, startPos, endPos);
    if(type == PRINTER_ERROR)
    {
        cerr << "Problem finding first sub printer" << endl;
        return false;
    }
    while(type != PRINTER_NONE)
    {
        string prefix = config.substr(lastEndPos + 1, startPos - lastEndPos - 1);
        lastEndPos = endPos;
        constStrings.push_back(prefix);
        string subConfig, subString;
        long int commaPos, lastCommaPos, childSwitchVar;
        //Set up the register printer
        RegPrinter * regPrinter = new RegPrinter(child);
        NestingPrinter * nestingPrinter = new NestingPrinter(child);
        switch(type)
        {
            //If we found a plain register printer
          case PRINTER_REG:
            numPrinters++;
            //Get the register name
            subConfig = config.substr(startPos + 2, endPos - startPos - 2);
            if(!regPrinter->configure(subConfig))
            {
                delete regPrinter;
                cerr << "Error configuring reg printer" << endl;
                return false;
            }
            printers.push_back(regPrinter);
            break;
            //If we found an embedded nesting printer
          case PRINTER_NESTING:
            numPrinters++;
            //Punt on reading in all the parameters of the nesting printer
            subConfig = config.substr(startPos + 2, endPos - startPos - 2);
            lastCommaPos = string::npos;
            commaPos = subConfig.find(",");
            if(commaPos == string::npos)
                return false;
            childSwitchVar = child->getRegNum(subConfig.substr(0, commaPos));
            if(childSwitchVar == -1)
            {
                cerr << "Couldn't configure switching variable!" << endl;
                return false;
            }
            //Eat up remaining arguments
            while(commaPos != string::npos)
            {
                lastCommaPos = commaPos;
                commaPos = subConfig.find(",", commaPos + 1);
            }
            if(lastCommaPos != string::npos)
            {
                subConfig = subConfig.substr(lastCommaPos + 1, subConfig.length() - lastCommaPos - 1);
            }
            if(!nestingPrinter->configure(subConfig))
            {
                delete nestingPrinter;
                cerr << "Error configuring nesting printer" << endl;
                return false;
            }
            nestingPrinter->switchVar = childSwitchVar;
            printers.push_back(nestingPrinter);
            break;
          default:
            cerr << "Unrecognized printer type" << endl;
            return false;
        }
        //Move down past what we just parsed
        startPos = endPos + 1;
        endPos = length;
        type = findSub(config, startPos, endPos);
        if(type == PRINTER_ERROR)
        {
            cerr << "Unable to find subprinters on later tries" << endl;
            return false;
        }
    }
    //Put in the trailing stuff
    string trailer = config.substr(startPos, length - startPos);
    constStrings.push_back(trailer);
    return true;
}

bool RegPrinter::configure(string config)
{
    //Figure out what our register number is based on the name we're given
    int num = child->getRegNum(config);
    if(num == -1)
    {
        cerr << "Couldn't find register " << config << endl;
        return false;
    }
    regNum(num);
    return true;
}

ostream & NestingPrinter::writeOut(ostream & os)
{
    if(switchVar == -1 || child->diffSinceUpdate(switchVar))
    {
        int x;
        for(x = 0; x < numPrinters; x++)
        {
            os << constStrings[x];
            os << printers[x];
        }
        os << constStrings[x];
    }
    return os;
}

ostream & RegPrinter::writeOut(ostream & os)
{
    os << child->printReg(intRegNum);
    return os;
}

<|endoftext|>


<commit_before><commit_msg>check glossary path for sanity<commit_after><|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "Client.hxx"

#ifndef _COM_SUN_STAR_EMBED_NOVISUALAREASIZEEXCEPTION_HPP_
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#endif

#ifndef _SVDOOLE2_HXX //autogen
#include <svx/svdoole2.hxx>
#endif
#ifndef _SVDOGRAF_HXX //autogen
#include <svx/svdograf.hxx>
#endif
#ifndef _SVDPAGV_HXX
#include <svx/svdpagv.hxx>
#endif

#include <toolkit/helper/vclunohelper.hxx>

#include "misc.hxx"

#ifdef STARIMAGE_AVAILABLE
#ifndef _SIMDLL_HXX
#include <sim2/simdll.hxx>
#endif
#endif

#include "strings.hrc"

#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_DRAW_VIEW_SHELL_HXX
#include "DrawViewShell.hxx"
#endif
#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_WINDOW_HXX
#include "Window.hxx"
#endif
#include "sdresid.hxx"
#include <vcl/svapp.hxx>

using namespace com::sun::star;

namespace sd {

/*************************************************************************
|*
|* Ctor
|*
\************************************************************************/

Client::Client(SdrOle2Obj* pObj, ViewShell* pViewShell, ::Window* pWindow) :
    SfxInPlaceClient(pViewShell->GetViewShell(), pWindow, pObj->GetAspect() ),
    mpViewShell(pViewShell),
    pSdrOle2Obj(pObj),
    pSdrGrafObj(NULL),
    pOutlinerParaObj (NULL)
{
    SetObject( pObj->GetObjRef() );
    DBG_ASSERT( GetObject().is(), "No object connected!" );
}

/*************************************************************************
|*
|* Dtor
|*
\************************************************************************/

Client::~Client()
{
}

/*************************************************************************
|*
|* Wenn IP-aktiv, dann kommt diese Anforderung um Vergroesserung des
|* sichtbaren Ausschnitts des Objektes
|*
\************************************************************************/

void Client::RequestNewObjectArea( Rectangle& aObjRect )
{
    ::sd::View* pView = mpViewShell->GetView();

    sal_Bool bSizeProtect = sal_False;
    sal_Bool bPosProtect = sal_False;

    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    if (rMarkList.GetMarkCount() == 1)
    {
        SdrMark* pMark = rMarkList.GetMark(0);
        SdrObject* pObj = pMark->GetMarkedSdrObj();

        // no need to check for changes, this method is called only if the area really changed
        bSizeProtect = pObj->IsResizeProtect();
        bPosProtect = pObj->IsMoveProtect();
    }

    Rectangle aOldRect = GetObjArea();
    if ( bPosProtect )
        aObjRect.SetPos( aOldRect.TopLeft() );

    if ( bSizeProtect )
        aObjRect.SetSize( aOldRect.GetSize() );

    Rectangle aWorkArea( pView->GetWorkArea() );
    if ( !aWorkArea.IsInside(aObjRect) && !bPosProtect && aObjRect != aOldRect )
    {
        // correct position
        Point aPos = aObjRect.TopLeft();
        Size  aSize = aObjRect.GetSize();
        Point aWorkAreaTL = aWorkArea.TopLeft();
        Point aWorkAreaBR = aWorkArea.BottomRight();

        aPos.X() = Max(aPos.X(), aWorkAreaTL.X());
        aPos.X() = Min(aPos.X(), aWorkAreaBR.X()-aSize.Width());
        aPos.Y() = Max(aPos.Y(), aWorkAreaTL.Y());
        aPos.Y() = Min(aPos.Y(), aWorkAreaBR.Y()-aSize.Height());

        aObjRect.SetPos(aPos);
    }
}

void Client::ObjectAreaChanged()
{
    ::sd::View* pView = mpViewShell->GetView();
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    if (rMarkList.GetMarkCount() == 1)
    {
        SdrMark* pMark = rMarkList.GetMark(0);
        SdrObject* pObj = pMark->GetMarkedSdrObj();

        // no need to check for changes, this method is called only if the area really changed
        pObj->SetLogicRect( GetScaledObjArea() );
    }
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void Client::ViewChanged()
{
    if ( GetAspect() == embed::Aspects::MSOLE_ICON )
    {
        // the iconified object seems not to need such a scaling handling
        // since the replacement image and the size a completely controlled by the container
        // TODO/LATER: when the icon exchange is implemented the scaling handling might be required again here

        pSdrOle2Obj->ActionChanged(); // draw needs it to remove lines in slide preview
        return;
    }

    //TODO/LATER: should we try to avoid the recalculation of the visareasize
    //if we know that it didn't change?
    if (mpViewShell->GetActiveWindow())
    {
        ::sd::View* pView = mpViewShell->GetView();
        if (pView)
        {
            // TODO/LEAN: maybe we can do this without requesting the VisualArea?
            // working with the visual area might need running state, so the object may switch itself to this state
            MapMode             aMap100( MAP_100TH_MM );
            Rectangle           aVisArea;
            Size aSize = pSdrOle2Obj->GetOrigObjSize( &aMap100 );

            aVisArea.SetSize( aSize );
            Rectangle           aLogicRect( pSdrOle2Obj->GetLogicRect() );
            Size                aScaledSize( static_cast< long >( GetScaleWidth() * Fraction( aVisArea.GetWidth() ) ),
                                                static_cast< long >( GetScaleHeight() * Fraction( aVisArea.GetHeight() ) ) );

            // react to the change if the difference is bigger than one pixel
            Size aPixelDiff =
                Application::GetDefaultDevice()->LogicToPixel(
                    Size( aLogicRect.GetWidth() - aScaledSize.Width(),
                          aLogicRect.GetHeight() - aScaledSize.Height() ),
                    aMap100 );
            if( aPixelDiff.Width() || aPixelDiff.Height() )
            {
                pSdrOle2Obj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aScaledSize ) );
                pSdrOle2Obj->BroadcastObjectChange();
            }
            else
                pSdrOle2Obj->ActionChanged();
        }
    }
}

/*************************************************************************
|*
|* Objekt in den sichtbaren Breich scrollen
|*
\************************************************************************/

void Client::MakeVisible()
{
    if (mpViewShell->ISA(DrawViewShell))
    {
        static_cast<DrawViewShell*>(mpViewShell)->MakeVisible(
            pSdrOle2Obj->GetLogicRect(),
            *mpViewShell->GetActiveWindow());
    }
}

} // end of namespace sd

<commit_msg>INTEGRATION: CWS chart15 (1.20.168); FILE MERGED 2007/12/07 16:09:08 iha 1.20.168.1: #i84323# charts never should be stretched<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sdclient.cxx,v $
 *
 *  $Revision: 1.21 $
 *
 *  last change: $Author: ihi $ $Date: 2008-01-14 13:44:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "Client.hxx"

#ifndef _COM_SUN_STAR_EMBED_NOVISUALAREASIZEEXCEPTION_HPP_
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#endif

#ifndef _SVDOOLE2_HXX //autogen
#include <svx/svdoole2.hxx>
#endif
#ifndef _SVDOGRAF_HXX //autogen
#include <svx/svdograf.hxx>
#endif
#ifndef _SVDPAGV_HXX
#include <svx/svdpagv.hxx>
#endif

#include <toolkit/helper/vclunohelper.hxx>

#include "misc.hxx"

#ifdef STARIMAGE_AVAILABLE
#ifndef _SIMDLL_HXX
#include <sim2/simdll.hxx>
#endif
#endif

#include "strings.hrc"

#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_DRAW_VIEW_SHELL_HXX
#include "DrawViewShell.hxx"
#endif
#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_WINDOW_HXX
#include "Window.hxx"
#endif
#include "sdresid.hxx"
#include <vcl/svapp.hxx>

using namespace com::sun::star;

namespace sd {

/*************************************************************************
|*
|* Ctor
|*
\************************************************************************/

Client::Client(SdrOle2Obj* pObj, ViewShell* pViewShell, ::Window* pWindow) :
    SfxInPlaceClient(pViewShell->GetViewShell(), pWindow, pObj->GetAspect() ),
    mpViewShell(pViewShell),
    pSdrOle2Obj(pObj),
    pSdrGrafObj(NULL),
    pOutlinerParaObj (NULL)
{
    SetObject( pObj->GetObjRef() );
    DBG_ASSERT( GetObject().is(), "No object connected!" );
}

/*************************************************************************
|*
|* Dtor
|*
\************************************************************************/

Client::~Client()
{
}

/*************************************************************************
|*
|* Wenn IP-aktiv, dann kommt diese Anforderung um Vergroesserung des
|* sichtbaren Ausschnitts des Objektes
|*
\************************************************************************/

void Client::RequestNewObjectArea( Rectangle& aObjRect )
{
    ::sd::View* pView = mpViewShell->GetView();

    sal_Bool bSizeProtect = sal_False;
    sal_Bool bPosProtect = sal_False;

    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    if (rMarkList.GetMarkCount() == 1)
    {
        SdrMark* pMark = rMarkList.GetMark(0);
        SdrObject* pObj = pMark->GetMarkedSdrObj();

        // no need to check for changes, this method is called only if the area really changed
        bSizeProtect = pObj->IsResizeProtect();
        bPosProtect = pObj->IsMoveProtect();
    }

    Rectangle aOldRect = GetObjArea();
    if ( bPosProtect )
        aObjRect.SetPos( aOldRect.TopLeft() );

    if ( bSizeProtect )
        aObjRect.SetSize( aOldRect.GetSize() );

    Rectangle aWorkArea( pView->GetWorkArea() );
    if ( !aWorkArea.IsInside(aObjRect) && !bPosProtect && aObjRect != aOldRect )
    {
        // correct position
        Point aPos = aObjRect.TopLeft();
        Size  aSize = aObjRect.GetSize();
        Point aWorkAreaTL = aWorkArea.TopLeft();
        Point aWorkAreaBR = aWorkArea.BottomRight();

        aPos.X() = Max(aPos.X(), aWorkAreaTL.X());
        aPos.X() = Min(aPos.X(), aWorkAreaBR.X()-aSize.Width());
        aPos.Y() = Max(aPos.Y(), aWorkAreaTL.Y());
        aPos.Y() = Min(aPos.Y(), aWorkAreaBR.Y()-aSize.Height());

        aObjRect.SetPos(aPos);
    }
}

void Client::ObjectAreaChanged()
{
    ::sd::View* pView = mpViewShell->GetView();
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    if (rMarkList.GetMarkCount() == 1)
    {
        SdrMark* pMark = rMarkList.GetMark(0);
        SdrObject* pObj = pMark->GetMarkedSdrObj();

        // no need to check for changes, this method is called only if the area really changed
        pObj->SetLogicRect( GetScaledObjArea() );
    }
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void Client::ViewChanged()
{
    if ( GetAspect() == embed::Aspects::MSOLE_ICON )
    {
        // the iconified object seems not to need such a scaling handling
        // since the replacement image and the size a completely controlled by the container
        // TODO/LATER: when the icon exchange is implemented the scaling handling might be required again here

        pSdrOle2Obj->ActionChanged(); // draw needs it to remove lines in slide preview
        return;
    }

    //TODO/LATER: should we try to avoid the recalculation of the visareasize
    //if we know that it didn't change?
    if (mpViewShell->GetActiveWindow())
    {
        ::sd::View* pView = mpViewShell->GetView();
        if (pView)
        {
            Rectangle aLogicRect( pSdrOle2Obj->GetLogicRect() );
            Size aLogicSize( aLogicRect.GetWidth(), aLogicRect.GetHeight() );

            if( pSdrOle2Obj->IsChart() )
            {
                //charts never should be stretched see #i84323# for example
                pSdrOle2Obj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aLogicSize ) );
                pSdrOle2Obj->BroadcastObjectChange();
                return;
            }

            // TODO/LEAN: maybe we can do this without requesting the VisualArea?
            // working with the visual area might need running state, so the object may switch itself to this state
            MapMode             aMap100( MAP_100TH_MM );
            Rectangle           aVisArea;
            Size aSize = pSdrOle2Obj->GetOrigObjSize( &aMap100 );

            aVisArea.SetSize( aSize );
            Size                aScaledSize( static_cast< long >( GetScaleWidth() * Fraction( aVisArea.GetWidth() ) ),
                                                static_cast< long >( GetScaleHeight() * Fraction( aVisArea.GetHeight() ) ) );

            // react to the change if the difference is bigger than one pixel
            Size aPixelDiff =
                Application::GetDefaultDevice()->LogicToPixel(
                    Size( aLogicRect.GetWidth() - aScaledSize.Width(),
                          aLogicRect.GetHeight() - aScaledSize.Height() ),
                    aMap100 );
            if( aPixelDiff.Width() || aPixelDiff.Height() )
            {
                pSdrOle2Obj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aScaledSize ) );
                pSdrOle2Obj->BroadcastObjectChange();
            }
            else
                pSdrOle2Obj->ActionChanged();
        }
    }
}

/*************************************************************************
|*
|* Objekt in den sichtbaren Breich scrollen
|*
\************************************************************************/

void Client::MakeVisible()
{
    if (mpViewShell->ISA(DrawViewShell))
    {
        static_cast<DrawViewShell*>(mpViewShell)->MakeVisible(
            pSdrOle2Obj->GetLogicRect(),
            *mpViewShell->GetActiveWindow());
    }
}

} // end of namespace sd

<|endoftext|>


<commit_before>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2016 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  pipeline_fixed/window_buffer.cpp                                                */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// include i/f header

#include "window_buffer.hpp"

// includes, system

#include <gdkmm/general.h> // Gdk::*::set_source_pixbuf()
#include <stdexcept>       // std::runtime_error

// includes, project

#include <hugh/render/software/buffer/color.hpp>
#include <hugh/render/software/buffer/depth.hpp>

#define HUGH_USE_TRACE
#undef HUGH_USE_TRACE
#include <hugh/support/trace.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  // variables, internal

  // functions, internal

} // namespace {

// variables, exported

// functions, exported

/* explicit */
window_buffer::window_buffer(std::string const& a, cbuffer_type* b)
  : window_buffer(a, b, type::color)
{
  TRACE("window_buffer::window_buffer(buffer::color)");
}

/* explicit */
window_buffer::window_buffer(std::string const& a, dbuffer_type* b)
  : window_buffer(a, b, type::depth)
{
  TRACE("window_buffer::window_buffer(buffer::depth)");
}

/* virtual */
window_buffer::~window_buffer()
{
  TRACE("window_buffer::~window_buffer");
}

/* explicit */
window_buffer::window_buffer(std::string const& a, buffer_type* b, type c)
  : hugh::gtkmm::window(),
    buffer_            (b),
    type_              (c)
{
  TRACE("window_buffer::window_buffer(buffer::base)");

  if (!buffer_) {
    throw std::runtime_error("window_buffer::window_buffer: "
                             "buffer argument cannot be a null pointer");
  }

  {
    buffer_type::viewport_type const& vp(*buffer_->viewport);

    set_size_request(vp.width - vp.x, vp.height - vp.y);
  }

  show_all();

  set_title(a + ": " + ((type_ == type::color) ? "color" : "depth"));
}

/* virtual */ bool
window_buffer::on_draw(::Cairo::RefPtr<::Cairo::Context> const& cr)
{
  TRACE("window_buffer::on_draw");

  buffer_type::viewport_type const& vp  (*buffer_->viewport);
  glm::uvec2 const                  size(vp.width - vp.x, vp.height - vp.y);

  using ImageSurface = ::Cairo::ImageSurface;

  ::Cairo::RefPtr<ImageSurface> dst(ImageSurface::create(::Cairo::FORMAT_RGB24, size.x, size.y));

  unsigned const dst_row_len(dst->get_stride());
  guint8*        dst_data   (dst->get_data());
  unsigned       buf_idx(0);

  for (unsigned y(0); y < size.y; ++y) {
    for (unsigned x(0); x < dst_row_len; x += 4) {
      switch (type_) {
      case type::color:
        {
          glm::vec4 const& src(static_cast<cbuffer_type const&>(*buffer_)[buf_idx]);

          *(dst_data + ((y * dst_row_len) + x + 0)) = 255 * src.b; // b
          *(dst_data + ((y * dst_row_len) + x + 1)) = 255 * src.g; // g
          *(dst_data + ((y * dst_row_len) + x + 2)) = 255 * src.r; // r
          *(dst_data + ((y * dst_row_len) + x + 3)) = 255 * src.a; // a
        }
        break;

      case type::depth:
        {
          glm::vec1 const& src(static_cast<dbuffer_type const&>(*buffer_)[buf_idx]);

          *(dst_data + ((y * dst_row_len) + x + 0)) = 255 * src.x;  // b
          *(dst_data + ((y * dst_row_len) + x + 1)) = 255 * src.x;  // g
          *(dst_data + ((y * dst_row_len) + x + 2)) = 255 * src.x;  // r
          *(dst_data + ((y * dst_row_len) + x + 3)) = 255;          // a
        }
        break;

      default:
        {
          throw std::runtime_error("window_buffer::on_draw: unrecognized buffe type (" +
                                   std::to_string(unsigned(type_)) + ")");
        }
        break;
      }

      ++buf_idx;
    }
  }

  cr->scale     (get_allocation().get_width()  / double(size.x),
                 get_allocation().get_height() / double(size.y));
  cr->set_source(dst, 0, 0);
  cr->paint     ();

  return false;
}
<commit_msg>fixed: window y-flipping<commit_after>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2016 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  pipeline_fixed/window_buffer.cpp                                                */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// include i/f header

#include "window_buffer.hpp"

// includes, system

#include <gdkmm/general.h> // Gdk::*::set_source_pixbuf()
#include <stdexcept>       // std::runtime_error

// includes, project

#include <hugh/render/software/buffer/color.hpp>
#include <hugh/render/software/buffer/depth.hpp>

#define HUGH_USE_TRACE
#undef HUGH_USE_TRACE
#include <hugh/support/trace.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  // variables, internal

  // functions, internal

} // namespace {

// variables, exported

// functions, exported

/* explicit */
window_buffer::window_buffer(std::string const& a, cbuffer_type* b)
  : window_buffer(a, b, type::color)
{
  TRACE("window_buffer::window_buffer(buffer::color)");
}

/* explicit */
window_buffer::window_buffer(std::string const& a, dbuffer_type* b)
  : window_buffer(a, b, type::depth)
{
  TRACE("window_buffer::window_buffer(buffer::depth)");
}

/* virtual */
window_buffer::~window_buffer()
{
  TRACE("window_buffer::~window_buffer");
}

/* explicit */
window_buffer::window_buffer(std::string const& a, buffer_type* b, type c)
  : hugh::gtkmm::window(),
    buffer_            (b),
    type_              (c)
{
  TRACE("window_buffer::window_buffer(buffer::base)");

  if (!buffer_) {
    throw std::runtime_error("window_buffer::window_buffer: "
                             "buffer argument cannot be a null pointer");
  }

  {
    buffer_type::viewport_type const& vp(*buffer_->viewport);

    set_size_request(vp.width - vp.x, vp.height - vp.y);
  }

  show_all();

  set_title(a + ": " + ((type_ == type::color) ? "color" : "depth"));
}

/* virtual */ bool
window_buffer::on_draw(::Cairo::RefPtr<::Cairo::Context> const& cr)
{
  TRACE("window_buffer::on_draw");

  buffer_type::viewport_type const& vp  (*buffer_->viewport);
  glm::uvec2 const                  size(vp.width - vp.x, vp.height - vp.y);

  using ImageSurface = ::Cairo::ImageSurface;

  ::Cairo::RefPtr<ImageSurface> dst(ImageSurface::create(::Cairo::FORMAT_RGB24, size.x, size.y));

  unsigned const dst_row_len(dst->get_stride());
  guint8*        dst_data   (dst->get_data());
  unsigned       buf_idx(0);

  for (unsigned y(0); y < size.y; ++y) {
    for (unsigned x(0); x < dst_row_len; x += 4) {
      switch (type_) {
      case type::color:
        {
          glm::vec4 const& src(static_cast<cbuffer_type const&>(*buffer_)[buf_idx]);

          *(dst_data + ((y * dst_row_len) + x + 0)) = 255 * src.b; // b
          *(dst_data + ((y * dst_row_len) + x + 1)) = 255 * src.g; // g
          *(dst_data + ((y * dst_row_len) + x + 2)) = 255 * src.r; // r
          *(dst_data + ((y * dst_row_len) + x + 3)) = 255 * src.a; // a
        }
        break;

      case type::depth:
        {
          glm::vec1 const& src(static_cast<dbuffer_type const&>(*buffer_)[buf_idx]);

          *(dst_data + ((y * dst_row_len) + x + 0)) = 255 * src.x;  // b
          *(dst_data + ((y * dst_row_len) + x + 1)) = 255 * src.x;  // g
          *(dst_data + ((y * dst_row_len) + x + 2)) = 255 * src.x;  // r
          *(dst_data + ((y * dst_row_len) + x + 3)) = 255;          // a
        }
        break;

      default:
        {
          throw std::runtime_error("window_buffer::on_draw: unrecognized buffe type (" +
                                   std::to_string(unsigned(type_)) + ")");
        }
        break;
      }

      ++buf_idx;
    }
  }

  cr->set_identity_matrix();
  {
    glm::vec2 const alloc(get_allocation().get_width(), get_allocation().get_height());
    double const    xx( alloc.x / size.x);
    double const    yx( 0.0);
    double const    xy( 0.0);
    double const    yy(-alloc.y / size.y);
    double const    x0( 0.0);
    double const    y0( alloc.y);

    cr->set_matrix(::Cairo::Matrix(xx, yx, xy, yy, x0, y0));
  }
  cr->set_source(dst, 0, 0);
  cr->paint     ();

  return false;
}
<|endoftext|>


<commit_before>/*
 * VapourSynth D2V Plugin
 *
 * Copyright (c) 2012 Derek Buitenhuis
 *
 * This file is part of d2vsource.
 *
 * d2vsource 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.
 *
 * d2vsource 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 d2vsource; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

extern "C" {
#include <stdint.h>
#include <stdlib.h>
}

#include <VapourSynth.h>
#include <VSHelper.h>

#include "d2v.hpp"
#include "d2vsource.hpp"
#include "decode.hpp"
#include "directrender.hpp"

void VS_CC d2vInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) *instanceData;
    vsapi->setVideoInfo(&d->vi, 1, node);
}

const VSFrameRef *VS_CC d2vGetFrame(int n, int activationReason, void **instanceData, void **frameData,
                                    VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) *instanceData;
    VSFrameRef *s, *f;
    string msg;
    int ret;

    /* Unreference the previously decoded frame. */
    av_frame_unref(d->frame);

    ret = decodeframe(n, d->d2v, d->dec, d->frame, msg);
    if (ret < 0) {
        vsapi->setFilterError(msg.c_str(), frameCtx);
        return NULL;
    }

    /* Grab our direct-rendered frame. */
    s = (VSFrameRef *) d->frame->opaque;

    /* If our width and height are the same, just return it. */
    if (d->vi.width == d->aligned_width && d->vi.height == d->aligned_height) {
        f = (VSFrameRef *) vsapi->cloneFrameRef(s);
        return f;
    }

    f = vsapi->newVideoFrame(d->vi.format, d->vi.width, d->vi.height, NULL, core);

    /* Copy into VS's buffers. */
    vs_bitblt(vsapi->getWritePtr(f, 0), vsapi->getStride(f, 0), vsapi->getWritePtr(s, 0), vsapi->getStride(s, 0),
              d->vi.width, d->vi.height);
    vs_bitblt(vsapi->getWritePtr(f, 1), vsapi->getStride(f, 1), vsapi->getWritePtr(s, 1), vsapi->getStride(s, 1),
              d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);
    vs_bitblt(vsapi->getWritePtr(f, 2), vsapi->getStride(f, 2), vsapi->getWritePtr(s, 2), vsapi->getStride(s, 2),
              d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);

    return f;
}

void VS_CC d2vFree(void *instanceData, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) instanceData;
    d2vfreep(&d->d2v);
    decodefreep(&d->dec);
    av_frame_unref(d->frame);
    av_freep(&d->frame);
    free(d);
}

void VS_CC d2vCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi)
{
    d2vData *data;
    string msg;
    bool no_crop;
    int err;

    /* Allocate our private data. */
    data = (d2vData *) malloc(sizeof(*data));
    if (!data) {
        vsapi->setError(out, "Cannot allocate private data.");
        return;
    }

    data->d2v = d2vparse((char *) vsapi->propGetData(in, "input", 0, 0), msg);
    if (!data->d2v) {
        vsapi->setError(out, msg.c_str());
        free(data);
        return;
    }

    data->dec = decodeinit(data->d2v, msg);
    if (!data->dec) {
        vsapi->setError(out, msg.c_str());
        d2vfreep(&data->d2v);
        free(data);
        return;
    }

    /*
     * Make our private data available to libavcodec, and
     * set our custom get/release_buffer funcs.
     */
    data->dec->avctx->opaque         = (void *) data;
    data->dec->avctx->get_buffer2    = VSGetBuffer;

    /* Last frame is crashy right now. */
    data->vi.numFrames = data->d2v->frames.size();
    data->vi.width     = data->d2v->width;
    data->vi.height    = data->d2v->height;
    data->vi.fpsNum    = data->d2v->fps_num;
    data->vi.fpsDen    = data->d2v->fps_den;

    /* Stash the pointer to our core. */
    data->core = core;
    data->api  = (VSAPI *) vsapi;

    /*
     * Stash our aligned width and height for use with our
     * custom get_buffer, since it could require this.
     */
    data->aligned_width  = FFALIGN(data->vi.width, 16);
    data->aligned_height = FFALIGN(data->vi.height, 32);

    data->frame = avcodec_alloc_frame();
    if (!data->frame) {
        vsapi->setError(out, "Cannot allocate AVFrame.");
        d2vfreep(&data->d2v);
        decodefreep(&data->dec);
        free(data);
        return;
    }

    /*
     * Decode 1 frame to find out how the chroma is subampled.
     * The first time our custom get_buffer is called, it will
     * fill in data->vi.format.
     */
    data->format_set = false;
    err              = decodeframe(0, data->d2v, data->dec, data->frame, msg);
    if (err < 0) {
        msg.insert(0, "Failed to decode test frame: ");
        vsapi->setError(out, msg.c_str());
        d2vfreep(&data->d2v);
        decodefreep(&data->dec);
        av_frame_unref(data->frame);
        av_freep(&data->frame);
        free(data);
        return;
    }

    /* See if nocrop is enabled, and set the width/height accordingly. */
    no_crop = !!vsapi->propGetInt(in, "nocrop", 0, &err);
    if (err)
        no_crop = false;

    if (no_crop) {
        data->vi.width  = data->aligned_width;
        data->vi.height = data->aligned_height;
    }

    vsapi->createFilter(in, out, "d2vsource", d2vInit, d2vGetFrame, d2vFree, fmSerial, 0, data, core);

    int rff = !!vsapi->propGetInt(in, "rff", 0, &err);
    if (err)
        rff = 1;

    if (rff) {
        VSPlugin *d2vPlugin = vsapi->getPluginByNs("d2v", core);
        VSNodeRef *before = vsapi->propGetNode(out, "clip", 0, NULL);
        VSNodeRef *after;
        VSMap *args = vsapi->createMap();
        VSMap *ret;
        const char *error;

        vsapi->propSetNode(args, "clip", before, paReplace);
        vsapi->freeNode(before);
        vsapi->propSetData(args, "d2v", vsapi->propGetData(in, "input", 0, NULL), vsapi->propGetDataSize(in, "input", 0, NULL), paReplace);

        ret = vsapi->invoke(d2vPlugin, "ApplyRFF", args);
        vsapi->freeMap(args);

        error = vsapi->getError(ret);
        if (error) {
            vsapi->setError(out, error);
            vsapi->freeMap(ret);
            d2vfreep(&data->d2v);
            decodefreep(&data->dec);
            av_frame_unref(data->frame);
            av_freep(&data->frame);
            free(data);
            return;
        }

        after = vsapi->propGetNode(ret, "clip", 0, NULL);

        vsapi->propSetNode(out, "clip", after, paReplace);
        vsapi->freeNode(after);
        vsapi->freeMap(ret);
    }
}
<commit_msg>Replace deprecated usage of avcodec_alloc_frame() with av_alloc_frame()<commit_after>/*
 * VapourSynth D2V Plugin
 *
 * Copyright (c) 2012 Derek Buitenhuis
 *
 * This file is part of d2vsource.
 *
 * d2vsource 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.
 *
 * d2vsource 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 d2vsource; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

extern "C" {
#include <stdint.h>
#include <stdlib.h>
}

#include <VapourSynth.h>
#include <VSHelper.h>

#include "d2v.hpp"
#include "d2vsource.hpp"
#include "decode.hpp"
#include "directrender.hpp"

void VS_CC d2vInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) *instanceData;
    vsapi->setVideoInfo(&d->vi, 1, node);
}

const VSFrameRef *VS_CC d2vGetFrame(int n, int activationReason, void **instanceData, void **frameData,
                                    VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) *instanceData;
    VSFrameRef *s, *f;
    string msg;
    int ret;

    /* Unreference the previously decoded frame. */
    av_frame_unref(d->frame);

    ret = decodeframe(n, d->d2v, d->dec, d->frame, msg);
    if (ret < 0) {
        vsapi->setFilterError(msg.c_str(), frameCtx);
        return NULL;
    }

    /* Grab our direct-rendered frame. */
    s = (VSFrameRef *) d->frame->opaque;

    /* If our width and height are the same, just return it. */
    if (d->vi.width == d->aligned_width && d->vi.height == d->aligned_height) {
        f = (VSFrameRef *) vsapi->cloneFrameRef(s);
        return f;
    }

    f = vsapi->newVideoFrame(d->vi.format, d->vi.width, d->vi.height, NULL, core);

    /* Copy into VS's buffers. */
    vs_bitblt(vsapi->getWritePtr(f, 0), vsapi->getStride(f, 0), vsapi->getWritePtr(s, 0), vsapi->getStride(s, 0),
              d->vi.width, d->vi.height);
    vs_bitblt(vsapi->getWritePtr(f, 1), vsapi->getStride(f, 1), vsapi->getWritePtr(s, 1), vsapi->getStride(s, 1),
              d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);
    vs_bitblt(vsapi->getWritePtr(f, 2), vsapi->getStride(f, 2), vsapi->getWritePtr(s, 2), vsapi->getStride(s, 2),
              d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);

    return f;
}

void VS_CC d2vFree(void *instanceData, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) instanceData;
    d2vfreep(&d->d2v);
    decodefreep(&d->dec);
    av_frame_unref(d->frame);
    av_freep(&d->frame);
    free(d);
}

void VS_CC d2vCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi)
{
    d2vData *data;
    string msg;
    bool no_crop;
    int err;

    /* Allocate our private data. */
    data = (d2vData *) malloc(sizeof(*data));
    if (!data) {
        vsapi->setError(out, "Cannot allocate private data.");
        return;
    }

    data->d2v = d2vparse((char *) vsapi->propGetData(in, "input", 0, 0), msg);
    if (!data->d2v) {
        vsapi->setError(out, msg.c_str());
        free(data);
        return;
    }

    data->dec = decodeinit(data->d2v, msg);
    if (!data->dec) {
        vsapi->setError(out, msg.c_str());
        d2vfreep(&data->d2v);
        free(data);
        return;
    }

    /*
     * Make our private data available to libavcodec, and
     * set our custom get/release_buffer funcs.
     */
    data->dec->avctx->opaque         = (void *) data;
    data->dec->avctx->get_buffer2    = VSGetBuffer;

    /* Last frame is crashy right now. */
    data->vi.numFrames = data->d2v->frames.size();
    data->vi.width     = data->d2v->width;
    data->vi.height    = data->d2v->height;
    data->vi.fpsNum    = data->d2v->fps_num;
    data->vi.fpsDen    = data->d2v->fps_den;

    /* Stash the pointer to our core. */
    data->core = core;
    data->api  = (VSAPI *) vsapi;

    /*
     * Stash our aligned width and height for use with our
     * custom get_buffer, since it could require this.
     */
    data->aligned_width  = FFALIGN(data->vi.width, 16);
    data->aligned_height = FFALIGN(data->vi.height, 32);

    data->frame = av_frame_alloc();
    if (!data->frame) {
        vsapi->setError(out, "Cannot allocate AVFrame.");
        d2vfreep(&data->d2v);
        decodefreep(&data->dec);
        free(data);
        return;
    }

    /*
     * Decode 1 frame to find out how the chroma is subampled.
     * The first time our custom get_buffer is called, it will
     * fill in data->vi.format.
     */
    data->format_set = false;
    err              = decodeframe(0, data->d2v, data->dec, data->frame, msg);
    if (err < 0) {
        msg.insert(0, "Failed to decode test frame: ");
        vsapi->setError(out, msg.c_str());
        d2vfreep(&data->d2v);
        decodefreep(&data->dec);
        av_frame_unref(data->frame);
        av_freep(&data->frame);
        free(data);
        return;
    }

    /* See if nocrop is enabled, and set the width/height accordingly. */
    no_crop = !!vsapi->propGetInt(in, "nocrop", 0, &err);
    if (err)
        no_crop = false;

    if (no_crop) {
        data->vi.width  = data->aligned_width;
        data->vi.height = data->aligned_height;
    }

    vsapi->createFilter(in, out, "d2vsource", d2vInit, d2vGetFrame, d2vFree, fmSerial, 0, data, core);

    int rff = !!vsapi->propGetInt(in, "rff", 0, &err);
    if (err)
        rff = 1;

    if (rff) {
        VSPlugin *d2vPlugin = vsapi->getPluginByNs("d2v", core);
        VSNodeRef *before = vsapi->propGetNode(out, "clip", 0, NULL);
        VSNodeRef *after;
        VSMap *args = vsapi->createMap();
        VSMap *ret;
        const char *error;

        vsapi->propSetNode(args, "clip", before, paReplace);
        vsapi->freeNode(before);
        vsapi->propSetData(args, "d2v", vsapi->propGetData(in, "input", 0, NULL), vsapi->propGetDataSize(in, "input", 0, NULL), paReplace);

        ret = vsapi->invoke(d2vPlugin, "ApplyRFF", args);
        vsapi->freeMap(args);

        error = vsapi->getError(ret);
        if (error) {
            vsapi->setError(out, error);
            vsapi->freeMap(ret);
            d2vfreep(&data->d2v);
            decodefreep(&data->dec);
            av_frame_unref(data->frame);
            av_freep(&data->frame);
            free(data);
            return;
        }

        after = vsapi->propGetNode(ret, "clip", 0, NULL);

        vsapi->propSetNode(out, "clip", after, paReplace);
        vsapi->freeNode(after);
        vsapi->freeMap(ret);
    }
}
<|endoftext|>


<commit_before>#include "ros/ros.h"
#include "std_msgs/String.h"
#include "nav_msgs/Odometry.h"
#include "se306Project/FieldMsg.h"
#include "geometry_msgs/Twist.h"

#include <sstream>
#include <stdlib.h>
#include <iostream>
#include <cstdlib>
#include <ctime>

class GrassNode {

public:
	GrassNode();
	GrassNode(int, int, int);
	void grassGrow();
	void rosSetup(int, char**);
	void spin();
	void stageOdom_callback(nav_msgs::Odometry);
	void fieldNode_callback(se306Project::FieldMsg);

	int grassNum;
	int robotNum;
	int fieldNum;
	double grassZ;	//heading
	double grassLife;	//life
	//parameters that need to be used eventually
	double growth; // %/s
	double decay; // %/s
	double netGrowth;	//angular v
	std::string soilQuality;
	int sunLight;
	int nextZ;

protected:
	ros::Subscriber StageOdo_sub;
	ros::Publisher commandPub;
	ros::Subscriber FieldNode_sub;
};

GrassNode::GrassNode() {
	grassNum = 0;
	robotNum = 0;
	fieldNum = 0;
	grassZ = 0;
	grassLife = 100;
	growth = 0;
	decay = 0;
	netGrowth = 0;
	soilQuality = "";
	sunLight = 0;
	nextZ = 0;
}

GrassNode::GrassNode (int grass, int robot, int field) {
	GrassNode();
	this->grassNum = grass;
	this->robotNum = robot;
	this->fieldNum = field;
}

void GrassNode::grassGrow(){

	netGrowth = growth + decay;

	grassLife

	geometry_msgs::Twist msg; // The default constructor will set all commands to 0
	msg.angular.z = netGrowth;
	commandPub.publish(msg);
}

void GrassNode::rosSetup(int argc, char **argv) {
/**
	std::ostringstream convertG;
	std::ostringstream convertR;
	std::ostringstream convertF;
	ros::init(argc, argv, "grass", ros::init_options::AnonymousName);
	ros::NodeHandle nh;
	ros::NodeHandle n("~");
	// Get grass number and robot number
	n.getParam("grassNum", grassNum);
	n.getParam("robotNum", robotNum);
	n.getParam("fieldNum", fieldNum);
	convertG << grassNum;
	convertR << robotNum;
	convertF << fieldNum;
	// Convert these into strings
	std::string g = "grass_" + convertG.str();
	ROS_INFO_STREAM(g);
	std::string r = "robot_" + convertR.str();
	ROS_INFO_STREAM(r);
	std::string f = "field_" + convertF.str();
	ROS_INFO_STREAM(f);
**/
	//Initate ros with name determined by field number.
	std::string name;
	std::ostringstream convert;
	std::ostringstream convertG;
	std::ostringstream convertR;
	std::ostringstream convertF;
	convert << this->grassNum;
	name = "Grass" + convert.str();

	ros::init(argc, argv, name);

	ros::NodeHandle n;

	convertG << this->grassNum;
	convertR << this->robotNum;
	convertF << this->fieldNum;
	// Convert these into strings
	std::string g = "grass_" + convertG.str();
	ROS_INFO_STREAM(g);
	std::string r = "robot_" + convertR.str();
	ROS_INFO_STREAM(r);
	std::string f = "Field" + convertF.str();
	ROS_INFO_STREAM(f);

	//initialise the talkies
	StageOdo_sub = n.subscribe<nav_msgs::Odometry>(r + "/odom",1000, &GrassNode::stageOdom_callback,this);
	commandPub = n.advertise<geometry_msgs::Twist>(r + "/cmd_vel",1000);
	//commandPub = n.advertise<nav_msgs::Odometry>(r + "/odom",1000);
	FieldNode_sub = n.subscribe<se306Project::FieldMsg>(f,1000, &GrassNode::fieldNode_callback, this);
	//sheepMovePub = n.advertise<se306Project::SheepMoveMsg>("grass_" + convert.str()+ "/move", 1000);
	//sheepdogPosSub = n.subscribe<std_msgs::String>("sheepdog_position",1000, &SheepNode::sheepdogDangerCallback,this);

	//: talk to the grass, and the field?

	GrassNode::spin();

}

void GrassNode::stageOdom_callback(nav_msgs::Odometry msg) {
	grassZ = 0 + msg.pose.pose.orientation.z;
}

void GrassNode::fieldNode_callback(se306Project::FieldMsg msg) {
	soilQuality = msg.quality;
	sunLight = msg.sunLight;

	ROS_INFO_STREAM("soilQuality:");
	ROS_INFO_STREAM(soilQuality); // Prints the current z value of the grass

	if (soilQuality == "Arid") {
		growth = 0.5; // %/s
	} else if (soilQuality == "Normal") {
		growth = 1; // %/s
	} else {
		growth = 2; // %/s
	}

	growth = ((50+(double)sunLight)/100)*growth; // %/s == 1.8*growth
}

void GrassNode::spin() {
	ros::Rate rate(10); // 10 Hz
	while (ros::ok()) {
		this->grassGrow();
		ros::spinOnce();
		rate.sleep();
	}
}

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

	int grassNum = atoi(argv[1]);
	int robotNum = atoi(argv[2]);
	int fieldNum = atoi(argv[3]);

	GrassNode grass = GrassNode(grassNum, robotNum, fieldNum);

	grass.rosSetup(argc, argv);

}
<commit_msg>no need for this<commit_after><|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
// CoinVault
//
// txactions.h
//
// Copyright (c) 2013-2014 Eric Lombrozo
//
// All Rights Reserved.

#include "txactions.h"

#include "txmodel.h"
#include "txview.h"
#include "accountmodel.h"

#include "rawtxdialog.h"
#include "txsearchdialog.h"
#include "signaturedialog.h"

#include "docdir.h"

#include <CoinDB/SynchedVault.h>

#include <QAction>
#include <QMenu>
#include <QUrl>
#include <QDesktopServices>
#include <QMessageBox>
#include <QApplication>
#include <QClipboard>
#include <QFileDialog>

#include <logger/logger.h>

#include <fstream>

TxActions::TxActions(TxModel* txModel, TxView* txView, AccountModel* accountModel, CoinDB::SynchedVault* synchedVault)
    : m_txModel(txModel), m_txView(txView), m_accountModel(accountModel), m_synchedVault(synchedVault), currentRow(-1)
{
    createActions();
    createMenus();
    connect(m_txView->selectionModel(), &QItemSelectionModel::currentChanged, this, &TxActions::updateCurrentTx);
}

void TxActions::updateCurrentTx(const QModelIndex& current, const QModelIndex& /*previous*/)
{
    currentRow = current.row();
    if (m_txModel && currentRow != -1)
    {
        QStandardItem* typeItem = m_txModel->item(currentRow, 2);
        signaturesAction->setEnabled(typeItem->text() == tr("Send"));

        typeItem = m_txModel->item(currentRow, 6);
        int type = typeItem->data(Qt::UserRole).toInt();
        if (type == CoinDB::Tx::UNSIGNED) {
            signTxAction->setEnabled(true);
        }
        else {
            signTxAction->setEnabled(false);
        }

        if (type == CoinDB::Tx::UNSENT) {
            sendTxAction->setText(tr("Send Transaction"));
            sendTxAction->setEnabled(m_synchedVault && m_synchedVault->isConnected());
        }
        else {
            sendTxAction->setText(tr("Resend Transaction"));
            sendTxAction->setEnabled(m_synchedVault && m_synchedVault->isConnected() && typeItem->text() == "0");
        }

        exportTxToFileAction->setEnabled(true);
        copyTxHashToClipboardAction->setEnabled(true);
        copyRawTxToClipboardAction->setEnabled(true);
        saveRawTxToFileAction->setEnabled(true);
        viewRawTxAction->setEnabled(true);
        viewTxOnWebAction->setEnabled(type == CoinDB::Tx::PROPAGATED || type == CoinDB::Tx::CONFIRMED);
        deleteTxAction->setEnabled(type != CoinDB::Tx::CONFIRMED);
    }
    else {
        signTxAction->setEnabled(false);
        sendTxAction->setEnabled(false);
        exportTxToFileAction->setEnabled(false);
        copyTxHashToClipboardAction->setEnabled(false);
        copyRawTxToClipboardAction->setEnabled(false);
        saveRawTxToFileAction->setEnabled(false);
        viewRawTxAction->setEnabled(false);
        viewTxOnWebAction->setEnabled(false);
        deleteTxAction->setEnabled(false);
    }

}

void TxActions::updateVaultStatus()
{
    bool bEnabled = (m_accountModel && m_accountModel->isOpen());
    importTxFromFileAction->setEnabled(bEnabled);
    insertRawTxFromFileAction->setEnabled(bEnabled);
}

void TxActions::searchTx()
{
    try
    {
        TxSearchDialog dlg(m_txModel);
        if (dlg.exec())
        {
            emit error("Not implemented yet.");
        }
    }
    catch (const std::exception& e)
    {
        emit error(e.what());
    }
}

void TxActions::showSignatureDialog()
{
    try
    {
        SignatureDialog dlg(*m_synchedVault, m_txModel->getTxHash(currentRow));
        if (m_txModel)
        {
            connect(&dlg, &SignatureDialog::txUpdated, [this]() { m_txModel->update(); });
        }
        dlg.exec();
    }
    catch (const std::exception& e)
    {
        emit error(e.what());
    }
}

void TxActions::signTx()
{
    try
    {
        m_txModel->signTx(currentRow);
        m_txView->update();
    }
    catch (const std::exception& e)
    {
        emit error(e.what());
    }
}

void TxActions::sendTx()
{
    try {
        m_txModel->sendTx(currentRow, m_synchedVault);
        m_txView->update();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::exportTxToFile()
{
    try {
        if (!m_accountModel || !m_accountModel->isOpen()) throw std::runtime_error("You must create a vault or open an existing vault before exporting transactions.");

        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        QString fileName = QString::fromStdString(uchar_vector(tx->hash()).getHex()) + ".tx";
        fileName = QFileDialog::getSaveFileName(
            nullptr,
            tr("Export Transaction"),
            getDocDir() + "/" + fileName,
            tr("Transactions (*.tx)"));
        if (fileName.isEmpty()) return;

        fileName = QFileInfo(fileName).absoluteFilePath();

        QFileInfo fileInfo(fileName);
        setDocDir(fileInfo.dir().absolutePath());

        // TODO: emit settings changed signal

        m_accountModel->getVault()->exportTx(tx, fileName.toStdString());
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::importTxFromFile()
{
    try {
        if (!m_accountModel || !m_accountModel->isOpen()) throw std::runtime_error("You must create a vault or open an existing vault before importing transactions.");

        QString fileName = QFileDialog::getOpenFileName(
            nullptr,
            tr("Import Transaction"),
            getDocDir(),
            tr("Transactions (*.tx)"));
        if (fileName.isEmpty()) return;

        fileName = QFileInfo(fileName).absoluteFilePath();

        QFileInfo fileInfo(fileName);
        setDocDir(fileInfo.dir().absolutePath());

        // TODO: emit settings changed signal

        std::shared_ptr<CoinDB::Tx> tx = m_accountModel->getVault()->importTx(fileName.toStdString());
        if (!tx) throw std::runtime_error("Transaction not inserted.");
        m_accountModel->update();
        m_txModel->update();
        m_txView->update();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::viewRawTx()
{
    try {
        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        RawTxDialog rawTxDlg(tr("Raw Transaction"));
        rawTxDlg.setRawTx(tx->raw());
        rawTxDlg.exec();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::copyTxHashToClipboard()
{
    try {
        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        QClipboard* clipboard = QApplication::clipboard();
        clipboard->setText(QString::fromStdString(uchar_vector(tx->hash()).getHex()));
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::copyRawTxToClipboard()
{
    try {
        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        QClipboard* clipboard = QApplication::clipboard();
        clipboard->setText(QString::fromStdString(uchar_vector(tx->raw()).getHex()));
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::saveRawTxToFile()
{
    try {
        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        QString fileName = QString::fromStdString(uchar_vector(tx->hash()).getHex()) + ".rawtx";
        fileName = QFileDialog::getSaveFileName(
            nullptr,
            tr("Save Raw Transaction"),
            getDocDir() + "/" + fileName,
            tr("Transactions (*.rawtx)"));
        if (fileName.isEmpty()) return;

        fileName = QFileInfo(fileName).absoluteFilePath();

        QFileInfo fileInfo(fileName);
        setDocDir(fileInfo.dir().absolutePath());

        // TODO: emit settings changed signal

        std::ofstream ofs(fileName.toStdString(), std::ofstream::out);
        ofs << uchar_vector(tx->raw()).getHex() << std::endl;
        ofs.close();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::insertRawTxFromFile()
{
    try {
        if (!m_accountModel || !m_accountModel->isOpen()) throw std::runtime_error("You must create a vault or open an existing vault before inserting transactions.");

        QString fileName = QFileDialog::getOpenFileName(
            nullptr,
            tr("Insert Raw Transaction"),
            getDocDir(),
            tr("Transactions (*.rawtx)"));
        if (fileName.isEmpty()) return;

        fileName = QFileInfo(fileName).absoluteFilePath();

        QFileInfo fileInfo(fileName);
        setDocDir(fileInfo.dir().absolutePath());

        // TODO: emit settings changed signal

        std::string rawhex;
        std::ifstream ifs(fileName.toStdString(), std::ifstream::in);
        if (ifs.bad()) throw std::runtime_error("Error opening file.");
        ifs >> rawhex;
        if (!ifs.good()) throw std::runtime_error("Error reading file.");

        std::shared_ptr<CoinDB::Tx> tx(new CoinDB::Tx());
        tx->set(uchar_vector(rawhex));
        tx = m_accountModel->insertTx(tx);
        m_txModel->update();
        m_txView->update();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::viewTxOnWeb()
{
    const QString URL_PREFIX("https://blockchain.info/tx/");

    try {
        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        if (!QDesktopServices::openUrl(QUrl(URL_PREFIX + QString::fromStdString(uchar_vector(tx->hash()).getHex())))) {
            throw std::runtime_error(tr("Unable to open browser.").toStdString());
        }
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::deleteTx()
{
    QMessageBox msgBox;
    msgBox.setText(tr("Delete confirmation."));
    msgBox.setInformativeText(tr("Are you sure you want to delete this transaction?"));
    msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
    msgBox.setDefaultButton(QMessageBox::Cancel);
    if (msgBox.exec() == QMessageBox::Cancel) return;

    try {
        m_txModel->deleteTx(currentRow);
        m_txView->update();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::createActions()
{
    signaturesAction = new QAction(tr("Signatures..."), this);
    signaturesAction->setEnabled(false);
    connect(signaturesAction, SIGNAL(triggered()), this, SLOT(showSignatureDialog()));

    signTxAction = new QAction(tr("Sign Transaction"), this);
    signTxAction->setEnabled(false);
    connect(signTxAction, SIGNAL(triggered()), this, SLOT(signTx()));

    sendTxAction = new QAction(tr("Send Transaction"), this);
    sendTxAction->setEnabled(false);
    connect(sendTxAction, SIGNAL(triggered()), this, SLOT(sendTx()));

    exportTxToFileAction = new QAction(tr("Export Transaction To File..."), this);
    exportTxToFileAction->setEnabled(false);
    connect(exportTxToFileAction, SIGNAL(triggered()), this, SLOT(exportTxToFile()));

    importTxFromFileAction = new QAction(tr("Import Transaction From File..."), this);
    importTxFromFileAction->setEnabled(false);
    connect(importTxFromFileAction, SIGNAL(triggered()), this, SLOT(importTxFromFile()));

    viewRawTxAction = new QAction(tr("View Raw Transaction"), this);
    viewRawTxAction->setEnabled(false);
    connect(viewRawTxAction, SIGNAL(triggered()), this, SLOT(viewRawTx()));

    copyTxHashToClipboardAction = new QAction(tr("Copy Transaction Hash To Clipboard"), this);
    copyTxHashToClipboardAction->setEnabled(false);
    connect(copyTxHashToClipboardAction, SIGNAL(triggered()), this, SLOT(copyTxHashToClipboard()));

    copyRawTxToClipboardAction = new QAction(tr("Copy Raw Transaction To Clipboard"), this);
    copyRawTxToClipboardAction->setEnabled(false);
    connect(copyRawTxToClipboardAction, SIGNAL(triggered()), this, SLOT(copyRawTxToClipboard()));

    saveRawTxToFileAction = new QAction(tr("Save Raw Transaction To File..."), this);
    saveRawTxToFileAction->setEnabled(false);
    connect(saveRawTxToFileAction, SIGNAL(triggered()), this, SLOT(saveRawTxToFile()));

    insertRawTxFromFileAction = new QAction(tr("Insert Raw Transaction From File..."), this);
    insertRawTxFromFileAction->setEnabled(false);
    connect(insertRawTxFromFileAction, SIGNAL(triggered()), this, SLOT(insertRawTxFromFile()));

    viewTxOnWebAction = new QAction(tr("View At Blockchain.info"), this);
    viewTxOnWebAction->setEnabled(false);
    connect(viewTxOnWebAction, SIGNAL(triggered()), this, SLOT(viewTxOnWeb()));

    deleteTxAction = new QAction(tr("Delete Transaction"), this);
    deleteTxAction->setEnabled(false);
    connect(deleteTxAction, SIGNAL(triggered()), this, SLOT(deleteTx()));
}

void TxActions::createMenus()
{
    menu = new QMenu();
    menu->addAction(signaturesAction);
    //menu->addAction(signTxAction);
    menu->addAction(sendTxAction);
    menu->addSeparator();
    menu->addAction(exportTxToFileAction);
    menu->addAction(importTxFromFileAction);
    menu->addSeparator();
    //menu->addAction(viewRawTxAction);
    menu->addAction(copyTxHashToClipboardAction);
    menu->addAction(copyRawTxToClipboardAction);
    menu->addAction(saveRawTxToFileAction);
    menu->addAction(insertRawTxFromFileAction);
    menu->addAction(viewTxOnWebAction);
    menu->addSeparator();
    menu->addAction(deleteTxAction);
}

<commit_msg>Added searchTxAction to TxActions menu.<commit_after>///////////////////////////////////////////////////////////////////////////////
//
// CoinVault
//
// txactions.h
//
// Copyright (c) 2013-2014 Eric Lombrozo
//
// All Rights Reserved.

#include "txactions.h"

#include "txmodel.h"
#include "txview.h"
#include "accountmodel.h"

#include "rawtxdialog.h"
#include "txsearchdialog.h"
#include "signaturedialog.h"

#include "docdir.h"

#include <CoinDB/SynchedVault.h>

#include <QAction>
#include <QMenu>
#include <QUrl>
#include <QDesktopServices>
#include <QMessageBox>
#include <QApplication>
#include <QClipboard>
#include <QFileDialog>

#include <logger/logger.h>

#include <fstream>

TxActions::TxActions(TxModel* txModel, TxView* txView, AccountModel* accountModel, CoinDB::SynchedVault* synchedVault)
    : m_txModel(txModel), m_txView(txView), m_accountModel(accountModel), m_synchedVault(synchedVault), currentRow(-1)
{
    createActions();
    createMenus();
    connect(m_txView->selectionModel(), &QItemSelectionModel::currentChanged, this, &TxActions::updateCurrentTx);
}

void TxActions::updateCurrentTx(const QModelIndex& current, const QModelIndex& /*previous*/)
{
    currentRow = current.row();
    if (m_txModel && currentRow != -1)
    {
        QStandardItem* typeItem = m_txModel->item(currentRow, 2);
        signaturesAction->setEnabled(typeItem->text() == tr("Send"));

        typeItem = m_txModel->item(currentRow, 6);
        int type = typeItem->data(Qt::UserRole).toInt();
        if (type == CoinDB::Tx::UNSIGNED) {
            signTxAction->setEnabled(true);
        }
        else {
            signTxAction->setEnabled(false);
        }

        if (type == CoinDB::Tx::UNSENT) {
            sendTxAction->setText(tr("Send Transaction"));
            sendTxAction->setEnabled(m_synchedVault && m_synchedVault->isConnected());
        }
        else {
            sendTxAction->setText(tr("Resend Transaction"));
            sendTxAction->setEnabled(m_synchedVault && m_synchedVault->isConnected() && typeItem->text() == "0");
        }

        exportTxToFileAction->setEnabled(true);
        copyTxHashToClipboardAction->setEnabled(true);
        copyRawTxToClipboardAction->setEnabled(true);
        saveRawTxToFileAction->setEnabled(true);
        viewRawTxAction->setEnabled(true);
        viewTxOnWebAction->setEnabled(type == CoinDB::Tx::PROPAGATED || type == CoinDB::Tx::CONFIRMED);
        deleteTxAction->setEnabled(type != CoinDB::Tx::CONFIRMED);
    }
    else {
        signTxAction->setEnabled(false);
        sendTxAction->setEnabled(false);
        exportTxToFileAction->setEnabled(false);
        copyTxHashToClipboardAction->setEnabled(false);
        copyRawTxToClipboardAction->setEnabled(false);
        saveRawTxToFileAction->setEnabled(false);
        viewRawTxAction->setEnabled(false);
        viewTxOnWebAction->setEnabled(false);
        deleteTxAction->setEnabled(false);
    }

}

void TxActions::updateVaultStatus()
{
    bool bEnabled = (m_accountModel && m_accountModel->isOpen());
    searchTxAction->setEnabled(bEnabled);
    importTxFromFileAction->setEnabled(bEnabled);
    insertRawTxFromFileAction->setEnabled(bEnabled);
}

void TxActions::searchTx()
{
    try
    {
        TxSearchDialog dlg(m_txModel);
        if (dlg.exec())
        {
            emit error("Not implemented yet.");
        }
    }
    catch (const std::exception& e)
    {
        emit error(e.what());
    }
}

void TxActions::showSignatureDialog()
{
    try
    {
        SignatureDialog dlg(*m_synchedVault, m_txModel->getTxHash(currentRow));
        if (m_txModel)
        {
            connect(&dlg, &SignatureDialog::txUpdated, [this]() { m_txModel->update(); });
        }
        dlg.exec();
    }
    catch (const std::exception& e)
    {
        emit error(e.what());
    }
}

void TxActions::signTx()
{
    try
    {
        m_txModel->signTx(currentRow);
        m_txView->update();
    }
    catch (const std::exception& e)
    {
        emit error(e.what());
    }
}

void TxActions::sendTx()
{
    try {
        m_txModel->sendTx(currentRow, m_synchedVault);
        m_txView->update();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::exportTxToFile()
{
    try {
        if (!m_accountModel || !m_accountModel->isOpen()) throw std::runtime_error("You must create a vault or open an existing vault before exporting transactions.");

        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        QString fileName = QString::fromStdString(uchar_vector(tx->hash()).getHex()) + ".tx";
        fileName = QFileDialog::getSaveFileName(
            nullptr,
            tr("Export Transaction"),
            getDocDir() + "/" + fileName,
            tr("Transactions (*.tx)"));
        if (fileName.isEmpty()) return;

        fileName = QFileInfo(fileName).absoluteFilePath();

        QFileInfo fileInfo(fileName);
        setDocDir(fileInfo.dir().absolutePath());

        // TODO: emit settings changed signal

        m_accountModel->getVault()->exportTx(tx, fileName.toStdString());
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::importTxFromFile()
{
    try {
        if (!m_accountModel || !m_accountModel->isOpen()) throw std::runtime_error("You must create a vault or open an existing vault before importing transactions.");

        QString fileName = QFileDialog::getOpenFileName(
            nullptr,
            tr("Import Transaction"),
            getDocDir(),
            tr("Transactions (*.tx)"));
        if (fileName.isEmpty()) return;

        fileName = QFileInfo(fileName).absoluteFilePath();

        QFileInfo fileInfo(fileName);
        setDocDir(fileInfo.dir().absolutePath());

        // TODO: emit settings changed signal

        std::shared_ptr<CoinDB::Tx> tx = m_accountModel->getVault()->importTx(fileName.toStdString());
        if (!tx) throw std::runtime_error("Transaction not inserted.");
        m_accountModel->update();
        m_txModel->update();
        m_txView->update();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::viewRawTx()
{
    try {
        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        RawTxDialog rawTxDlg(tr("Raw Transaction"));
        rawTxDlg.setRawTx(tx->raw());
        rawTxDlg.exec();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::copyTxHashToClipboard()
{
    try {
        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        QClipboard* clipboard = QApplication::clipboard();
        clipboard->setText(QString::fromStdString(uchar_vector(tx->hash()).getHex()));
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::copyRawTxToClipboard()
{
    try {
        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        QClipboard* clipboard = QApplication::clipboard();
        clipboard->setText(QString::fromStdString(uchar_vector(tx->raw()).getHex()));
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::saveRawTxToFile()
{
    try {
        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        QString fileName = QString::fromStdString(uchar_vector(tx->hash()).getHex()) + ".rawtx";
        fileName = QFileDialog::getSaveFileName(
            nullptr,
            tr("Save Raw Transaction"),
            getDocDir() + "/" + fileName,
            tr("Transactions (*.rawtx)"));
        if (fileName.isEmpty()) return;

        fileName = QFileInfo(fileName).absoluteFilePath();

        QFileInfo fileInfo(fileName);
        setDocDir(fileInfo.dir().absolutePath());

        // TODO: emit settings changed signal

        std::ofstream ofs(fileName.toStdString(), std::ofstream::out);
        ofs << uchar_vector(tx->raw()).getHex() << std::endl;
        ofs.close();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::insertRawTxFromFile()
{
    try {
        if (!m_accountModel || !m_accountModel->isOpen()) throw std::runtime_error("You must create a vault or open an existing vault before inserting transactions.");

        QString fileName = QFileDialog::getOpenFileName(
            nullptr,
            tr("Insert Raw Transaction"),
            getDocDir(),
            tr("Transactions (*.rawtx)"));
        if (fileName.isEmpty()) return;

        fileName = QFileInfo(fileName).absoluteFilePath();

        QFileInfo fileInfo(fileName);
        setDocDir(fileInfo.dir().absolutePath());

        // TODO: emit settings changed signal

        std::string rawhex;
        std::ifstream ifs(fileName.toStdString(), std::ifstream::in);
        if (ifs.bad()) throw std::runtime_error("Error opening file.");
        ifs >> rawhex;
        if (!ifs.good()) throw std::runtime_error("Error reading file.");

        std::shared_ptr<CoinDB::Tx> tx(new CoinDB::Tx());
        tx->set(uchar_vector(rawhex));
        tx = m_accountModel->insertTx(tx);
        m_txModel->update();
        m_txView->update();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::viewTxOnWeb()
{
    const QString URL_PREFIX("https://blockchain.info/tx/");

    try {
        std::shared_ptr<CoinDB::Tx> tx = m_txModel->getTx(currentRow);
        if (!QDesktopServices::openUrl(QUrl(URL_PREFIX + QString::fromStdString(uchar_vector(tx->hash()).getHex())))) {
            throw std::runtime_error(tr("Unable to open browser.").toStdString());
        }
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::deleteTx()
{
    QMessageBox msgBox;
    msgBox.setText(tr("Delete confirmation."));
    msgBox.setInformativeText(tr("Are you sure you want to delete this transaction?"));
    msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
    msgBox.setDefaultButton(QMessageBox::Cancel);
    if (msgBox.exec() == QMessageBox::Cancel) return;

    try {
        m_txModel->deleteTx(currentRow);
        m_txView->update();
    }
    catch (const std::exception& e) {
        emit error(e.what());
    }
}

void TxActions::createActions()
{
    searchTxAction = new QAction(tr("Search For Transaction..."), this);
    searchTxAction->setEnabled(true);
    connect(searchTxAction, SIGNAL(triggered()), this, SLOT(searchTx()));

    signaturesAction = new QAction(tr("Signatures..."), this);
    signaturesAction->setEnabled(false);
    connect(signaturesAction, SIGNAL(triggered()), this, SLOT(showSignatureDialog()));

    signTxAction = new QAction(tr("Sign Transaction"), this);
    signTxAction->setEnabled(false);
    connect(signTxAction, SIGNAL(triggered()), this, SLOT(signTx()));

    sendTxAction = new QAction(tr("Send Transaction"), this);
    sendTxAction->setEnabled(false);
    connect(sendTxAction, SIGNAL(triggered()), this, SLOT(sendTx()));

    exportTxToFileAction = new QAction(tr("Export Transaction To File..."), this);
    exportTxToFileAction->setEnabled(false);
    connect(exportTxToFileAction, SIGNAL(triggered()), this, SLOT(exportTxToFile()));

    importTxFromFileAction = new QAction(tr("Import Transaction From File..."), this);
    importTxFromFileAction->setEnabled(false);
    connect(importTxFromFileAction, SIGNAL(triggered()), this, SLOT(importTxFromFile()));

    viewRawTxAction = new QAction(tr("View Raw Transaction"), this);
    viewRawTxAction->setEnabled(false);
    connect(viewRawTxAction, SIGNAL(triggered()), this, SLOT(viewRawTx()));

    copyTxHashToClipboardAction = new QAction(tr("Copy Transaction Hash To Clipboard"), this);
    copyTxHashToClipboardAction->setEnabled(false);
    connect(copyTxHashToClipboardAction, SIGNAL(triggered()), this, SLOT(copyTxHashToClipboard()));

    copyRawTxToClipboardAction = new QAction(tr("Copy Raw Transaction To Clipboard"), this);
    copyRawTxToClipboardAction->setEnabled(false);
    connect(copyRawTxToClipboardAction, SIGNAL(triggered()), this, SLOT(copyRawTxToClipboard()));

    saveRawTxToFileAction = new QAction(tr("Save Raw Transaction To File..."), this);
    saveRawTxToFileAction->setEnabled(false);
    connect(saveRawTxToFileAction, SIGNAL(triggered()), this, SLOT(saveRawTxToFile()));

    insertRawTxFromFileAction = new QAction(tr("Insert Raw Transaction From File..."), this);
    insertRawTxFromFileAction->setEnabled(false);
    connect(insertRawTxFromFileAction, SIGNAL(triggered()), this, SLOT(insertRawTxFromFile()));

    viewTxOnWebAction = new QAction(tr("View At Blockchain.info"), this);
    viewTxOnWebAction->setEnabled(false);
    connect(viewTxOnWebAction, SIGNAL(triggered()), this, SLOT(viewTxOnWeb()));

    deleteTxAction = new QAction(tr("Delete Transaction"), this);
    deleteTxAction->setEnabled(false);
    connect(deleteTxAction, SIGNAL(triggered()), this, SLOT(deleteTx()));
}

void TxActions::createMenus()
{
    menu = new QMenu();
    menu->addAction(searchTxAction);
    menu->addSeparator();
    menu->addAction(signaturesAction);
    //menu->addAction(signTxAction);
    menu->addAction(sendTxAction);
    menu->addSeparator();
    menu->addAction(exportTxToFileAction);
    menu->addAction(importTxFromFileAction);
    menu->addSeparator();
    //menu->addAction(viewRawTxAction);
    menu->addAction(copyTxHashToClipboardAction);
    menu->addAction(copyRawTxToClipboardAction);
    menu->addAction(saveRawTxToFileAction);
    menu->addAction(insertRawTxFromFileAction);
    menu->addAction(viewTxOnWebAction);
    menu->addSeparator();
    menu->addAction(deleteTxAction);
}

<|endoftext|>


<commit_before>#include <immintrin.h>
#include <x86intrin.h>

namespace base64 {

    namespace xop {

    #define packed_byte(x) _mm_set1_epi8(char(x))

        __m128i lookup(const __m128i input) {

            // Even characters from "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".
            // The difference between codes of adjacent letters is 1, except '+' and '/', for
            // them difference is 4.
            const __m128i base64_lo = _mm_setr_epi8(
                'A', 'C', 'E', 'G', 'I', 'K', 'M', 'O', 'Q', 'S', 'U', 'W', 'Y', 'a', 'c', 'e'
            );

            const __m128i base64_hi = _mm_setr_epi8(
                'g', 'i', 'k', 'm', 'o', 'q', 's', 'u', 'w', 'y', '0', '2', '4', '6', '8', '+'
            );

            // input   = packed_byte(00ab_cdef)
            // bits15  = packed_byte(000a_bcde) -- five higest bits
            const __m128i bits15 = _mm_and_si128(_mm_srli_epi16(input, 1), packed_byte(0x01f));

            // bit0    = packed_byte(0000_000f) -- the LSB
            const __m128i bit0   = _mm_and_si128(input, packed_byte(0x01));

            // t0      = bits 5:1 translated into ASCII codes
            const __m128i t0     = _mm_perm_epi8(base64_lo, base64_hi, bits15);

            // t1      = the codes adjusted by 0th bit
            const __m128i t1     = _mm_add_epi8(t0, bit0);

            // t3      = special fixup for input == 63
            const __m128i t3     = _mm_and_si128(_mm_cmpeq_epi8(input, packed_byte(63)), packed_byte(3));

            return _mm_add_epi8(t1, t3);
        }

    #undef packed_byte

    } // namespace xop

} // namespace base64

<commit_msg>simplified XOP lookup<commit_after>#include <immintrin.h>
#include <x86intrin.h>

namespace base64 {

    namespace xop {

    #define packed_byte(x) _mm_set1_epi8(char(x))

        __m128i lookup(const __m128i input) {

            // Even characters from "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".
            // The difference between codes of adjacent letters is 1, except '+' and '/', for
            // them difference is 4.
            const __m128i base64_lo = _mm_setr_epi8(
                'A', 'C', 'E', 'G', 'I', 'K', 'M', 'O', 'Q', 'S', 'U', 'W', 'Y', 'a', 'c', 'e'
            );

            const __m128i base64_hi = _mm_setr_epi8(
                'g', 'i', 'k', 'm', 'o', 'q', 's', 'u', 'w', 'y', '0', '2', '4', '6', '8', '+'
            );

            // input   = packed_byte(00ab_cdef)
            // bits15  = packed_byte(000a_bcde) -- five highest bits
            const __m128i bits15 = _mm_shl_epi8(input, packed_byte(-1));

            // bit0    = packed_byte(0000_000f) -- the LSB
            const __m128i bit0   = _mm_and_si128(input, packed_byte(0x01));

            // t0      = bits 5:1 translated into ASCII codes
            const __m128i t0     = _mm_perm_epi8(base64_lo, base64_hi, bits15);

            // t1      = the codes adjusted by 0th bit
            const __m128i t1     = _mm_add_epi8(t0, bit0);

            // t3      = special fixup for input == 63
            const __m128i t3     = _mm_and_si128(_mm_cmpeq_epi8(input, packed_byte(63)), packed_byte(3));

            return _mm_add_epi8(t1, t3);
        }

    #undef packed_byte

    } // namespace xop

} // namespace base64

<|endoftext|>