Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "texternfx.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tdoubleparam.h"
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
//#include "tfx.h"
Toshihiro Shimizu 890ddd
#include "trasterfx.h"
Toshihiro Shimizu 890ddd
//#include "tsystem.h"
Toshihiro Shimizu 890ddd
//#include "tparamcontainer.h"
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFilePath getExternFxPath() {
Shinya Kitaoka 120a6e
  return TSystem::getBinDir() + "plugins" + "externFxs";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// not implemented yet
Shinya Kitaoka 120a6e
void TExternFx::getNames(std::vector<std::string> &names) {}</std::string>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TExternFx *TExternFx::create(std::string name) {
Shinya Kitaoka 120a6e
  TExternalProgramFx *fx = new TExternalProgramFx(name);
Shinya Kitaoka 120a6e
  return fx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
TExternalProgramFx::TExternalProgramFx(std::string name)
Shinya Kitaoka 120a6e
    : m_externFxName(name) {
Shinya Kitaoka 120a6e
  initialize(name);
Shinya Kitaoka 120a6e
  setName(L"ExternalProgramFx");
Shinya Kitaoka 120a6e
  //    addInputPort("input2", m_input2);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TExternalProgramFx::TExternalProgramFx() : m_externFxName() {
Shinya Kitaoka 120a6e
  setName(L"ExternalProgramFx");
Shinya Kitaoka 120a6e
  //    addInputPort("input2", m_input2);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TExternalProgramFx::~TExternalProgramFx() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TExternalProgramFx::initialize(std::string name) {
Shinya Kitaoka 120a6e
  TFilePath fp = getExternFxPath() + (name + ".xml");
Shinya Kitaoka 120a6e
  TIStream is(fp);
Shinya Kitaoka 120a6e
  if (!is) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string tagName;
Shinya Kitaoka 120a6e
  if (!is.matchTag(tagName) || tagName != "externFx") return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    while (is.matchTag(tagName)) {
Shinya Kitaoka 120a6e
      if (tagName == "executable") {
Shinya Kitaoka 120a6e
        TFilePath executable = TFilePath(is.getTagAttribute("path"));
Shinya Kitaoka 120a6e
        std::string args     = is.getTagAttribute("args");
Shinya Kitaoka 120a6e
        if (executable == TFilePath())
Shinya Kitaoka 120a6e
          throw TException("missing executable path");
Shinya Kitaoka 120a6e
        if (args == "") throw TException("missing args string");
Shinya Kitaoka 120a6e
        setExecutable(executable, args);
Shinya Kitaoka 120a6e
      } else if (tagName == "inport" || tagName == "outport") {
Shinya Kitaoka 120a6e
        std::string portName = is.getTagAttribute("name");
Shinya Kitaoka 120a6e
        std::string ext      = is.getTagAttribute("ext");
Shinya Kitaoka 120a6e
        if (portName == "") throw TException("missing port name");
Shinya Kitaoka 120a6e
        if (ext == "") throw TException("missing port ext");
Shinya Kitaoka 120a6e
        addPort(portName, ext, tagName == "inport");
Shinya Kitaoka 120a6e
      } else if (tagName == "param") {
Shinya Kitaoka 120a6e
        std::string paramName = is.getTagAttribute("name");
Shinya Kitaoka 120a6e
        if (paramName == "") throw TException("missing param name");
Shinya Kitaoka 120a6e
        std::string type = is.getTagAttribute("type");
Shinya Kitaoka 120a6e
        if (type == "") throw TException("missing param type");
Shinya Kitaoka 120a6e
        if (type != "double")
Shinya Kitaoka 120a6e
          throw TException("param type not yet implemented");
Shinya Kitaoka 120a6e
        TDoubleParamP param = new TDoubleParam();
Shinya Kitaoka 120a6e
        param->setName(paramName);
Shinya Kitaoka 120a6e
        m_params.push_back(param);
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        throw TException("unexpected tag " + tagName);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    is.closeChild();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)m_params.size(); i++)
Shinya Kitaoka 120a6e
      bindParam(this, m_params[i]->getName(), m_params[i]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TExternalProgramFx::addPort(std::string portName, std::string ext,
Shinya Kitaoka 120a6e
                                 bool isInput) {
Shinya Kitaoka 120a6e
  if (isInput) {
Shinya Kitaoka 120a6e
    TRasterFxPort *port = new TRasterFxPort();
Shinya Kitaoka 120a6e
    m_ports[portName]   = Port(portName, ext, port);
Shinya Kitaoka 120a6e
    addInputPort(portName, *port);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    m_ports[portName] = Port(portName, ext, 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// void TExternalProgramFx::addParam(string paramName, const TParamP ¶m)
Toshihiro Shimizu 890ddd
//{
Toshihiro Shimizu 890ddd
//  m_params[paramName] = param;
Toshihiro Shimizu 890ddd
//  TFx::addParam(paramName, param);
Toshihiro Shimizu 890ddd
//}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFx *TExternalProgramFx::clone(bool recursive) const {
Shinya Kitaoka 120a6e
  TExternalProgramFx *fx =
Shinya Kitaoka 120a6e
      dynamic_cast<texternalprogramfx *="">(TExternFx::create(m_externFxName));</texternalprogramfx>
Shinya Kitaoka 120a6e
  assert(fx);
Shinya Kitaoka 120a6e
  // new TExternalProgramFx();
Shinya Kitaoka 120a6e
  // fx->setExecutable(m_executablePath, m_args);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // copia della time region
Shinya Kitaoka 120a6e
  fx->setActiveTimeRegion(getActiveTimeRegion());
Shinya Kitaoka 120a6e
  // fx->m_imp->m_activeTimeRegion = m_imp->m_activeTimeRegion;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  fx->getParams()->copy(getParams());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(getInputPortCount() == fx->getInputPortCount());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // std::map<std::string, port="">::const_iterator j;</std::string,>
Shinya Kitaoka 120a6e
  // for(j=m_ports.begin(); j!=m_ports.end(); ++j)
Shinya Kitaoka 120a6e
  //  fx->addPort(j->first, j->second.m_ext, j->second.m_port != 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // copia ricorsiva sulle porte
Shinya Kitaoka 120a6e
  if (recursive) {
Shinya Kitaoka 120a6e
    for (int i = 0; i < getInputPortCount(); ++i) {
Shinya Kitaoka 120a6e
      TFxPort *port = getInputPort(i);
Shinya Kitaoka 120a6e
      if (port->getFx())
Shinya Kitaoka 120a6e
        fx->connect(getInputPortName(i), port->getFx()->clone(true));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // std::map<std::string, tparamp="">::const_iterator j;</std::string,>
Shinya Kitaoka 120a6e
  // for(j=m_params.begin(); j!=m_params.end(); ++j)
Shinya Kitaoka 120a6e
  //  fx->addParam(j->first, j->second->clone());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return fx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TExternalProgramFx::doGetBBox(double frame, TRectD &bBox,
Shinya Kitaoka 120a6e
                                   const TRenderSettings &info) {
Shinya Kitaoka 120a6e
  // bBox = TRectD(-30,-30,30,30);
Shinya Kitaoka 120a6e
  //  return true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, port="">::const_iterator portIt;</std::string,>
Shinya Kitaoka 120a6e
  for (portIt = m_ports.begin(); portIt != m_ports.end(); ++portIt) {
Shinya Kitaoka 120a6e
    if (portIt->second.m_port != 0) {
Shinya Kitaoka 120a6e
      TRasterFxPort *tmp;
Shinya Kitaoka 120a6e
      tmp = portIt->second.m_port;
Shinya Kitaoka 120a6e
      if (tmp->isConnected()) {
Shinya Kitaoka 120a6e
        TRectD tmpbBox;
Shinya Kitaoka 120a6e
        (*tmp)->doGetBBox(frame, tmpbBox, info);
Shinya Kitaoka 120a6e
        bBox += tmpbBox;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (bBox.isEmpty()) {
Shinya Kitaoka 120a6e
    bBox = TRectD();
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  /*
Toshihiro Shimizu 890ddd
if(m_input1.isConnected() || m_input2.isConnected())
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
bool ret = m_input1->doGetBBox(frame, bBox) || m_input1->doGetBBox(frame, bBox);
Shinya Kitaoka 120a6e
return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
else
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
bBox = TRectD();
Shinya Kitaoka 120a6e
return false;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TExternalProgramFx::doCompute(TTile &tile, double frame,
Shinya Kitaoka 120a6e
                                   const TRenderSettings &ri) {
Shinya Kitaoka 120a6e
  TRaster32P ras = tile.getRaster();
Shinya Kitaoka 120a6e
  if (!ras) return;
Shinya Kitaoka 120a6e
  std::string args           = m_args;
Shinya Kitaoka 120a6e
  std::string executablePath = ::to_string(m_executablePath);
Shinya Kitaoka 120a6e
  std::map<std::string, tfilepath=""> tmpFiles;  // portname --> file</std::string,>
Shinya Kitaoka 120a6e
  TFilePath outputTmpFile;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, port="">::const_iterator portIt;</std::string,>
Shinya Kitaoka 120a6e
  for (portIt = m_ports.begin(); portIt != m_ports.end(); ++portIt) {
Shinya Kitaoka 120a6e
    TFilePath fp            = TSystem::getUniqueFile("externfx");
Shinya Kitaoka 120a6e
    fp                      = fp.withType(portIt->second.m_ext);
Shinya Kitaoka 120a6e
    tmpFiles[portIt->first] = fp;
Shinya Kitaoka 120a6e
    if (portIt->second.m_port == 0)  // solo una porta e' di output
Shinya Kitaoka 120a6e
      outputTmpFile = fp;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      TRasterFxPort *tmp;
Shinya Kitaoka 120a6e
      tmp = portIt->second.m_port;
Shinya Kitaoka 120a6e
      if (tmp->isConnected()) {
Shinya Kitaoka 120a6e
        (*tmp)->compute(tile, frame, ri);
Shinya Kitaoka 120a6e
        TImageWriter::save(fp, ras);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // args e' della forma "$src $ctrl -o $out -v $value"
Shinya Kitaoka 120a6e
  // sostituisco le variabili
Shinya Kitaoka 120a6e
  int i = 0;
Shinya Kitaoka 120a6e
  for (;;) {
Shinya Kitaoka 120a6e
    i = args.find('$', i);
Shinya Kitaoka 120a6e
    if (i == (int)std::string::npos) break;
Shinya Kitaoka 120a6e
    int j   = i + 1;
Shinya Kitaoka 120a6e
    int len = args.length();
Shinya Kitaoka 120a6e
    while (j < len && isalnum(args[j])) j++;
Shinya Kitaoka 120a6e
    // un '$' non seguito da caratteri alfanumerici va ignorato
Shinya Kitaoka 120a6e
    if (j == i + 1) {
Shinya Kitaoka 120a6e
      // la sequenza '$$' diventa '$'
Shinya Kitaoka 120a6e
      if (j < len && args[j] == '$') args.replace(i, 2, "$");
Shinya Kitaoka 120a6e
      i++;
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // ho trovato una variabile
Shinya Kitaoka 120a6e
    int m            = j - i - 1;
Shinya Kitaoka 120a6e
    std::string name = args.substr(i + 1, m);
Shinya Kitaoka 120a6e
    // calcolo il valore.
Shinya Kitaoka 120a6e
    std::string value;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::map<std::string, tfilepath="">::const_iterator it;</std::string,>
Shinya Kitaoka 120a6e
    it = tmpFiles.find(name);
Shinya Kitaoka 120a6e
    if (it != tmpFiles.end()) {
Shinya Kitaoka 120a6e
      // e' una porta. il valore e' il nome del
Shinya Kitaoka 120a6e
      // file temporaneo
Shinya Kitaoka 120a6e
      value = "\"" + ::to_string(it->second.getWideString()) + "\"";
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      // e' un parametro
Shinya Kitaoka 120a6e
      // se il nome non viene riconosciuto sostituisco la stringa nulla
Shinya Kitaoka 120a6e
      TDoubleParamP param = TParamP(getParams()->getParam(name));
Shinya Kitaoka 120a6e
      if (param) value    = std::to_string(param->getValue(frame));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    args.replace(i, m + 1, value);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  args = " " + args;  // aggiungo uno spazio per sicurezza
Shinya Kitaoka 120a6e
  // ofstream os("C:\\temp\\butta.txt");
Shinya Kitaoka 120a6e
  // os << args << endl;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // bisognerebbe calcolare le immagini dalla/e porta/e di input
Shinya Kitaoka 120a6e
  // scrivere il/i valore/i nei files temporanei/o
Shinya Kitaoka 120a6e
  // chiamare "m_executablePath args"
Shinya Kitaoka 120a6e
  // e leggere l'immagine scritta in outputTmpFile
Shinya Kitaoka 120a6e
  // poi cancellare tutto
Shinya Kitaoka 120a6e
  std::string expandedargs;
Shinya Kitaoka 120a6e
  char buffer[1024];
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  ExpandEnvironmentStrings(args.c_str(), buffer, 1024);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  STARTUPINFO si;
Shinya Kitaoka 120a6e
  PROCESS_INFORMATION pinfo;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  GetStartupInfo(&si);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  BOOL ret = CreateProcess(
Shinya Kitaoka 120a6e
      (char *)executablePath.c_str(),           // name of executable module
Shinya Kitaoka 120a6e
      buffer,                                   // command line string
Shinya Kitaoka 120a6e
      NULL,                                     // SD
Shinya Kitaoka 120a6e
      NULL,                                     // SD
Shinya Kitaoka 120a6e
      TRUE,                                     // handle inheritance option
Shinya Kitaoka 120a6e
      CREATE_NO_WINDOW, /*CREATE_NEW_CONSOLE*/  // creation flags
Shinya Kitaoka 120a6e
      NULL,                                     // new environment block
Shinya Kitaoka 120a6e
      NULL,                                     // current directory name
Shinya Kitaoka 120a6e
      &si,                                      // startup information
Shinya Kitaoka 120a6e
      &pinfo                                    // process information
Shinya Kitaoka 120a6e
      );
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!ret) DWORD err = GetLastError();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // aspetta che il processo termini
Shinya Kitaoka 120a6e
  WaitForSingleObject(pinfo.hProcess, INFINITE);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  DWORD exitCode;
Shinya Kitaoka 120a6e
  ret = GetExitCodeProcess(pinfo.hProcess,  // handle to the process
Shinya Kitaoka 120a6e
                           &exitCode);      // termination status
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  std::string cmdline = executablePath + buffer;
Shinya Kitaoka 120a6e
  //    int exitCode =
Shinya Kitaoka 120a6e
  system(cmdline.c_str());
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
string name = m_executablePath.getName();
Shinya Kitaoka 120a6e
TPixel32 color;
Shinya Kitaoka 120a6e
if(name == "saturate") color = TPixel32::Magenta;
Shinya Kitaoka 120a6e
else if(name == "over") color = TPixel32::Green;
Shinya Kitaoka 120a6e
else color = TPixel32::Red;
Shinya Kitaoka 120a6e
for(int iy=0;iy<ras->getLy();iy++)</ras->
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
TPixel32 *pix = ras->pixels(iy);
Shinya Kitaoka 120a6e
TPixel32 *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
double x = tile.m_pos.x;
Shinya Kitaoka 120a6e
double y = tile.m_pos.y + iy;
Shinya Kitaoka 120a6e
while(pix
Shinya Kitaoka 120a6e
 {
Shinya Kitaoka 120a6e
  if(x*x+y*y<900) *pix = color;
Shinya Kitaoka 120a6e
  else *pix = TPixel32(0,0,0,0);
Shinya Kitaoka 120a6e
  ++pix;
Shinya Kitaoka 120a6e
  x+=1.0;
Shinya Kitaoka 120a6e
 }
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    TRasterP ras = tile.getRaster();
Shinya Kitaoka 120a6e
    TImageReader::load(outputTmpFile, ras);
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // butto i file temporanei creati
Shinya Kitaoka 120a6e
  std::map<std::string, tfilepath="">::const_iterator fileIt;</std::string,>
Shinya Kitaoka 120a6e
  for (fileIt = tmpFiles.begin(); fileIt != tmpFiles.end(); ++fileIt) {
Shinya Kitaoka 120a6e
    if (TFileStatus(fileIt->second).doesExist() == true) try {
Shinya Kitaoka 120a6e
        TSystem::deleteFile(fileIt->second);
Shinya Kitaoka 120a6e
      } catch (...) {
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (TFileStatus(outputTmpFile).doesExist() == true) try {
Shinya Kitaoka 120a6e
      TSystem::deleteFile(outputTmpFile);
Shinya Kitaoka 120a6e
    } catch (...) {
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TExternalProgramFx::loadData(TIStream &is) {
Shinya Kitaoka 120a6e
  std::string tagName;
Shinya Kitaoka 120a6e
  while (is.openChild(tagName)) {
Shinya Kitaoka 120a6e
    if (tagName == "path") {
Shinya Kitaoka 120a6e
      is >> m_executablePath;
Shinya Kitaoka 120a6e
    } else if (tagName == "args") {
Shinya Kitaoka 120a6e
      is >> m_args;
Shinya Kitaoka 120a6e
    } else if (tagName == "name") {
Shinya Kitaoka 120a6e
      is >> m_externFxName;
Shinya Kitaoka 120a6e
      // initialize(m_externFxName);
Shinya Kitaoka 120a6e
    } else if (tagName == "params") {
Shinya Kitaoka 120a6e
      while (is.matchTag(tagName)) {
Shinya Kitaoka 120a6e
        if (tagName == "param") {
Shinya Kitaoka 120a6e
          // assert(0);
Shinya Kitaoka 120a6e
          std::string paramName = is.getTagAttribute("name");
Shinya Kitaoka 120a6e
          TDoubleParamP param   = new TDoubleParam();
Shinya Kitaoka 120a6e
          param->setName(paramName);
Shinya Kitaoka 120a6e
          m_params.push_back(param);
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          throw TException("unexpected tag " + tagName);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      for (int i = 0; i < (int)m_params.size(); i++)
Shinya Kitaoka 120a6e
        bindParam(this, m_params[i]->getName(), m_params[i]);
Shinya Kitaoka 120a6e
    } else if (tagName == "ports") {
Shinya Kitaoka 120a6e
      while (is.matchTag(tagName)) {
Shinya Kitaoka 120a6e
        if (tagName == "port") {
Shinya Kitaoka 120a6e
          std::string name = is.getTagAttribute("name");
Shinya Kitaoka 120a6e
          std::string ext  = is.getTagAttribute("ext");
Shinya Kitaoka 120a6e
          addPort(name, ext, true);
Shinya Kitaoka 120a6e
        } else if (tagName == "outport") {
Shinya Kitaoka 120a6e
          std::string name = is.getTagAttribute("name");
Shinya Kitaoka 120a6e
          std::string ext  = is.getTagAttribute("ext");
Shinya Kitaoka 120a6e
          addPort(name, ext, false);
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          throw TException("unexpected tag " + tagName);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (tagName == "super") {
Shinya Kitaoka 120a6e
      TExternFx::loadData(is);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      throw TException("unexpected tag " + tagName);
Shinya Kitaoka 120a6e
    is.closeChild();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TExternalProgramFx::saveData(TOStream &os) {
Shinya Kitaoka 120a6e
  os.child("name") << m_externFxName;
Shinya Kitaoka 120a6e
  os.child("path") << m_executablePath;
Shinya Kitaoka 120a6e
  os.child("args") << m_args;
Shinya Kitaoka 120a6e
  os.openChild("params");
Shinya Kitaoka 120a6e
  for (int i = 0; i < getParams()->getParamCount(); i++) {
Shinya Kitaoka 120a6e
    std::map<std::string, std::string=""> attr;</std::string,>
Shinya Kitaoka 120a6e
    attr["name"] = getParams()->getParamName(i);
Shinya Kitaoka 120a6e
    attr["type"] = "double";
Shinya Kitaoka 120a6e
    os.openCloseChild("param", attr);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  os.closeChild();
Shinya Kitaoka 120a6e
  os.openChild("ports");
Shinya Kitaoka 120a6e
  std::map<std::string, port="">::iterator portIt;</std::string,>
Shinya Kitaoka 120a6e
  for (portIt = m_ports.begin(); portIt != m_ports.end(); ++portIt) {
Shinya Kitaoka 120a6e
    std::map<std::string, std::string=""> attr;</std::string,>
Shinya Kitaoka 120a6e
    attr["name"]        = portIt->second.m_name;
Shinya Kitaoka 120a6e
    attr["ext"]         = portIt->second.m_ext;
Shinya Kitaoka 120a6e
    std::string tagName = portIt->second.m_port == 0 ? "outport" : "port";
Shinya Kitaoka 120a6e
    os.openCloseChild(tagName, attr);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  os.closeChild();
Shinya Kitaoka 120a6e
  os.openChild("super");
Shinya Kitaoka 120a6e
  TExternFx::saveData(os);
Shinya Kitaoka 120a6e
  os.closeChild();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef CICCIO
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ExternalProgramFx::doCompute(TTile &tile, double frame,
Shinya Kitaoka 120a6e
                                  const TRenderSettings &ri) {
Shinya Kitaoka 120a6e
  if (!m_input1.isConnected() || !m_input2.isConnected()) {
Shinya Kitaoka 120a6e
    tile.getRaster()->clear();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::string name1("C:\\temp\\uno..tif");
Shinya Kitaoka 120a6e
  std::string name2("C:\\temp\\due..tif");
Shinya Kitaoka 120a6e
  std::string outname("C:\\temp\\outfile.0001.jpg");
Shinya Kitaoka 120a6e
  std::string program("C:\\temp\\xdissolve.exe");
Shinya Kitaoka 120a6e
  std::string extension(".jpg");
Shinya Kitaoka 120a6e
  TFilePath programpath(program);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_input1->compute(tile, frame, ri);
Shinya Kitaoka 120a6e
  TFilePath fname1(name1);
Shinya Kitaoka 120a6e
  TFilePath fname2(name2);
Shinya Kitaoka 120a6e
  std::string tmp1 = fname1.getName() + extension;
Shinya Kitaoka 120a6e
  std::string tmp2 = fname2.getName() + extension;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePath tmpname1(fname1.getParentDir() + tmp1);
Shinya Kitaoka 120a6e
  TFilePath tmpname2(fname2.getParentDir() + tmp2);
Shinya Kitaoka 120a6e
  TFilePath out(outname);
Shinya Kitaoka 120a6e
  TImageWriter::save(tmpname1, tile.getRaster());
Shinya Kitaoka 120a6e
  m_input2->compute(tile, frame, ri);
Shinya Kitaoka 120a6e
  TImageWriter::save(tmpname2, tile.getRaster());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string arglist = " -range1 1 1 -start2 1 -startout 1 ";
Shinya Kitaoka 120a6e
  arglist += toString(tmpname1.getWideString());
Shinya Kitaoka 120a6e
  arglist += " " + toString(tmpname2.getWideString());
Shinya Kitaoka 120a6e
  arglist += " " + outname;
Shinya Kitaoka 120a6e
  std::string cmdline = program + arglist;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  STARTUPINFO si;
Shinya Kitaoka 120a6e
  PROCESS_INFORMATION pinfo;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  GetStartupInfo(&si);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  BOOL ret =
Shinya Kitaoka 120a6e
      CreateProcess(NULL,                     // name of executable module
Shinya Kitaoka 120a6e
                    (char *)cmdline.c_str(),  // command line string
Shinya Kitaoka 120a6e
                    NULL,                     // SD
Shinya Kitaoka 120a6e
                    NULL,                     // SD
Shinya Kitaoka 120a6e
                    TRUE,                     // handle inheritance option
Shinya Kitaoka 120a6e
                    CREATE_NO_WINDOW, /*CREATE_NEW_CONSOLE*/  // creation flags
Shinya Kitaoka 120a6e
                    NULL,   // new environment block
Shinya Kitaoka 120a6e
                    NULL,   // current directory name
Shinya Kitaoka 120a6e
                    &si,    // startup information
Shinya Kitaoka 120a6e
                    &pinfo  // process information
Shinya Kitaoka 120a6e
                    );
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!ret) DWORD err = GetLastError();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // aspetta che il processo termini
Shinya Kitaoka 120a6e
  WaitForSingleObject(pinfo.hProcess, INFINITE);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  DWORD exitCode;
Shinya Kitaoka 120a6e
  ret = GetExitCodeProcess(pinfo.hProcess,  // handle to the process
Shinya Kitaoka 120a6e
                           &exitCode);      // termination status
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  int exitCode = system(cmdline.c_str());
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  TImageReader::load(out, tile.getRaster());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TSystem::deleteFile(tmpname1);
Shinya Kitaoka 120a6e
  TSystem::deleteFile(tmpname2);
Shinya Kitaoka 120a6e
  TSystem::deleteFile(out);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(ExternalProgramFx, "externalProgramFx");
Toshihiro Shimizu 890ddd
* /
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    FX_IDENTIFIER(TExternalProgramFx, "externalProgramFx")