Add arrow_band_format and band_names to the mode data struct

This commit is contained in:
wiredfool 2025-10-20 22:07:32 +01:00
parent 693df7b42c
commit 139e6d0984
5 changed files with 42 additions and 79 deletions

View File

@ -62,6 +62,7 @@ image_band_json(Imaging im) {
// Bands can be 4 bands * 2 characters each // Bands can be 4 bands * 2 characters each
int len = strlen(format) + 8 + 1; int len = strlen(format) + 8 + 1;
int err; int err;
ModeData *modedata = getModeData(im->mode);
json = calloc(1, len); json = calloc(1, len);
@ -73,10 +74,10 @@ image_band_json(Imaging im) {
json, json,
len, len,
format, format,
im->band_names[0], modedata->band_names[0],
im->band_names[1], modedata->band_names[1],
im->band_names[2], modedata->band_names[2],
im->band_names[3] modedata->band_names[3]
); );
if (err < 0) { if (err < 0) {
return NULL; return NULL;
@ -98,7 +99,7 @@ single_band_json(Imaging im) {
return NULL; return NULL;
} }
err = PyOS_snprintf(json, len, format, im->band_names[0]); err = PyOS_snprintf(json, len, format, getModeData(im->mode)->band_names[0]);
if (err < 0) { if (err < 0) {
return NULL; return NULL;
} }
@ -188,8 +189,9 @@ int
export_imaging_schema(Imaging im, struct ArrowSchema *schema) { export_imaging_schema(Imaging im, struct ArrowSchema *schema) {
int retval = 0; int retval = 0;
char *band_json; char *band_json;
ModeData *modedata = getModeData(im->mode);
if (strcmp(im->arrow_band_format, "") == 0) { if (strcmp(modedata->arrow_band_format, "") == 0) {
return IMAGING_ARROW_INCOMPATIBLE_MODE; return IMAGING_ARROW_INCOMPATIBLE_MODE;
} }
@ -198,8 +200,10 @@ export_imaging_schema(Imaging im, struct ArrowSchema *schema) {
return IMAGING_ARROW_MEMORY_LAYOUT; return IMAGING_ARROW_MEMORY_LAYOUT;
} }
modedata = getModeData(im->mode);
if (im->bands == 1) { if (im->bands == 1) {
retval = export_named_type(schema, im->arrow_band_format, im->band_names[0]); retval = export_named_type(schema, modedata->arrow_band_format, modedata->band_names[0]);
if (retval != 0) { if (retval != 0) {
return retval; return retval;
} }
@ -221,7 +225,7 @@ export_imaging_schema(Imaging im, struct ArrowSchema *schema) {
schema->children = calloc(1, sizeof(struct ArrowSchema *)); schema->children = calloc(1, sizeof(struct ArrowSchema *));
schema->children[0] = (struct ArrowSchema *)calloc(1, sizeof(struct ArrowSchema)); schema->children[0] = (struct ArrowSchema *)calloc(1, sizeof(struct ArrowSchema));
retval = export_named_type( retval = export_named_type(
schema->children[0], im->arrow_band_format, getModeData(im->mode)->name schema->children[0], modedata->arrow_band_format, modedata->name
); );
if (retval != 0) { if (retval != 0) {
free(schema->children[0]); free(schema->children[0]);
@ -405,7 +409,7 @@ err:
int int
export_imaging_array(Imaging im, struct ArrowArray *array) { export_imaging_array(Imaging im, struct ArrowArray *array) {
if (strcmp(im->arrow_band_format, "") == 0) { if (strcmp(getModeData(im->mode)->arrow_band_format, "") == 0) {
return IMAGING_ARROW_INCOMPATIBLE_MODE; return IMAGING_ARROW_INCOMPATIBLE_MODE;
} }

View File

@ -106,8 +106,6 @@ struct ImagingMemoryInstance {
/* arrow */ /* arrow */
int refcount; /* Number of arrow arrays that have been allocated */ int refcount; /* 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 */
PyObject *arrow_array_capsule; /* upstream arrow array source */ PyObject *arrow_array_capsule; /* upstream arrow array source */

View File

@ -9,18 +9,30 @@
const ModeData MODES[] = { const ModeData MODES[] = {
[IMAGING_MODE_UNKNOWN] = {""}, [IMAGING_MODE_UNKNOWN] = {""},
[IMAGING_MODE_1] = {"1"}, [IMAGING_MODE_CMYK] = {"CMYK"}, // Name, Arrow Format, Band Names
[IMAGING_MODE_F] = {"F"}, [IMAGING_MODE_HSV] = {"HSV"}, [IMAGING_MODE_1] = {"1", "C", {"1"}},
[IMAGING_MODE_I] = {"I"}, [IMAGING_MODE_L] = {"L"}, [IMAGING_MODE_CMYK] = {"CMYK", "C", {"C", "M", "Y", "K"}},
[IMAGING_MODE_LA] = {"LA"}, [IMAGING_MODE_LAB] = {"LAB"}, [IMAGING_MODE_F] = {"F", "f", {"F"}},
[IMAGING_MODE_La] = {"La"}, [IMAGING_MODE_P] = {"P"}, [IMAGING_MODE_HSV] = {"HSV", "C", {"H", "S", "V", "X"}},
[IMAGING_MODE_PA] = {"PA"}, [IMAGING_MODE_RGB] = {"RGB"}, [IMAGING_MODE_I] = {"I", "i", {"I"}},
[IMAGING_MODE_RGBA] = {"RGBA"}, [IMAGING_MODE_RGBX] = {"RGBX"}, [IMAGING_MODE_L] = {"L", "C", {"L"}},
[IMAGING_MODE_RGBa] = {"RGBa"}, [IMAGING_MODE_YCbCr] = {"YCbCr"}, [IMAGING_MODE_LA] = {"LA", "C", {"L", "X", "X", "A"}},
[IMAGING_MODE_LAB] = {"LAB", "C", {"L", "a", "b", "X"}},
[IMAGING_MODE_La] = {"La", "C", {"L", "X", "X", "a"}},
[IMAGING_MODE_P] = {"P", "C", {"P"}},
[IMAGING_MODE_PA] = {"PA", "C", {"P", "X", "X", "A"}},
[IMAGING_MODE_RGB] = {"RGB", "C", {"R", "G", "B", "X"}},
[IMAGING_MODE_RGBA] = {"RGBA", "C", {"R", "G", "B", "A"}},
[IMAGING_MODE_RGBX] = {"RGBX", "C", {"R", "G", "B", "X"}},
[IMAGING_MODE_RGBa] = {"RGBa", "C", {"R", "G", "B", "a"}},
[IMAGING_MODE_YCbCr] = {"YCbCr", "C", {"Y", "Cb", "Cr", "X"}},
[IMAGING_MODE_I_16] = {"I;16"}, [IMAGING_MODE_I_16L] = {"I;16L"}, [IMAGING_MODE_I_16] = {"I;16", "s", {"I"}},
[IMAGING_MODE_I_16B] = {"I;16B"}, [IMAGING_MODE_I_16N] = {"I;16N"}, [IMAGING_MODE_I_16L] = {"I;16L", "s", {"I"}},
[IMAGING_MODE_I_32L] = {"I;32L"}, [IMAGING_MODE_I_32B] = {"I;32B"}, [IMAGING_MODE_I_16B] = {"I;16B", "s", {"I"}},
[IMAGING_MODE_I_16N] = {"I;16N", "s", {"I"}},
[IMAGING_MODE_I_32L] = {"I;32L", "i", {"I"}},
[IMAGING_MODE_I_32B] = {"I;32B", "i", {"I"}},
}; };
const ModeID const ModeID

View File

@ -31,6 +31,8 @@ typedef enum {
typedef struct { typedef struct {
const char *const name; const char *const name;
const char *const arrow_band_format;
const char *band_names[4]; /* names of bands */
} ModeData; } ModeData;
const ModeID const ModeID

View File

@ -60,20 +60,17 @@ ImagingNewPrologueSubtype(const ModeID mode, int xsize, int ysize, int size) {
im->ysize = ysize; im->ysize = ysize;
im->refcount = 1; im->refcount = 1;
im->type = IMAGING_TYPE_UINT8; im->type = IMAGING_TYPE_UINT8;
strcpy(im->arrow_band_format, "C");
if (mode == IMAGING_MODE_1) { if (mode == IMAGING_MODE_1) {
/* 1-bit images */ /* 1-bit images */
im->bands = im->pixelsize = 1; im->bands = im->pixelsize = 1;
im->linesize = xsize; im->linesize = xsize;
strcpy(im->band_names[0], "1");
} else if (mode == IMAGING_MODE_P) { } else if (mode == IMAGING_MODE_P) {
/* 8-bit palette mapped images */ /* 8-bit palette mapped images */
im->bands = im->pixelsize = 1; im->bands = im->pixelsize = 1;
im->linesize = xsize; im->linesize = xsize;
im->palette = ImagingPaletteNew(IMAGING_MODE_RGB); im->palette = ImagingPaletteNew(IMAGING_MODE_RGB);
strcpy(im->band_names[0], "P");
} else if (mode == IMAGING_MODE_PA) { } else if (mode == IMAGING_MODE_PA) {
/* 8-bit palette with alpha */ /* 8-bit palette with alpha */
@ -81,36 +78,23 @@ ImagingNewPrologueSubtype(const ModeID mode, int xsize, int ysize, int size) {
im->pixelsize = 4; /* store in image32 memory */ im->pixelsize = 4; /* store in image32 memory */
im->linesize = xsize * 4; im->linesize = xsize * 4;
im->palette = ImagingPaletteNew(IMAGING_MODE_RGB); im->palette = ImagingPaletteNew(IMAGING_MODE_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");
} else if (mode == IMAGING_MODE_L) { } else if (mode == IMAGING_MODE_L) {
/* 8-bit grayscale (luminance) images */ /* 8-bit grayscale (luminance) images */
im->bands = im->pixelsize = 1; im->bands = im->pixelsize = 1;
im->linesize = xsize; im->linesize = xsize;
strcpy(im->band_names[0], "L");
} else if (mode == IMAGING_MODE_LA) { } else if (mode == IMAGING_MODE_LA) {
/* 8-bit grayscale (luminance) with alpha */ /* 8-bit grayscale (luminance) with alpha */
im->bands = 2; im->bands = 2;
im->pixelsize = 4; /* store in image32 memory */ im->pixelsize = 4; /* store in image32 memory */
im->linesize = xsize * 4; 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");
} else if (mode == IMAGING_MODE_La) { } else if (mode == IMAGING_MODE_La) {
/* 8-bit grayscale (luminance) with premultiplied alpha */ /* 8-bit grayscale (luminance) with premultiplied alpha */
im->bands = 2; im->bands = 2;
im->pixelsize = 4; /* store in image32 memory */ im->pixelsize = 4; /* store in image32 memory */
im->linesize = xsize * 4; 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");
} else if (mode == IMAGING_MODE_F) { } else if (mode == IMAGING_MODE_F) {
/* 32-bit floating point images */ /* 32-bit floating point images */
@ -118,8 +102,6 @@ ImagingNewPrologueSubtype(const ModeID mode, int xsize, int ysize, int size) {
im->pixelsize = 4; im->pixelsize = 4;
im->linesize = xsize * 4; im->linesize = xsize * 4;
im->type = IMAGING_TYPE_FLOAT32; im->type = IMAGING_TYPE_FLOAT32;
strcpy(im->arrow_band_format, "f");
strcpy(im->band_names[0], "F");
} else if (mode == IMAGING_MODE_I) { } else if (mode == IMAGING_MODE_I) {
/* 32-bit integer images */ /* 32-bit integer images */
@ -127,8 +109,6 @@ ImagingNewPrologueSubtype(const ModeID mode, int xsize, int ysize, int size) {
im->pixelsize = 4; im->pixelsize = 4;
im->linesize = xsize * 4; im->linesize = xsize * 4;
im->type = IMAGING_TYPE_INT32; im->type = IMAGING_TYPE_INT32;
strcpy(im->arrow_band_format, "i");
strcpy(im->band_names[0], "I");
} else if (isModeI16(mode)) { } else if (isModeI16(mode)) {
/* EXPERIMENTAL */ /* EXPERIMENTAL */
@ -137,64 +117,38 @@ ImagingNewPrologueSubtype(const ModeID mode, int xsize, int ysize, int size) {
im->pixelsize = 2; im->pixelsize = 2;
im->linesize = xsize * 2; im->linesize = xsize * 2;
im->type = IMAGING_TYPE_SPECIAL; im->type = IMAGING_TYPE_SPECIAL;
strcpy(im->arrow_band_format, "s");
strcpy(im->band_names[0], "I");
} else if (mode == IMAGING_MODE_RGB) { } else if (mode == IMAGING_MODE_RGB) {
/* 24-bit true colour images */ /* 24-bit true colour images */
im->bands = 3; im->bands = 3;
im->pixelsize = 4; im->pixelsize = 4;
im->linesize = xsize * 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");
} else if (mode == IMAGING_MODE_RGBX) { } else if (mode == IMAGING_MODE_RGBX) {
/* 32-bit true colour images with padding */ /* 32-bit true colour images with padding */
im->bands = im->pixelsize = 4; im->bands = im->pixelsize = 4;
im->linesize = xsize * 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");
} else if (mode == IMAGING_MODE_RGBA) { } else if (mode == IMAGING_MODE_RGBA) {
/* 32-bit true colour images with alpha */ /* 32-bit true colour images with alpha */
im->bands = im->pixelsize = 4; im->bands = im->pixelsize = 4;
im->linesize = xsize * 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");
} else if (mode == IMAGING_MODE_RGBa) { } else if (mode == IMAGING_MODE_RGBa) {
/* 32-bit true colour images with premultiplied alpha */ /* 32-bit true colour images with premultiplied alpha */
im->bands = im->pixelsize = 4; im->bands = im->pixelsize = 4;
im->linesize = xsize * 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");
} else if (mode == IMAGING_MODE_CMYK) { } else if (mode == IMAGING_MODE_CMYK) {
/* 32-bit colour separation */ /* 32-bit colour separation */
im->bands = im->pixelsize = 4; im->bands = im->pixelsize = 4;
im->linesize = xsize * 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");
} else if (mode == IMAGING_MODE_YCbCr) { } else if (mode == IMAGING_MODE_YCbCr) {
/* 24-bit video format */ /* 24-bit video format */
im->bands = 3; im->bands = 3;
im->pixelsize = 4; im->pixelsize = 4;
im->linesize = xsize * 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");
} else if (mode == IMAGING_MODE_LAB) { } else if (mode == IMAGING_MODE_LAB) {
/* 24-bit color, luminance, + 2 color channels */ /* 24-bit color, luminance, + 2 color channels */
@ -202,10 +156,6 @@ ImagingNewPrologueSubtype(const ModeID mode, int xsize, int ysize, int size) {
im->bands = 3; im->bands = 3;
im->pixelsize = 4; im->pixelsize = 4;
im->linesize = xsize * 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");
} else if (mode == IMAGING_MODE_HSV) { } else if (mode == IMAGING_MODE_HSV) {
/* 24-bit color, luminance, + 2 color channels */ /* 24-bit color, luminance, + 2 color channels */
@ -213,10 +163,6 @@ ImagingNewPrologueSubtype(const ModeID mode, int xsize, int ysize, int size) {
im->bands = 3; im->bands = 3;
im->pixelsize = 4; im->pixelsize = 4;
im->linesize = xsize * 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");
} else { } else {
free(im); free(im);
@ -689,6 +635,7 @@ ImagingNewArrow(
if (!im) { if (!im) {
return NULL; return NULL;
} }
ModeData *modedata = getModeData(mode);
int64_t pixels = (int64_t)xsize * (int64_t)ysize; int64_t pixels = (int64_t)xsize * (int64_t)ysize;
@ -699,7 +646,7 @@ ImagingNewArrow(
&& im->pixelsize == 4 // 4xchar* storage && im->pixelsize == 4 // 4xchar* storage
&& im->bands >= 2) // INT32 into any INT32 Storage mode && im->bands >= 2) // INT32 into any INT32 Storage mode
|| // (()||()) && || // (()||()) &&
(strcmp(schema->format, im->arrow_band_format) == 0 // same mode (strcmp(schema->format, modedata->arrow_band_format) == 0 // same mode
&& im->bands == 1)) // Single band match && im->bands == 1)) // Single band match
&& pixels == external_array->length) { && pixels == external_array->length) {
// one arrow element per, and it matches a pixelsize*char // one arrow element per, and it matches a pixelsize*char
@ -713,7 +660,7 @@ ImagingNewArrow(
&& schema->n_children > 0 // make sure schema is well formed. && schema->n_children > 0 // make sure schema is well formed.
&& schema->children // make sure schema is well formed && schema->children // make sure schema is well formed
&& strcmp(schema->children[0]->format, "C") == 0 // Expected format && strcmp(schema->children[0]->format, "C") == 0 // Expected format
&& strcmp(im->arrow_band_format, "C") == 0 // Expected Format && strcmp(modedata->arrow_band_format, "C") == 0 // Expected Format
&& pixels == external_array->length // expected length && pixels == external_array->length // expected length
&& external_array->n_children == 1 // array is well formed && external_array->n_children == 1 // array is well formed
&& external_array->children // array is well formed && external_array->children // array is well formed
@ -727,7 +674,7 @@ ImagingNewArrow(
if (strcmp(schema->format, "C") == 0 // uint8 if (strcmp(schema->format, "C") == 0 // uint8
&& im->pixelsize == 4 // storage as 32 bpc && im->pixelsize == 4 // storage as 32 bpc
&& schema->n_children == 0 // make sure schema is well formed. && schema->n_children == 0 // make sure schema is well formed.
&& strcmp(im->arrow_band_format, "C") == 0 // expected format && strcmp(modedata->arrow_band_format, "C") == 0 // expected format
&& 4 * pixels == external_array->length) { // expected length && 4 * pixels == external_array->length) { // expected length
// single flat array, interleaved storage. // single flat array, interleaved storage.
if (ImagingBorrowArrow(im, external_array, 1, array_capsule)) { if (ImagingBorrowArrow(im, external_array, 1, array_capsule)) {