diff --git a/src/libImaging/Arrow.c b/src/libImaging/Arrow.c index d2ed10f0a..d00db3cc6 100644 --- a/src/libImaging/Arrow.c +++ b/src/libImaging/Arrow.c @@ -73,10 +73,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] + im->modedata->band_names[0], + im->modedata->band_names[1], + im->modedata->band_names[2], + im->modedata->band_names[3] ); if (err < 0) { return NULL; @@ -98,7 +98,7 @@ single_band_json(Imaging im) { return NULL; } - err = PyOS_snprintf(json, len, format, im->band_names[0]); + err = PyOS_snprintf(json, len, format, im->modedata->band_names[0]); if (err < 0) { return NULL; } @@ -189,7 +189,7 @@ export_imaging_schema(Imaging im, struct ArrowSchema *schema) { int retval = 0; char *band_json; - if (strcmp(im->arrow_band_format, "") == 0) { + if (strcmp(im->modedata->arrow_band_format, "") == 0) { return IMAGING_ARROW_INCOMPATIBLE_MODE; } @@ -199,7 +199,9 @@ export_imaging_schema(Imaging im, struct ArrowSchema *schema) { } if (im->bands == 1) { - retval = export_named_type(schema, im->arrow_band_format, im->band_names[0]); + retval = export_named_type( + schema, im->modedata->arrow_band_format, im->modedata->band_names[0] + ); if (retval != 0) { return retval; } @@ -221,7 +223,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], im->modedata->arrow_band_format, im->modedata->name ); if (retval != 0) { free(schema->children[0]); @@ -405,7 +407,7 @@ err: int export_imaging_array(Imaging im, struct ArrowArray *array) { - if (strcmp(im->arrow_band_format, "") == 0) { + if (strcmp(im->modedata->arrow_band_format, "") == 0) { return IMAGING_ARROW_INCOMPATIBLE_MODE; } diff --git a/src/libImaging/Imaging.h b/src/libImaging/Imaging.h index f7049c892..db8f7b96e 100644 --- a/src/libImaging/Imaging.h +++ b/src/libImaging/Imaging.h @@ -79,11 +79,12 @@ typedef struct { struct ImagingMemoryInstance { /* Format */ - ModeID mode; /* Image mode (IMAGING_MODE_*) */ - int type; /* Data type (IMAGING_TYPE_*) */ - int depth; /* Depth (ignored in this version) */ - int bands; /* Number of bands (1, 2, 3, or 4) */ - int xsize; /* Image dimension. */ + ModeID mode; /* Image mode (IMAGING_MODE_*) */ + const ModeData *modedata; /* mode data struct */ + int type; /* Data type (IMAGING_TYPE_*) */ + int depth; /* Depth (ignored in this version) */ + int bands; /* Number of bands (1, 2, 3, or 4) */ + int xsize; /* Image dimension. */ int ysize; /* Colour palette (for "P" images only) */ @@ -105,9 +106,7 @@ struct ImagingMemoryInstance { void (*destroy)(Imaging im); /* 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 refcount; /* Number of arrow arrays that have been allocated */ 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..9d8ff9c98 100644 --- a/src/libImaging/Mode.c +++ b/src/libImaging/Mode.c @@ -9,18 +9,182 @@ 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"}, + [IMAGING_MODE_1] = + { + .name = "1", + .arrow_band_format = "C", + .bands = 1, + .pixelsize = 1, + .band_names = {"1"}, + }, + [IMAGING_MODE_CMYK] = + { + .name = "CMYK", + .bands = 4, + .pixelsize = 4, + .arrow_band_format = "C", + .band_names = {"C", "M", "Y", "K"}, + }, + [IMAGING_MODE_F] = + { + .name = "F", + .bands = 1, + .pixelsize = 4, + .arrow_band_format = "f", + .band_names = {"F"}, + }, + [IMAGING_MODE_HSV] = + { + .name = "HSV", + .bands = 3, + .pixelsize = 4, + .arrow_band_format = "C", + .band_names = {"H", "S", "V", "X"}, + }, + [IMAGING_MODE_I] = + { + .name = "I", + .bands = 1, + .pixelsize = 4, + .arrow_band_format = "i", + .band_names = {"I"}, + }, + [IMAGING_MODE_L] = + { + .name = "L", + .bands = 1, + .pixelsize = 1, + .arrow_band_format = "C", + .band_names = {"L"}, + }, + [IMAGING_MODE_LA] = + { + .name = "LA", + .bands = 2, + .pixelsize = 4, + .arrow_band_format = "C", + .band_names = {"L", "X", "X", "A"}, + }, + [IMAGING_MODE_LAB] = + { + .name = "LAB", + .bands = 3, + .pixelsize = 4, + .arrow_band_format = "C", + .band_names = {"L", "a", "b", "X"}, + }, + [IMAGING_MODE_La] = + { + .name = "La", + .bands = 2, + .pixelsize = 4, + .arrow_band_format = "C", + .band_names = {"L", "X", "X", "a"}, + }, + [IMAGING_MODE_P] = + { + .name = "P", + .bands = 1, + .pixelsize = 1, + .arrow_band_format = "C", + .band_names = {"P"}, + }, + [IMAGING_MODE_PA] = + { + .name = "PA", + .bands = 2, + .pixelsize = 4, + .arrow_band_format = "C", + .band_names = {"P", "X", "X", "A"}, + }, + [IMAGING_MODE_RGB] = + { + .name = "RGB", + .bands = 3, + .pixelsize = 4, + .arrow_band_format = "C", + .band_names = {"R", "G", "B", "X"}, + }, + [IMAGING_MODE_RGBA] = + { + .name = "RGBA", + .bands = 4, + .pixelsize = 4, + .arrow_band_format = "C", + .band_names = {"R", "G", "B", "A"}, + }, + [IMAGING_MODE_RGBX] = + { + .name = "RGBX", + .bands = 4, + .pixelsize = 4, + .arrow_band_format = "C", + .band_names = {"R", "G", "B", "X"}, + }, + [IMAGING_MODE_RGBa] = + { + .name = "RGBa", + .bands = 4, + .pixelsize = 4, + .arrow_band_format = "C", + .band_names = {"R", "G", "B", "a"}, + }, + [IMAGING_MODE_YCbCr] = + { + .name = "YCbCr", + .bands = 3, + .pixelsize = 4, + .arrow_band_format = "C", + .band_names = {"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] = + { + .name = "I;16", + .bands = 1, + .pixelsize = 2, + .arrow_band_format = "s", + .band_names = {"I"}, + }, + [IMAGING_MODE_I_16L] = + { + .name = "I;16L", + .bands = 1, + .pixelsize = 2, + .arrow_band_format = "s", + .band_names = {"I"}, + }, + [IMAGING_MODE_I_16B] = + { + .name = "I;16B", + .bands = 1, + .pixelsize = 2, + .arrow_band_format = "s", + .band_names = {"I"}, + }, + [IMAGING_MODE_I_16N] = + { + .name = "I;16N", + .bands = 1, + .pixelsize = 2, + .arrow_band_format = "s", + .band_names = {"I"}, + }, + [IMAGING_MODE_I_32L] = + { + .name = "I;32L", + .bands = 1, + .pixelsize = 4, + .arrow_band_format = "i", + .band_names = {"I"}, + }, + [IMAGING_MODE_I_32B] = { + .name = "I;32B", + .bands = 1, + .pixelsize = 4, + .arrow_band_format = "i", + .band_names = {"I"}, + }, }; const ModeID diff --git a/src/libImaging/Mode.h b/src/libImaging/Mode.h index a3eb3d86d..4baf04319 100644 --- a/src/libImaging/Mode.h +++ b/src/libImaging/Mode.h @@ -31,6 +31,10 @@ typedef enum { typedef struct { const char *const name; + const char *const arrow_band_format; + const int bands; + const int pixelsize; + 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..f8c73988a 100644 --- a/src/libImaging/Storage.c +++ b/src/libImaging/Storage.c @@ -60,163 +60,70 @@ 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"); + im->modedata = getModeData(mode); + + im->bands = im->modedata->bands; + im->pixelsize = im->modedata->pixelsize; + im->linesize = xsize * im->pixelsize; 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 */ - im->bands = 2; - 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 */ - im->bands = 1; - 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 */ - im->bands = 1; - 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 */ /* 16-bit raw integer images */ - im->bands = 1; - 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 */ /* L is uint8, a,b are int8 */ - 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 */ /* L is uint8, a,b are int8 */ - 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); @@ -699,8 +606,8 @@ 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 - && im->bands == 1)) // Single band match + (strcmp(schema->format, im->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 if (ImagingBorrowArrow(im, external_array, im->pixelsize, array_capsule)) { @@ -712,11 +619,11 @@ ImagingNewArrow( && im->pixelsize == 4 // storage as 32 bpc && 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 - && pixels == external_array->length // expected length - && external_array->n_children == 1 // array is well formed - && external_array->children // array is well formed + && strcmp(schema->children[0]->format, "C") == 0 // Expected format + && strcmp(im->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 && 4 * pixels == external_array->children[0]->length) { // 4 up element of char into pixelsize == 4 if (ImagingBorrowArrow(im, external_array, 1, array_capsule)) { @@ -724,11 +631,11 @@ ImagingNewArrow( } } // Stored as [r,g,b,a,r,g,b,a,...] - 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 - && 4 * pixels == external_array->length) { // expected length + 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->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)) { return im;