コード例 #1
0
ファイル: pix_freeframe.cpp プロジェクト: ch-nry/Gem
  bool initParameters_(void) {
    m_parameterNames.clear();
    m_parameter.clear();
    unsigned int count=getNumParameters_();
    unsigned int i;

    m_parameterNames.push_back(""); // dummy parameter
    for(i=0; i<count; i++) {
      std::string name=getParameterName_(i);
      FFUInt32 type = getParameterType_ (i);
      FFMixed def = getParameterDefault_(i);

      gem::any val;
      switch(type) {
      case FF_TYPE_EVENT:
        //?
        break;
      case FF_TYPE_TEXT:
        val = std::string(reinterpret_cast<const char*>(def.PointerValue));
        break;
      default:
        val = def.FloatValue;
      }
      std::cout << "param#"<<i<<": "<<name<<std::endl;
      m_parameterNames.push_back(name);
      m_parameter.set(name, val);
    }
    return true;
  }
コード例 #2
0
ファイル: imageBase.cpp プロジェクト: jptrkz/Gem
bool imageBase :: enumProperties(gem::Properties&readable,
                                 gem::Properties&writeable)
{
    readable.clear();
    writeable.clear();
    return false;
}
コード例 #3
0
ファイル: videoVLC.cpp プロジェクト: umlaeute/Gem
void videoVLC::setProperties(gem::Properties&props)
{
  int width=-1;
  int height=-1;

  m_props=props;

  double d;
  if(props.get("width", d)) {
    if(d>0) {
      width = d;
    }
  }
  if(props.get("height", d)) {
    if(d>0) {
      height=d;
    }
  }

  if(!m_mediaplayer) {
    if(width>0) {
      m_pixBlock.image.xsize=width;
    }
    if(height>0) {
      m_pixBlock.image.ysize=height;
    }
  } else {
    // changes will take effect with next restart
  }
}
コード例 #4
0
ファイル: pix_record.cpp プロジェクト: kmatheussen/libpd
  static void addProperties(gem::Properties&props, int argc, t_atom*argv)
  {
    if(!argc)return;
    
    if(argv->a_type != A_SYMBOL) {
      ::error("no key given...");
      return;
    }
    std::string key=std::string(atom_getsymbol(argv)->s_name);
    std::vector<gem::any> values;
    argc--; argv++;
    while(argc-->0) {
      values.push_back(atom2any(argv++));
    }
    switch(values.size()) {
    default:
      props.set(key, values);
      break;
    case 1:
      props.set(key, values[0]);
      break;
    case 0: 
      {
	gem::any dummy;
	props.set(key, dummy);
      }
      break;
    }
  }
