PyObject *engine_buffer_setup(Evas_PyObject *o, PyObject *kwargs) { Evas_Engine_Info_Buffer *einfo; int buflen, w, h; PyObject *value, *buffer; BENCH_START evas_output_method_set(o->evas, evas_render_method_lookup("buffer")); BENCH_END einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(o->evas); if (!einfo) { PyErr_Format(PyExc_SystemError, "Evas is not built with buffer engine support."); return NULL; } einfo->info.func.new_update_region = NULL; einfo->info.func.free_update_region = NULL; einfo->info.use_color_key = 0; einfo->info.alpha_threshold = 0; // Class wrapper ensures these kwargs exist. if (!PyArg_ParseTuple(PyDict_GetItemString(kwargs, "size"), "ii", &w, &h)) return 0; einfo->info.depth_type = PyLong_AsLong(PyDict_GetItemString(kwargs, "depth")); einfo->info.dest_buffer_row_bytes = PyLong_AsLong(PyDict_GetItemString(kwargs, "stride")); einfo->info.dest_buffer = 0; value = PyDict_GetItemString(kwargs, "buffer"); if (!value || value == Py_None) { buffer = PyBuffer_New(einfo->info.dest_buffer_row_bytes * h); if (PyObject_AsWriteBuffer(buffer, &einfo->info.dest_buffer, &buflen) == -1) return 0; } else { if (PyNumber_Check(value)) { einfo->info.dest_buffer = (void *) PyLong_AsLong(value); buffer = PyBuffer_FromReadWriteMemory(einfo->info.dest_buffer, einfo->info.dest_buffer_row_bytes * h); } else { if (PyObject_AsWriteBuffer(value, &einfo->info.dest_buffer, &buflen) == -1) return 0; if (buflen < einfo->info.dest_buffer_row_bytes * h) { PyErr_SetString(PyExc_AttributeError, "Buffer not big enough"); return 0; } buffer = value; Py_INCREF(buffer); } } BENCH_START evas_engine_info_set(o->evas, (Evas_Engine_Info *) einfo); BENCH_END return buffer; }
Py::Object Image::color_conv(const Py::Tuple& args) { _VERBOSE("Image::color_conv"); args.verify_length(1); int format = Py::Int(args[0]); int row_len = colsOut * 4; PyObject* py_buffer = PyBuffer_New(row_len * rowsOut); if (py_buffer ==NULL) throw Py::MemoryError("Image::color_conv could not allocate memory"); void* buf; Py_ssize_t buffer_len; int ret = PyObject_AsWriteBuffer(py_buffer, &buf, &buffer_len); if (ret !=0) throw Py::MemoryError("Image::color_conv could not allocate memory"); agg::rendering_buffer rtmp; rtmp.attach(reinterpret_cast<unsigned char*>(buf), colsOut, rowsOut, row_len); switch (format) { case 0: agg::color_conv(&rtmp, rbufOut, agg::color_conv_rgba32_to_bgra32()); break; case 1: agg::color_conv(&rtmp, rbufOut, agg::color_conv_rgba32_to_argb32()); break; default: throw Py::ValueError("Image::color_conv unknown format"); } PyObject* o = Py_BuildValue("llN", rowsOut, colsOut, py_buffer); return Py::asObject(o); }
static PyObject *DoPyRead_Buffer(nsIInputStream *pI, PyObject *obBuffer, PRUint32 n) { PRUint32 nread; void *buf; Py_ssize_t buf_len; if (PyObject_AsWriteBuffer(obBuffer, &buf, &buf_len) != 0) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "The buffer object does not have a write buffer!"); return NULL; } if ( (buf_len & 0xFFFFFFFF) != buf_len) { PyErr_Clear(); PyErr_SetString(PyExc_RuntimeError, "Python Buffer length overflows 32-bit in PyObject_AsWriteBuffer"); return NULL; } if (n==(PRUint32)-1) { n = buf_len; } else { if (n > buf_len) { NS_WARNING("Warning: PyIInputStream::read() was passed an integer size greater than the size of the passed buffer! Buffer size used.\n"); n = buf_len; } } nsresult r; Py_BEGIN_ALLOW_THREADS; r = pI->Read((char *)buf, n, &nread); Py_END_ALLOW_THREADS; if ( NS_FAILED(r) ) return PyXPCOM_BuildPyException(r); return PyInt_FromLong(nread); }
/** * Return a pointer to the data of a writable buffer from obj. If only a * read-only buffer is available and force is True, a read-write buffer based on * the read-only buffer is obtained. Note that this may have some surprising * effects on buffers which expect the data from their read-only buffer not to * be modified. */ static PyObject* memoryview_get_buffer(PyObject *self, PyObject *args){ PyObject *obj = NULL; int force = 0; PyObject *ret = NULL; void * ptr = NULL; const void* roptr = NULL; Py_ssize_t buflen; Py_buffer buf; if (!PyArg_ParseTuple(args, "O|i", &obj, &force)) return NULL; if (!get_buffer(obj, &buf, force)) { /* new buffer api */ ret = PyLong_FromVoidPtr(buf.buf); free_buffer(&buf); } else { /* old buffer api */ PyErr_Clear(); if (-1 == PyObject_AsWriteBuffer(obj, &ptr, &buflen)) { if (!force) return NULL; PyErr_Clear(); if(-1 == PyObject_AsReadBuffer(obj, &roptr, &buflen)) return NULL; ptr = (void*) roptr; } ret = PyLong_FromVoidPtr(ptr); } return ret; }
BOOL PyWinObject_AsWriteBuffer(PyObject *ob, void **buf, DWORD *buf_len, BOOL bNoneOk) { if (ob==Py_None){ if (bNoneOk){ *buf_len=0; *buf=NULL; return TRUE; } PyErr_SetString(PyExc_TypeError, "Buffer cannot be None"); return FALSE; } Py_ssize_t py_len; if (PyObject_AsWriteBuffer(ob, buf, &py_len)==-1) return FALSE; #ifdef _WIN64 if (py_len>MAXDWORD){ PyErr_Format(PyExc_ValueError,"Buffer length can be at most %d characters", MAXDWORD); return FALSE; } #endif *buf_len=(DWORD)py_len; return TRUE; }
static PyObject *Wiimote_read(Wiimote *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = { "flags", "offset", "len", NULL }; unsigned char flags; unsigned int offset; Py_ssize_t len; void *buf; PyObject *pyRetBuf; if (!self->wiimote) { SET_CLOSED_ERROR; return NULL; } if (!PyArg_ParseTupleAndKeywords(args, kwds, "BII:cwiid.Wiimote.read", kwlist, &flags, &offset, &len)) { return NULL; } if (!(pyRetBuf = PyBuffer_New(len))) { return NULL; } if (PyObject_AsWriteBuffer(pyRetBuf, &buf, &len)) { Py_DECREF(pyRetBuf); return NULL; } if (cwiid_read(self->wiimote,flags,offset,len,buf)) { PyErr_SetString(PyExc_RuntimeError, "Error reading wiimote data"); Py_DECREF(pyRetBuf); return NULL; } return pyRetBuf; }
/*NUMPY_API * Get buffer chunk from object * * this function takes a Python object which exposes the (single-segment) * buffer interface and returns a pointer to the data segment * * You should increment the reference count by one of buf->base * if you will hang on to a reference * * You only get a borrowed reference to the object. Do not free the * memory... */ NPY_NO_EXPORT int PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf) { Py_ssize_t buflen; buf->ptr = NULL; buf->flags = BEHAVED; buf->base = NULL; if (obj == Py_None) { return PY_SUCCEED; } if (PyObject_AsWriteBuffer(obj, &(buf->ptr), &buflen) < 0) { PyErr_Clear(); buf->flags &= ~WRITEABLE; if (PyObject_AsReadBuffer(obj, (const void **)&(buf->ptr), &buflen) < 0) { return PY_FAIL; } } buf->len = (intp) buflen; /* Point to the base of the buffer object if present */ if (PyBuffer_Check(obj)) { buf->base = ((PyArray_Chunk *)obj)->base; } if (buf->base == NULL) { buf->base = obj; } return PY_SUCCEED; }
/*NUMPY_API * Get buffer chunk from object * * this function takes a Python object which exposes the (single-segment) * buffer interface and returns a pointer to the data segment * * You should increment the reference count by one of buf->base * if you will hang on to a reference * * You only get a borrowed reference to the object. Do not free the * memory... */ NPY_NO_EXPORT int PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf) { #if defined(NPY_PY3K) Py_buffer view; #else Py_ssize_t buflen; #endif buf->ptr = NULL; buf->flags = NPY_ARRAY_BEHAVED; buf->base = NULL; if (obj == Py_None) { return NPY_SUCCEED; } #if defined(NPY_PY3K) if (PyObject_GetBuffer(obj, &view, PyBUF_ANY_CONTIGUOUS|PyBUF_WRITABLE) != 0) { PyErr_Clear(); buf->flags &= ~NPY_ARRAY_WRITEABLE; if (PyObject_GetBuffer(obj, &view, PyBUF_ANY_CONTIGUOUS) != 0) { return NPY_FAIL; } } buf->ptr = view.buf; buf->len = (npy_intp) view.len; /* * XXX: PyObject_AsWriteBuffer does also this, but it is unsafe, as there is * no strict guarantee that the buffer sticks around after being released. */ PyBuffer_Release(&view); /* Point to the base of the buffer object if present */ if (PyMemoryView_Check(obj)) { buf->base = PyMemoryView_GET_BASE(obj); } #else if (PyObject_AsWriteBuffer(obj, &(buf->ptr), &buflen) < 0) { PyErr_Clear(); buf->flags &= ~NPY_ARRAY_WRITEABLE; if (PyObject_AsReadBuffer(obj, (const void **)&(buf->ptr), &buflen) < 0) { return NPY_FAIL; } } buf->len = (npy_intp) buflen; /* Point to the base of the buffer object if present */ if (PyBuffer_Check(obj)) { buf->base = ((PyArray_Chunk *)obj)->base; } #endif if (buf->base == NULL) { buf->base = obj; } return NPY_SUCCEED; }
NPY_NO_EXPORT npy_bool _IsWriteable(PyArrayObject *ap) { PyObject *base=PyArray_BASE(ap); #if defined(NPY_PY3K) Py_buffer view; #else void *dummy; Py_ssize_t n; #endif /* If we own our own data, then no-problem */ if ((base == NULL) || (PyArray_FLAGS(ap) & NPY_ARRAY_OWNDATA)) { return NPY_TRUE; } /* * Get to the final base object * If it is a writeable array, then return TRUE * If we can find an array object * or a writeable buffer object as the final base object * or a string object (for pickling support memory savings). * - this last could be removed if a proper pickleable * buffer was added to Python. * * MW: I think it would better to disallow switching from READONLY * to WRITEABLE like this... */ while(PyArray_Check(base)) { if (PyArray_CHKFLAGS((PyArrayObject *)base, NPY_ARRAY_OWNDATA)) { return (npy_bool) (PyArray_ISWRITEABLE((PyArrayObject *)base)); } base = PyArray_BASE((PyArrayObject *)base); } /* * here so pickle support works seamlessly * and unpickled array can be set and reset writeable * -- could be abused -- */ if (PyString_Check(base)) { return NPY_TRUE; } #if defined(NPY_PY3K) if (PyObject_GetBuffer(base, &view, PyBUF_WRITABLE|PyBUF_SIMPLE) < 0) { PyErr_Clear(); return NPY_FALSE; } PyBuffer_Release(&view); #else if (PyObject_AsWriteBuffer(base, &dummy, &n) < 0) { PyErr_Clear(); return NPY_FALSE; } #endif return NPY_TRUE; }
static PyObject * image_surface_create_for_data (PyTypeObject *type, PyObject *args) { cairo_surface_t *surface; cairo_format_t format; unsigned char *buffer; int width, height, stride = -1, res; Py_ssize_t buffer_len; PyObject *obj; if (!PyArg_ParseTuple(args, "Oiii|i:Surface.create_for_data", &obj, &format, &width, &height, &stride)) return NULL; res = PyObject_AsWriteBuffer (obj, (void **)&buffer, &buffer_len); if (res == -1) return NULL; if (width <= 0) { PyErr_SetString(PyExc_ValueError, "width must be positive"); return NULL; } if (height <= 0) { PyErr_SetString(PyExc_ValueError, "height must be positive"); return NULL; } /* if stride is missing, calculate it from width */ if (stride < 0) { switch (format) { case CAIRO_FORMAT_ARGB32: case CAIRO_FORMAT_RGB24: stride = width * 4; break; case CAIRO_FORMAT_RGB16_565: stride = width * 2; break; case CAIRO_FORMAT_A8: stride = width; break; case CAIRO_FORMAT_A1: /* should be stride = (width + 31) / 32 * 4 ? */ stride = (width + 1) / 8; break; default: PyErr_SetString(CairoError, "Unknown format"); return NULL; } } if (height * stride > buffer_len) { PyErr_SetString(PyExc_TypeError, "buffer is not long enough"); return NULL; } surface = cairo_image_surface_create_for_data (buffer, format, width, height, stride); return PycairoSurface_FromSurface(surface, obj); }
int object_as_write_buffer(PyObject *obj, void ** buffer, Py_ssize_t * buffer_len) { Py_buffer *wpybuf; if (PyMemoryView_Check(obj)) { wpybuf = PyMemoryView_GET_BUFFER(obj); if (wpybuf->buf==NULL) return 1; buffer[0] = wpybuf->buf; return 0; } return PyObject_AsWriteBuffer(obj, buffer, buffer_len); }
static PyObject* multiprocessing_address_of_buffer(PyObject *self, PyObject *obj) { void *buffer; Py_ssize_t buffer_len; if (PyObject_AsWriteBuffer(obj, &buffer, &buffer_len) < 0) return NULL; return Py_BuildValue("N" F_PY_SSIZE_T, PyLong_FromVoidPtr(buffer), buffer_len); }
static PyObject *DoPyRead_Size(nsIInputStream *pI, PRUint32 n) { if (n==(PRUint32)-1) { nsresult r; Py_BEGIN_ALLOW_THREADS; r = pI->Available(&n); Py_END_ALLOW_THREADS; if (NS_FAILED(r)) return PyXPCOM_BuildPyException(r); } if (n==0) { // mozilla will assert if we alloc zero bytes. return PyBuffer_New(0); } char *buf = (char *)nsMemory::Alloc(n); if (buf==NULL) { PyErr_NoMemory(); return NULL; } nsresult r; PRUint32 nread; Py_BEGIN_ALLOW_THREADS; r = pI->Read(buf, n, &nread); Py_END_ALLOW_THREADS; PyObject *rc = NULL; if ( NS_SUCCEEDED(r) ) { rc = PyBuffer_New(nread); if (rc != NULL) { void *ob_buf; Py_ssize_t buf_len; if (PyObject_AsWriteBuffer(rc, &ob_buf, &buf_len) != 0) { // should never fail - we just created it! return NULL; } if ( (buf_len & 0xFFFFFFFF) != buf_len) { PyErr_SetString(PyExc_RuntimeError, "Python Buffer length overflows 32-bit in PyObject_AsWriteBuffer"); return NULL; } if (buf_len != nread) { PyErr_SetString(PyExc_RuntimeError, "New buffer isn't the size we created it!"); return NULL; } memcpy(ob_buf, buf, nread); } } else PyXPCOM_BuildPyException(r); nsMemory::Free(buf); return rc; }
static PyObject * xpybCookie_reply(xpybCookie *self, PyObject *args) { xcb_generic_error_t *error; xcb_generic_reply_t *data; PyObject *shim, *reply; int is_void; void *buf; Py_ssize_t len; xpybRequest_get_attributes(self->request, &is_void, NULL, NULL); /* Check arguments and connection. */ if (is_void) { PyErr_SetString(xpybExcept_base, "Request has no reply."); return NULL; } if (xpybConn_invalid(self->conn)) return NULL; /* Make XCB call */ data = xcb_wait_for_reply(self->conn->conn, self->cookie.sequence, &error); if (xpybError_set(self->conn, error)) return NULL; if (data == NULL) { PyErr_SetString(PyExc_IOError, "I/O error on X server connection."); return NULL; } /* Create a shim protocol object */ shim = PyBuffer_New(32 + data->length * 4); if (shim == NULL) goto err1; if (PyObject_AsWriteBuffer(shim, &buf, &len) < 0) goto err2; memcpy(buf, data, len); free(data); /* Call the reply type object to get a new xcb.Reply instance */ reply = PyObject_CallFunctionObjArgs((PyObject *)self->reply_type, shim, NULL); Py_DECREF(shim); return reply; err2: Py_DECREF(shim); err1: free(data); return NULL; }
PyObject * render_svg_to_buffer(PyObject *module, PyObject *args, PyObject *kwargs) { int len, w, h, i; guchar *svgdata; GError *error; RsvgHandle *svg; GdkPixbuf *pixbuf; gboolean res; size_cb_data cbdata; PyObject *buffer; guchar *buffer_ptr; if (!PyArg_ParseTuple(args, "iis#", &w, &h, &svgdata, &len)) return NULL; cbdata.w = w; cbdata.h = h; svg = rsvg_handle_new(); rsvg_handle_set_size_callback(svg, size_cb, &cbdata, NULL); res = rsvg_handle_write(svg, svgdata, len, &error); res = rsvg_handle_close(svg, &error); pixbuf = rsvg_handle_get_pixbuf(svg); rsvg_handle_free(svg); w = gdk_pixbuf_get_width(pixbuf); h = gdk_pixbuf_get_height(pixbuf); buffer = PyBuffer_New(w*h*4); PyObject_AsWriteBuffer(buffer, (void **)&buffer_ptr, &len); memcpy(buffer_ptr, gdk_pixbuf_get_pixels(pixbuf), w*h*4); g_object_unref(pixbuf); // RGBA to BGRA conversion. // FIXME: MMXify. for (i = 0; i < w*h*4; i+=4) { guchar save = buffer_ptr[i+2]; buffer_ptr[i+2] = buffer_ptr[i]; buffer_ptr[i] = save; } return Py_BuildValue("(iiO)", w, h, buffer); }
void py_curand_get_scramble_constants32(py::object dst, int count) { void *buf; PYCUDA_BUFFER_SIZE_T len; int n = 0; if (PyObject_AsWriteBuffer(dst.ptr(), &buf, &len)) throw py::error_already_set(); unsigned int *vectors; CURAND_CALL_GUARDED(curandGetScrambleConstants32, (&vectors)); // Documentation does not mention number of dimensions // Assuming the same as in getDirectionVectors* while (count > 0) { int size = ((count > 20000) ? 20000 : count)*sizeof(unsigned int); memcpy((unsigned int *)buf+n*20000, vectors, size); count -= size/sizeof(unsigned int); n++; } }
void copy_tile_data_to_py_array(const Tile& tile, bpy::object& buffer) { void* array = 0; Py_ssize_t len; const int success = PyObject_AsWriteBuffer(buffer.ptr(), &array, &len); if (success != 0) bpy::throw_error_already_set(); if (static_cast<size_t>(len) < tile.get_size()) { PyErr_SetString(PyExc_IndexError, "Buffer size is smaller than data size"); bpy::throw_error_already_set(); } std::copy( tile.get_storage(), tile.get_storage() + tile.get_size(), reinterpret_cast<uint8*>(array)); }
/* Note: this has been copied verbatim from <opencv_root>/interfaces/python/cv.cpp */ static int convert_to_IplImage(PyObject *o, IplImage **dst) { iplimage_t *ipl = (iplimage_t*)o; void *buffer; Py_ssize_t buffer_len; if (!is_iplimage(o)) { return -1; //failmsg("Argument must be IplImage"); } else if (PyString_Check(ipl->data)) { cvSetData(ipl->a, PyString_AsString(ipl->data) + ipl->offset, ipl->a->widthStep); assert(cvGetErrStatus() == 0); *dst = ipl->a; return 1; } else if (ipl->data && PyObject_AsWriteBuffer(ipl->data, &buffer, &buffer_len) == 0) { cvSetData(ipl->a, (void*)((char*)buffer + ipl->offset), ipl->a->widthStep); assert(cvGetErrStatus() == 0); *dst = ipl->a; return 1; } else { return -1;// failmsg("IplImage argument has no data"); } }
void py_curand_get_direction_vectors( curandDirectionVectorSet_t set, py::object dst, int count) { void *buf; PYCUDA_BUFFER_SIZE_T len; int n = 0; if (PyObject_AsWriteBuffer(dst.ptr(), &buf, &len)) throw py::error_already_set(); if (CURAND_DIRECTION_VECTORS_32_JOEKUO6 == set #if CUDAPP_CUDA_VERSION >= 4000 || CURAND_SCRAMBLED_DIRECTION_VECTORS_32_JOEKUO6 == set #endif ) { curandDirectionVectors32_t *vectors; CURAND_CALL_GUARDED(curandGetDirectionVectors32, (&vectors, set)); while (count > 0) { int size = ((count > 20000) ? 20000 : count)*sizeof(curandDirectionVectors32_t); memcpy((unsigned int *)buf+n*20000*sizeof(curandDirectionVectors32_t)/sizeof(unsigned int), vectors, size); count -= size/sizeof(curandDirectionVectors32_t); n++; } } #if CUDAPP_CUDA_VERSION >= 4000 if (CURAND_DIRECTION_VECTORS_64_JOEKUO6 == set || CURAND_SCRAMBLED_DIRECTION_VECTORS_64_JOEKUO6 == set) { curandDirectionVectors64_t *vectors; CURAND_CALL_GUARDED(curandGetDirectionVectors64, (&vectors, set)); while (count > 0) { int size = ((count > 20000) ? 20000 : count)*sizeof(curandDirectionVectors64_t); memcpy((unsigned long long *)buf+n*20000*sizeof(curandDirectionVectors64_t)/sizeof(unsigned long long), vectors, size); count -= size/sizeof(curandDirectionVectors64_t); n++; } } #endif }
/*NUMPY_API * Get buffer chunk from object * * this function takes a Python object which exposes the (single-segment) * buffer interface and returns a pointer to the data segment * * You should increment the reference count by one of buf->base * if you will hang on to a reference * * You only get a borrowed reference to the object. Do not free the * memory... */ NPY_NO_EXPORT int PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf) { Py_ssize_t buflen; buf->ptr = NULL; buf->flags = NPY_ARRAY_BEHAVED; buf->base = NULL; if (obj == Py_None) { return NPY_SUCCEED; } if (PyObject_AsWriteBuffer(obj, &(buf->ptr), &buflen) < 0) { PyErr_Clear(); buf->flags &= ~NPY_ARRAY_WRITEABLE; if (PyObject_AsReadBuffer(obj, (const void **)&(buf->ptr), &buflen) < 0) { return NPY_FAIL; } } buf->len = (npy_intp) buflen; /* Point to the base of the buffer object if present */ #if defined(NPY_PY3K) if (PyMemoryView_Check(obj)) { buf->base = PyMemoryView_GET_BASE(obj); } #else if (PyBuffer_Check(obj)) { buf->base = ((PyArray_Chunk *)obj)->base; } #endif if (buf->base == NULL) { buf->base = obj; } return NPY_SUCCEED; }
PyObject *TileEngine::getTileData( PyObject *tileFunction, PyObject *tileMap, int col, int row, int cols, int rows, int code, PyObject *tileViewCache) { if ((tileFunction != Py_None) && !PyCallable_Check(tileFunction)) { PyErr_SetString( PyExc_TypeError, "expected tileFunction to be a callable function or None"); Py_INCREF(Py_None); return Py_None; } const int *tileMapData = NULL; unsigned int tileMapCount = 0; if (tileMap != Py_None) { if (!PySequence_Check(tileMap)) { PyErr_SetString( PyExc_TypeError, "expected tileMap to be an array " "of 4 byte integers or None"); Py_INCREF(Py_None); return Py_None; } tileMapCount = (unsigned int)PySequence_Size(tileMap); Py_ssize_t tileMapLength = 0; if (PyObject_AsReadBuffer( tileMap, (const void **)&tileMapData, &tileMapLength) != 0) { PyErr_SetString( PyExc_TypeError, "expected tileMap with read buffer"); Py_INCREF(Py_None); return Py_None; } int tileMapDataCount = (int)tileMapLength / sizeof(unsigned int); if (tileMapDataCount != (int)tileMapCount) { PyErr_SetString( PyExc_TypeError, "expected tileMap read buffer of 4 byte integers"); Py_INCREF(Py_None); return Py_None; } } int *tileViewCacheData = NULL; int tileViewCacheCount = 0; if (tileViewCache != Py_None) { tileViewCacheCount = (unsigned int)PySequence_Size(tileViewCache); Py_ssize_t tileViewCacheLength = 0; if ((tileViewCacheCount != (width * height)) || (PyObject_AsWriteBuffer( tileViewCache, (void **)&tileViewCacheData, &tileViewCacheLength) != 0)) { PyErr_SetString( PyExc_TypeError, "expected tileViewCache with write buffer"); Py_INCREF(Py_None); return Py_None; } } const char *textCodeString = "0123456789" "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ+-"; int tileSize = sizeof(unsigned short); int r, c; int bufSize = 0; char *buf = NULL; bool returnBuffer = false; switch (code) { case TILE_CODE_RAW_BINARY_16: { bufSize = tileSize * rows * cols; buf = (char *)malloc(bufSize); unsigned char *dst = (unsigned char *)buf; for (r = 0; r < rows; r++) { for (c = 0; c < cols; c++) { int tile = getValue( col + c, row + r, tileFunction, tileMapData, tileMapCount); *dst++ = (tile >> 8) & 0xff; // High byte. *dst++ = tile & 0xff; // Low byte. } } break; } case TILE_CODE_COMPRESSED_TEXT: { bufSize = tileSize * rows * cols * 3; // to be safe buf = (char *)malloc(bufSize); unsigned char *dst = (unsigned char *)buf; int tileIndex = 0; int tileIndexMax = rows * cols; int offset = 0; int skip = 0; while ((tileIndex < tileIndexMax) && (offset < bufSize)) { int c = tileIndex % cols; int r = tileIndex / cols; int tileCacheOffset = (col + c) + ((row + r) * width); // printf("tileIndex %d tileCacheOffset %d tileViewCacheCount %d c %d r %d cols %d rows %d ", // tileIndex, // tileCacheOffset, // tileViewCacheCount, // c, r, cols, rows); int tile = getValue( col + c, row + r, tileFunction, tileMapData, tileMapCount); // printf("tile %d\n", tile); int curTile = (tileViewCacheData == NULL) ? -1 : tileViewCacheData[tileCacheOffset]; if (tile == curTile) { skip++; } else { // printf("tile %d skip %d offset %d r %d c %d index %d\n", tile, skip, offset, r, c, c + (r * width)); if (skip) { if (skip == 1) { // printf("skip 1\n"); *dst++ = TILE_CODE_COMPRESSED_TEXT_SKIP_0; offset++; } else if (skip == 2) { // printf("skip 2/1\n"); *dst++ = TILE_CODE_COMPRESSED_TEXT_SKIP_0; *dst++ = TILE_CODE_COMPRESSED_TEXT_SKIP_0; offset += 2; } else if (skip < 64) { // printf("skip %d/64\n", skip); int val = skip; *dst++ = TILE_CODE_COMPRESSED_TEXT_SKIP_1; *dst++ = textCodeString[val]; offset += 2; } else if (skip < 4096) { // printf("skip %d/4096\n", skip); int val = skip; *dst++ = TILE_CODE_COMPRESSED_TEXT_SKIP_2; *dst++ = textCodeString[(val >> 6) & 63]; // High. *dst++ = textCodeString[val & 63]; // Low. offset += 3; } else { // printf("skip %d/999999\n", skip); int val = skip; *dst++ = TILE_CODE_COMPRESSED_TEXT_SKIP_3; *dst++ = textCodeString[(val >> 12) & 63]; // Highest. *dst++ = textCodeString[(val >> 6) & 63]; // High. *dst++ = textCodeString[val & 63]; // Low. offset += 4; } skip = 0; } if (tileViewCacheData != NULL) { tileViewCacheData[tileCacheOffset] = tile; } int low = tile & 63; int high = (tile >> 6) & 63; *dst++ = textCodeString[low]; *dst++ = textCodeString[high]; offset += 2; } tileIndex++; } bufSize = offset; break; }
void TileEngine::renderTilesLazy( cairo_t *ctx, PyObject *tileFunction, PyObject *tileMap, int tileSize, int renderCol, int renderRow, int renderCols, int renderRows, double alpha, PyObject *tileGenerator, PyObject *tileCache, PyObject *tileCacheSurfaces, PyObject *tileState) { if ((tileFunction != Py_None) && !PyCallable_Check(tileFunction)) { PyErr_SetString( PyExc_TypeError, "expected tileFunction to be a callable function or None"); return; } // The tileMap should be None, or an array of 4 byte integers, // mapping virtual tiles indices to absolute tile numbers. const int *tileMapData = NULL; unsigned int tileMapCount = 0; if (tileMap != Py_None) { if (!PySequence_Check(tileMap)) { PyErr_SetString( PyExc_TypeError, "expected tileMap to be an array " "of 4 byte integers or None"); return; } tileMapCount = (unsigned int)PySequence_Size(tileMap); Py_ssize_t tileMapLength = 0; if (PyObject_AsReadBuffer( tileMap, (const void **)&tileMapData, &tileMapLength) != 0) { PyErr_SetString( PyExc_TypeError, "expected tileMap with read buffer"); return; } int tileMapDataCount = (int)tileMapLength / sizeof(unsigned int); if (tileMapDataCount != (int)tileMapCount) { PyErr_SetString( PyExc_TypeError, "expected tileMap read buffer of 4 byte integers"); return; } } // The tileGenerator should be a function that takes one integer // tile parameter, and returns a tuple of three integers: a // surface index, a tileX and a tileY position. if (!PyCallable_Check(tileGenerator)) { PyErr_SetString( PyExc_TypeError, "expected tileGenerator callable object"); return; } // The tileCache should be an array of integers, 4 integers per // tile. The first is a "cached" flag, the second is a surface // index, the 3rd and 4th are a tileX and tileY position. int *tileCacheData = NULL; Py_ssize_t tileCacheLength = 0; if (PyObject_AsWriteBuffer( tileCache, (void **)&tileCacheData, &tileCacheLength) != 0) { PyErr_SetString( PyExc_TypeError, "expected tileCache array"); return; } // The tileCacheSurfaces parameters should be a list of Cairo // surfaces. if (!PySequence_Check(tileCacheSurfaces)) { PyErr_SetString( PyExc_TypeError, "expected tileCacheSurfaces sequence"); return; } // The tileState parameters should be None or a list of tile state // parameters. if ((tileState != Py_None) && !PySequence_Check(tileState)) { PyErr_SetString( PyExc_TypeError, "expected tileState sequence or None"); return; } int renderX = renderCol * tileSize; int renderY = renderRow * tileSize; int r; for (r = 0; r < renderRows; r++) { int c; for (c = 0; c < renderCols; c++) { int col = (renderCol + c) % width; int row = (renderRow + r) % height; unsigned long tile = getValue( col, row, tileFunction, tileMapData, tileMapCount); double x = col * tileSize; double y = row * tileSize; // Get the tile surface index, tileX and tileY from the // cache, or call the tileGenerator function to produce // them, if they are not already cached. int cacheOffset = tile * 4; int tileSurfaceIndex = 0; int tileX = 0; int tileY = 0; if (tileCacheData[cacheOffset + 0]) { // The tile is already cached. // Get the values from the tileCache. tileSurfaceIndex = tileCacheData[cacheOffset + 1]; tileX = tileCacheData[cacheOffset + 2]; tileY = tileCacheData[cacheOffset + 3]; } else { // The tile has not already been cached. Call the // tileGenerator function to produce the tile, passing // it the absolute tile number as a parameter. // Mark the tile as cached, so we don't do this again. tileCacheData[cacheOffset + 0] = 1; PyObject *result = PyObject_CallFunction( tileGenerator, "i", tile); // The tile function returns a tuple of three numbers: // the surface index (into the tileCacheSurfaces array // of Cairo surfaces), the tileX and tileY position in // the surface. if (result == NULL) { PyErr_SetString( PyExc_TypeError, "tile generator did not return a result"); return; } int success = PyArg_ParseTuple( result, "iii", &tileSurfaceIndex, &tileX, &tileY); Py_DECREF(result); if (!success) { PyErr_SetString( PyExc_TypeError, "tile generator return wrong number of " "results in tuple"); return; } // Cache the returned values. tileCacheData[cacheOffset + 1] = tileSurfaceIndex; tileCacheData[cacheOffset + 2] = tileX; tileCacheData[cacheOffset + 3] = tileY; } // Get the Python object wrapping the Cairo surface for // the tile. PyObject *tiles = PySequence_GetItem( tileCacheSurfaces, tileSurfaceIndex); if (tiles == NULL) { PyErr_SetString( PyExc_TypeError, "tile generator returned invalid tile " "surface index"); return; } if (!PyObject_TypeCheck( tiles, &PycairoSurface_Type)) { PyErr_SetString( PyExc_TypeError, "expected cairo_surface_t objects " "in tileCacheSurfaces"); return; } // Get the cairo_surface_t from the Python object. cairo_surface_t *tilesSurf = PycairoSurface_GET(tiles); Py_DECREF(tiles); // Draw a tile. cairo_save(ctx); cairo_translate( ctx, x - renderX, y - renderY); cairo_rectangle( ctx, 0, 0, tileSize, tileSize); cairo_clip(ctx); cairo_set_source_surface( ctx, tilesSurf, -tileX, -tileY); if (alpha >= 1.0) { cairo_paint(ctx); } else { cairo_paint_with_alpha(ctx, alpha); } cairo_restore(ctx); } } }
PyObject *lightblueobex_readheaders(obex_t *obex, obex_object_t *obj) { PyObject *headers; uint8_t hi; obex_headerdata_t hv; uint32_t hv_size; int r; PyObject *value = NULL; DEBUG("%s()\n", __func__); headers = PyDict_New(); if (headers == NULL) return NULL; if (obex == NULL || obj == NULL || headers == NULL) { DEBUG("\treadheaders() got null argument\n"); return NULL; } if (!PyDict_Check(headers)) { DEBUG("\treadheaders() arg must be dict\n"); return NULL; } while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hv, &hv_size)) { DEBUG("\tread header: 0x%02x\n", hi); switch (hi & OBEX_HI_MASK) { case OBEX_UNICODE: { if (hv_size < 2) { value = PyUnicode_FromUnicode(NULL, 0); } else { /* hv_size-2 for 2-byte null terminator */ int byteorder = OBEX_BIG_ENDIAN; value = PyUnicode_DecodeUTF16((const char*)hv.bs, hv_size-2, NULL, &byteorder); if (value == NULL) { DEBUG("\terror reading unicode header 0x%02x\n", hi); if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); /* let caller set exception */ } return NULL; } } break; } case OBEX_BYTE_STREAM: { value = PyBuffer_New(hv_size); if (value != NULL) { void *buf; Py_ssize_t buflen; if (PyObject_AsWriteBuffer(value, &buf, &buflen) < 0) { Py_DECREF(value); DEBUG("\terror writing to buffer for header 0x%02x\n", hi); return NULL; } memcpy(buf, hv.bs, buflen); } break; } case OBEX_BYTE: { value = PyInt_FromLong(hv.bq1); break; } case OBEX_INT: { value = PyLong_FromUnsignedLong(hv.bq4); break; } default: DEBUG("\tunknown header id encoding %d\n", (hi & OBEX_HI_MASK)); return NULL; } if (value == NULL) { if (PyErr_Occurred() == NULL) DEBUG("\terror reading headers\n"); return NULL; } r = PyDict_SetItem(headers, PyInt_FromLong((long)hi), value); Py_DECREF(value); if (r < 0) { DEBUG("\tPyDict_SetItem() error\n"); if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); /* let caller set exception */ } return NULL; } } return headers; }
/*NUMPY_API * Get buffer chunk from object * * this function takes a Python object which exposes the (single-segment) * buffer interface and returns a pointer to the data segment * * You should increment the reference count by one of buf->base * if you will hang on to a reference * * You only get a borrowed reference to the object. Do not free the * memory... */ NPY_NO_EXPORT int PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf) { #if defined(NPY_PY3K) Py_buffer view; #else Py_ssize_t buflen; #endif buf->ptr = NULL; buf->flags = NPY_ARRAY_BEHAVED; buf->base = NULL; if (obj == Py_None) { return NPY_SUCCEED; } #if defined(NPY_PY3K) if (PyObject_GetBuffer(obj, &view, PyBUF_ANY_CONTIGUOUS|PyBUF_WRITABLE|PyBUF_SIMPLE) != 0) { PyErr_Clear(); buf->flags &= ~NPY_ARRAY_WRITEABLE; if (PyObject_GetBuffer(obj, &view, PyBUF_ANY_CONTIGUOUS|PyBUF_SIMPLE) != 0) { return NPY_FAIL; } } buf->ptr = view.buf; buf->len = (npy_intp) view.len; /* * In Python 3 both of the deprecated functions PyObject_AsWriteBuffer and * PyObject_AsReadBuffer that this code replaces release the buffer. It is * up to the object that supplies the buffer to guarantee that the buffer * sticks around after the release. */ PyBuffer_Release(&view); _dealloc_cached_buffer_info(obj); /* Point to the base of the buffer object if present */ if (PyMemoryView_Check(obj)) { buf->base = PyMemoryView_GET_BASE(obj); } #else if (PyObject_AsWriteBuffer(obj, &(buf->ptr), &buflen) < 0) { PyErr_Clear(); buf->flags &= ~NPY_ARRAY_WRITEABLE; if (PyObject_AsReadBuffer(obj, (const void **)&(buf->ptr), &buflen) < 0) { return NPY_FAIL; } } buf->len = (npy_intp) buflen; /* Point to the base of the buffer object if present */ if (PyBuffer_Check(obj)) { buf->base = ((PyArray_Chunk *)obj)->base; } #endif if (buf->base == NULL) { buf->base = obj; } return NPY_SUCCEED; }
static PyObject *DoPyRead_Buffer(nsIInputStream *pI, PyObject *obBuffer, PRUint32 n) { PRUint32 nread; void *buf; #ifndef VBOX /* unsafe cast on 64-bit hosts. */ PRUint32 buf_len; if (PyObject_AsWriteBuffer(obBuffer, &buf, (Py_ssize_t *)&buf_len) != 0) { #else /* VBOX */ # if PY_VERSION_HEX >= 0x02050000 || defined(PY_SSIZE_T_MIN) Py_ssize_t buf_len; # else int buf_len; # endif /* VBOX */ if (PyObject_AsWriteBuffer(obBuffer, &buf, &buf_len) != 0) { #endif PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "The buffer object does not have a write buffer!"); return NULL; } if (n==(PRUint32)-1) { n = buf_len; } else { if (n > buf_len) { NS_WARNING("Warning: PyIInputStream::read() was passed an integer size greater than the size of the passed buffer! Buffer size used.\n"); n = buf_len; } } nsresult r; Py_BEGIN_ALLOW_THREADS; r = pI->Read((char *)buf, n, &nread); Py_END_ALLOW_THREADS; if ( NS_FAILED(r) ) return PyXPCOM_BuildPyException(r); return PyInt_FromLong(nread); } static PyObject *DoPyRead_Size(nsIInputStream *pI, PRUint32 n) { if (n==(PRUint32)-1) { nsresult r; Py_BEGIN_ALLOW_THREADS; r = pI->Available(&n); Py_END_ALLOW_THREADS; if (NS_FAILED(r)) return PyXPCOM_BuildPyException(r); } if (n==0) { // mozilla will assert if we alloc zero bytes. #if PY_MAJOR_VERSION <= 2 return PyBuffer_New(0); #else return PyBytes_FromString(""); #endif } char *buf = (char *)nsMemory::Alloc(n); if (buf==NULL) { PyErr_NoMemory(); return NULL; } nsresult r; PRUint32 nread; Py_BEGIN_ALLOW_THREADS; r = pI->Read(buf, n, &nread); Py_END_ALLOW_THREADS; PyObject *rc = NULL; if ( NS_SUCCEEDED(r) ) { #if PY_MAJOR_VERSION <= 2 rc = PyBuffer_New(nread); if (rc != NULL) { void *ob_buf; #ifndef VBOX /* unsafe cast on 64-bit hosts. */ PRUint32 buf_len; if (PyObject_AsWriteBuffer(rc, &ob_buf, (Py_ssize_t *)&buf_len) != 0) { #else /* VBOX */ # if PY_VERSION_HEX >= 0x02050000 || defined(PY_SSIZE_T_MIN) Py_ssize_t buf_len; # else int buf_len; # endif /* VBOX */ if (PyObject_AsWriteBuffer(rc, &ob_buf, &buf_len) != 0) { #endif // should never fail - we just created it! return NULL; } if (buf_len != nread) { PyErr_SetString(PyExc_RuntimeError, "New buffer isnt the size we create it!"); return NULL; } memcpy(ob_buf, buf, nread); } #else rc = PyBytes_FromStringAndSize(buf, nread); #endif } else PyXPCOM_BuildPyException(r); nsMemory::Free(buf); return rc; } static PyObject *PyRead(PyObject *self, PyObject *args) { PyObject *obBuffer = NULL; PRUint32 n = (PRUint32)-1; nsIInputStream *pI = GetI(self); if (pI==NULL) return NULL; if (PyArg_ParseTuple(args, "|i", (int *)&n)) // This worked - no args, or just an int. return DoPyRead_Size(pI, n); // try our other supported arg format. PyErr_Clear(); if (!PyArg_ParseTuple(args, "O|i", &obBuffer, (int *)&n)) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "'read()' must be called as (buffer_ob, int_size=-1) or (int_size=-1)"); return NULL; } return DoPyRead_Buffer(pI, obBuffer, n); } struct PyMethodDef PyMethods_IInputStream[] = { { "read", PyRead, 1}, // The rest are handled as normal {NULL} };