Пример #1
0
static void Bitmap_setPixels(Bitmap& bitmap, PyObject* exporter)
{
    Py_buffer bufferView;
//    PyObject_Print(PyObject_Type(exporter), stderr, 0);
    if (PyObject_CheckBuffer(exporter)) {
        PyObject_GetBuffer(exporter, &bufferView, PyBUF_READ);
        const unsigned char* pBuf = reinterpret_cast<unsigned char*>(bufferView.buf);
        bitmap.setPixels(pBuf);
        PyBuffer_Release(&bufferView);
    } else if (PyBuffer_Check(exporter)) {
        PyTypeObject * pType = exporter->ob_type;
        PyBufferProcs * pProcs = pType->tp_as_buffer;
        AVG_ASSERT(pProcs);
        Py_ssize_t numBytes;
        Py_ssize_t numSegments = pProcs->bf_getsegcount(exporter, &numBytes);
        if (numBytes != bitmap.getMemNeeded()) {
            throw Exception(AVG_ERR_INVALID_ARGS,
                    "Second parameter to Bitmap.setPixels must fit bitmap size.");
        }
        // TODO: check if bitmap size is correct
        unsigned char* pDestPixels = bitmap.getPixels();
        for (unsigned i=0; i<numSegments; ++i) {
            void* pSrcPixels;
            long bytesInSegment = pProcs->bf_getreadbuffer(exporter, i, &pSrcPixels);
            memcpy(pDestPixels, pSrcPixels, bytesInSegment);
            pDestPixels += bytesInSegment;
        }
    } else {
        throw Exception(AVG_ERR_INVALID_ARGS,
               "Second parameter to Bitmap.setPixels must support the buffer interface.");
    }
}
Пример #2
0
Py_ssize_t
PyBuffer_GetMemory(PyObject* buffer, const char** pp)
{
    PyBufferProcs* procs = buffer->ob_type->tp_as_buffer;

    if (!procs || !PyType_HasFeature(buffer->ob_type, Py_TPFLAGS_HAVE_GETCHARBUFFER))
    {
        // Can't access the memory directly because the buffer object doesn't support it.
        return -1;
    }

    if (procs->bf_getsegcount(buffer, 0) != 1)
    {
        // Can't access the memory directly because there is more than one segment.
        return -1;
    }

#if PY_VERSION_HEX >= 0x02050000
    char* pT = 0;
#else
    const char* pT = 0;
#endif
    Py_ssize_t cb = procs->bf_getcharbuffer(buffer, 0, &pT);

    if (pp)
        *pp = pT;

    return cb;
}
Пример #3
0
static int
_read_from_handle(void *wasread, const int length, void *handle)
{
    PyObject *py_handle = (PyObject *)handle,
	*py_retval = NULL;
    void *retval;
    int success = 0;
    PyBufferProcs *buffer;
    int segment;
    int bytes_read, bytes_left;

    if(!length) {
        PyErr_SetString(PyExc_RuntimeError, "data length is zero");
	goto _read_from_handle_cleanup;
     }

    if(!(py_retval = PyObject_CallMethod(py_handle, "read", "i", length)))
	goto _read_from_handle_cleanup;
    if(!py_retval->ob_type->tp_as_buffer) {
	PyErr_SetString(PyExc_ValueError, "read method should return buffer");
	goto _read_from_handle_cleanup;
    }
    if(!(py_retval->ob_type->tp_flags & Py_TPFLAGS_DEFAULT)) {
	PyErr_SetString(PyExc_ValueError, "no bf_getcharbuffer slot");
	goto _read_from_handle_cleanup;
    }
    buffer = py_retval->ob_type->tp_as_buffer;
    if(!buffer->bf_getreadbuffer) {
	PyErr_SetString(PyExc_ValueError, "no bf_getreadbuffer");
	goto _read_from_handle_cleanup;
    }

    bytes_left = length;
    segment = 0;
    while(bytes_left > 0) {
	if((bytes_read = buffer->bf_getreadbuffer(py_retval,
						  segment, &retval)) == -1) {
	    PyErr_SetString(PyExc_ValueError, "failed to read from buffer");
	    goto _read_from_handle_cleanup;
        }
	memcpy(wasread, retval, bytes_read);
	wasread = (void *)((char *)wasread + bytes_read);
	bytes_left -= bytes_read;
	segment += 1;
    }

    success = 1;

 _read_from_handle_cleanup:
    if(py_retval) {
	Py_DECREF(py_retval);
    }
    return success;
}
Пример #4
0
static Py_ssize_t get_buffer(PyObject *obj, unsigned char **buf_p, PyObject **tmp_obj_p)
{
	PyBufferProcs *bfp;
	PyObject *str = NULL;
	Py_ssize_t res;

	/* check for None */
	if (obj == Py_None) {
		PyErr_Format(PyExc_TypeError, "None is not allowed");
		return -1;
	}

	/* is string or unicode ? */
	if (PyString_Check(obj) || PyUnicode_Check(obj)) {
		if (PyString_AsStringAndSize(obj, (char**)buf_p, &res) < 0)
			return -1;
		return res;
	}

	/* try to get buffer */
	bfp = obj->ob_type->tp_as_buffer;
	if (bfp && bfp->bf_getsegcount && bfp->bf_getreadbuffer) {
		if (bfp->bf_getsegcount(obj, NULL) == 1)
			return bfp->bf_getreadbuffer(obj, 0, (void**)buf_p);
	}

	/*
	 * Not a string-like object, run str() or it.
	 */

	/* are we in recursion? */
	if (tmp_obj_p == NULL) {
		PyErr_Format(PyExc_TypeError, "Cannot convert to string - get_buffer() recusively failed");
		return -1;
	}

	/* do str() then */
	str = PyObject_Str(obj);
	res = -1;
	if (str != NULL) {
		res = get_buffer(str, buf_p, NULL);
		if (res >= 0) {
			*tmp_obj_p = str;
		} else {
			Py_CLEAR(str);
		}
	}
	return res;
}
Пример #5
0
static Py_ssize_t
_getbuffer(PyObject *obj, Py_buffer *view)
{
    PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;

    if (buffer == NULL || buffer->bf_getbuffer == NULL)
    {
        PyErr_Format(PyExc_TypeError,
                     "Type %.100s doesn't support the buffer API",
                     Py_TYPE(obj)->tp_name);
        return -1;
    }

    if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
        return -1;
    return view->len;
}
Пример #6
0
static launch_data_t
python2launch(PyObject* object)
{
	launch_data_t result;

	if (PyDict_Check(object)) {
		/* PyMapping_Check doesn't work because a lot of sequence types
		 * are mappings as wel to support extended slices a[i:j:k]
		 */
		return pythondict2launch(object);
	} else if (PySequence_Check(object)) {
		return pythonarray2launch(object);
	} else if (PyInt_Check(object)) {
		long value = PyInt_AsLong(object);
		
		result = launch_data_alloc(LAUNCH_DATA_INTEGER);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_integer(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}
	} else if (PyLong_Check(object)) {
		long long value = PyLong_AsLongLong(object);

		result = launch_data_alloc(LAUNCH_DATA_INTEGER);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_integer(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if (PyString_Check(object)) {
		char* value = PyString_AsString(object);

		result = launch_data_alloc(LAUNCH_DATA_STRING);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_string(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if ((PyObject*)(object->ob_type) == file_descriptor_type) {
		long value = PyInt_AsLong(object);
		
		result = launch_data_alloc(LAUNCH_DATA_FD);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_fd(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if ((PyObject*)(object->ob_type) == errno_type) {
		long value = PyInt_AsLong(object);
		
		result = launch_data_alloc(LAUNCH_DATA_ERRNO);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_errno(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if (object->ob_type->tp_as_buffer != NULL) {
		PyBufferProcs* bp = object->ob_type->tp_as_buffer;
		void* ptr;
		size_t size;

		size = bp->bf_getreadbuffer(object, 0, &ptr);
		if (size == (size_t)-1) {
			return NULL;
		}

		result = launch_data_alloc(LAUNCH_DATA_OPAQUE);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_opaque(result, ptr, size)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else {
		PyErr_Format(PyExc_TypeError,
			"Don't know how to convert object of type %s to launch",
			object->ob_type->tp_name);
		return NULL;
	}
}
Пример #7
0
// Convert the Python values to a raw array.
static void *convert_values(Array *array, PyObject *values, GLenum gl_type,
        sipErrorState *estate)
{
#if PY_VERSION_HEX >= 0x02060300
    int rc = sipGetBufferInfo(values, &array->buffer);

    if (rc < 0)
    {
        *estate = sipErrorFail;
        return 0;
    }

    if (rc > 0)
    {
        // Check the buffer is compatible with what we need.
        GLenum array_type;

        switch (*array->buffer.bi_format)
        {
        case 'b':
            array_type = GL_BYTE;
            break;

        case 'B':
            array_type = GL_UNSIGNED_BYTE;
            break;

        case 'h':
            array_type = GL_SHORT;
            break;

        case 'H':
            array_type = GL_UNSIGNED_SHORT;
            break;

        case 'i':
            array_type = GL_INT;
            break;

        case 'I':
            array_type = GL_UNSIGNED_INT;
            break;

        case 'f':
            array_type = GL_FLOAT;
            break;

#if defined(SIP_FEATURE_PyQt_Desktop_OpenGL)
        case 'd':
            array_type = GL_DOUBLE;
            break;
#endif

        default:
            PyErr_Format(PyExc_TypeError, "unsupported buffer type '%s'",
                    array->buffer.bi_format);
            *estate = sipErrorFail;
            return 0;
        }

        if (array_type != gl_type)
        {
            PyErr_SetString(PyExc_TypeError,
                    "the buffer type is not the same as the array type");
            *estate = sipErrorFail;
            return 0;
        }

        return array->buffer.bi_buf;
    }
#else
    PyBufferProcs *bf = Py_TYPE(values)->tp_as_buffer;

    if (bf && bf->bf_getreadbuffer && bf->bf_getsegcount)
    {
        if (bf->bf_getsegcount(values, 0) != 1)
        {
            PyErr_SetString(PyExc_TypeError,
                    "single-segment buffer object expected");
            *estate = sipErrorFail;
            return 0;
        }

        if (bf->bf_getreadbuffer(values, 0, reinterpret_cast<void **>(&array)) < 0)
        {
            *estate = sipErrorFail;
            return 0;
        }

        Py_INCREF(values);
        array->buffer = values;

        return array;
    }
#endif

    PyObject *seq = PySequence_Fast(values,
            "array must be a sequence or a buffer");

    if (!seq)
    {
        *estate = sipErrorContinue;
        return 0;
    }

    Py_ssize_t nr_items = Sequence_Fast_Size(seq);

    if (nr_items < 1)
    {
        Py_DECREF(seq);

        PyErr_SetString(PyExc_TypeError,
                "array must have at least one element");
        *estate = sipErrorFail;
        return 0;
    }

    void (*convertor)(PyObject *, void *, Py_ssize_t);
    size_t element_size;

    switch (gl_type)
    {
    case GL_BYTE:
        convertor = convert_byte;
        element_size = sizeof (GLbyte);
        break;

    case GL_UNSIGNED_BYTE:
        convertor = convert_ubyte;
        element_size = sizeof (GLubyte);
        break;

    case GL_SHORT:
        convertor = convert_short;
        element_size = sizeof (GLshort);
        break;

    case GL_UNSIGNED_SHORT:
        convertor = convert_ushort;
        element_size = sizeof (GLushort);
        break;

    case GL_INT:
        convertor = convert_int;
        element_size = sizeof (GLint);
        break;

    case GL_UNSIGNED_INT:
        convertor = convert_uint;
        element_size = sizeof (GLuint);
        break;

    case GL_FLOAT:
        convertor = convert_float;
        element_size = sizeof (GLfloat);
        break;

#if defined(SIP_FEATURE_PyQt_Desktop_OpenGL)
#if GL_DOUBLE != GL_FLOAT
    case GL_DOUBLE:
        convertor = convert_double;
        element_size = sizeof (GLdouble);
        break;
#endif
#endif

    default:
        Py_DECREF(seq);

        PyErr_SetString(PyExc_TypeError, "unsupported GL element type");
        *estate = sipErrorFail;
        return 0;
    }

    void *data = sipMalloc(nr_items * element_size);

    if (!data)
    {
        Py_DECREF(seq);

        *estate = sipErrorFail;
        return 0;
    }

    for (Py_ssize_t i = 0; i < nr_items; ++i)
    {
        PyErr_Clear();

        convertor(Sequence_Fast_GetItem(seq, i), data, i);

        if (PyErr_Occurred())
        {
            sipFree(data);
            Py_DECREF(seq);

            *estate = sipErrorFail;
            return 0;
        }
    }

    Py_DECREF(seq);

    array->data = data;

    return data;
}