コード例 #5
0
ファイル: videoUNICAP.cpp プロジェクト: Jackovic/Gem
bool videoUNICAP :: enumProperties(gem::Properties&readable,
                                   gem::Properties&writeable) {
  readable.clear();
  writeable.clear();

  if(m_handle) {
    int count=0;
    unicap_status_t status= unicap_reenumerate_properties(m_handle, &count );
    if(!SUCCESS(status))
      return false;

    int id=0;
    for(id=0; id<count; id++) {
      unicap_property_t prop;
      gem::any typ;

      status = unicap_enumerate_properties(m_handle, NULL, &prop, id);
      if(!SUCCESS(status))
        continue;

      debugPost("id='%s'\tcat='%s'\tunit='%s'\tflags=%d", 
                prop.identifier,
                prop.category,
                prop.unit,
                prop.flags);


      switch(prop.type) {
      case UNICAP_PROPERTY_TYPE_RANGE: 
        debugPost("range %f-%f", prop.range.min, prop.range.min);
        typ=prop.range.max; 
        break;
      case UNICAP_PROPERTY_TYPE_VALUE_LIST: 
        debugPost("value_list %d", prop.value_list.value_count);
        typ=prop.value_list.value_count;
        break;
      case UNICAP_PROPERTY_TYPE_MENU: 
        debugPost("menu '%s' of %d", prop.menu_item, prop.menu.menu_item_count);
        typ=std::string(prop.menu_item);//prop.menu.menu_item_count;
        break;
      case UNICAP_PROPERTY_TYPE_FLAGS: 
        debugPost("flags");
        break;
      default:
        debugPost("unknown");
        // ?
        break;
      }

      readable.set(prop.identifier, typ);
      if(!(prop.flags & UNICAP_FLAGS_READ_ONLY))
        writeable.set(prop.identifier, typ);

#warning check UNICAP_FLAGS_ON_OFF & UNICAP_FLAGS_ONE_PUSH
    }
  }
  return true;
}
コード例 #6
0
ファイル: imageBase.cpp プロジェクト: jptrkz/Gem
void imageBase :: getProperties(gem::Properties&props) {
    // nada
    std::vector<std::string>keys=props.keys();
    unsigned int i=0;
    for(i=0; i<keys.size(); i++) {
        gem::any unset;
        props.set(keys[i], unset);
    }
}
コード例 #7
0
ファイル: pix_freeframe.cpp プロジェクト: ch-nry/Gem
 void setParameters(gem::Properties&parms) {
   unsigned int i=0;
   for(i=0; i<m_parameterNames.size(); i++) {
     std::string key=m_parameterNames[i];
     std::string s1, s2;
     double d1, d2;
     switch(m_parameter.type(key)) {
     case gem::Properties::NONE:
       if(gem::Properties::NONE==parms.type(key)) {
         parms.erase(key);
         setParameter(i);
       }
       break;
     case gem::Properties::DOUBLE:
       if(m_parameter.get(key, d1) && parms.get(key, d2)) {
         if(d1!=d2) {
           m_parameter.set(key, d2);
           setParameter(i, d2);
         }
       }
       break;
     case gem::Properties::STRING:
       if(m_parameter.get(key, s1) && parms.get(key, s2)) {
         if(s1!=s2) {
           m_parameter.set(key, s2);
           setParameter(i, s2);
         }
       }
       break;
     default: break;
     }
   }
 }
