From 139e6d09844b2c81216f67c7de14cff227282e17 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Mon, 20 Oct 2025 22:07:32 +0100 Subject: [PATCH] Add arrow_band_format and band_names to the mode data struct --- src/libImaging/Arrow.c | 22 +++++++++------ src/libImaging/Imaging.h | 2 -- src/libImaging/Mode.c | 34 ++++++++++++++-------- src/libImaging/Mode.h | 2 ++ src/libImaging/Storage.c | 61 +++------------------------------------- 5 files changed, 42 insertions(+), 79 deletions(-) diff --git a/src/libImaging/Arrow.c b/src/libImaging/Arrow.c index e353ab2e9..135450aa5 100644 --- a/src/libImaging/Arrow.c +++ b/src/libImaging/Arrow.c @@ -62,6 +62,7 @@ image_band_json(Imaging im) { // Bands can be 4 bands * 2 characters each int len = strlen(format) + 8 + 1; int err; + ModeData *modedata = getModeData(im->mode); json = calloc(1, len); @@ -73,10 +74,10 @@ image_band_json(Imaging im) { json, len, format, - im->band_names[0], - im->band_names[1], - im->band_names[2], - im->band_names[3] + modedata->band_names[0], + modedata->band_names[1], + modedata->band_names[2], + modedata->band_names[3] ); if (err < 0) { return NULL; @@ -98,7 +99,7 @@ single_band_json(Imaging im) { 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) { return NULL; } @@ -188,8 +189,9 @@ int export_imaging_schema(Imaging im, struct ArrowSchema *schema) { int retval = 0; 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; } @@ -198,8 +200,10 @@ export_imaging_schema(Imaging im, struct ArrowSchema *schema) { return IMAGING_ARROW_MEMORY_LAYOUT; } + modedata = getModeData(im->mode); + 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) { return retval; } @@ -221,7 +225,7 @@ export_imaging_schema(Imaging im, struct ArrowSchema *schema) { schema->children = calloc(1, sizeof(struct ArrowSchema *)); schema->children[0] = (struct ArrowSchema *)calloc(1, sizeof(struct ArrowSchema)); 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) { free(schema->children[0]); @@ -405,7 +409,7 @@ err: int 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; } diff --git a/src/libImaging/Imaging.h b/src/libImaging/Imaging.h index f7049c892..c043e1714 100644 --- a/src/libImaging/Imaging.h +++ b/src/libImaging/Imaging.h @@ -106,8 +106,6 @@ struct ImagingMemoryInstance { /* arrow */ 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 */ PyObject *arrow_array_capsule; /* upstream arrow array source */ diff --git a/src/libImaging/Mode.c b/src/libImaging/Mode.c index 7521f4cda..55062df1d 100644 --- a/src/libImaging/Mode.c +++ b/src/libImaging/Mode.c @@ -9,18 +9,30 @@ const ModeData MODES[] = { [IMAGING_MODE_UNKNOWN] = {""}, - [IMAGING_MODE_1] = {"1"}, [IMAGING_MODE_CMYK] = {"CMYK"}, - [IMAGING_MODE_F] = {"F"}, [IMAGING_MODE_HSV] = {"HSV"}, - [IMAGING_MODE_I] = {"I"}, [IMAGING_MODE_L] = {"L"}, - [IMAGING_MODE_LA] = {"LA"}, [IMAGING_MODE_LAB] = {"LAB"}, - [IMAGING_MODE_La] = {"La"}, [IMAGING_MODE_P] = {"P"}, - [IMAGING_MODE_PA] = {"PA"}, [IMAGING_MODE_RGB] = {"RGB"}, - [IMAGING_MODE_RGBA] = {"RGBA"}, [IMAGING_MODE_RGBX] = {"RGBX"}, - [IMAGING_MODE_RGBa] = {"RGBa"}, [IMAGING_MODE_YCbCr] = {"YCbCr"}, + // Name, Arrow Format, Band Names + [IMAGING_MODE_1] = {"1", "C", {"1"}}, + [IMAGING_MODE_CMYK] = {"CMYK", "C", {"C", "M", "Y", "K"}}, + [IMAGING_MODE_F] = {"F", "f", {"F"}}, + [IMAGING_MODE_HSV] = {"HSV", "C", {"H", "S", "V", "X"}}, + [IMAGING_MODE_I] = {"I", "i", {"I"}}, + [IMAGING_MODE_L] = {"L", "C", {"L"}}, + [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_16B] = {"I;16B"}, [IMAGING_MODE_I_16N] = {"I;16N"}, - [IMAGING_MODE_I_32L] = {"I;32L"}, [IMAGING_MODE_I_32B] = {"I;32B"}, + [IMAGING_MODE_I_16] = {"I;16", "s", {"I"}}, + [IMAGING_MODE_I_16L] = {"I;16L", "s", {"I"}}, + [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 diff --git a/src/libImaging/Mode.h b/src/libImaging/Mode.h index a3eb3d86d..07f6d9366 100644 --- a/src/libImaging/Mode.h +++ b/src/libImaging/Mode.h @@ -31,6 +31,8 @@ typedef enum { typedef struct { const char *const name; + const char *const arrow_band_format; + const char *band_names[4]; /* names of bands */ } ModeData; const ModeID diff --git a/src/libImaging/Storage.c b/src/libImaging/Storage.c index c09062c92..dae1ec2dd 100644 --- a/src/libImaging/Storage.c +++ b/src/libImaging/Storage.c @@ -60,20 +60,17 @@ ImagingNewPrologueSubtype(const ModeID mode, int xsize, int ysize, int size) { im->ysize = ysize; im->refcount = 1; im->type = IMAGING_TYPE_UINT8; - strcpy(im->arrow_band_format, "C"); if (mode == IMAGING_MODE_1) { /* 1-bit images */ im->bands = im->pixelsize = 1; im->linesize = xsize; - strcpy(im->band_names[0], "1"); } else if (mode == IMAGING_MODE_P) { /* 8-bit palette mapped images */ im->bands = im->pixelsize = 1; im->linesize = xsize; im->palette = ImagingPaletteNew(IMAGING_MODE_RGB); - strcpy(im->band_names[0], "P"); } else if (mode == IMAGING_MODE_PA) { /* 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->linesize = xsize * 4; 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) { /* 8-bit grayscale (luminance) images */ im->bands = im->pixelsize = 1; im->linesize = xsize; - strcpy(im->band_names[0], "L"); } else if (mode == IMAGING_MODE_LA) { /* 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"); } else if (mode == IMAGING_MODE_La) { /* 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"); } else if (mode == IMAGING_MODE_F) { /* 32-bit floating point images */ @@ -118,8 +102,6 @@ ImagingNewPrologueSubtype(const ModeID 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"); } else if (mode == IMAGING_MODE_I) { /* 32-bit integer images */ @@ -127,8 +109,6 @@ ImagingNewPrologueSubtype(const ModeID 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"); } else if (isModeI16(mode)) { /* EXPERIMENTAL */ @@ -137,64 +117,38 @@ ImagingNewPrologueSubtype(const ModeID 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"); } else if (mode == IMAGING_MODE_RGB) { /* 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"); } else if (mode == IMAGING_MODE_RGBX) { /* 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"); } else if (mode == IMAGING_MODE_RGBA) { /* 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"); } else if (mode == IMAGING_MODE_RGBa) { /* 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"); } else if (mode == IMAGING_MODE_CMYK) { /* 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"); } else if (mode == IMAGING_MODE_YCbCr) { /* 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"); } else if (mode == IMAGING_MODE_LAB) { /* 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->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"); } else if (mode == IMAGING_MODE_HSV) { /* 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->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"); } else { free(im); @@ -689,6 +635,7 @@ ImagingNewArrow( if (!im) { return NULL; } + ModeData *modedata = getModeData(mode); int64_t pixels = (int64_t)xsize * (int64_t)ysize; @@ -699,7 +646,7 @@ ImagingNewArrow( && im->pixelsize == 4 // 4xchar* storage && 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 && pixels == external_array->length) { // 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->children // make sure schema is well formed && 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 && external_array->n_children == 1 // array is well formed && external_array->children // array is well formed @@ -727,7 +674,7 @@ ImagingNewArrow( if (strcmp(schema->format, "C") == 0 // uint8 && im->pixelsize == 4 // storage as 32 bpc && 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 // single flat array, interleaved storage. if (ImagingBorrowArrow(im, external_array, 1, array_capsule)) {