diff --git a/setup.py b/setup.py index def341784..d1b699d16 100644 --- a/setup.py +++ b/setup.py @@ -93,6 +93,7 @@ _LIB_IMAGING = ( "JpegDecode", "JpegEncode", "Matrix", + "Mode", "ModeFilter", "Negative", "Offset", diff --git a/src/libImaging/Imaging.h b/src/libImaging/Imaging.h index 31052c68a..0f0f65507 100644 --- a/src/libImaging/Imaging.h +++ b/src/libImaging/Imaging.h @@ -11,6 +11,7 @@ */ #include "ImPlatform.h" +#include "Mode.h" #if defined(__cplusplus) extern "C" { @@ -69,9 +70,6 @@ typedef struct ImagingPaletteInstance *ImagingPalette; #define IMAGING_TYPE_FLOAT32 2 #define IMAGING_TYPE_SPECIAL 3 /* check mode for details */ -#define IMAGING_MODE_LENGTH \ - 6 + 1 /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "BGR;xy") */ - typedef struct { char *ptr; int size; @@ -79,12 +77,11 @@ typedef struct { struct ImagingMemoryInstance { /* Format */ - char mode[IMAGING_MODE_LENGTH]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK", - "YCbCr", "BGR;xy") */ - 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. */ + const Mode *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. */ int ysize; /* Colour palette (for "P" images only) */ @@ -123,15 +120,15 @@ struct ImagingMemoryInstance { #define IMAGING_PIXEL_FLOAT32(im, x, y) (((FLOAT32 *)(im)->image32[y])[x]) struct ImagingAccessInstance { - const char *mode; + const Mode *mode; void (*get_pixel)(Imaging im, int x, int y, void *pixel); void (*put_pixel)(Imaging im, int x, int y, const void *pixel); }; struct ImagingHistogramInstance { /* Format */ - char mode[IMAGING_MODE_LENGTH]; /* Band names (of corresponding source image) */ - int bands; /* Number of bands (1, 3, or 4) */ + const Mode *mode; /* Mode of corresponding source image */ + int bands; /* Number of bands (1, 3, or 4) */ /* Data */ long *histogram; /* Histogram (bands*256 longs) */ @@ -139,7 +136,7 @@ struct ImagingHistogramInstance { struct ImagingPaletteInstance { /* Format */ - char mode[IMAGING_MODE_LENGTH]; /* Band names */ + const Mode *mode; /* Data */ int size; diff --git a/src/libImaging/Mode.c b/src/libImaging/Mode.c new file mode 100644 index 000000000..5b9c9dae1 --- /dev/null +++ b/src/libImaging/Mode.c @@ -0,0 +1,115 @@ +#include "Mode.h" +#include + + +#define CREATE_MODE(TYPE, NAME, INIT) \ +const TYPE IMAGING_##NAME##_VAL = INIT;\ +const TYPE * const IMAGING_##NAME = &IMAGING_##NAME##_VAL; + + +CREATE_MODE(Mode, MODE_1, {"1"}) +CREATE_MODE(Mode, MODE_CMYK, {"CMYK"}) +CREATE_MODE(Mode, MODE_F, {"F"}) +CREATE_MODE(Mode, MODE_HSV, {"HSV"}) +CREATE_MODE(Mode, MODE_I, {"I"}) +CREATE_MODE(Mode, MODE_L, {"L"}) +CREATE_MODE(Mode, MODE_LA, {"LA"}) +CREATE_MODE(Mode, MODE_LAB, {"LAB"}) +CREATE_MODE(Mode, MODE_La, {"La"}) +CREATE_MODE(Mode, MODE_P, {"P"}) +CREATE_MODE(Mode, MODE_PA, {"PA"}) +CREATE_MODE(Mode, MODE_RGB, {"RGB"}) +CREATE_MODE(Mode, MODE_RGBA, {"RGBA"}) +CREATE_MODE(Mode, MODE_RGBX, {"RGBX"}) +CREATE_MODE(Mode, MODE_RGBa, {"RGBa"}) +CREATE_MODE(Mode, MODE_YCbCr, {"YCbCr"}) + +const Mode * const MODES[] = { + IMAGING_MODE_1, + IMAGING_MODE_CMYK, + IMAGING_MODE_F, + IMAGING_MODE_HSV, + IMAGING_MODE_I, + IMAGING_MODE_L, + IMAGING_MODE_LA, + IMAGING_MODE_LAB, + IMAGING_MODE_La, + IMAGING_MODE_P, + IMAGING_MODE_PA, + IMAGING_MODE_RGB, + IMAGING_MODE_RGBA, + IMAGING_MODE_RGBX, + IMAGING_MODE_RGBa, + IMAGING_MODE_YCbCr, + NULL +}; + +const Mode * findMode(const char * const name) { + int i = 0; + const Mode * mode; + while ((mode = MODES[i++]) != NULL) { + if (!strcmp(mode->name, name)) { + return mode; + } + } + return NULL; +} + + +// Alias all of the modes as rawmodes so that the addresses are the same. +#define ALIAS_MODE_AS_RAWMODE(NAME) const RawMode * const IMAGING_RAWMODE_##NAME = (const RawMode * const)IMAGING_MODE_##NAME; +ALIAS_MODE_AS_RAWMODE(1) +ALIAS_MODE_AS_RAWMODE(CMYK) +ALIAS_MODE_AS_RAWMODE(F) +ALIAS_MODE_AS_RAWMODE(HSV) +ALIAS_MODE_AS_RAWMODE(I) +ALIAS_MODE_AS_RAWMODE(L) +ALIAS_MODE_AS_RAWMODE(LA) +ALIAS_MODE_AS_RAWMODE(LAB) +ALIAS_MODE_AS_RAWMODE(La) +ALIAS_MODE_AS_RAWMODE(P) +ALIAS_MODE_AS_RAWMODE(PA) +ALIAS_MODE_AS_RAWMODE(RGB) +ALIAS_MODE_AS_RAWMODE(RGBA) +ALIAS_MODE_AS_RAWMODE(RGBX) +ALIAS_MODE_AS_RAWMODE(RGBa) +ALIAS_MODE_AS_RAWMODE(YCbCr) + +CREATE_MODE(RawMode, RAWMODE_BGR_15, {"BGR;15"}) +CREATE_MODE(RawMode, RAWMODE_BGR_16, {"BGR;16"}) + +const RawMode * const RAWMODES[] = { + IMAGING_RAWMODE_1, + IMAGING_RAWMODE_CMYK, + IMAGING_RAWMODE_F, + IMAGING_RAWMODE_HSV, + IMAGING_RAWMODE_I, + IMAGING_RAWMODE_L, + IMAGING_RAWMODE_LA, + IMAGING_RAWMODE_LAB, + IMAGING_RAWMODE_La, + IMAGING_RAWMODE_P, + IMAGING_RAWMODE_PA, + IMAGING_RAWMODE_RGB, + IMAGING_RAWMODE_RGBA, + IMAGING_RAWMODE_RGBX, + IMAGING_RAWMODE_RGBa, + IMAGING_RAWMODE_YCbCr, + + IMAGING_RAWMODE_BGR_15, + IMAGING_RAWMODE_BGR_16, + + NULL +}; + +const RawMode * findRawMode(const char * const name) { + int i = 0; + const RawMode * rawmode; + while ((rawmode = RAWMODES[i++]) != NULL) { + const RawMode * const rawmode = RAWMODES[i]; + if (!strcmp(rawmode->name, name)) { + return rawmode; + } + } + return NULL; +} diff --git a/src/libImaging/Mode.h b/src/libImaging/Mode.h new file mode 100644 index 000000000..2d4d27c31 --- /dev/null +++ b/src/libImaging/Mode.h @@ -0,0 +1,60 @@ +#ifndef __MODE_H__ +#define __MODE_H__ + + +// Maximum length (including null terminator) for both mode and rawmode names. +#define IMAGING_MODE_LENGTH 6+1 + + +typedef struct { + const char * const name; +} Mode; + +extern const Mode * const IMAGING_MODE_1; +extern const Mode * const IMAGING_MODE_CMYK; +extern const Mode * const IMAGING_MODE_F; +extern const Mode * const IMAGING_MODE_HSV; +extern const Mode * const IMAGING_MODE_I; +extern const Mode * const IMAGING_MODE_L; +extern const Mode * const IMAGING_MODE_LA; +extern const Mode * const IMAGING_MODE_LAB; +extern const Mode * const IMAGING_MODE_La; +extern const Mode * const IMAGING_MODE_P; +extern const Mode * const IMAGING_MODE_PA; +extern const Mode * const IMAGING_MODE_RGB; +extern const Mode * const IMAGING_MODE_RGBA; +extern const Mode * const IMAGING_MODE_RGBX; +extern const Mode * const IMAGING_MODE_RGBa; +extern const Mode * const IMAGING_MODE_YCbCr; + +const Mode * findMode(const char * const name); + + +typedef struct { + const char * const name; +} RawMode; + +extern const RawMode * const IMAGING_RAWMODE_1; +extern const RawMode * const IMAGING_RAWMODE_CMYK; +extern const RawMode * const IMAGING_RAWMODE_F; +extern const RawMode * const IMAGING_RAWMODE_HSV; +extern const RawMode * const IMAGING_RAWMODE_I; +extern const RawMode * const IMAGING_RAWMODE_L; +extern const RawMode * const IMAGING_RAWMODE_LA; +extern const RawMode * const IMAGING_RAWMODE_LAB; +extern const RawMode * const IMAGING_RAWMODE_La; +extern const RawMode * const IMAGING_RAWMODE_P; +extern const RawMode * const IMAGING_RAWMODE_PA; +extern const RawMode * const IMAGING_RAWMODE_RGB; +extern const RawMode * const IMAGING_RAWMODE_RGBA; +extern const RawMode * const IMAGING_RAWMODE_RGBX; +extern const RawMode * const IMAGING_RAWMODE_RGBa; +extern const RawMode * const IMAGING_RAWMODE_YCbCr; + +extern const RawMode * const IMAGING_RAWMODE_BGR_15; +extern const RawMode * const IMAGING_RAWMODE_BGR_16; + +const RawMode * findRawMode(const char * const name); + + +#endif // __MODE_H__