コード例 #8
0
ファイル: imageMAGICK.cpp プロジェクト: rfabbri/Gem
void imageMAGICK::getWriteCapabilities(std::vector<std::string>&mimetypes, gem::Properties&props) {
    mimetypes.clear();
    props.clear();

    mimetypes = m_mimetypes;

    gem::any value;

    value=100.f;
    props.set("quality", value);
}
コード例 #9
0
ファイル: imageJPEG.cpp プロジェクト: Jackovic/Gem
void imageJPEG::getWriteCapabilities(std::vector<std::string>&mimetypes, gem::Properties&props) {
  mimetypes.clear();
  props.clear();

  mimetypes.push_back("image/jpeg");
  mimetypes.push_back("image/pjpeg");

  gem::any value;

  value=100.f;
  props.set("quality", value);
}
コード例 #10
0
ファイル: videoVFW.cpp プロジェクト: rfabbri/Gem
bool videoVFW :: enumProperties(gem::Properties&readable, gem::Properties&writeable) {
    readable.clear();
    writeable.clear();

    gem::any type=0;

    writeable.set("width", type);
    writeable.set("height", type);


    return true;
}
コード例 #11
0
ファイル: videoDECKLINK.cpp プロジェクト: umlaeute/Gem
void videoDECKLINK::getProperties(gem::Properties&props)
{
  std::vector<std::string>keys=props.keys();
  unsigned int i;
  for(i=0; i<keys.size(); i++) {
    if("width"==keys[i]) {
      props.set(keys[i], m_pixBlock.image.xsize);
    }
    if("height"==keys[i]) {
      props.set(keys[i], m_pixBlock.image.ysize);
    }
  }
}
コード例 #12
0
ファイル: modelASSIMP3.cpp プロジェクト: avilleret/Gem
void modelASSIMP3 :: setProperties(gem::Properties&props) {
  double d;

#if 0
  std::vector<std::string>keys=props.keys();
  unsigned int i;
  for(i=0; i<keys.size(); i++) {
    post("key[%d]=%s ... %d", i, keys[i].c_str(), props.type(keys[i]));
  }
#endif

  std::string s;
  if(props.get("textype", s)) {
    // if there are NO texcoords, we only accept 'linear' and 'spheremap'
    // else, we also allow 'UV'
    // not-accepted textype, simply use the last one
    if(m_have_texcoords && "UV" == s)
      m_textype = "";
    else
    if(("linear" == s) || ("spheremap" == s))
      m_textype = s;
    m_rebuild = true;
  }

  if(props.get("rescale", d)) {
    bool b=(bool)d;
    if(b) {
      float tmp;
      tmp = m_max.x-m_min.x;
      tmp = aisgl_max(m_max.y - m_min.y,tmp);
      tmp = aisgl_max(m_max.z - m_min.z,tmp);
      m_scale = 2.f / tmp;

      m_offset.x=-m_center.x;
      m_offset.y=-m_center.y;
      m_offset.z=-m_center.z;
    } else {
      // FIXXME shouldn't this be the default???
      m_scale=1.;
      m_offset.x=m_offset.y=m_offset.z=0.f;
    }
  }
  if(props.get("usematerials", d)) {
    bool useMaterial=d;
    if(useMaterial!=m_useMaterial)
      m_rebuild=true;
    m_useMaterial=useMaterial;
  }

  render();
}
コード例 #13
0
ファイル: imageQT.cpp プロジェクト: Jackovic/Gem
void imageQT::getWriteCapabilities(std::vector<std::string>&mimetypes, gem::Properties&props) {
  mimetypes.clear();
  props.clear();

  std::map<std::string, OSType>::iterator it;
  for(it = s_mime2type.begin(); it!=s_mime2type.end(); ++it) {
    mimetypes.push_back(it->first);
  }

  gem::any value;

  value=100.f;
  props.set("quality", value);
}
コード例 #14
0
ファイル: imageTIFF.cpp プロジェクト: Jackovic/Gem
float imageTIFF::estimateSave(const imageStruct&img, const std::string&filename, const std::string&mimetype, const gem::Properties&props) {
  float result=0;
  if(mimetype == "image/tiff" || mimetype == "image/x-tiff")
    result += 100;

  if(gem::Properties::UNSET != props.type("xresolution"))result+=1.;
  if(gem::Properties::UNSET != props.type("yresolution"))result+=1.;
  if(gem::Properties::UNSET != props.type("resolutionunit"))result+=1.;
  if(gem::Properties::UNSET != props.type("software"))result+=1.;
  if(gem::Properties::UNSET != props.type("artist"))result+=1.;
  if(gem::Properties::UNSET != props.type("hostcomputer"))result+=1.;

  return result;
}
コード例 #15
0
ファイル: filmTEST.cpp プロジェクト: Jackovic/Gem
void filmTEST::getProperties(gem::Properties&props) {
  std::vector<std::string> keys=props.keys();
  unsigned int i=0;
  for(i=0; i<keys.size(); i++) {
    std::string key=keys[i];
    props.erase(key);
#define SETPROP(k, v) } else if(k == key) { double d=(double)v; props.set(key, v)
    if(""==key) {
      SETPROP("fps", m_fps);
      SETPROP("frames", m_numFrames);
      SETPROP("width", m_image.image.xsize);
      SETPROP("height", m_image.image.ysize);
    }
  }
}
コード例 #16
0
ファイル: modelloader.cpp プロジェクト: avilleret/Gem
  virtual bool enumProperties(gem::Properties&readable,
                              gem::Properties&writeable) {
    // LATER: shouldn't we merge properties of all handles?
#ifdef __GNUC__
# warning enumProperties stub
#endif

    readable.clear();
    writeable.clear();

    if(m_handle)
      return m_handle->enumProperties(readable, writeable);

    return false;
  }
