[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
This commit is contained in:
pre-commit-ci[bot] 2025-01-21 21:41:54 +00:00
parent 97eb7c09ba
commit f1349e973d
8 changed files with 413 additions and 414 deletions

View File

@ -1,19 +1,20 @@
from __future__ import annotations
import warnings
from typing import Any # undone
import pytest
from PIL import Image
from .helper import assert_deep_equal, assert_image, hopper, skip_unless_feature, assert_image_equal
from typing import Any # undone
from .helper import (
assert_deep_equal,
assert_image_equal,
hopper,
)
pyarrow = pytest.importorskip("pyarrow", reason="PyArrow not installed")
TEST_IMAGE_SIZE = (10, 10)
from numbers import Number
def _test_img_equals_pyarray(img: Image.Image, arr: Any, mask) -> None:
@ -24,19 +25,16 @@ def _test_img_equals_pyarray(img: Image.Image, arr: Any, mask) -> None:
for y in range(0, img.size[1], int(img.size[1] / 10)):
if mask:
for ix, elt in enumerate(mask):
assert px[x,y][ix] == arr[y * img.width + x].as_py()[elt]
assert px[x, y][ix] == arr[y * img.width + x].as_py()[elt]
else:
assert_deep_equal(px[x, y], arr[y * img.width + x].as_py())
# really hard to get a non-nullable list type
fl_uint8_4_type = pyarrow.field("_",
pyarrow.list_(
pyarrow.field("_",
pyarrow.uint8()
).with_nullable(False)
,4)
).type
fl_uint8_4_type = pyarrow.field(
"_", pyarrow.list_(pyarrow.field("_", pyarrow.uint8()).with_nullable(False), 4)
).type
@pytest.mark.parametrize(
"mode, dtype, mask",
@ -44,16 +42,16 @@ fl_uint8_4_type = pyarrow.field("_",
("L", pyarrow.uint8(), None),
("I", pyarrow.int32(), None),
("F", pyarrow.float32(), None),
("LA", fl_uint8_4_type, [0,3]),
("RGB", fl_uint8_4_type, [0,1,2]),
("LA", fl_uint8_4_type, [0, 3]),
("RGB", fl_uint8_4_type, [0, 1, 2]),
("RGBA", fl_uint8_4_type, None),
("RGBX", fl_uint8_4_type, None),
("CMYK", fl_uint8_4_type, None),
("YCbCr", fl_uint8_4_type, [0,1,2]),
("HSV", fl_uint8_4_type, [0,1,2]),
("YCbCr", fl_uint8_4_type, [0, 1, 2]),
("HSV", fl_uint8_4_type, [0, 1, 2]),
),
)
def test_to_array(mode: str, dtype: Any, mask: Any ) -> None:
def test_to_array(mode: str, dtype: Any, mask: Any) -> None:
img = hopper(mode)
# Resize to non-square
@ -70,39 +68,40 @@ def test_to_array(mode: str, dtype: Any, mask: Any ) -> None:
assert_image_equal(img, reloaded)
def test_lifetime():
# valgrind shouldn't error out here.
# arrays should be accessible after the image is deleted.
img = hopper('L')
img = hopper("L")
arr_1 = pyarrow.array(img)
arr_2 = pyarrow.array(img)
del(img)
del img
assert arr_1.sum().as_py() > 0
del(arr_1)
del arr_1
assert arr_2.sum().as_py() > 0
del(arr_2)
del arr_2
def test_lifetime2():
# valgrind shouldn't error out here.
# img should remain after the arrays are collected.
img = hopper('L')
img = hopper("L")
arr_1 = pyarrow.array(img)
arr_2 = pyarrow.array(img)
assert arr_1.sum().as_py() > 0
del(arr_1)
del arr_1
assert arr_2.sum().as_py() > 0
del(arr_2)
del arr_2
img2 = img.copy()
px = img2.load()
assert isinstance(px[0,0], int)
assert isinstance(px[0, 0], int)

View File

@ -61,12 +61,12 @@ optional-dependencies.tests = [
"markdown2",
"olefile",
"packaging",
"pyarrow",
"pyroma",
"pytest",
"pytest-cov",
"pytest-timeout",
"trove-classifiers>=2024.10.12",
"pyarrow",
]
optional-dependencies.typing = [
"typing-extensions; python_version<'3.10'",

View File

@ -748,12 +748,13 @@ class Image:
new["shape"], new["typestr"] = _conv_type_shape(self)
return new
def __arrow_c_schema__(self) -> object:
self.load()
return self.im.__arrow_c_schema__()
def __arrow_c_array__(self, requested_schema: object | None = None) -> Tuple[object, object]:
def __arrow_c_array__(
self, requested_schema: object | None = None
) -> Tuple[object, object]:
self.load()
return (self.im.__arrow_c_schema__(), self.im.__arrow_c_array__())
@ -3258,12 +3259,15 @@ class SupportsArrayInterface(Protocol):
def __array_interface__(self) -> dict[str, Any]:
raise NotImplementedError()
class SupportsArrowArrayInterface(Protocol):
"""
An object that has an ``__arrow_c_array__`` method corresponding to the arrow c data interface.
"""
def __arrow_c_array__(self, requested_schema:"PyCapsule"=None) -> tuple["PyCapsule", "PyCapsule"]:
def __arrow_c_array__(
self, requested_schema: PyCapsule = None
) -> tuple[PyCapsule, PyCapsule]:
raise NotImplementedError()
@ -3356,12 +3360,12 @@ def fromarray(obj: SupportsArrayInterface, mode: str | None = None) -> Image:
def fromarrow(obj: SupportsArrowArrayIngerface, mode, size) -> ImageFile.ImageFile:
if not hasattr(obj, '__arrow_c_array__'):
if not hasattr(obj, "__arrow_c_array__"):
raise ValueError("arrow_c_array interface not found")
(schema_capsule, array_capsule) = obj.__arrow_c_array__()
_im = core.new_arrow(mode, size, schema_capsule, array_capsule)
if (_im):
if _im:
return Image()._new(_im)
return None

View File

@ -227,39 +227,42 @@ PyImaging_GetBuffer(PyObject *buffer, Py_buffer *view) {
/* Arrow HANDLING */
/* -------------------------------------------------------------------- */
void ReleaseArrowSchemaPyCapsule(PyObject* capsule) {
struct ArrowSchema* schema =
(struct ArrowSchema*)PyCapsule_GetPointer(capsule, "arrow_schema");
void
ReleaseArrowSchemaPyCapsule(PyObject *capsule) {
struct ArrowSchema *schema =
(struct ArrowSchema *)PyCapsule_GetPointer(capsule, "arrow_schema");
if (schema->release != NULL) {
schema->release(schema);
}
free(schema);
}
PyObject* ExportArrowSchemaPyCapsule(ImagingObject *self) {
struct ArrowSchema* schema =
(struct ArrowSchema*)calloc(1, sizeof(struct ArrowSchema));
PyObject *
ExportArrowSchemaPyCapsule(ImagingObject *self) {
struct ArrowSchema *schema =
(struct ArrowSchema *)calloc(1, sizeof(struct ArrowSchema));
export_imaging_schema(self->image, schema);
return PyCapsule_New(schema, "arrow_schema", ReleaseArrowSchemaPyCapsule);
}
void ReleaseArrowArrayPyCapsule(PyObject* capsule) {
struct ArrowArray* array =
(struct ArrowArray*)PyCapsule_GetPointer(capsule, "arrow_array");
void
ReleaseArrowArrayPyCapsule(PyObject *capsule) {
struct ArrowArray *array =
(struct ArrowArray *)PyCapsule_GetPointer(capsule, "arrow_array");
if (array->release != NULL) {
array->release(array);
}
free(array);
}
PyObject* ExportArrowArrayPyCapsule(ImagingObject *self) {
struct ArrowArray* array =
(struct ArrowArray*)calloc(1, sizeof(struct ArrowArray));
PyObject *
ExportArrowArrayPyCapsule(ImagingObject *self) {
struct ArrowArray *array =
(struct ArrowArray *)calloc(1, sizeof(struct ArrowArray));
export_imaging_array(self->image, array);
return PyCapsule_New(array, "arrow_array", ReleaseArrowArrayPyCapsule);
}
static PyObject *
_new_arrow(PyObject *self, PyObject *args) {
char *mode;
@ -267,31 +270,30 @@ _new_arrow(PyObject *self, PyObject *args) {
PyObject *schema_capsule, *array_capsule;
PyObject *ret;
if (!PyArg_ParseTuple(args, "s(ii)OO", &mode, &xsize, &ysize,
&schema_capsule, &array_capsule)) {
if (!PyArg_ParseTuple(
args, "s(ii)OO", &mode, &xsize, &ysize, &schema_capsule, &array_capsule
)) {
return NULL;
}
struct ArrowSchema* schema =
(struct ArrowSchema*)PyCapsule_GetPointer(schema_capsule, "arrow_schema");
struct ArrowSchema *schema =
(struct ArrowSchema *)PyCapsule_GetPointer(schema_capsule, "arrow_schema");
struct ArrowArray* array =
(struct ArrowArray*)PyCapsule_GetPointer(array_capsule, "arrow_array");
struct ArrowArray *array =
(struct ArrowArray *)PyCapsule_GetPointer(array_capsule, "arrow_array");
ret = PyImagingNew(ImagingNewArrow(mode, xsize, ysize, schema, array));
if (schema->release){
schema->release(schema);
schema->release = NULL;
if (schema->release) {
schema->release(schema);
schema->release = NULL;
}
if (!ret && array->release) {
array->release(array);
array->release = NULL;
array->release(array);
array->release = NULL;
}
return ret;
}
/* -------------------------------------------------------------------- */
/* EXCEPTION REROUTING */
/* -------------------------------------------------------------------- */

View File

@ -9,292 +9,285 @@
/* } */
static void
ReleaseExportedSchema(struct ArrowSchema* array) {
// This should not be called on already released array
//assert(array->release != NULL);
ReleaseExportedSchema(struct ArrowSchema *array) {
// This should not be called on already released array
// assert(array->release != NULL);
if (!array->release) {
return;
}
if (array->format) {
free((void*)array->format);
array->format = NULL;
}
if (array->name) {
free((void*)array->name);
array->name = NULL;
}
// Release children
for (int64_t i = 0; i < array->n_children; ++i) {
struct ArrowSchema* child = array->children[i];
if (child->release != NULL) {
child->release(child);
//assert(child->release == NULL);
if (!array->release) {
return;
}
if (array->format) {
free((void *)array->format);
array->format = NULL;
}
if (array->name) {
free((void *)array->name);
array->name = NULL;
}
}
// Release dictionary
struct ArrowSchema* dict = array->dictionary;
if (dict != NULL && dict->release != NULL) {
dict->release(dict);
//assert(dict->release == NULL);
}
// Release children
for (int64_t i = 0; i < array->n_children; ++i) {
struct ArrowSchema *child = array->children[i];
if (child->release != NULL) {
child->release(child);
// assert(child->release == NULL);
}
}
// TODO here: release and/or deallocate all data directly owned by
// the ArrowArray struct, such as the private_data.
// Release dictionary
struct ArrowSchema *dict = array->dictionary;
if (dict != NULL && dict->release != NULL) {
dict->release(dict);
// assert(dict->release == NULL);
}
// Mark array released
array->release = NULL;
// TODO here: release and/or deallocate all data directly owned by
// the ArrowArray struct, such as the private_data.
// Mark array released
array->release = NULL;
}
int
export_named_type(struct ArrowSchema *schema, char *format, char *name) {
char *formatp;
char *namep;
size_t format_len = strlen(format) + 1;
size_t name_len = strlen(name) + 1;
formatp = calloc(format_len, 1);
int export_named_type(struct ArrowSchema* schema,
char* format,
char* name) {
if (!formatp) {
return 1;
}
char* formatp;
char* namep;
size_t format_len = strlen(format) + 1;
size_t name_len = strlen(name) + 1;
namep = calloc(name_len, 1);
if (!namep) {
free(formatp);
return 1;
}
formatp = calloc(format_len, 1);
strncpy(formatp, format, format_len);
strncpy(namep, name, name_len);
if (!formatp) {
return 1;
}
namep = calloc(name_len, 1);
if (!namep){
free(formatp);
return 1;
}
strncpy(formatp, format, format_len);
strncpy(namep, name, name_len);
*schema = (struct ArrowSchema) {
// Type description
.format = formatp,
.name = namep,
.metadata = NULL,
.flags = 0,
.n_children = 0,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &ReleaseExportedSchema
};
return 0;
*schema = (struct ArrowSchema){// Type description
.format = formatp,
.name = namep,
.metadata = NULL,
.flags = 0,
.n_children = 0,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &ReleaseExportedSchema
};
return 0;
}
int export_imaging_schema(Imaging im, struct ArrowSchema* schema) {
int retval = 0;
int
export_imaging_schema(Imaging im, struct ArrowSchema *schema) {
int retval = 0;
if (strcmp(im->arrow_band_format, "") == 0) {
return 1;
}
if (strcmp(im->arrow_band_format, "") == 0) {
return 1;
}
if (im->bands == 1) {
return export_named_type(schema, im->arrow_band_format, im->band_names[0]);
}
if (im->bands == 1) {
return export_named_type(schema, im->arrow_band_format, im->band_names[0]);
}
retval = export_named_type(schema, "+w:4", "");
if (retval) {
return retval;
}
// if it's not 1 band, it's an int32 at the moment. 4 unint8 bands.
schema->n_children = 1;
schema->children = calloc(1, sizeof(struct ArrowSchema*));
schema->children[0] = (struct ArrowSchema*)calloc(1, sizeof(struct ArrowSchema));
if (export_named_type(schema->children[0], im->arrow_band_format, "pixel")) {
free(schema->children[0]);
schema->release(schema);
return 2;
}
return 0;
retval = export_named_type(schema, "+w:4", "");
if (retval) {
return retval;
}
// if it's not 1 band, it's an int32 at the moment. 4 unint8 bands.
schema->n_children = 1;
schema->children = calloc(1, sizeof(struct ArrowSchema *));
schema->children[0] = (struct ArrowSchema *)calloc(1, sizeof(struct ArrowSchema));
if (export_named_type(schema->children[0], im->arrow_band_format, "pixel")) {
free(schema->children[0]);
schema->release(schema);
return 2;
}
return 0;
}
static void release_simple_type(struct ArrowSchema* schema) {
// Mark released
schema->release = NULL;
static void
release_simple_type(struct ArrowSchema *schema) {
// Mark released
schema->release = NULL;
}
void export_uint32_type(struct ArrowSchema* schema) {
*schema = (struct ArrowSchema) {
// Type description
.format = "I",
.name = "",
.metadata = NULL,
.flags = 0,
.n_children = 0,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &release_simple_type
};
void
export_uint32_type(struct ArrowSchema *schema) {
*schema = (struct ArrowSchema){// Type description
.format = "I",
.name = "",
.metadata = NULL,
.flags = 0,
.n_children = 0,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &release_simple_type
};
}
static void release_uint32_array(struct ArrowArray* array) {
//assert(array->n_buffers == 2);
// Free the buffers and the buffers array
free((void *) array->buffers[1]);
free(array->buffers);
// Mark released
array->release = NULL;
static void
release_uint32_array(struct ArrowArray *array) {
// assert(array->n_buffers == 2);
// Free the buffers and the buffers array
free((void *)array->buffers[1]);
free(array->buffers);
// Mark released
array->release = NULL;
}
void export_uint32_array(const uint32_t* data, int64_t nitems,
struct ArrowArray* array) {
// Initialize primitive fields
*array = (struct ArrowArray) {
// Data description
.length = nitems,
.offset = 0,
.null_count = 0,
.n_buffers = 2,
.n_children = 0,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &release_uint32_array
};
// Allocate list of buffers
array->buffers = (const void**) malloc(sizeof(void*) * array->n_buffers);
//assert(array->buffers != NULL);
array->buffers[0] = NULL; // no nulls, null bitmap can be omitted
array->buffers[1] = data;
void
export_uint32_array(const uint32_t *data, int64_t nitems, struct ArrowArray *array) {
// Initialize primitive fields
*array = (struct ArrowArray){// Data description
.length = nitems,
.offset = 0,
.null_count = 0,
.n_buffers = 2,
.n_children = 0,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &release_uint32_array
};
// Allocate list of buffers
array->buffers = (const void **)malloc(sizeof(void *) * array->n_buffers);
// assert(array->buffers != NULL);
array->buffers[0] = NULL; // no nulls, null bitmap can be omitted
array->buffers[1] = data;
}
static void release_const_array(struct ArrowArray* array) {
Imaging im = (Imaging)array->private_data;
static void
release_const_array(struct ArrowArray *array) {
Imaging im = (Imaging)array->private_data;
ImagingDelete(im);
ImagingDelete(im);
//assert(array->n_buffers == 2);
// Free the buffers and the buffers array
free(array->buffers);
// Mark released
array->release = NULL;
// assert(array->n_buffers == 2);
// Free the buffers and the buffers array
free(array->buffers);
// Mark released
array->release = NULL;
}
int
export_single_channel_array(Imaging im, struct ArrowArray *array) {
int length = im->xsize * im->ysize;
int export_single_channel_array(Imaging im, struct ArrowArray* array){
int length = im->xsize * im->ysize;
/* undone -- for now, single block images */
// assert (im->block_count = 0 || im->block_count = 1);
/* undone -- for now, single block images */
//assert (im->block_count = 0 || im->block_count = 1);
if (im->lines_per_block && im->lines_per_block < im->ysize) {
length = im->xsize * im->lines_per_block;
}
if (im->lines_per_block && im->lines_per_block < im->ysize) {
length = im->xsize * im->lines_per_block;
}
im->arrow_borrow++;
// Initialize primitive fields
*array = (struct ArrowArray){// Data description
.length = length,
.offset = 0,
.null_count = 0,
.n_buffers = 2,
.n_children = 0,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &release_const_array,
.private_data = im
};
im->arrow_borrow++;
// Initialize primitive fields
*array = (struct ArrowArray) {
// Data description
.length = length,
.offset = 0,
.null_count = 0,
.n_buffers = 2,
.n_children = 0,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &release_const_array,
.private_data = im
};
// Allocate list of buffers
array->buffers = (const void **)malloc(sizeof(void *) * array->n_buffers);
// assert(array->buffers != NULL);
array->buffers[0] = NULL; // no nulls, null bitmap can be omitted
// Allocate list of buffers
array->buffers = (const void**) malloc(sizeof(void*) * array->n_buffers);
//assert(array->buffers != NULL);
array->buffers[0] = NULL; // no nulls, null bitmap can be omitted
if (im->block) {
array->buffers[1] = im->block;
} else {
array->buffers[1] = im->blocks[0].ptr;
}
return 0;
if (im->block) {
array->buffers[1] = im->block;
} else {
array->buffers[1] = im->blocks[0].ptr;
}
return 0;
}
int
export_fixed_pixel_array(Imaging im, struct ArrowArray *array) {
int length = im->xsize * im->ysize;
int export_fixed_pixel_array(Imaging im, struct ArrowArray* array) {
/* undone -- for now, single block images */
// assert (im->block_count = 0 || im->block_count = 1);
int length = im->xsize * im->ysize;
if (im->lines_per_block && im->lines_per_block < im->ysize) {
length = im->xsize * im->lines_per_block;
}
/* undone -- for now, single block images */
//assert (im->block_count = 0 || im->block_count = 1);
im->arrow_borrow++;
// Initialize primitive fields
// Fixed length arrays are 1 buffer of validity, and the length in pixels.
// Data is in a child array.
*array = (struct ArrowArray){// Data description
.length = length,
.offset = 0,
.null_count = 0,
.n_buffers = 1,
.n_children = 1,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &release_const_array,
.private_data = im
};
if (im->lines_per_block && im->lines_per_block < im->ysize) {
length = im->xsize * im->lines_per_block;
}
// Allocate list of buffers
array->buffers = (const void **)calloc(1, sizeof(void *) * array->n_buffers);
// assert(array->buffers != NULL);
array->buffers[0] = NULL; // no nulls, null bitmap can be omitted
im->arrow_borrow++;
// Initialize primitive fields
// Fixed length arrays are 1 buffer of validity, and the length in pixels.
// Data is in a child array.
*array = (struct ArrowArray) {
// Data description
.length = length,
.offset = 0,
.null_count = 0,
.n_buffers = 1,
.n_children = 1,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &release_const_array,
.private_data = im
};
// if it's not 1 band, it's an int32 at the moment. 4 unint8 bands.
array->n_children = 1;
array->children = calloc(1, sizeof(struct ArrowArray *));
array->children[0] = (struct ArrowArray *)calloc(1, sizeof(struct ArrowArray));
// Allocate list of buffers
array->buffers = (const void**) calloc(1, sizeof(void*) * array->n_buffers);
//assert(array->buffers != NULL);
array->buffers[0] = NULL; // no nulls, null bitmap can be omitted
im->arrow_borrow++;
*array->children[0] = (struct ArrowArray){// Data description
.length = length * 4,
.offset = 0,
.null_count = 0,
.n_buffers = 2,
.n_children = 0,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &release_const_array,
.private_data = im
};
array->children[0]->buffers =
(const void **)calloc(2, sizeof(void *) * array->n_buffers);
// if it's not 1 band, it's an int32 at the moment. 4 unint8 bands.
array->n_children = 1;
array->children = calloc(1, sizeof(struct ArrowArray*));
array->children[0] = (struct ArrowArray*)calloc(1, sizeof(struct ArrowArray));
im->arrow_borrow++;
*array->children[0] = (struct ArrowArray) {
// Data description
.length = length * 4,
.offset = 0,
.null_count = 0,
.n_buffers = 2,
.n_children = 0,
.children = NULL,
.dictionary = NULL,
// Bookkeeping
.release = &release_const_array,
.private_data = im
};
array->children[0]->buffers = (const void**) calloc(2, sizeof(void*) * array->n_buffers);
if (im->block) {
array->children[0]->buffers[1] = im->block;
} else {
array->children[0]->buffers[1] = im->blocks[0].ptr;
}
return 0;
if (im->block) {
array->children[0]->buffers[1] = im->block;
} else {
array->children[0]->buffers[1] = im->blocks[0].ptr;
}
return 0;
}
int
export_imaging_array(Imaging im, struct ArrowArray *array) {
if (strcmp(im->arrow_band_format, "") == 0) {
return 1;
}
int export_imaging_array(Imaging im, struct ArrowArray* array) {
if (strcmp(im->arrow_band_format, "") == 0) {
return 1;
}
if (im->bands == 1) {
return export_single_channel_array(im, array);
}
if (im->bands == 1) {
return export_single_channel_array(im, array);
}
return export_fixed_pixel_array(im, array);
return export_fixed_pixel_array(im, array);
}

View File

@ -13,36 +13,36 @@
#define ARROW_FLAG_MAP_KEYS_SORTED 4
struct ArrowSchema {
// Array type description
const char* format;
const char* name;
const char* metadata;
int64_t flags;
int64_t n_children;
struct ArrowSchema** children;
struct ArrowSchema* dictionary;
// Array type description
const char *format;
const char *name;
const char *metadata;
int64_t flags;
int64_t n_children;
struct ArrowSchema **children;
struct ArrowSchema *dictionary;
// Release callback
void (*release)(struct ArrowSchema*);
// Opaque producer-specific data
void* private_data;
// Release callback
void (*release)(struct ArrowSchema *);
// Opaque producer-specific data
void *private_data;
};
struct ArrowArray {
// Array data description
int64_t length;
int64_t null_count;
int64_t offset;
int64_t n_buffers;
int64_t n_children;
const void** buffers;
struct ArrowArray** children;
struct ArrowArray* dictionary;
// Array data description
int64_t length;
int64_t null_count;
int64_t offset;
int64_t n_buffers;
int64_t n_children;
const void **buffers;
struct ArrowArray **children;
struct ArrowArray *dictionary;
// Release callback
void (*release)(struct ArrowArray*);
// Opaque producer-specific data
void* private_data;
// Release callback
void (*release)(struct ArrowArray *);
// Opaque producer-specific data
void *private_data;
};
#endif // ARROW_C_DATA_INTERFACE

View File

@ -108,18 +108,15 @@ struct ImagingMemoryInstance {
void (*destroy)(Imaging im);
/* arrow */
int arrow_borrow; /* Number of arrow arrays that have been allocated */
char band_names[4][3]; /* names of bands, max 2 char + null terminator */
int arrow_borrow; /* Number of arrow arrays that have been allocated */
char band_names[4][3]; /* names of bands, max 2 char + null terminator */
char arrow_band_format[2]; /* single character + null terminator */
int read_only; /* flag for read-only. set for arrow borrowed arrays */
int read_only; /* flag for read-only. set for arrow borrowed arrays */
struct ArrowArray *arrow_array_capsule; /* upstream arrow array source */
int blocks_count; /* Number of blocks that have been allocated */
int blocks_count; /* Number of blocks that have been allocated */
int lines_per_block; /* Number of lines in a block have been allocated */
};
#define IMAGING_PIXEL_1(im, x, y) ((im)->image8[(y)][(x)])
@ -204,9 +201,13 @@ extern Imaging
ImagingNewBlock(const char *mode, int xsize, int ysize);
extern Imaging
ImagingNewArrow(const char *mode, int xsize, int ysize,
struct ArrowSchema *schema,
struct ArrowArray *external_array);
ImagingNewArrow(
const char *mode,
int xsize,
int ysize,
struct ArrowSchema *schema,
struct ArrowArray *external_array
);
extern Imaging
ImagingNewPrologue(const char *mode, int xsize, int ysize);
@ -725,9 +726,12 @@ _imaging_tell_pyFd(PyObject *fd);
/* Arrow */
extern int export_imaging_array(Imaging im, struct ArrowArray* array);
extern int export_imaging_schema(Imaging im, struct ArrowSchema* schema);
extern void export_uint32_type(struct ArrowSchema* schema);
extern int
export_imaging_array(Imaging im, struct ArrowArray *array);
extern int
export_imaging_schema(Imaging im, struct ArrowSchema *schema);
extern void
export_uint32_type(struct ArrowSchema *schema);
/* Errcodes */
#define IMAGING_CODEC_END 1

View File

@ -66,14 +66,14 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
/* 1-bit images */
im->bands = im->pixelsize = 1;
im->linesize = xsize;
strcpy(im->band_names[0],"1");
strcpy(im->band_names[0], "1");
} else if (strcmp(mode, "P") == 0) {
/* 8-bit palette mapped images */
im->bands = im->pixelsize = 1;
im->linesize = xsize;
im->palette = ImagingPaletteNew("RGB");
strcpy(im->band_names[0],"P");
strcpy(im->band_names[0], "P");
} else if (strcmp(mode, "PA") == 0) {
/* 8-bit palette with alpha */
@ -81,36 +81,36 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
im->pixelsize = 4; /* store in image32 memory */
im->linesize = xsize * 4;
im->palette = ImagingPaletteNew("RGB");
strcpy(im->band_names[0],"P");
strcpy(im->band_names[1],"X");
strcpy(im->band_names[2],"X");
strcpy(im->band_names[3],"A");
strcpy(im->band_names[0], "P");
strcpy(im->band_names[1], "X");
strcpy(im->band_names[2], "X");
strcpy(im->band_names[3], "A");
} else if (strcmp(mode, "L") == 0) {
/* 8-bit grayscale (luminance) images */
im->bands = im->pixelsize = 1;
im->linesize = xsize;
strcpy(im->band_names[0],"L");
strcpy(im->band_names[0], "L");
} else if (strcmp(mode, "LA") == 0) {
/* 8-bit grayscale (luminance) with alpha */
im->bands = 2;
im->pixelsize = 4; /* store in image32 memory */
im->linesize = xsize * 4;
strcpy(im->band_names[0],"L");
strcpy(im->band_names[1],"X");
strcpy(im->band_names[2],"X");
strcpy(im->band_names[3],"A");
strcpy(im->band_names[0], "L");
strcpy(im->band_names[1], "X");
strcpy(im->band_names[2], "X");
strcpy(im->band_names[3], "A");
} else if (strcmp(mode, "La") == 0) {
/* 8-bit grayscale (luminance) with premultiplied alpha */
im->bands = 2;
im->pixelsize = 4; /* store in image32 memory */
im->linesize = xsize * 4;
strcpy(im->band_names[0],"L");
strcpy(im->band_names[1],"X");
strcpy(im->band_names[2],"X");
strcpy(im->band_names[3],"a");
strcpy(im->band_names[0], "L");
strcpy(im->band_names[1], "X");
strcpy(im->band_names[2], "X");
strcpy(im->band_names[3], "a");
} else if (strcmp(mode, "F") == 0) {
/* 32-bit floating point images */
@ -118,8 +118,8 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
im->pixelsize = 4;
im->linesize = xsize * 4;
im->type = IMAGING_TYPE_FLOAT32;
strcpy(im->arrow_band_format , "f");
strcpy(im->band_names[0],"F");
strcpy(im->arrow_band_format, "f");
strcpy(im->band_names[0], "F");
} else if (strcmp(mode, "I") == 0) {
/* 32-bit integer images */
@ -127,8 +127,8 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
im->pixelsize = 4;
im->linesize = xsize * 4;
im->type = IMAGING_TYPE_INT32;
strcpy(im->arrow_band_format , "i");
strcpy(im->band_names[0],"I");
strcpy(im->arrow_band_format, "i");
strcpy(im->band_names[0], "I");
} else if (strcmp(mode, "I;16") == 0 || strcmp(mode, "I;16L") == 0 ||
strcmp(mode, "I;16B") == 0 || strcmp(mode, "I;16N") == 0) {
@ -138,18 +138,18 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
im->pixelsize = 2;
im->linesize = xsize * 2;
im->type = IMAGING_TYPE_SPECIAL;
strcpy(im->arrow_band_format , "s");
strcpy(im->band_names[0],"I");
strcpy(im->arrow_band_format, "s");
strcpy(im->band_names[0], "I");
} else if (strcmp(mode, "RGB") == 0) {
/* 24-bit true colour images */
im->bands = 3;
im->pixelsize = 4;
im->linesize = xsize * 4;
strcpy(im->band_names[0],"R");
strcpy(im->band_names[1],"G");
strcpy(im->band_names[2],"B");
strcpy(im->band_names[3],"X");
strcpy(im->band_names[0], "R");
strcpy(im->band_names[1], "G");
strcpy(im->band_names[2], "B");
strcpy(im->band_names[3], "X");
} else if (strcmp(mode, "BGR;15") == 0) {
/* EXPERIMENTAL */
@ -159,7 +159,7 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
im->linesize = (xsize * 2 + 3) & -4;
im->type = IMAGING_TYPE_SPECIAL;
/* not allowing arrow due to line length packing */
strcpy(im->arrow_band_format , "");
strcpy(im->arrow_band_format, "");
} else if (strcmp(mode, "BGR;16") == 0) {
/* EXPERIMENTAL */
@ -169,7 +169,7 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
im->linesize = (xsize * 2 + 3) & -4;
im->type = IMAGING_TYPE_SPECIAL;
/* not allowing arrow due to line length packing */
strcpy(im->arrow_band_format , "");
strcpy(im->arrow_band_format, "");
} else if (strcmp(mode, "BGR;24") == 0) {
/* EXPERIMENTAL */
@ -179,53 +179,53 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
im->linesize = (xsize * 3 + 3) & -4;
im->type = IMAGING_TYPE_SPECIAL;
/* not allowing arrow due to line length packing */
strcpy(im->arrow_band_format , "");
strcpy(im->arrow_band_format, "");
} else if (strcmp(mode, "RGBX") == 0) {
/* 32-bit true colour images with padding */
im->bands = im->pixelsize = 4;
im->linesize = xsize * 4;
strcpy(im->band_names[0],"R");
strcpy(im->band_names[1],"G");
strcpy(im->band_names[2],"B");
strcpy(im->band_names[3],"X");
strcpy(im->band_names[0], "R");
strcpy(im->band_names[1], "G");
strcpy(im->band_names[2], "B");
strcpy(im->band_names[3], "X");
} else if (strcmp(mode, "RGBA") == 0) {
/* 32-bit true colour images with alpha */
im->bands = im->pixelsize = 4;
im->linesize = xsize * 4;
strcpy(im->band_names[0],"R");
strcpy(im->band_names[1],"G");
strcpy(im->band_names[2],"B");
strcpy(im->band_names[3],"A");
strcpy(im->band_names[0], "R");
strcpy(im->band_names[1], "G");
strcpy(im->band_names[2], "B");
strcpy(im->band_names[3], "A");
} else if (strcmp(mode, "RGBa") == 0) {
/* 32-bit true colour images with premultiplied alpha */
im->bands = im->pixelsize = 4;
im->linesize = xsize * 4;
strcpy(im->band_names[0],"R");
strcpy(im->band_names[1],"G");
strcpy(im->band_names[2],"B");
strcpy(im->band_names[3],"a");
strcpy(im->band_names[0], "R");
strcpy(im->band_names[1], "G");
strcpy(im->band_names[2], "B");
strcpy(im->band_names[3], "a");
} else if (strcmp(mode, "CMYK") == 0) {
/* 32-bit colour separation */
im->bands = im->pixelsize = 4;
im->linesize = xsize * 4;
strcpy(im->band_names[0],"C");
strcpy(im->band_names[1],"M");
strcpy(im->band_names[2],"Y");
strcpy(im->band_names[3],"K");
strcpy(im->band_names[0], "C");
strcpy(im->band_names[1], "M");
strcpy(im->band_names[2], "Y");
strcpy(im->band_names[3], "K");
} else if (strcmp(mode, "YCbCr") == 0) {
/* 24-bit video format */
im->bands = 3;
im->pixelsize = 4;
im->linesize = xsize * 4;
strcpy(im->band_names[0],"Y");
strcpy(im->band_names[1],"Cb");
strcpy(im->band_names[2],"Cr");
strcpy(im->band_names[3],"X");
strcpy(im->band_names[0], "Y");
strcpy(im->band_names[1], "Cb");
strcpy(im->band_names[2], "Cr");
strcpy(im->band_names[3], "X");
} else if (strcmp(mode, "LAB") == 0) {
/* 24-bit color, luminance, + 2 color channels */
@ -233,10 +233,10 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
im->bands = 3;
im->pixelsize = 4;
im->linesize = xsize * 4;
strcpy(im->band_names[0],"L");
strcpy(im->band_names[1],"a");
strcpy(im->band_names[2],"b");
strcpy(im->band_names[3],"X");
strcpy(im->band_names[0], "L");
strcpy(im->band_names[1], "a");
strcpy(im->band_names[2], "b");
strcpy(im->band_names[3], "X");
} else if (strcmp(mode, "HSV") == 0) {
/* 24-bit color, luminance, + 2 color channels */
@ -244,10 +244,10 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
im->bands = 3;
im->pixelsize = 4;
im->linesize = xsize * 4;
strcpy(im->band_names[0],"H");
strcpy(im->band_names[1],"S");
strcpy(im->band_names[2],"V");
strcpy(im->band_names[3],"X");
strcpy(im->band_names[0], "H");
strcpy(im->band_names[1], "S");
strcpy(im->band_names[2], "V");
strcpy(im->band_names[3], "X");
} else {
free(im);
@ -301,8 +301,8 @@ ImagingDelete(Imaging im) {
im->arrow_borrow--;
if (im->arrow_borrow>0) {
return;
if (im->arrow_borrow > 0) {
return;
}
if (im->palette) {
@ -561,7 +561,6 @@ ImagingAllocateBlock(Imaging im) {
/* --------------------------- */
/* Don't allocate the image. */
static void
ImagingDestroyArrow(Imaging im) {
if (im->arrow_array_capsule && im->arrow_array_capsule->release) {
@ -576,8 +575,8 @@ ImagingAllocateArrow(Imaging im, struct ArrowArray *external_array) {
/* don't really allocate, but naming patterns */
Py_ssize_t y, i;
char* borrowed_buffer = NULL;
struct ArrowArray* arr = external_array;
char *borrowed_buffer = NULL;
struct ArrowArray *arr = external_array;
/* overflow check for malloc */
if (im->linesize && im->ysize > INT_MAX / im->linesize) {
@ -596,7 +595,7 @@ ImagingAllocateArrow(Imaging im, struct ArrowArray *external_array) {
borrowed_buffer = (char *)arr->buffers[1];
}
if (! borrowed_buffer) {
if (!borrowed_buffer) {
// UNDONE better error here.
// currently, only wanting one where
return (Imaging)ImagingError_MemoryError();
@ -685,9 +684,13 @@ ImagingNewBlock(const char *mode, int xsize, int ysize) {
}
Imaging
ImagingNewArrow(const char *mode, int xsize, int ysize,
struct ArrowSchema *schema,
struct ArrowArray *external_array) {
ImagingNewArrow(
const char *mode,
int xsize,
int ysize,
struct ArrowSchema *schema,
struct ArrowArray *external_array
) {
/* A borrowed arrow array */
Imaging im;
@ -702,25 +705,19 @@ ImagingNewArrow(const char *mode, int xsize, int ysize,
int64_t pixels = (int64_t)xsize * (int64_t)ysize;
if (((strcmp(schema->format, "i") == 0 &&
im->pixelsize == 4) ||
(strcmp(schema->format, im->arrow_band_format) == 0 &&
im->bands == 1))
&& pixels == external_array->length) {
if (((strcmp(schema->format, "i") == 0 && im->pixelsize == 4) ||
(strcmp(schema->format, im->arrow_band_format) == 0 && im->bands == 1)) &&
pixels == external_array->length) {
// one arrow element per, and it matches a pixelsize*char
if (ImagingAllocateArrow(im, external_array)) {
return im;
}
}
if (strcmp(schema->format, "+w:4") == 0
&& im->pixelsize == 4
&& schema->n_children > 0
&& schema->children
&& strcmp(schema->children[0]->format, "C") == 0
&& pixels == external_array->length
&& external_array->n_children == 1
&& external_array->children
&& 4 * pixels == external_array->children[0]->length) {
if (strcmp(schema->format, "+w:4") == 0 && im->pixelsize == 4 &&
schema->n_children > 0 && schema->children &&
strcmp(schema->children[0]->format, "C") == 0 &&
pixels == external_array->length && external_array->n_children == 1 &&
external_array->children && 4 * pixels == external_array->children[0]->length) {
// 4 up element of char into pixelsize == 4
if (ImagingAllocateArrow(im, external_array)) {
return im;