(buffer Protocol)
Python buffer bytes bytearray array.array
Python buffer protocol C :
- "buffer " (buffer object structure)
buffer write() : buffer write() readinto() buffer
buffer:
-
PyObject_GetBuffer(); PyArg_ParseTuple()()y*w*s*format codes
buffer PyBuffer_Release()
buffer
"buffers"PythonPythonC
Python PyObject C memoryview
Buffer Object Structures PyObject_GetBuffer()
-
Py_buffer -
-
void *
obj PyBuffer_Release()NULL C-API
-
Py_ssize_t
len product(shape) * itemsizecontiguouscontiguous contiguous((char *)buf)[0]((char *)buf)[len-1](contiguity)PyBUF_SIMPLEPyBUF_WRITABLE
-
Py_ssize_t
itemsize byte
struct.calcsize()NULLformat:
PyBUF_FORMATformatNULLitemsizeshapeproduct(shape) * itemsize == lenitemsizebufferPyBUF_SIMPLEPyBUF_WRITABLEshapeNULLitemsizeitemsize == 1
-
const char *
format structNUL NULL"B"()
-
int
ndim N
0buf1shape,strides,suboffsetsNULLPyBUF_MAX_NDIM64PyBUF_MAX_NDIM
-
Py_ssize_t *
shape N
ndimPy_ssize_tshape[0] * ... * shape[ndim-1] * itemsizelenshape
shape[n] >= 0shape[n] == 0complex arraysshepe ()
-
Py_ssize_t *
strides ndimPy_ssize_tstrides[n] <= 0complex arraysstrides
-
Py_ssize_t *
suboffsets Py_ssize_tndimsuboffsets[n] >= 0n suboffset suboffset ()suboffset () NULL ()
Python Imaging Library (PIL) complex arrays
suboffsets
-
void *
PyObject_GetBuffer() flags
shape, strides, suboffsets
| shape | strides | suboffsets | |
|---|---|---|---|
| yes | yes | ||
| yes | yes | NULL | |
| yes | NULL | NULL | |
| NULL | NULL | NULL |
| shape | strides | suboffsets | contig | |
|---|---|---|---|---|
| yes | yes | NULL | C | |
| yes | yes | NULL | F | |
| yes | yes | NULL | C F | |
|
yes | NULL | NULL | C |
NumPy : shape, strides
NumPy itemsize, ndim, shape, strides
ndim == 0 buf itemsize
shape strides NULL
strides NULL n C
n :
ptr = (char *)buf + indices[0] * strides[0] + ... + indices[n-1] * strides[n-1]item = *((typeof(item) *)ptr);
def verify_structure(memlen, itemsize, ndim, shape, strides, offset):
"""Verify that the parameters represent a valid array within
the bounds of the allocated memory:
char *mem: start of the physical memory block
memlen: length of the physical memory block
offset: (char *)buf - mem
"""
if offset % itemsize:
return False
if offset < 0 or offset+itemsize > memlen:
return False
if any(v % itemsize for v in strides):
return False
if ndim <= 0:
return ndim == 0 and not shape and not strides
if 0 in shape:
return True
imin = sum(strides[j]*(shape[j]-1) for j in range(ndim)
if strides[j] <= 0)
imax = sum(strides[j]*(shape[j]-1) for j in range(ndim)
if strides[j] > 0)
return 0 <= offset+imin and offset+imax+itemsize <= memlen
PIL : shape, strides, suboffsets
PIL
3 C char v[2][2][3] 2 2 char (*v[2])[2][3]
suboffset 2 buf 2 char x[2][3]
strides suboffsets NULL N N
void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides,
Py_ssize_t *suboffsets, Py_ssize_t *indices) {
char *pointer = (char*)buf;
int i;
for (i = 0; i < ndim; i++) {
pointer += strides[i] * indices[i];
if (suboffsets[i] >=0 ) {
pointer = *((char**)pointer) + suboffsets[i];
}
}
return (void*)pointer;
}