コード例 #17
0
ファイル: filmQT4L.cpp プロジェクト: umlaeute/Gem
void filmQT4L::setProperties(gem::Properties&props)
{
  double d;
  if(props.get("colorspace", d)) {
    m_wantedFormat=d;
  }
}
コード例 #18
0
ファイル: filmQT4L.cpp プロジェクト: umlaeute/Gem
/////////////////////////////////////////////////////////
// really open the file ! (OS dependent)
//
/////////////////////////////////////////////////////////
bool filmQT4L :: open(const std::string&filename,
                      const gem::Properties&wantProps)
{
  int wantedFormat=GEM_RGBA;
  double d;
  unsigned int format=0;
  if(wantProps.get("format", d)) {
    format=d;
  }
  switch(format) {
  default:
    break;
  case GEM_RGBA:
  case GEM_YUV:
  case GEM_GRAY:
    m_wantedFormat=format;
    break;
  }

  char*cfilename=const_cast<char*>(filename.c_str());
  if (quicktime_check_sig(cfilename)) { /* ok, this is quicktime */
    if (!(m_quickfile = quicktime_open(filename.c_str(), 1, 0))) {
      verbose(0, "[GEM:filmQT4L] Unable to open file: %s", filename.c_str());
      return false;
    }
    m_curFrame = -1;

    // Get the number of tracks
    m_numTracks = quicktime_video_tracks(m_quickfile);
    // Get the length of the movie (on track current track)
    m_numFrames = quicktime_video_length(m_quickfile, m_curTrack);
    // Get the frame-rate
    m_fps = quicktime_frame_rate(m_quickfile, m_curTrack);
    // Get the video dimensions
    m_image.image.xsize = quicktime_video_width (m_quickfile, m_curTrack);
    m_image.image.ysize = quicktime_video_height(m_quickfile, m_curTrack);
    if (!quicktime_supported_video(m_quickfile, m_curTrack)) {
      char *codec = quicktime_video_compressor(m_quickfile, m_curTrack);
      verbose(0, "[GEM:filmQT4L] unsupported CODEC '%s'!", codec);
      quicktime_close(m_quickfile);
      m_quickfile=0;
      return false;
    }
    m_image.image.setCsizeByFormat(wantedFormat);
    m_image.image.reallocate();

    m_qtimage.xsize=m_image.image.xsize;
    m_qtimage.ysize=m_image.image.ysize;
    m_qtimage.setCsizeByFormat(GEM_RGB);
    m_qtimage.reallocate();

    m_newfilm = true;
    return true;
  }
  goto unsupported;
unsupported:
  close();
  return false;
}
コード例 #19
0
ファイル: videoVFW.cpp プロジェクト: rfabbri/Gem
void videoVFW :: setProperties(gem::Properties&props) {
    double d;
    bool dorestart=false;

    if (props.get("width", d)) {
        m_width=d;
        dorestart=true;
    }

    if (props.get("height", d)) {
        m_height=d;
        dorestart=true;
    }

    if(dorestart && m_hWndC)
        reset();
}
コード例 #20
0
ファイル: filmQT4L.cpp プロジェクト: Jackovic/Gem
void filmQT4L::getProperties(gem::Properties&props) {
  std::vector<std::string> keys=props.keys();
  gem::any value;
  double d;
  unsigned int i=0;
  for(i=0; i<keys.size(); i++) {
    std::string key=keys[i];
    props.erase(key);
    if("fps"==key) {
      d=m_fps;
      value=d; props.set(key, value);
    }
    if("frames"==key) {
      d=m_numFrames;
      value=d; props.set(key, value);
    }
    if("tracks"==key) {
      d=m_numTracks;
      value=d; props.set(key, value);
    }
    if("width"==key) {
      d=m_image.image.xsize;
      value=d; props.set(key, value);
    }
    if("height"==key) {
      d=m_image.image.ysize;
      value=d; props.set(key, value);
    }
  }
}
コード例 #21
0
ファイル: modelloader.cpp プロジェクト: avilleret/Gem
  virtual void getProperties(gem::Properties&props) {
    std::vector<std::string> ids;
    if(props.type("backends")!=gem::Properties::UNSET) {
      unsigned int i;
      for(i=0; i<m_ids.size(); i++) {
        ids.push_back(m_ids[i]);
      }
    }
    props.erase("backends");

    if(m_handle)
      m_handle->getProperties(props);
    else
      props.clear();

    if(!ids.empty()) {
      props.set("backends", ids);
    }
  }
