コード例 #1
0
ファイル: wsgi.cpp プロジェクト: AndreLouisCaron/cxxpy
 py::Object next ( py::Object self )
 {
     const py::Object line = readline(self);
     if (line.handle() == py::none.handle()) {
         return (py::Object());
     }
     return (line);
 }
コード例 #2
0
ファイル: CallTips.cpp プロジェクト: AllenBootung/FreeCAD
void CallTipsList::extractTipsFromObject(Py::Object& obj, Py::List& list, QMap<QString, CallTip>& tips) const
{
    try {
        for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
            Py::String attrname(*it);
            Py::Object attr = obj.getAttr(attrname.as_string());

            CallTip tip;
            QString str = QString::fromLatin1(attrname.as_string().c_str());
            tip.name = str;

            if (attr.isCallable()) {
                union PyType_Object basetype = {&PyBaseObject_Type};
                if (PyObject_IsSubclass(attr.ptr(), basetype.o) == 1) {
                    tip.type = CallTip::Class;
                }
                else {
                    PyErr_Clear(); // PyObject_IsSubclass might set an exception
                    tip.type = CallTip::Method;
                }
            }
            else if (PyModule_Check(attr.ptr())) {
                tip.type = CallTip::Module;
            }
            else {
                tip.type = CallTip::Member;
            }

            if (str == QLatin1String("__doc__") && attr.isString()) {
                Py::Object help = attr;
                if (help.isString()) {
                    Py::String doc(help);
                    QString longdoc = QString::fromUtf8(doc.as_string().c_str());
                    int pos = longdoc.indexOf(QLatin1Char('\n'));
                    pos = qMin(pos, 70);
                    if (pos < 0) 
                        pos = qMin(longdoc.length(), 70);
                    tip.description = stripWhiteSpace(longdoc);
                    tip.parameter = longdoc.left(pos);
                }
            }
            else if (attr.hasAttr("__doc__")) {
                Py::Object help = attr.getAttr("__doc__");
                if (help.isString()) {
                    Py::String doc(help);
                    QString longdoc = QString::fromUtf8(doc.as_string().c_str());
                    int pos = longdoc.indexOf(QLatin1Char('\n'));
                    pos = qMin(pos, 70);
                    if (pos < 0) 
                        pos = qMin(longdoc.length(), 70);
                    tip.description = stripWhiteSpace(longdoc);
                    tip.parameter = longdoc.left(pos);
                }
            }
            tips[str] = tip;
        }
    }
    catch (Py::Exception& e) {
        // Just clear the Python exception
        e.clear();
    }
}
コード例 #3
0
ファイル: CallTips.cpp プロジェクト: AllenBootung/FreeCAD
QMap<QString, CallTip> CallTipsList::extractTips(const QString& context) const
{
    Base::PyGILStateLocker lock;
    QMap<QString, CallTip> tips;
    if (context.isEmpty())
        return tips;

    try {
        Py::Module module("__main__");
        Py::Dict dict = module.getDict();
#if 0
        QStringList items = context.split(QLatin1Char('.'));
        QString modname = items.front();
        items.pop_front();
        if (!dict.hasKey(std::string(modname.toLatin1())))
            return tips; // unknown object

        // get the Python object we need
        Py::Object obj = dict.getItem(std::string(modname.toLatin1()));
        while (!items.isEmpty()) {
            QByteArray name = items.front().toLatin1();
            std::string attr = name.constData();
            items.pop_front();
            if (obj.hasAttr(attr))
                obj = obj.getAttr(attr);
            else
                return tips;
        }
#else
        // Don't use hasattr & getattr because if a property is bound to a method this will be executed twice.
        PyObject* code = Py_CompileString(static_cast<const char*>(context.toLatin1()), "<CallTipsList>", Py_eval_input);
        if (!code) {
            PyErr_Clear();
            return tips;
        }

        PyObject* eval = 0;
        if (PyCode_Check(code)) {
            eval = PyEval_EvalCode(reinterpret_cast<PyCodeObject*>(code), dict.ptr(), dict.ptr());
        }
        Py_DECREF(code);
        if (!eval) {
            PyErr_Clear();
            return tips;
        }
        Py::Object obj(eval, true);
#endif

        // Checks whether the type is a subclass of PyObjectBase because to get the doc string
        // of a member we must get it by its type instead of its instance otherwise we get the
        // wrong string, namely that of the type of the member. 
        // Note: 3rd party libraries may use their own type object classes so that we cannot 
        // reliably use Py::Type. To be on the safe side we should use Py::Object to assign
        // the used type object to.
        //Py::Object type = obj.type();
        Py::Object type(PyObject_Type(obj.ptr()), true);
        Py::Object inst = obj; // the object instance 
        union PyType_Object typeobj = {&Base::PyObjectBase::Type};
        union PyType_Object typedoc = {&App::DocumentObjectPy::Type};
        union PyType_Object basetype = {&PyBaseObject_Type};

        if (PyObject_IsSubclass(type.ptr(), typedoc.o) == 1) {
            // From the template Python object we don't query its type object because there we keep
            // a list of additional methods that we won't see otherwise. But to get the correct doc
            // strings we query the type's dict in the class itself.
            // To see if we have a template Python object we check for the existence of supportedProperties
            if (!type.hasAttr("supportedProperties")) {
                obj = type;
            }
        }
        else if (PyObject_IsSubclass(type.ptr(), typeobj.o) == 1) {
            obj = type;
        }
        else if (PyInstance_Check(obj.ptr())) {
            // instances of old style classes
            PyInstanceObject* inst = reinterpret_cast<PyInstanceObject*>(obj.ptr());
            PyObject* classobj = reinterpret_cast<PyObject*>(inst->in_class);
            obj = Py::Object(classobj);
        }
        else if (PyObject_IsInstance(obj.ptr(), basetype.o) == 1) {
            // New style class which can be a module, type, list, tuple, int, float, ...
            // Make sure it's not a type objec
            union PyType_Object typetype = {&PyType_Type};
            if (PyObject_IsInstance(obj.ptr(), typetype.o) != 1) {
                // this should be now a user-defined Python class
                // http://stackoverflow.com/questions/12233103/in-python-at-runtime-determine-if-an-object-is-a-class-old-and-new-type-instan
                if (Py_TYPE(obj.ptr())->tp_flags & Py_TPFLAGS_HEAPTYPE) {
                    obj = type;
                }
            }
        }

        // If we have an instance of PyObjectBase then determine whether it's valid or not
        if (PyObject_IsInstance(inst.ptr(), typeobj.o) == 1) {
            Base::PyObjectBase* baseobj = static_cast<Base::PyObjectBase*>(inst.ptr());
            const_cast<CallTipsList*>(this)->validObject = baseobj->isValid();
        }
        else {
            // PyObject_IsInstance might set an exception
            PyErr_Clear();
        }

        Py::List list(obj.dir());

        // If we derive from PropertyContainerPy we can search for the properties in the
        // C++ twin class.
        union PyType_Object proptypeobj = {&App::PropertyContainerPy::Type};
        if (PyObject_IsSubclass(type.ptr(), proptypeobj.o) == 1) {
            // These are the attributes of the instance itself which are NOT accessible by
            // its type object
            extractTipsFromProperties(inst, tips);
        }

        // If we derive from App::DocumentPy we have direct access to the objects by their internal
        // names. So, we add these names to the list, too.
        union PyType_Object appdoctypeobj = {&App::DocumentPy::Type};
        if (PyObject_IsSubclass(type.ptr(), appdoctypeobj.o) == 1) {
            App::DocumentPy* docpy = (App::DocumentPy*)(inst.ptr());
            App::Document* document = docpy->getDocumentPtr();
            // Make sure that the C++ object is alive
            if (document) {
                std::vector<App::DocumentObject*> objects = document->getObjects();
                Py::List list;
                for (std::vector<App::DocumentObject*>::iterator it = objects.begin(); it != objects.end(); ++it)
                    list.append(Py::String((*it)->getNameInDocument()));
                extractTipsFromObject(inst, list, tips);
            }
        }

        // If we derive from Gui::DocumentPy we have direct access to the objects by their internal
        // names. So, we add these names to the list, too.
        union PyType_Object guidoctypeobj = {&Gui::DocumentPy::Type};
        if (PyObject_IsSubclass(type.ptr(), guidoctypeobj.o) == 1) {
            Gui::DocumentPy* docpy = (Gui::DocumentPy*)(inst.ptr());
            if (docpy->getDocumentPtr()) {
                App::Document* document = docpy->getDocumentPtr()->getDocument();
                // Make sure that the C++ object is alive
                if (document) {
                    std::vector<App::DocumentObject*> objects = document->getObjects();
                    Py::List list;
                    for (std::vector<App::DocumentObject*>::iterator it = objects.begin(); it != objects.end(); ++it)
                        list.append(Py::String((*it)->getNameInDocument()));
                    extractTipsFromObject(inst, list, tips);
                }
            }
        }

        // These are the attributes from the type object
        extractTipsFromObject(obj, list, tips);
    }
    catch (Py::Exception& e) {
        // Just clear the Python exception
        e.clear();
    }

    return tips;
}
コード例 #4
0
Py::Object
RendererAgg::draw_lines(const Py::Tuple& args) {
  
  theRasterizer->reset_clipping();
  _VERBOSE("RendererAgg::draw_lines");
  args.verify_length(3);  
  Py::Object gc = args[0];
  Py::SeqBase<Py::Object> x = args[1];  //todo: use numerix for efficiency
  Py::SeqBase<Py::Object> y = args[2];  //todo: use numerix for efficiency
  
  set_clip_rectangle(gc);
  size_t Nx = x.length();
  size_t Ny = y.length();
  
  if (Nx!=Ny) 
    throw Py::ValueError("x and y must be equal length sequences");
  
  
  if (Nx<2) 
    throw Py::ValueError("x and y must have length >= 2");
  
  
  agg::vcgen_stroke::line_cap_e cap = get_linecap(gc);
  agg::vcgen_stroke::line_join_e join = get_joinstyle(gc);
  
  
  double lw = points_to_pixels ( gc.getAttr("_linewidth") ) ;
  //std::cout << "agg lw " << lw << std::endl;
  agg::rgba color = get_color(gc);
  
  
  // process the dashes
  Py::Tuple dashes = get_dashes(gc);
  
  bool useDashes = dashes[0].ptr() != Py_None;
  double offset = 0;
  Py::SeqBase<Py::Object> dashSeq;
  
  if ( dashes[0].ptr() != Py_None ) { // use dashes
    //TODO: use offset
    offset = points_to_pixels_snapto(dashes[0]);
    dashSeq = dashes[1]; 
  };
  
  
  agg::path_storage path;
  
  int isaa = antialiased(gc);

  double heightd = double(height);
  if (Nx==2) { 
    // this is a little hack - len(2) lines are probably grid and
    // ticks so I'm going to snap to pixel
    //printf("snapto %d\n", Nx);
    double x0 = Py::Float(x[0]);
    double y0 = Py::Float(y[0]);
    double x1 = Py::Float(x[1]);
    double y1 = Py::Float(y[1]);
    
    if (x0==x1) {
      x0 = (int)x0 + 0.5;
      x1 = (int)x1 + 0.5;
    }

    if (y0==y1) {
      y0 = (int)y0 + 0.5;
      y1 = (int)y1 + 0.5;
    }

    y0 = heightd-y0;
    y1 = heightd-y1;

    path.move_to(x0, y0);
    path.line_to(x1, y1);
    
  }
  else {
    double thisX = Py::Float( x[0] );
    double thisY = Py::Float( y[0] );
    thisY = heightd - thisY; //flipy
    path.move_to(thisX, thisY);
    for (size_t i=1; i<Nx; ++i) {
      thisX = Py::Float( x[i] );
      thisY = Py::Float( y[i] );
      thisY = heightd - thisY;  //flipy
      //if ((i<10) || i>=19990)
      //std::cout << i << " " << Nx << " " << thisX << " " << thisY << std::endl;
      path.line_to(thisX, thisY);
    }
  }  
  
  //std::cout << width << " " << height << std::endl;
  if (! useDashes ) {
    
    agg::conv_stroke<agg::path_storage> stroke(path);
    stroke.line_cap(cap);
    stroke.line_join(join);
    stroke.width(lw);
    //freeze was here std::cout << "\t adding path!" << std::endl;         
    theRasterizer->add_path(stroke);
  }
  else {
    // set the dashes //TODO: scale for DPI
    
    size_t N = dashSeq.length();
    if (N%2 != 0  ) 
      throw Py::ValueError("dashes must be an even length sequence");     
    
    typedef agg::conv_dash<agg::path_storage> dash_t;
    dash_t dash(path);
    
    double on, off;
    
    for (size_t i=0; i<N/2; i+=1) {
      on = points_to_pixels_snapto(dashSeq[2*i]);
      off = points_to_pixels_snapto(dashSeq[2*i+1]);
      dash.add_dash(on, off);
    }
    agg::conv_stroke<dash_t> stroke(dash);
    stroke.line_cap(cap);
    stroke.line_join(join);
    stroke.width(lw);
    theRasterizer->add_path(stroke);
    
  }
  
  if ( isaa ) {
    rendererAA->color(color);    
    agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA); 
  }
  else {
    rendererBin->color(color);     
    agg::render_scanlines(*theRasterizer, *slineBin, *rendererBin); 
  }
  
  return Py::Object();
  
}
コード例 #5
0
Py::Object
_image_module::fromarray(const Py::Tuple& args) {
  _VERBOSE("_image_module::fromarray");
  
  args.verify_length(2);
  
  Py::Object x = args[0];
  int isoutput = Py::Int(args[1]);
  PyArrayObject *A = (PyArrayObject *) PyArray_ContiguousFromObject(x.ptr(), PyArray_DOUBLE, 2, 3); 
  
  if (A==NULL) 
    throw Py::ValueError("Array must be rank 2 or 3 of doubles"); 
  
  
  Image* imo = new Image;
  
  imo->rowsIn  = A->dimensions[0];
  imo->colsIn  = A->dimensions[1];
  
  
  size_t NUMBYTES(imo->colsIn * imo->rowsIn * imo->BPP);
  agg::int8u *buffer = new agg::int8u[NUMBYTES];  
  if (buffer==NULL) //todo: also handle allocation throw
    throw Py::MemoryError("_image_module::fromarray could not allocate memory");
  
  imo->bufferIn = buffer;
  imo->rbufIn = new agg::rendering_buffer;
  imo->rbufIn->attach(buffer, imo->colsIn, imo->rowsIn, imo->colsIn*imo->BPP);
  
  
  if   (A->nd == 2) { //assume luminance for now; 
    
    agg::int8u gray;
    int start = 0;    
    for (size_t rownum=0; rownum<imo->rowsIn; rownum++) 
      for (size_t colnum=0; colnum<imo->colsIn; colnum++) {
	
	double val = *(double *)(A->data + rownum*A->strides[0] + colnum*A->strides[1]);
	
	gray = int(255 * val);
	*(buffer+start++) = gray;       // red
	*(buffer+start++) = gray;       // green
	*(buffer+start++) = gray;       // blue
	*(buffer+start++)   = 255;        // alpha
      }
    
  }
  else if   (A->nd == 3) { // assume RGB
    
    if (A->dimensions[2] != 3 && A->dimensions[2] != 4 ) {
      Py_XDECREF(A);  
      throw Py::ValueError(Printf("3rd dimension must be length 3 (RGB) or 4 (RGBA); found %d", A->dimensions[2]).str()); 
      
    }
    
    int rgba = A->dimensions[2]==4;
    
    int start = 0;    
    double r,g,b,alpha;
    int offset =0;
    
    for (size_t rownum=0; rownum<imo->rowsIn; rownum++) 
      for (size_t colnum=0; colnum<imo->colsIn; colnum++) {
	offset = rownum*A->strides[0] + colnum*A->strides[1];
	r = *(double *)(A->data + offset);
	g = *(double *)(A->data + offset + A->strides[2] );
	b = *(double *)(A->data + offset + 2*A->strides[2] );
 	
	if (rgba) 
	  alpha = *(double *)(A->data + offset + 3*A->strides[2] );
	else
	  alpha = 1.0;
	
	*(buffer+start++) = int(255*r);         // red
	*(buffer+start++) = int(255*g);         // green
	*(buffer+start++) = int(255*b);         // blue
	*(buffer+start++) = int(255*alpha);     // alpha
	
      }
  } 
  else   { // error
    Py_XDECREF(A);  
    throw Py::ValueError("Illegal array rank; must be rank; must 2 or 3"); 
  }
  Py_XDECREF(A);  
  
  if (isoutput) {
    // make the output buffer point to the input buffer
    
    imo->rowsOut  = imo->rowsIn;
    imo->colsOut  = imo->colsIn;
    
    imo->bufferOut = new agg::int8u[NUMBYTES];  
    if (buffer == imo->bufferOut) //todo: also handle allocation throw
      throw Py::MemoryError("_image_module::fromarray could not allocate memory");
    
    imo->rbufOut = new agg::rendering_buffer;
    imo->rbufOut->attach(imo->bufferOut, imo->colsOut, imo->rowsOut, imo->colsOut * imo->BPP);
    
    for (size_t i=0; i<NUMBYTES; i++)
      *(imo->bufferOut +i) = *(imo->bufferIn +i);
  }
  return Py::asObject( imo );
}
コード例 #6
0
ファイル: pythonobject.cpp プロジェクト: 0xd34df00d/Qross
PythonObject::PythonObject(const Py::Object& object)
    : Qross::Object()
    , d(new Private(object))
{
    #ifdef QROSS_PYTHON_FUNCTION_DEBUG
        qrossdebug( QString("PythonObject::PythonObject() constructor") );
    #endif

    Py::List x( object.dir() );
    for(Py::Sequence::iterator i= x.begin(); i != x.end(); ++i) {
        std::string s = (*i).str();
        if(s == "__init__")
            continue;

        //if(! m_pyobject.hasAttr( (*i).str() )) continue;
        Py::Object o = d->m_pyobject.getAttr(s);

        #ifdef QROSS_PYTHON_FUNCTION_DEBUG
            QString t;
            if(o.isCallable()) t += "isCallable ";
            if(o.isDict()) t += "isDict ";
            if(o.isList()) t += "isList ";
            if(o.isMapping()) t += "isMapping ";
            if(o.isNumeric()) t += "isNumeric ";
            if(o.isSequence()) t += "isSequence ";
            if(o.isTrue()) t += "isTrue ";
            if(o.isInstance()) t += "isInstance ";
            qrossdebug( QString("PythonObject::PythonObject() method '%1' (%2)").arg( (*i).str().as_string().c_str() ).arg(t) );
        #endif

        if(o.isCallable())
            d->m_calls.append( (*i).str().as_string().c_str() );
    }
}
コード例 #7
0
TaskWatcherPython::TaskWatcherPython(const Py::Object& o)
  : TaskWatcher(0), watcher(o)
{
    QString title;
    if (watcher.hasAttr(std::string("title"))) {
        Py::String name(watcher.getAttr(std::string("title")));
        std::string s = (std::string)name;
        title = QString::fromUtf8(s.c_str());
    }

    QPixmap icon;
    if (watcher.hasAttr(std::string("icon"))) {
        Py::String name(watcher.getAttr(std::string("icon")));
        std::string s = (std::string)name;
        icon = BitmapFactory().pixmap(s.c_str());
    }

    Gui::TaskView::TaskBox *tb = 0;
    if (watcher.hasAttr(std::string("commands"))) {
        if (!tb) tb = new Gui::TaskView::TaskBox(icon, title, true, 0);
        Py::List cmds(watcher.getAttr(std::string("commands")));
        CommandManager &mgr = Gui::Application::Instance->commandManager();
        for (Py::List::iterator it = cmds.begin(); it != cmds.end(); ++it) {
            Py::String name(*it);
            std::string s = (std::string)name;
            Command *c = mgr.getCommandByName(s.c_str());
            if (c)
                c->addTo(tb);
        }
    }

    if (watcher.hasAttr(std::string("widgets"))) {
        if (!tb && !title.isEmpty())
            tb = new Gui::TaskView::TaskBox(icon, title, true, 0);
        Py::List list(watcher.getAttr(std::string("widgets")));
        Py::Module mainmod(PyImport_AddModule((char*)"sip"));
        Py::Callable func = mainmod.getDict().getItem("unwrapinstance");
        for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
            Py::Tuple arguments(1);
            arguments[0] = *it; //PyQt pointer
            Py::Object result = func.apply(arguments);
            void* ptr = PyLong_AsVoidPtr(result.ptr());
            QObject* object = reinterpret_cast<QObject*>(ptr);
            if (object) {
                QWidget* w = qobject_cast<QWidget*>(object);
                if (w) {
                    if (tb)
                        tb->groupLayout()->addWidget(w);
                    else
                        Content.push_back(w);
                }
            }
        }
    }

    if (tb) Content.push_back(tb);

    if (watcher.hasAttr(std::string("filter"))) {
        Py::String name(watcher.getAttr(std::string("filter")));
        std::string s = (std::string)name;
        this->setFilter(s.c_str());
    }
}
コード例 #8
0
ファイル: CallTips.cpp プロジェクト: 5263/FreeCAD
QMap<QString, CallTip> CallTipsList::extractTips(const QString& context) const
{
    Base::PyGILStateLocker lock;
    QMap<QString, CallTip> tips;
    if (context.isEmpty())
        return tips;

    try {
        QStringList items = context.split(QLatin1Char('.'));
        Py::Module module("__main__");
        Py::Dict dict = module.getDict();
        QString modname = items.front();
        items.pop_front();
        if (!dict.hasKey(std::string(modname.toAscii())))
            return tips; // unknown object

        // get the Python object we need
        Py::Object obj = dict.getItem(std::string(modname.toAscii()));
        while (!items.isEmpty()) {
            QByteArray name = items.front().toAscii();
            std::string attr = name.constData();
            items.pop_front();
            if (obj.hasAttr(attr))
                obj = obj.getAttr(attr);
            else
                return tips;
        }
        
        // Checks whether the type is a subclass of PyObjectBase because to get the doc string
        // of a member we must get it by its type instead of its instance otherwise we get the
        // wrong string, namely that of the type of the member. 
        // Note: 3rd party libraries may use their own type object classes so that we cannot 
        // reliably use Py::Type. To be on the safe side we should use Py::Object to assign
        // the used type object to.
        //Py::Object type = obj.type();
        Py::Object type(PyObject_Type(obj.ptr()), true);
        Py::Object inst = obj; // the object instance 
        union PyType_Object typeobj = {&Base::PyObjectBase::Type};
        union PyType_Object typedoc = {&App::DocumentObjectPy::Type};
        if (PyObject_IsSubclass(type.ptr(), typedoc.o) == 1) {
            // From the template Python object we don't query its type object because there we keep
            // a list of additional methods that we won't see otherwise. But to get the correct doc
            // strings we query the type's dict in the class itself.
            // To see if we have a template Python object we check for the existence of supportedProperties
            if (!type.hasAttr("supportedProperties")) {
                obj = type;
            }
        }
        else if (PyObject_IsSubclass(type.ptr(), typeobj.o) == 1) {
            obj = type;
        }
        
        // If we have an instance of PyObjectBase then determine whether it's valid or not
        if (PyObject_IsInstance(inst.ptr(), typeobj.o) == 1) {
            Base::PyObjectBase* baseobj = static_cast<Base::PyObjectBase*>(inst.ptr());
            const_cast<CallTipsList*>(this)->validObject = baseobj->isValid();
        }
        else {
            // PyObject_IsInstance might set an exception
            PyErr_Clear();
        }

        Py::List list(PyObject_Dir(obj.ptr()), true);

        // If we derive from PropertyContainerPy we can search for the properties in the
        // C++ twin class.
        union PyType_Object proptypeobj = {&App::PropertyContainerPy::Type};
        if (PyObject_IsSubclass(type.ptr(), proptypeobj.o) == 1) {
            // These are the attributes of the instance itself which are NOT accessible by
            // its type object
            extractTipsFromProperties(inst, tips);
        }

        // If we derive from App::DocumentPy we have direct access to the objects by their internal
        // names. So, we add these names to the list, too.
        union PyType_Object appdoctypeobj = {&App::DocumentPy::Type};
        if (PyObject_IsSubclass(type.ptr(), appdoctypeobj.o) == 1) {
            App::DocumentPy* docpy = (App::DocumentPy*)(inst.ptr());
            App::Document* document = docpy->getDocumentPtr();
            // Make sure that the C++ object is alive
            if (document) {
                std::vector<App::DocumentObject*> objects = document->getObjects();
                Py::List list;
                for (std::vector<App::DocumentObject*>::iterator it = objects.begin(); it != objects.end(); ++it)
                    list.append(Py::String((*it)->getNameInDocument()));
                extractTipsFromObject(inst, list, tips);
            }
        }

        // If we derive from Gui::DocumentPy we have direct access to the objects by their internal
        // names. So, we add these names to the list, too.
        union PyType_Object guidoctypeobj = {&Gui::DocumentPy::Type};
        if (PyObject_IsSubclass(type.ptr(), guidoctypeobj.o) == 1) {
            Gui::DocumentPy* docpy = (Gui::DocumentPy*)(inst.ptr());
            if (docpy->getDocumentPtr()) {
                App::Document* document = docpy->getDocumentPtr()->getDocument();
                // Make sure that the C++ object is alive
                if (document) {
                    std::vector<App::DocumentObject*> objects = document->getObjects();
                    Py::List list;
                    for (std::vector<App::DocumentObject*>::iterator it = objects.begin(); it != objects.end(); ++it)
                        list.append(Py::String((*it)->getNameInDocument()));
                    extractTipsFromObject(inst, list, tips);
                }
            }
        }

        // These are the attributes from the type object
        extractTipsFromObject(obj, list, tips);
    }
    catch (Py::Exception& e) {
        // Just clear the Python exception
        e.clear();
    }

    return tips;
}
コード例 #9
0
Py::Object
RendererAgg::draw_text(const Py::Tuple& args) {
  _VERBOSE("RendererAgg::draw_text");
  theRasterizer->reset_clipping();
  args.verify_length(4);
  
  
  FT2Font *font = static_cast<FT2Font*>(args[0].ptr());
  
  int x = Py::Int( args[1] );
  int y = Py::Int( args[2] );
  Py::Object gc = args[3];

  Py::Object o ( gc.getAttr( "_cliprect" ) );

  bool useClip = o.ptr()!=Py_None;
  double l = 0;
  double b = 0;
  double r = width;
  double t = height;
  if (useClip) {
    Py::SeqBase<Py::Object> rect( o );
  
    l = Py::Float(rect[0]) ; 
    b = Py::Float(rect[1]) ; 
    double w = Py::Float(rect[2]) ; 
    double h = Py::Float(rect[3]) ; 
    r = l+w;
    t = b+h;
    //std::cout << b << " " << h << " " << " " << t << std::endl;
  }

  agg::rgba color = get_color(gc);  
  pixfmt::color_type p;
  p.r = int(255*color.r); p.b = int(255*color.b); 
  p.g = int(255*color.g); p.a = int(255*color.a);
   
  //y = y-font->image.height;
  unsigned thisx, thisy;
  
  for (size_t i=0; i<font->image.width; ++i) {
    for (size_t j=0; j<font->image.height; ++j) {
      thisx = i+x+font->image.offsetx; 
      thisy = j+y+font->image.offsety; 
      if (thisx<l || thisx>=r)  continue;
      if (thisy<height-t || thisy>=height-b) continue;
      pixFmt->blend_pixel
	(thisx, thisy, p, font->image.buffer[i + j*font->image.width]);
    }
  }

  /*  bbox the text for debug purposes

  agg::path_storage path;
  
  path.move_to(x, y);
  path.line_to(x, y+font->image.height);
  path.line_to(x+font->image.width, y+font->image.height);
  path.line_to(x+font->image.width, y);
  path.close_polygon();
  
  agg::rgba edgecolor(1,0,0,1);
  
  //now fill the edge
  agg::conv_stroke<agg::path_storage> stroke(path);
  stroke.width(1.0);
  rendererAA->color(edgecolor);
  //self->theRasterizer->gamma(agg::gamma_power(gamma));
  theRasterizer->add_path(stroke);
  agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);  
  
  */

  return Py::Object();
  
}
コード例 #10
0
// this code is heavily adapted from the paint license, which is in
// the file paint.license (BSD compatible) included in this
// distribution.  TODO, add license file to MANIFEST.in and CVS
Py::Object 
RendererAgg::write_png(const Py::Tuple& args)
{
  //small memory leak in this function - JDH 2004-06-08
  _VERBOSE("RendererAgg::write_png");
  
  args.verify_length(1);
  
  FILE *fp;
  Py::Object o = Py::Object(args[0]);
  bool fpclose = true;
  if (o.isString()) {
    std::string fileName = Py::String(o);
    const char *file_name = fileName.c_str();
    fp = fopen(file_name, "wb");
  }
  else {
    if ((fp = PyFile_AsFile(o.ptr())) == NULL) 
      throw Py::TypeError("Could not convert object to file pointer");
    fpclose = false;
  }

  png_structp png_ptr;
  png_infop info_ptr;
  struct        png_color_8_struct sig_bit;
  png_uint_32 row;
  
  png_bytep row_pointers[height];
  for (row = 0; row < height; ++row) {
    row_pointers[row] = pixBuffer + row * width * 4;
  }
  

  if (fp == NULL) 
    throw Py::RuntimeError("could not open file");
  
  
  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if (png_ptr == NULL) {
    if (fpclose) fclose(fp);
    throw Py::RuntimeError("could not create write struct");
  }
  
  info_ptr = png_create_info_struct(png_ptr);
  if (info_ptr == NULL) {
    if (fpclose) fclose(fp);
    png_destroy_write_struct(&png_ptr, &info_ptr);
    throw Py::RuntimeError("could not create info struct");
  }
  
  if (setjmp(png_ptr->jmpbuf)) {
    if (fpclose) fclose(fp);
    png_destroy_write_struct(&png_ptr, &info_ptr);
    throw Py::RuntimeError("error building image");
  }
  
  png_init_io(png_ptr, fp);
  png_set_IHDR(png_ptr, info_ptr,
	       width, height, 8,
	       PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
	       PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  
  // this a a color image!
  sig_bit.gray = 0;
  sig_bit.red = 8;
  sig_bit.green = 8;
  sig_bit.blue = 8;
  /* if the image has an alpha channel then */
  sig_bit.alpha = 8;
  png_set_sBIT(png_ptr, info_ptr, &sig_bit);
  
  png_write_info(png_ptr, info_ptr);
  png_write_image(png_ptr, row_pointers);
  png_write_end(png_ptr, info_ptr);

  /* Changed calls to png_destroy_write_struct to follow
     http://www.libpng.org/pub/png/libpng-manual.txt.  
     This ensures the info_ptr memory is released.  
  */

  png_destroy_write_struct(&png_ptr, &info_ptr);

 
  if (fpclose) fclose(fp);
  
  return Py::Object();
}
コード例 #11
0
Py::Object
Transformation::numerix_x_y(const Py::Tuple & args) {
  _VERBOSE("Transformation::numerix_x_y");
  args.verify_length(2);


  Py::Object xo = args[0];
  Py::Object yo = args[1];

  PyArrayObject *x = (PyArrayObject *) PyArray_ContiguousFromObject(xo.ptr(), PyArray_DOUBLE, 1, 1); 
  
  if (x==NULL) 
    throw Py::TypeError("Transformation::numerix_x_y expected numerix array");

  
  PyArrayObject *y = (PyArrayObject *) PyArray_ContiguousFromObject(yo.ptr(), PyArray_DOUBLE, 1, 1); 
  
  if (y==NULL) 
    throw Py::TypeError("Transformation::numerix_x_y expected numerix array");

  
  size_t Nx = x->dimensions[0];
  size_t Ny = y->dimensions[0];
  
  if (Nx!=Ny) 
    throw Py::ValueError("x and y must be equal length sequences");

  // evaluate the lazy objects  
  if (!_frozen) eval_scalars();

  int dimensions[1];
  dimensions[0] = Nx;

  
  PyArrayObject *retx = (PyArrayObject *)PyArray_FromDims(1,dimensions,PyArray_DOUBLE);
  if (retx==NULL) {
    Py_XDECREF(x);
    Py_XDECREF(y);
    throw Py::RuntimeError("Could not create return x array");
  }

  PyArrayObject *rety = (PyArrayObject *)PyArray_FromDims(1,dimensions,PyArray_DOUBLE);
  if (rety==NULL) {
    Py_XDECREF(x);
    Py_XDECREF(y);
    throw Py::RuntimeError("Could not create return x array");
  }

  for (size_t i=0; i< Nx; ++i) {

    double thisx = *(double *)(x->data + i*x->strides[0]);
    double thisy = *(double *)(y->data + i*y->strides[0]);
    //std::cout << "calling operator " << thisx << " " << thisy << " " << std::endl;
    this->operator()(thisx, thisy);
    *(double *)(retx->data + i*retx->strides[0]) = xy.first;
    *(double *)(rety->data + i*rety->strides[0]) = xy.second;
  }
  
  Py_XDECREF(x);
  Py_XDECREF(y);

  Py::Tuple ret(2);
  ret[0] = Py::Object((PyObject*)retx);
  ret[1] = Py::Object((PyObject*)rety);
  Py_XDECREF(retx);
  Py_XDECREF(rety);
  return ret;
}
コード例 #12
0
Py::Object
Bbox::update_numerix(const Py::Tuple &args) {
  //update the box from the numerix arrays x and y
  _VERBOSE("Bbox::update_numerix");

  args.verify_length(3);

  Py::Object xo = args[0];
  Py::Object yo = args[1];

  PyArrayObject *x = (PyArrayObject *) PyArray_ContiguousFromObject(xo.ptr(), PyArray_DOUBLE, 1, 1);

  if (x==NULL)
    throw Py::TypeError("Bbox::update_numerix expected numerix array");


  PyArrayObject *y = (PyArrayObject *) PyArray_ContiguousFromObject(yo.ptr(), PyArray_DOUBLE, 1, 1);

  if (y==NULL)
    throw Py::TypeError("Bbox::update_numerix expected numerix array");


  size_t Nx = x->dimensions[0];
  size_t Ny = y->dimensions[0];

  if (Nx!=Ny)
    throw Py::ValueError("x and y must be equal length sequences");

  //don't use current bounds when updating box if ignore==1


  if (Nx==0) return Py::Object();

  double minx = _ll->xval();
  double maxx = _ur->xval();
  double miny = _ll->yval();
  double maxy = _ur->yval();

  double thisx, thisy;
  int ignore = Py::Int(args[2]);
  if (ignore) {
    int xok=0;
    int yok=0;
    // loop through values until we find some nans...
    for (size_t i=0; i< Nx; ++i) {
      thisx = *(double *)(x->data + i*x->strides[0]);
      thisy = *(double *)(y->data + i*y->strides[0]);

      if (!xok) {
	if (!MPL_isnan64(thisx)) {
	  minx=thisx;
	  maxx=thisx;
	  xok=1;
	}
      }

      if (!yok) {
	if (!MPL_isnan64(thisy)) {
	  miny=thisy;
	  maxy=thisy;
	  yok=1;
	}
      }
      
      if (xok && yok) break;
    }
  }

  for (size_t i=0; i< Nx; ++i) {
    thisx = *(double *)(x->data + i*x->strides[0]);
    thisy = *(double *)(y->data + i*y->strides[0]);

    _posx.update(thisx);
    _posy.update(thisy);
    if (thisx<minx) minx=thisx;
    if (thisx>maxx) maxx=thisx;
    if (thisy<miny) miny=thisy;
    if (thisy>maxy) maxy=thisy;


  }

  Py_XDECREF(x);
  Py_XDECREF(y);


  _ll->x_api()->set_api(minx);
  _ll->y_api()->set_api(miny);
  _ur->x_api()->set_api(maxx);
  _ur->y_api()->set_api(maxy);
  return Py::Object();
}
コード例 #13
0
PythonInterpreter::PythonInterpreter(Kross::InterpreterInfo* info)
    : Kross::Interpreter(info)
    , d(new PythonInterpreterPrivate())
{
    // Initialize the python interpreter.
    initialize();

    // Set name of the program.
    Py_SetProgramName(const_cast<char*>("Kross"));

    /*
    // Set arguments.
    //char* comm[0];
    const char* comm = const_cast<char*>("kross"); // name.
    PySys_SetArgv(1, comm);
    */

    // In the python sys.path are all module-directories are
    // listed in.
    QString path;

    // First import the sys-module to remember it's sys.path
    // list in our path QString.
    Py::Module sysmod( PyImport_ImportModule( (char*)"sys" ), true );
    Py::Dict sysmoddict = sysmod.getDict();
    Py::Object syspath = sysmoddict.getItem("path");
    if(syspath.isList()) {
        Py::List syspathlist = syspath;
        for(Py::List::iterator it = syspathlist.begin(); it != syspathlist.end(); ++it) {
            if( ! (*it).isString() ) continue;
            QString s = PythonType<QString>::toVariant(*it);
            path.append( s + PYPATHDELIMITER );
        }
    }
    else
        path = Py_GetPath();

#if 0
    // Determinate additional module-paths we like to add.
    // First add the global Kross modules-path.
    QStringList krossdirs = KGlobal::dirs()->findDirs("data", "kross/python");
    for(QStringList::Iterator krossit = krossdirs.begin(); krossit != krossdirs.end(); ++krossit)
        path.append(*krossit + PYPATHDELIMITER);
    // Then add the application modules-path.
    QStringList appdirs = KGlobal::dirs()->findDirs("appdata", "kross/python");
    for(QStringList::Iterator appit = appdirs.begin(); appit != appdirs.end(); ++appit)
        path.append(*appit + PYPATHDELIMITER);
#endif

    // Set the extended sys.path.
    PySys_SetPath( (char*) path.toLatin1().data() );

    #ifdef KROSS_PYTHON_INTERPRETER_DEBUG
        krossdebug(QString("Python ProgramName: %1").arg(Py_GetProgramName()));
        krossdebug(QString("Python ProgramFullPath: %1").arg(Py_GetProgramFullPath()));
        krossdebug(QString("Python Version: %1").arg(Py_GetVersion()));
        krossdebug(QString("Python Platform: %1").arg(Py_GetPlatform()));
        krossdebug(QString("Python Prefix: %1").arg(Py_GetPrefix()));
        krossdebug(QString("Python ExecPrefix: %1").arg(Py_GetExecPrefix()));
        //krossdebug(QString("Python Path: %1").arg(Py_GetPath()));
        //krossdebug(QString("Python System Path: %1").arg(path));
    #endif

    // Initialize the main module.
    d->mainmodule = new PythonModule(this);

    // The main dictonary.
    Py::Dict moduledict = d->mainmodule->getDict();
    //TODO moduledict["KrossPythonVersion"] = Py::Int(KROSS_PYTHON_VERSION);

    // Prepare the interpreter.
    QString s =
        //"# -*- coding: iso-8859-1 -*-\n"
        //"import locale\n"
        //"locale.setlocale(locale.LC_ALL, '')\n"
        //"# -*- coding: latin-1 -*\n"
        //"# -*- coding: utf-8 -*-\n"
        //"import locale\n"
        //"locale.setlocale(locale.LC_ALL, '')\n"
        //"from __future__ import absolute_import\n"
        "import sys\n"
        //"import os, os.path\n"
        //"sys.setdefaultencoding('latin-1')\n"

        // Dirty hack to get sys.argv defined. Needed for e.g. TKinter.
        "sys.argv = ['']\n"

        // On the try to read something from stdin always return an empty
        // string. That way such reads don't block our script.
        // Deactivated since sys.stdin has the encoding attribute needed
        // by e.g. LiquidWeather and those attr is missing in StringIO
        // and cause it's buildin we can't just add it but would need to
        // implement our own class. Grrrr, what a stupid design :-/
        //"try:\n"
        //"    import cStringIO\n"
        //"    sys.stdin = cStringIO.StringIO()\n"
        //"except:\n"
        //"    pass\n"

        // Class to redirect something. We use this class e.g. to redirect
        // <stdout> and <stderr> to a c++ event.
        //"class Redirect:\n"
        //"  def __init__(self, target):\n"
        //"    self.target = target\n"
        //"  def write(self, s):\n"
        //"    self.target.call(s)\n"

        // Wrap builtin __import__ method. All import requests are
        // first redirected to our PythonModule.import method and
        // if the call returns None, then we call the original
        // python import mechanism.
        "import __builtin__\n"
        "import __main__\n"
        "import traceback\n"
        "sys.modules['_oldmain'] = sys.modules['__main__']\n"
        "_main_builtin_import_ = __main__.__builtin__.__import__\n"
        "class _Importer:\n"
        "   def __init__(self, script):\n"
        "       self.script = script\n"
        "       self.realImporter = __main__.__builtin__.__import__\n"
        "       __main__.__builtin__.__import__ = self._import\n"
        "   def _import(self, name, globals=None, locals=None, fromlist=[], level = -1):\n"
        //"       try:\n"
        //"           print \"1===========> _Importer name=%s fromlist=%s\" % (name,fromlist)\n"
#if PY_MAJOR_VERSION >= 3 || (PY_MAJOR_VERSION >= 2 && PY_MINOR_VERSION >= 5)
        "           mod = __main__._import(self.script, name, globals, locals, fromlist, level)\n"
#else
        "           mod = __main__._import(self.script, name, globals, locals, fromlist)\n"
#endif
        "           if mod == None:\n"
        "               if name == 'qt':\n"
        "                   raise ImportError('Import of the PyQt3 module is not allowed. Please use PyQt4 instead.')\n"
        "               if name == 'dcop':\n"
        "                   raise ImportError('Import of the KDE3 DCOP module is not allowed. Please use PyQt4 DBUS instead.')\n"
#if PY_MAJOR_VERSION >= 3 || (PY_MAJOR_VERSION >= 2 && PY_MINOR_VERSION >= 5)
        "               mod = self.realImporter(name, globals, locals, fromlist, level)\n"
#else
        "               mod = self.realImporter(name, globals, locals, fromlist)\n"
#endif
        "           if mod != None:\n"
        //"               print \"3===========> _Importer name=%s fromlist=%s\" % (name,fromlist)\n"
        "               if globals != None and (not fromlist or len(fromlist)==0 or '*' in fromlist):\n"
        "                   globals[name] = mod\n"
        "           return mod\n"
        //"       except ImportError:\n"
        //"       except:\n"
        //"           print \"9===========> _Importer Trying ImportError with name=%s fromlist=%s insysmodules=%s\" % (name,fromlist,name in sys.modules)\n"
        //"           print \" \".join( traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2]) )\n"
        //"       return None\n"

/*
        "       print \"_Importer name=%s fromlist=%s\" % (name,fromlist)\n"
        "       if fromlist == None:\n"
        "           mod = __main__._import(self.script, name, globals, locals, fromlist)\n"
        "           if mod != None:\n"
        "               print \"2===========> _Importer name=%s fromlist=%s\" % (name,fromlist)\n"
        "               globals[name] = mod\n"
        "               return mod\n"
        //"           if name in sys.modules:\n" // hack to preserve module paths, needed e.g. for "import os.path"
        //"               print \"3===========> _Importer name=%s fromlist=%s\" % (name,fromlist)\n"
        //"               return sys.modules[name]\n"
        "       print \"3===========> _Importer Trying realImporter with name=%s fromlist=%s insysmodules=%s\" % (name,fromlist,name in sys.modules)\n"
        "       try:\n"
        "           mod = self.realImporter(name, globals, locals, fromlist)\n"
        "           print \"4===========> _Importer Trying realImporter with name=%s fromlist=%s insysmodules=%s module=%s\" % (name,fromlist,name in sys.modules,mod)\n"
        //"           mod.__init__(name)\n"
        //"           globals[name] = mod\n"
        //"           sys.modules[name] = mod\n"
        "           print \"5===========> _Importer Trying realImporter with name=%s fromlist=%s insysmodules=%s module=%s\" % (name,fromlist,name in sys.modules,mod)\n"
        "           return mod\n"
        "       except ImportError:\n"
        "           print \"6===========> _Importer Trying ImportError with name=%s fromlist=%s insysmodules=%s\" % (name,fromlist,name in sys.modules)\n"
        "           n = name.split('.')\n"
        "           if len(n) >= 2:\n"
        "               print \"7===========> _Importer Trying ImportError with name=%s fromlist=%s insysmodules=%s\" % (name,fromlist,name in sys.modules)\n"
        "               m = self._import(\".\".join(n[:-1]),globals,locals,[n[-1],])\n"
        "               print \"8===========> _Importer Trying ImportError with name=%s fromlist=%s insysmodules=%s\" % (name,fromlist,name in sys.modules)\n"
        "               return self.realImporter(name, globals, locals, fromlist)\n"
        "           print \"9===========> _Importer Trying ImportError with name=%s fromlist=%s insysmodules=%s\" % (name,fromlist,name in sys.modules)\n"
        "           raise\n"
*/
        ;

    PyObject* pyrun = PyRun_String(s.toLatin1().data(), Py_file_input, moduledict.ptr(), moduledict.ptr());
    if(! pyrun) {
        Py::Object errobj = Py::value(Py::Exception()); // get last error
        setError( QString("Failed to prepare the __main__ module: %1").arg(errobj.as_string().c_str()) );
    }
    Py_XDECREF(pyrun); // free the reference.
}
コード例 #14
0
Py::Object
_image_module::pcolor2(const Py::Tuple& args) {
    _VERBOSE("_image_module::pcolor2");

    if (args.length() != 7)
        throw Py::TypeError("Incorrect number of arguments (6 expected)");

    Py::Object xp = args[0];
    Py::Object yp = args[1];
    Py::Object dp = args[2];
    int rows = Py::Int(args[3]);
    int cols = Py::Int(args[4]);
    Py::Tuple bounds = args[5];
    Py::Object bgp = args[6];

    if (bounds.length() !=4)
        throw Py::TypeError("Incorrect number of bounds (4 expected)");
    double x_left = Py::Float(bounds[0]);
    double x_right = Py::Float(bounds[1]);
    double y_bot = Py::Float(bounds[2]);
    double y_top = Py::Float(bounds[3]);

    // Check we have something to output to
    if (rows == 0 || cols ==0)
        throw Py::ValueError("rows or cols is zero; there are no pixels");

    // Get numpy arrays
    PyArrayObject *x = (PyArrayObject *) PyArray_ContiguousFromObject(xp.ptr(),
                                                          PyArray_DOUBLE, 1, 1);
    if (x == NULL)
        throw Py::ValueError("x is of incorrect type (wanted 1D double)");
    PyArrayObject *y = (PyArrayObject *) PyArray_ContiguousFromObject(yp.ptr(),
                                                          PyArray_DOUBLE, 1, 1);
    if (y == NULL) {
        Py_XDECREF(x);
        throw Py::ValueError("y is of incorrect type (wanted 1D double)");
    }
    PyArrayObject *d = (PyArrayObject *) PyArray_ContiguousFromObject(dp.ptr(),
                                                          PyArray_UBYTE, 3, 3);
    if (d == NULL) {
        Py_XDECREF(x);
        Py_XDECREF(y);
        throw Py::ValueError("data is of incorrect type (wanted 3D uint8)");
    }
    if (d->dimensions[2] != 4) {
        Py_XDECREF(x);
        Py_XDECREF(y);
        Py_XDECREF(d);
        throw Py::ValueError("data must be in RGBA format");
    }

    // Check dimensions match
    int nx = x->dimensions[0];
    int ny = y->dimensions[0];
    if (nx != d->dimensions[1]+1 || ny != d->dimensions[0]+1) {
        Py_XDECREF(x);
        Py_XDECREF(y);
        Py_XDECREF(d);
        throw Py::ValueError("data and axis bin boundary dimensions are incompatible");
    }

    PyArrayObject *bg = (PyArrayObject *) PyArray_ContiguousFromObject(bgp.ptr(),
                                                          PyArray_UBYTE, 1, 1);
    if (bg == NULL) {
        Py_XDECREF(x);
        Py_XDECREF(y);
        Py_XDECREF(d);
        throw Py::ValueError("bg is of incorrect type (wanted 1D uint8)");
    }
    if (bg->dimensions[0] != 4) {
        Py_XDECREF(x);
        Py_XDECREF(y);
        Py_XDECREF(d);
        Py_XDECREF(bg);
        throw Py::ValueError("bg must be in RGBA format");
    }


    // Allocate memory for pointer arrays
    int * irows = reinterpret_cast<int*>(PyMem_Malloc(sizeof(int)*rows));
    if (irows == NULL) {
        Py_XDECREF(x);
        Py_XDECREF(y);
        Py_XDECREF(d);
        Py_XDECREF(bg);
        throw Py::MemoryError("Cannot allocate memory for lookup table");
    }
    int * jcols = reinterpret_cast<int*>(PyMem_Malloc(sizeof(int*)*cols));
    if (jcols == NULL) {
        Py_XDECREF(x);
        Py_XDECREF(y);
        Py_XDECREF(d);
        Py_XDECREF(bg);
        PyMem_Free(irows);
        throw Py::MemoryError("Cannot allocate memory for lookup table");
    }

    // Create output
    Image* imo = new Image;
    imo->rowsIn = rows;
    imo->rowsOut = rows;
    imo->colsIn = cols;
    imo->colsOut = cols;
    size_t NUMBYTES(rows * cols * 4);
    agg::int8u *buffer = new agg::int8u[NUMBYTES];
    if (buffer == NULL) {
        Py_XDECREF(x);
        Py_XDECREF(y);
        Py_XDECREF(d);
        Py_XDECREF(bg);
        PyMem_Free(irows);
        PyMem_Free(jcols);
        throw Py::MemoryError("Could not allocate memory for image");
    }

    // Calculate the pointer arrays to map input x to output x
    int i, j;
    double *x0 = reinterpret_cast<double*>(x->data);
    double *y0 = reinterpret_cast<double*>(y->data);
    double sx = cols/(x_right - x_left);
    double sy = rows/(y_top - y_bot);
    _bin_indices(jcols, cols, x0, nx, sx, x_left);
    _bin_indices(irows, rows, y0, ny, sy, y_bot);

    // Copy data to output buffer
    agg::int8u * position = buffer;
    unsigned char *start = reinterpret_cast<unsigned char*>(d->data);
    unsigned char *bgptr = reinterpret_cast<unsigned char*>(bg->data);
    int s0 = d->strides[0];
    int s1 = d->strides[1];

    for (i=0; i<rows; i++)
    {
        for (j=0; j<cols; j++)
        {
            if (irows[i] == -1 || jcols[j] == -1) {
                memcpy(position, bgptr, 4*sizeof(agg::int8u));
            }
            else {
                memcpy(position, (start + s0*irows[i] + s1*jcols[j]),
                                                  4*sizeof(agg::int8u));
            }
            position += 4;
        }
    }

    // Attach output buffer to output buffer
    imo->rbufOut = new agg::rendering_buffer;
    imo->bufferOut = buffer;
    imo->rbufOut->attach(imo->bufferOut, imo->colsOut, imo->rowsOut, imo->colsOut * imo->BPP);

    Py_XDECREF(x);
    Py_XDECREF(y);
    Py_XDECREF(d);
    Py_XDECREF(bg);
    PyMem_Free(irows);
    PyMem_Free(jcols);

    return Py::asObject(imo);
}
コード例 #15
0
Py::Object
_image_module::pcolor(const Py::Tuple& args) {
  _VERBOSE("_image_module::pcolor");


  if (args.length() != 6)
      throw Py::TypeError("Incorrect number of arguments (6 expected)");

  Py::Object xp = args[0];
  Py::Object yp = args[1];
  Py::Object dp = args[2];
  unsigned int rows = Py::Int(args[3]);
  unsigned int cols = Py::Int(args[4]);
  Py::Tuple bounds = args[5];

  if (bounds.length() !=4)
      throw Py::TypeError("Incorrect number of bounds (4 expected)");
  float x_min = Py::Float(bounds[0]);
  float x_max = Py::Float(bounds[1]);
  float y_min = Py::Float(bounds[2]);
  float y_max = Py::Float(bounds[3]);
  float width = x_max - x_min;
  float height = y_max - y_min;
  float dx = width / ((float) cols);
  float dy = height / ((float) rows);

  // Check we have something to output to
  if (rows == 0 || cols ==0)
      throw Py::ValueError("Cannot scale to zero size");

  // Get numpy arrays
  PyArrayObject *x = (PyArrayObject *) PyArray_ContiguousFromObject(xp.ptr(), PyArray_FLOAT, 1, 1);
  if (x == NULL)
      throw Py::ValueError("x is of incorrect type (wanted 1D float)");
  PyArrayObject *y = (PyArrayObject *) PyArray_ContiguousFromObject(yp.ptr(), PyArray_FLOAT, 1, 1);
  if (y == NULL) {
      Py_XDECREF(x);
      throw Py::ValueError("y is of incorrect type (wanted 1D float)");
  }
  PyArrayObject *d = (PyArrayObject *) PyArray_ContiguousFromObject(dp.ptr(), PyArray_UBYTE, 3, 3);
  if (d == NULL) {
      Py_XDECREF(x);
      Py_XDECREF(y);
      throw Py::ValueError("data is of incorrect type (wanted 3D UInt8)");
  }
  if (d->dimensions[2] != 4) {
      Py_XDECREF(x);
      Py_XDECREF(y);
      Py_XDECREF(d);
      throw Py::ValueError("data must be in RGBA format");
  }

  // Check dimensions match
  int nx = x->dimensions[0];
  int ny = y->dimensions[0];
  if (nx != d->dimensions[1] || ny != d->dimensions[0]) {
      Py_XDECREF(x);
      Py_XDECREF(y);
      Py_XDECREF(d);
      throw Py::ValueError("data and axis dimensions do not match");
  }

  // Allocate memory for pointer arrays
  unsigned int * rowstarts = reinterpret_cast<unsigned int*>(PyMem_Malloc(sizeof(unsigned int)*rows));
  if (rowstarts == NULL) {
      Py_XDECREF(x);
      Py_XDECREF(y);
      Py_XDECREF(d);
      throw Py::MemoryError("Cannot allocate memory for lookup table");
  }
  unsigned int * colstarts = reinterpret_cast<unsigned int*>(PyMem_Malloc(sizeof(unsigned int*)*cols));
  if (colstarts == NULL) {
      Py_XDECREF(x);
      Py_XDECREF(y);
      Py_XDECREF(d);
      PyMem_Free(rowstarts);
      throw Py::MemoryError("Cannot allocate memory for lookup table");
  }

  // Create output
  Image* imo = new Image;
  imo->rowsIn = rows;
  imo->colsIn = cols;
  imo->rowsOut = rows;
  imo->colsOut = cols;
  size_t NUMBYTES(rows * cols * 4);
  agg::int8u *buffer = new agg::int8u[NUMBYTES];
  if (buffer == NULL) {
      Py_XDECREF(x);
      Py_XDECREF(y);
      Py_XDECREF(d);
      PyMem_Free(rowstarts);
      PyMem_Free(colstarts);
      throw Py::MemoryError("Could not allocate memory for image");
  }

  // Calculate the pointer arrays to map input x to output x
  unsigned int i, j, j_last;
  unsigned int * colstart = colstarts;
  unsigned int * rowstart = rowstarts;
  float *xs1 = reinterpret_cast<float*>(x->data);
  float *ys1 = reinterpret_cast<float*>(y->data);
  float *xs2 = xs1+1;
  float *ys2 = ys1+1;
  float *xl = xs1 + nx - 1;
  float *yl = ys1 + ny - 1;
  float xo = x_min + dx/2.0;
  float yo = y_min + dy/2.0;
  float xm = 0.5*(*xs1 + *xs2);
  float ym = 0.5*(*ys1 + *ys2);
  // x/cols
  j = 0;
  j_last = j;
  for (i=0;i<cols;i++,xo+=dx,colstart++) {
      while(xs2 != xl && xo > xm) {
          xs1 = xs2;
          xs2 = xs1+1;
          xm = 0.5*(*xs1 + *xs2);
          j++;
      }
      *colstart = j - j_last;
      j_last = j;
  }
  // y/rows
  j = 0;
  j_last = j;
  for (i=0;i<rows;i++,yo+=dy,rowstart++) {
      while(ys2 != yl && yo > ym) {
          ys1 = ys2;
          ys2 = ys1+1;
          ym = 0.5*(*ys1 + *ys2);
          j++;
      }
      *rowstart = j - j_last;
      j_last = j;
  }


  // Copy data to output buffer
  unsigned char *start;
  unsigned char *inposition;
  size_t inrowsize(nx*4);
  size_t rowsize(cols*4);
  rowstart = rowstarts;
  agg::int8u * position = buffer;
  agg::int8u * oldposition = NULL;
  start = reinterpret_cast<unsigned char*>(d->data);
  for(i=0;i<rows;i++,rowstart++)
  {
      if (i > 0 && *rowstart == 0) {
          memcpy(position, oldposition, rowsize*sizeof(agg::int8u));
          oldposition = position;
          position += rowsize;
      } else {
          oldposition = position;
          start += *rowstart * inrowsize;
          inposition = start;
          for(j=0,colstart=colstarts;j<cols;j++,position+=4,colstart++) {
              inposition += *colstart * 4;
              memcpy(position, inposition, 4*sizeof(agg::int8u));
          }
      }
  }

  // Attatch output buffer to output buffer
  imo->rbufOut = new agg::rendering_buffer;
  imo->bufferOut = buffer;
  imo->rbufOut->attach(imo->bufferOut, imo->colsOut, imo->rowsOut, imo->colsOut * imo->BPP);

  Py_XDECREF(x);
  Py_XDECREF(y);
  Py_XDECREF(d);
  PyMem_Free(rowstarts);
  PyMem_Free(colstarts);

  return Py::asObject(imo);
}
コード例 #16
0
Py::Object
_image_module::frombyte(const Py::Tuple& args) {
  _VERBOSE("_image_module::frombyte");

  args.verify_length(2);

  Py::Object x = args[0];
  int isoutput = Py::Int(args[1]);

  PyArrayObject *A = (PyArrayObject *) PyArray_ContiguousFromObject(x.ptr(), PyArray_UBYTE, 3, 3);
  if (A == NULL)
      throw Py::ValueError("Array must have 3 dimensions");
  if (A->dimensions[2]<3 || A->dimensions[2]>4)
      throw Py::ValueError("Array dimension 3 must have size 3 or 4");

  Image* imo = new Image;

  imo->rowsIn = A->dimensions[0];
  imo->colsIn = A->dimensions[1];

  agg::int8u *arrbuf;
  agg::int8u *buffer;

  arrbuf = reinterpret_cast<agg::int8u *>(A->data);

  size_t NUMBYTES(imo->colsIn * imo->rowsIn * imo->BPP);
  buffer = new agg::int8u[NUMBYTES];

  if (buffer==NULL) //todo: also handle allocation throw
      throw Py::MemoryError("_image_module::frombyte could not allocate memory");

  const size_t N = imo->rowsIn * imo->colsIn * imo->BPP;
  size_t i = 0;
  if (A->dimensions[2] == 4) {
      memmove(buffer, arrbuf, N);
  } else {
      while (i < N) {
          memmove(buffer, arrbuf, 3);
          buffer += 3;
          arrbuf += 3;
          *buffer++ = 255;
          i += 4;
      }
      buffer -= N;
      arrbuf -= imo->rowsIn * imo->colsIn;
  }
  Py_XDECREF(A);

  if (isoutput) {
    // make the output buffer point to the input buffer

    imo->rowsOut  = imo->rowsIn;
    imo->colsOut  = imo->colsIn;

    imo->rbufOut = new agg::rendering_buffer;
    imo->bufferOut = buffer;
    imo->rbufOut->attach(imo->bufferOut, imo->colsOut, imo->rowsOut, imo->colsOut * imo->BPP);

  }
  else {
    imo->bufferIn = buffer;
    imo->rbufIn = new agg::rendering_buffer;
    imo->rbufIn->attach(buffer, imo->colsIn, imo->rowsIn, imo->colsIn*imo->BPP);
  }

  return Py::asObject( imo );
}
コード例 #17
-1
Py::Object
Transformation::nonlinear_only_numerix(const Py::Tuple & args, const Py::Dict &kwargs) {
  _VERBOSE("Transformation::nonlinear_only_numerix");
  args.verify_length(2);

  int returnMask = false;
  if (kwargs.hasKey("returnMask")) {
    returnMask = Py::Int(kwargs["returnMask"]);
  }

  Py::Object xo = args[0];
  Py::Object yo = args[1];

  PyArrayObject *x = (PyArrayObject *) PyArray_ContiguousFromObject(xo.ptr(), PyArray_DOUBLE, 1, 1);

  if (x==NULL)
    throw Py::TypeError("Transformation::nonlinear_only_numerix expected numerix array");


  PyArrayObject *y = (PyArrayObject *) PyArray_ContiguousFromObject(yo.ptr(), PyArray_DOUBLE, 1, 1);

  if (y==NULL)
    throw Py::TypeError("Transformation::nonlinear_only_numerix expected numerix array");


  size_t Nx = x->dimensions[0];
  size_t Ny = y->dimensions[0];

  if (Nx!=Ny)
    throw Py::ValueError("x and y must be equal length sequences");

  int dimensions[1];
  dimensions[0] = Nx;


  PyArrayObject *retx = (PyArrayObject *)PyArray_FromDims(1,dimensions,PyArray_DOUBLE);
  if (retx==NULL) {
    Py_XDECREF(x);
    Py_XDECREF(y);
    throw Py::RuntimeError("Could not create return x array");
  }

  PyArrayObject *rety = (PyArrayObject *)PyArray_FromDims(1,dimensions,PyArray_DOUBLE);
  if (rety==NULL) {
    Py_XDECREF(x);
    Py_XDECREF(y);
    Py_XDECREF(retx);
    throw Py::RuntimeError("Could not create return x array");
  }

  PyArrayObject *retmask = NULL;

  if (returnMask) {
    retmask = (PyArrayObject *)PyArray_FromDims(1,dimensions,PyArray_UBYTE);
    if (retmask==NULL) {
      Py_XDECREF(x);
      Py_XDECREF(y);
      Py_XDECREF(retx);
      Py_XDECREF(rety);
      throw Py::RuntimeError("Could not create return mask array");
    }

  }


  for (size_t i=0; i< Nx; ++i) {

    double thisx = *(double *)(x->data + i*x->strides[0]);
    double thisy = *(double *)(y->data + i*y->strides[0]);
    try {
      this->nonlinear_only_api(&thisx, &thisy);
    }
    catch(...) {

      if (returnMask) {
	*(unsigned char *)(retmask->data + i*retmask->strides[0]) = 0;
	*(double *)(retx->data + i*retx->strides[0]) = 0.0;
	*(double *)(rety->data + i*rety->strides[0]) = 0.0;
	continue;
      }
      else {
	throw Py::ValueError("Domain error on this->nonlinear_only_api(&thisx, &thisy) in Transformation::nonlinear_only_numerix");
      }
    }

    *(double *)(retx->data + i*retx->strides[0]) = thisx;
    *(double *)(rety->data + i*rety->strides[0]) = thisy;
    if (returnMask) {
      *(unsigned char *)(retmask->data + i*retmask->strides[0]) = 1;
    }

  }

  Py_XDECREF(x);
  Py_XDECREF(y);

  if (returnMask) {
    Py::Tuple ret(3);
    ret[0] = Py::Object((PyObject*)retx);
    ret[1] = Py::Object((PyObject*)rety);
    ret[2] = Py::Object((PyObject*)retmask);
    Py_XDECREF(retx);
    Py_XDECREF(rety);
    Py_XDECREF(retmask);
    return ret;
  }
  else {
    Py::Tuple ret(2);
    ret[0] = Py::Object((PyObject*)retx);
    ret[1] = Py::Object((PyObject*)rety);
    Py_XDECREF(retx);
    Py_XDECREF(rety);
    return ret;

  }


}