コード例 #22
0
ファイル: MagickPlusPlus.cpp プロジェクト: Jackovic/Gem
bool imageMAGICK::save(const imageStruct&image, const std::string&filename, const std::string&mimetype, const gem::Properties&props) {
  imageStruct*img=const_cast<imageStruct*>(&image);
  imageStruct*pImage=img;

  std::string cs;
  switch(img->format) {
  case GL_LUMINANCE:
    cs="K";
    break;
  case GL_RGBA:
    cs="RGBA";
    break;
  default:
    pImage=new imageStruct();
    pImage->convertFrom(img, GL_RGB);
  case GL_RGB:
    cs="RGB";
    break;
  case GL_BGRA_EXT:
    cs="BGRA";
    break;
  }
  try{
    Magick::Image mimage(pImage->xsize, pImage->ysize, cs, Magick::CharPixel, pImage->data);
    // since openGL is upside down
    if(!pImage->upsidedown) {
      mimage.flip();
    }
    // 8 bits per channel are enough!
    // LATER make this dependent on the image->type
    mimage.depth(8);
    double quality;
    if(props.get("quality", quality)) {
      mimage.quality(quality);
    }

    try {
      // finally convert and export
      mimage.write(filename);
    } catch (Magick::Warning e) {
      verbose(1, "magick saving problem: %s", e.what());
    }

  } catch (Magick::Exception e){
    error("%s", e.what());
    if(pImage!=&image)delete pImage; pImage=NULL;
    return false;
  } catch (...) {
      error("imageMAGICK:: uncaught exception!");
      return false;
  }
  if(pImage!=&image)delete pImage; pImage=NULL;
  return true;
}
コード例 #23
0
ファイル: imageJPEG.cpp プロジェクト: Jackovic/Gem
float imageJPEG::estimateSave(const imageStruct&img, const std::string&filename, const std::string&mimetype, const gem::Properties&props) {
  float result=0.;
  if(mimetype == "image/jpeg")// || mimetype == "image/pjpeg")
    result += 100.;

  // LATER check some properties....
  if(gem::Properties::UNSET != props.type("quality"))
    result += 1.;

  return result;
}
コード例 #24
0
ファイル: imageBase.cpp プロジェクト: jptrkz/Gem
void imageBase :: setProperties(gem::Properties&props) {
    // nada
    m_properties=props;
#if 0
    std::vector<std::string> keys=props.keys();
    int i=0;
    for(i=0; i<keys.size(); i++) {
        enum gem::Properties::PropertyType typ=props.type(keys[i]);
        std::cerr  << "key["<<keys[i]<<"]: "<<typ<<" :: ";
        switch(typ) {
        case (gem::Properties::NONE):
            props.erase(keys[i]);
            break;
        case (gem::Properties::DOUBLE):
            std::cerr << gem::any_cast<double>(props.get(keys[i]));
            break;
        case (gem::Properties::STRING):
            std::cerr << "'" << gem::any_cast<std::string>(props.get(keys[i])) << "'";
            break;
        default:
            std::cerr << "<unknown:" << props.get(keys[i]).get_type().name() << ">";
            break;
        }
    }
    std::cerr << std::endl;
#endif
}
コード例 #25
0
ファイル: modelloader.cpp プロジェクト: avilleret/Gem
  virtual bool open(const std::string&name, const gem::Properties&requestprops) {
    if(m_handle)close();

    std::vector<std::string> backends;
    if(requestprops.type("backends")!=gem::Properties::UNSET) {
      requestprops.get("backends", backends);
    }
    //      requestprops.erase("backends");

    bool tried=false;
    if(!backends.empty()) {
      unsigned int i, j;
      for(j=0; !m_handle && j<backends.size(); j++) {
        std::string id=backends[j];

        for(i=0; i<m_handles.size(); i++) {
	    /* coverity[assign_where_compare_meant] we set 'tried' to true if we have found at least one matching backend */
          if(id==m_ids[i]&& (tried=true) && m_handles[i]->open(name, requestprops)) {
            m_handle=m_handles[i];
          }
        }
      }
    }
    if(!m_handle && !tried) {
      if(!backends.empty() && !m_handles.empty()) {
        verbose(2, "no available loader selected, falling back to valid ones");
      }
      unsigned int i=0;
      for(i=0; i<m_handles.size(); i++) {
        if(m_handles[i] && m_handles[i]->open(name, requestprops)) {
          m_handle=m_handles[i];
          break;
        } else {

        }
      }
    }
    return (NULL!=m_handle);
  }
コード例 #26
0
ファイル: imageQT.cpp プロジェクト: Jackovic/Gem
float imageQT::estimateSave(const imageStruct&img, const std::string&filename, const std::string&mimetype, const gem::Properties&props) {
  float result=0.;

  OSType			filetype; // just a dummy
  if(mime2type(mimetype, filetype))
    result+=100.;

  // LATER check some properties....
  if(gem::Properties::UNSET != props.type("quality"))
    result += 1.;

  return result;
}
コード例 #27
0
ファイル: videoTEST.cpp プロジェクト: rfabbri/Gem
bool videoTEST::enumProperties(gem::Properties&readable,
			       gem::Properties&writeable) {
  readable.clear();
  writeable.clear();


  writeable.set("width", 64);  readable.set("width", 64);
  writeable.set("height", 64); readable.set("height", 64);

  writeable.set("type", std::string("noise"));
  return true;
}
コード例 #28
0
ファイル: videoOptiTrack.cpp プロジェクト: megrimm/Gem
void videoOptiTrack::getProperties(gem::Properties&props)
{
  std::vector<std::string>keys=props.keys();
  double d;
  std::string s;

  props.clear();
  if(!m_camera) {
    return;
  }

  unsigned int i;
  for(i=0; i<keys.size(); i++) {
    const std::string key=keys[i];
    if("width"==key) {
      props.set(key, m_pixBlock.image.xsize);
      continue;
    }
    if("height"==key) {
      props.set(key, m_pixBlock.image.ysize);
      continue;
    }
    if("fanspeed"==key && m_camera->IsCameraFanSpeedValid()) {
      d=m_camera->CameraFanSpeed();
      props.set(key, d);
      continue;
    }
    if("temperature"==key && m_camera->IsCameraTempValid()) {
      d=m_camera->CameraTemp();
      props.set(key, d);
      continue;
    }

#define GETCAMERAPROP_BOOL(name) if(#name == key) {d=m_camera->##name(); props.set(key, d); continue; } else d=0
#define GETCAMERAPROP_INT(name)  if(#name == key) {d=m_camera->##name(); props.set(key, d); continue; } else d=0
#define GETCAMERAPROP_STR(name)  if(#name == key) {s=m_camera->##name(); props.set(key, s); continue; } else d=0
    GETCAMERAPROP_BOOL(AEC);
    GETCAMERAPROP_BOOL(AGC);
    GETCAMERAPROP_BOOL(ContinuousIR);
    GETCAMERAPROP_BOOL(HighPowerMode);
    GETCAMERAPROP_BOOL(IRFilter);
    GETCAMERAPROP_BOOL(MarkerOverlay);
    GETCAMERAPROP_BOOL(TextOverlay);
    GETCAMERAPROP_INT(Exposure);
    GETCAMERAPROP_INT(FrameDecimation);
    GETCAMERAPROP_INT(FrameRate);
    GETCAMERAPROP_INT(GrayscaleDecimation);
    GETCAMERAPROP_INT(Intensity);
    GETCAMERAPROP_INT(PrecisionCap);
    GETCAMERAPROP_INT(ShutterDelay);
    GETCAMERAPROP_INT(Threshold);
    GETCAMERAPROP_STR(Name);
#undef GETCAMERAPROP_BOOL
#undef GETCAMERAPROP_INT
#undef GETCAMERAPROP_STR
  }
}
コード例 #29
0
ファイル: imagesaver.cpp プロジェクト: avilleret/Gem
    virtual void getWriteCapabilities(std::vector<std::string>&mimetypes, gem::Properties&props) {
      mimetypes.clear();
      props.clear();

      unsigned int i;
      for(i=0; i<m_savers.size(); i++) {
	unsigned int j;

	std::vector<std::string>mimetypes_;
	gem::Properties props_;
	m_savers[i]->getWriteCapabilities(mimetypes_, props_);

	for(j=0; j<mimetypes_.size(); j++) {
	  const std::string&mimetype=mimetypes_[j];
	  if(std::find(mimetypes.begin(), mimetypes.end(), mimetype)==mimetypes.end()) {
	    mimetypes.push_back(mimetypes_[j]);
	  }
	}
	std::vector<std::string>keys=props_.keys();
	for(j=0; j<keys.size(); j++) {
	  props.set(keys[j], props_.get(keys[j]));
	}
      }
    }
コード例 #30
0
ファイル: imageMAGICK.cpp プロジェクト: rfabbri/Gem
float imageMAGICK::estimateSave(const imageStruct&image, const std::string&filename, const std::string&mimetype, const gem::Properties&props) {
    float result=0.5; // slightly preference for MAGICK
    int i;
    for(i=0; i<m_mimetypes.size(); i++) {
        if(mimetype==m_mimetypes[i]) {
            result+=100.;
            break;
        }
    }

    if(gem::Properties::UNSET != props.type("quality"))
        result += 1.;

    return result;
}