diff --git a/.ci/requirements-mypy.txt b/.ci/requirements-mypy.txt index c84a3533b85..f230edde0f3 100644 --- a/.ci/requirements-mypy.txt +++ b/.ci/requirements-mypy.txt @@ -9,4 +9,4 @@ sphinx types-atheris types-defusedxml types-olefile -types-setuptools +types-setuptools>=75.2.0 diff --git a/setup.py b/setup.py index 1a8c03eb337..69ff7384486 100644 --- a/setup.py +++ b/setup.py @@ -16,11 +16,14 @@ import sys import warnings from collections.abc import Iterator -from typing import Any +from typing import TYPE_CHECKING, Any from setuptools import Extension, setup from setuptools.command.build_ext import build_ext +if TYPE_CHECKING: + from setuptools import _BuildInfo + def get_version() -> str: version_file = "src/PIL/_version.py" @@ -1001,16 +1004,20 @@ def debug_build() -> bool: return hasattr(sys, "gettotalrefcount") or FUZZING_BUILD +libraries: list[tuple[str, _BuildInfo]] = [ + ("pil_imaging_mode", {"sources": ["src/libImaging/Mode.c"]}), +] + files: list[str | os.PathLike[str]] = ["src/_imaging.c"] for src_file in _IMAGING: files.append("src/" + src_file + ".c") for src_file in _LIB_IMAGING: files.append(os.path.join("src/libImaging", src_file + ".c")) ext_modules = [ - Extension("PIL._imaging", files), - Extension("PIL._imagingft", ["src/_imagingft.c"]), - Extension("PIL._imagingcms", ["src/_imagingcms.c"]), - Extension("PIL._webp", ["src/_webp.c"]), + Extension("PIL._imaging", files, libraries=["pil_imaging_mode"]), + Extension("PIL._imagingft", ["src/_imagingft.c"], libraries=["pil_imaging_mode"]), + Extension("PIL._imagingcms", ["src/_imagingcms.c"], libraries=["pil_imaging_mode"]), + Extension("PIL._webp", ["src/_webp.c"], libraries=["pil_imaging_mode"]), Extension("PIL._imagingtk", ["src/_imagingtk.c", "src/Tk/tkImaging.c"]), Extension("PIL._imagingmath", ["src/_imagingmath.c"]), Extension("PIL._imagingmorph", ["src/_imagingmorph.c"]), @@ -1026,6 +1033,7 @@ def debug_build() -> bool: setup( cmdclass={"build_ext": pil_build_ext}, ext_modules=ext_modules, + libraries=libraries, zip_safe=not (debug_build() or PLATFORM_MINGW), ) except RequiredDependencyException as err: diff --git a/src/Tk/tkImaging.c b/src/Tk/tkImaging.c index a36c3e0bdc4..834634bd7fa 100644 --- a/src/Tk/tkImaging.c +++ b/src/Tk/tkImaging.c @@ -121,15 +121,16 @@ PyImagingPhotoPut( /* Mode */ - if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) { + if (im->mode == IMAGING_MODE_1 || im->mode == IMAGING_MODE_L) { block.pixelSize = 1; block.offset[0] = block.offset[1] = block.offset[2] = block.offset[3] = 0; - } else if (strncmp(im->mode, "RGB", 3) == 0) { + } else if (im->mode == IMAGING_MODE_RGB || im->mode == IMAGING_MODE_RGBA || + im->mode == IMAGING_MODE_RGBX || im->mode == IMAGING_MODE_RGBa) { block.pixelSize = 4; block.offset[0] = 0; block.offset[1] = 1; block.offset[2] = 2; - if (strcmp(im->mode, "RGBA") == 0) { + if (im->mode == IMAGING_MODE_RGBA) { block.offset[3] = 3; /* alpha (or reserved, under Tk 8.2) */ } else { block.offset[3] = 0; /* no alpha */ diff --git a/src/_imaging.c b/src/_imaging.c index 2db4486b23e..ce65ab7ae2e 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -285,7 +285,7 @@ ImagingError_Clear(void) { /* -------------------------------------------------------------------- */ static int -getbands(const char *mode) { +getbands(const ModeID mode) { Imaging im; int bands; @@ -580,7 +580,7 @@ getink(PyObject *color, Imaging im, char *ink) { memcpy(ink, &ftmp, sizeof(ftmp)); return ink; case IMAGING_TYPE_SPECIAL: - if (strncmp(im->mode, "I;16", 4) == 0) { + if (isModeI16(im->mode)) { ink[0] = (UINT8)r; ink[1] = (UINT8)(r >> 8); ink[2] = ink[3] = 0; @@ -599,7 +599,7 @@ getink(PyObject *color, Imaging im, char *ink) { } else if (!PyArg_ParseTuple(color, "iiL", &b, &g, &r)) { return NULL; } - if (!strcmp(im->mode, "BGR;15")) { + if (im->mode == IMAGING_MODE_BGR_15) { UINT16 v = ((((UINT16)r) << 7) & 0x7c00) + ((((UINT16)g) << 2) & 0x03e0) + ((((UINT16)b) >> 3) & 0x001f); @@ -608,7 +608,7 @@ getink(PyObject *color, Imaging im, char *ink) { ink[1] = (UINT8)(v >> 8); ink[2] = ink[3] = 0; return ink; - } else if (!strcmp(im->mode, "BGR;16")) { + } else if (im->mode == IMAGING_MODE_BGR_16) { UINT16 v = ((((UINT16)r) << 8) & 0xf800) + ((((UINT16)g) << 3) & 0x07e0) + ((((UINT16)b) >> 3) & 0x001f); @@ -616,7 +616,7 @@ getink(PyObject *color, Imaging im, char *ink) { ink[1] = (UINT8)(v >> 8); ink[2] = ink[3] = 0; return ink; - } else if (!strcmp(im->mode, "BGR;24")) { + } else if (im->mode == IMAGING_MODE_BGR_24) { ink[0] = (UINT8)b; ink[1] = (UINT8)g; ink[2] = (UINT8)r; @@ -636,7 +636,7 @@ getink(PyObject *color, Imaging im, char *ink) { static PyObject * _fill(PyObject *self, PyObject *args) { - char *mode; + char *mode_name; int xsize, ysize; PyObject *color; char buffer[4]; @@ -645,10 +645,12 @@ _fill(PyObject *self, PyObject *args) { xsize = ysize = 256; color = NULL; - if (!PyArg_ParseTuple(args, "s|(ii)O", &mode, &xsize, &ysize, &color)) { + if (!PyArg_ParseTuple(args, "s|(ii)O", &mode_name, &xsize, &ysize, &color)) { return NULL; } + const ModeID mode = findModeID(mode_name); + im = ImagingNewDirty(mode, xsize, ysize); if (!im) { return NULL; @@ -669,47 +671,55 @@ _fill(PyObject *self, PyObject *args) { static PyObject * _new(PyObject *self, PyObject *args) { - char *mode; + char *mode_name; int xsize, ysize; - if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) { + if (!PyArg_ParseTuple(args, "s(ii)", &mode_name, &xsize, &ysize)) { return NULL; } + const ModeID mode = findModeID(mode_name); + return PyImagingNew(ImagingNew(mode, xsize, ysize)); } static PyObject * _new_block(PyObject *self, PyObject *args) { - char *mode; + char *mode_name; int xsize, ysize; - if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) { + if (!PyArg_ParseTuple(args, "s(ii)", &mode_name, &xsize, &ysize)) { return NULL; } + const ModeID mode = findModeID(mode_name); + return PyImagingNew(ImagingNewBlock(mode, xsize, ysize)); } static PyObject * _linear_gradient(PyObject *self, PyObject *args) { - char *mode; + char *mode_name; - if (!PyArg_ParseTuple(args, "s", &mode)) { + if (!PyArg_ParseTuple(args, "s", &mode_name)) { return NULL; } + const ModeID mode = findModeID(mode_name); + return PyImagingNew(ImagingFillLinearGradient(mode)); } static PyObject * _radial_gradient(PyObject *self, PyObject *args) { - char *mode; + char *mode_name; - if (!PyArg_ParseTuple(args, "s", &mode)) { + if (!PyArg_ParseTuple(args, "s", &mode_name)) { return NULL; } + const ModeID mode = findModeID(mode_name); + return PyImagingNew(ImagingFillRadialGradient(mode)); } @@ -849,7 +859,7 @@ _prepare_lut_table(PyObject *table, Py_ssize_t table_size) { static PyObject * _color_lut_3d(ImagingObject *self, PyObject *args) { - char *mode; + char *mode_name; int filter; int table_channels; int size1D, size2D, size3D; @@ -861,7 +871,7 @@ _color_lut_3d(ImagingObject *self, PyObject *args) { if (!PyArg_ParseTuple( args, "siiiiiO:color_lut_3d", - &mode, + &mode_name, &filter, &table_channels, &size1D, @@ -872,6 +882,8 @@ _color_lut_3d(ImagingObject *self, PyObject *args) { return NULL; } + const ModeID mode = findModeID(mode_name); + /* actually, it is trilinear */ if (filter != IMAGING_TRANSFORM_BILINEAR) { PyErr_SetString(PyExc_ValueError, "Only LINEAR filter is supported."); @@ -918,11 +930,11 @@ _color_lut_3d(ImagingObject *self, PyObject *args) { static PyObject * _convert(ImagingObject *self, PyObject *args) { - char *mode; + char *mode_name; int dither = 0; ImagingObject *paletteimage = NULL; - if (!PyArg_ParseTuple(args, "s|iO", &mode, &dither, &paletteimage)) { + if (!PyArg_ParseTuple(args, "s|iO", &mode_name, &dither, &paletteimage)) { return NULL; } if (paletteimage != NULL) { @@ -939,6 +951,8 @@ _convert(ImagingObject *self, PyObject *args) { } } + const ModeID mode = findModeID(mode_name); + return PyImagingNew(ImagingConvert( self->image, mode, paletteimage ? paletteimage->image->palette : NULL, dither )); @@ -964,14 +978,14 @@ _convert2(ImagingObject *self, PyObject *args) { static PyObject * _convert_matrix(ImagingObject *self, PyObject *args) { - char *mode; + char *mode_name; float m[12]; - if (!PyArg_ParseTuple(args, "s(ffff)", &mode, m + 0, m + 1, m + 2, m + 3)) { + if (!PyArg_ParseTuple(args, "s(ffff)", &mode_name, m + 0, m + 1, m + 2, m + 3)) { PyErr_Clear(); if (!PyArg_ParseTuple( args, "s(ffffffffffff)", - &mode, + &mode_name, m + 0, m + 1, m + 2, @@ -989,18 +1003,22 @@ _convert_matrix(ImagingObject *self, PyObject *args) { } } + const ModeID mode = findModeID(mode_name); + return PyImagingNew(ImagingConvertMatrix(self->image, mode, m)); } static PyObject * _convert_transparent(ImagingObject *self, PyObject *args) { - char *mode; + char *mode_name; int r, g, b; - if (PyArg_ParseTuple(args, "s(iii)", &mode, &r, &g, &b)) { + if (PyArg_ParseTuple(args, "s(iii)", &mode_name, &r, &g, &b)) { + const ModeID mode = findModeID(mode_name); return PyImagingNew(ImagingConvertTransparent(self->image, mode, r, g, b)); } PyErr_Clear(); - if (PyArg_ParseTuple(args, "si", &mode, &r)) { + if (PyArg_ParseTuple(args, "si", &mode_name, &r)) { + const ModeID mode = findModeID(mode_name); return PyImagingNew(ImagingConvertTransparent(self->image, mode, r, 0, 0)); } return NULL; @@ -1103,9 +1121,9 @@ _getpalette(ImagingObject *self, PyObject *args) { int bits; ImagingShuffler pack; - char *mode = "RGB"; - char *rawmode = "RGB"; - if (!PyArg_ParseTuple(args, "|ss", &mode, &rawmode)) { + char *mode_name = "RGB"; + char *rawmode_name = "RGB"; + if (!PyArg_ParseTuple(args, "|ss", &mode_name, &rawmode_name)) { return NULL; } @@ -1114,6 +1132,9 @@ _getpalette(ImagingObject *self, PyObject *args) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + pack = ImagingFindPacker(mode, rawmode, &bits); if (!pack) { PyErr_SetString(PyExc_ValueError, wrong_raw_mode); @@ -1140,7 +1161,7 @@ _getpalettemode(ImagingObject *self) { return NULL; } - return PyUnicode_FromString(self->image->palette->mode); + return PyUnicode_FromString(getModeData(self->image->palette->mode)->name); } static inline int @@ -1423,12 +1444,14 @@ _point(ImagingObject *self, PyObject *args) { Imaging im; PyObject *list; - char *mode; - if (!PyArg_ParseTuple(args, "Oz", &list, &mode)) { + char *mode_name; + if (!PyArg_ParseTuple(args, "Oz", &list, &mode_name)) { return NULL; } - if (mode && !strcmp(mode, "F")) { + const ModeID mode = findModeID(mode_name); + + if (mode == IMAGING_MODE_F) { FLOAT32 *data; /* map from 8-bit data to floating point */ @@ -1439,8 +1462,7 @@ _point(ImagingObject *self, PyObject *args) { } im = ImagingPoint(self->image, mode, (void *)data); free(data); - - } else if (!strcmp(self->image->mode, "I") && mode && !strcmp(mode, "L")) { + } else if (self->image->mode == IMAGING_MODE_I && mode == IMAGING_MODE_L) { UINT8 *data; /* map from 16-bit subset of 32-bit data to 8-bit */ @@ -1452,7 +1474,6 @@ _point(ImagingObject *self, PyObject *args) { } im = ImagingPoint(self->image, mode, (void *)data); free(data); - } else { INT32 *data; UINT8 lut[1024]; @@ -1473,7 +1494,7 @@ _point(ImagingObject *self, PyObject *args) { return NULL; } - if (mode && !strcmp(mode, "I")) { + if (mode == IMAGING_MODE_I) { im = ImagingPoint(self->image, mode, (void *)data); } else if (mode && bands > 1) { for (i = 0; i < 256; i++) { @@ -1579,9 +1600,9 @@ _putdata(ImagingObject *self, PyObject *args) { int bigendian = 0; if (image->type == IMAGING_TYPE_SPECIAL) { // I;16* - if (strcmp(image->mode, "I;16B") == 0 + if (image->mode == IMAGING_MODE_I_16B #ifdef WORDS_BIGENDIAN - || strcmp(image->mode, "I;16N") == 0 + || image->mode == IMAGING_MODE_I_16N #endif ) { bigendian = 1; @@ -1699,7 +1720,9 @@ _quantize(ImagingObject *self, PyObject *args) { if (!self->image->xsize || !self->image->ysize) { /* no content; return an empty image */ - return PyImagingNew(ImagingNew("P", self->image->xsize, self->image->ysize)); + return PyImagingNew( + ImagingNew(IMAGING_MODE_P, self->image->xsize, self->image->ysize) + ); } return PyImagingNew(ImagingQuantize(self->image, colours, method, kmeans)); @@ -1710,21 +1733,33 @@ _putpalette(ImagingObject *self, PyObject *args) { ImagingShuffler unpack; int bits; - char *palette_mode, *rawmode; + char *palette_mode_name, *rawmode_name; UINT8 *palette; Py_ssize_t palettesize; if (!PyArg_ParseTuple( - args, "ssy#", &palette_mode, &rawmode, &palette, &palettesize + args, "ssy#", &palette_mode_name, &rawmode_name, &palette, &palettesize )) { return NULL; } - if (strcmp(self->image->mode, "L") && strcmp(self->image->mode, "LA") && - strcmp(self->image->mode, "P") && strcmp(self->image->mode, "PA")) { + if (self->image->mode != IMAGING_MODE_L && self->image->mode != IMAGING_MODE_LA && + self->image->mode != IMAGING_MODE_P && self->image->mode != IMAGING_MODE_PA) { + PyErr_SetString(PyExc_ValueError, wrong_mode); + return NULL; + } + + const ModeID palette_mode = findModeID(palette_mode_name); + if (palette_mode == IMAGING_MODE_UNKNOWN) { PyErr_SetString(PyExc_ValueError, wrong_mode); return NULL; } + const RawModeID rawmode = findRawModeID(rawmode_name); + if (rawmode == IMAGING_RAWMODE_UNKNOWN) { + PyErr_SetString(PyExc_ValueError, wrong_raw_mode); + return NULL; + } + unpack = ImagingFindUnpacker(palette_mode, rawmode, &bits); if (!unpack) { PyErr_SetString(PyExc_ValueError, wrong_raw_mode); @@ -1738,7 +1773,13 @@ _putpalette(ImagingObject *self, PyObject *args) { ImagingPaletteDelete(self->image->palette); - strcpy(self->image->mode, strlen(self->image->mode) == 2 ? "PA" : "P"); + if (self->image->mode == IMAGING_MODE_LA) { + self->image->mode = IMAGING_MODE_PA; + } else if (self->image->mode == IMAGING_MODE_L) { + self->image->mode = IMAGING_MODE_P; + } else { + // The image already has a palette mode so we don't need to change it. + } self->image->palette = ImagingPaletteNew(palette_mode); @@ -1767,7 +1808,7 @@ _putpalettealpha(ImagingObject *self, PyObject *args) { return NULL; } - strcpy(self->image->palette->mode, "RGBA"); + self->image->palette->mode = IMAGING_MODE_RGBA; self->image->palette->palette[index * 4 + 3] = (UINT8)alpha; Py_INCREF(Py_None); @@ -1793,7 +1834,7 @@ _putpalettealphas(ImagingObject *self, PyObject *args) { return NULL; } - strcpy(self->image->palette->mode, "RGBA"); + self->image->palette->mode = IMAGING_MODE_RGBA; for (i = 0; i < length; i++) { self->image->palette->palette[i * 4 + 3] = (UINT8)values[i]; } @@ -1963,8 +2004,11 @@ _reduce(ImagingObject *self, PyObject *args) { return PyImagingNew(imOut); } -#define IS_RGB(mode) \ - (!strcmp(mode, "RGB") || !strcmp(mode, "RGBA") || !strcmp(mode, "RGBX")) +static int +isRGB(const ModeID mode) { + return mode == IMAGING_MODE_RGB || mode == IMAGING_MODE_RGBA || + mode == IMAGING_MODE_RGBX; +} static PyObject * im_setmode(ImagingObject *self, PyObject *args) { @@ -1972,23 +2016,25 @@ im_setmode(ImagingObject *self, PyObject *args) { Imaging im; - char *mode; + char *mode_name; Py_ssize_t modelen; - if (!PyArg_ParseTuple(args, "s#:setmode", &mode, &modelen)) { + if (!PyArg_ParseTuple(args, "s#:setmode", &mode_name, &modelen)) { return NULL; } + const ModeID mode = findModeID(mode_name); + im = self->image; /* move all logic in here to the libImaging primitive */ - if (!strcmp(im->mode, mode)) { + if (im->mode == mode) { ; /* same mode; always succeeds */ - } else if (IS_RGB(im->mode) && IS_RGB(mode)) { + } else if (isRGB(im->mode) && isRGB(mode)) { /* color to color */ - strcpy(im->mode, mode); + im->mode = mode; im->bands = modelen; - if (!strcmp(mode, "RGBA")) { + if (mode == IMAGING_MODE_RGBA) { (void)ImagingFillBand(im, 3, 255); } } else { @@ -2270,7 +2316,7 @@ _getextrema(ImagingObject *self) { case IMAGING_TYPE_FLOAT32: return Py_BuildValue("dd", extrema.f[0], extrema.f[1]); case IMAGING_TYPE_SPECIAL: - if (strcmp(self->image->mode, "I;16") == 0) { + if (self->image->mode == IMAGING_MODE_I_16) { return Py_BuildValue("HH", extrema.s[0], extrema.s[1]); } } @@ -2362,7 +2408,7 @@ _putband(ImagingObject *self, PyObject *args) { static PyObject * _merge(PyObject *self, PyObject *args) { - char *mode; + char *mode_name; ImagingObject *band0 = NULL; ImagingObject *band1 = NULL; ImagingObject *band2 = NULL; @@ -2372,7 +2418,7 @@ _merge(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple( args, "sO!|O!O!O!", - &mode, + &mode_name, &Imaging_Type, &band0, &Imaging_Type, @@ -2385,6 +2431,8 @@ _merge(PyObject *self, PyObject *args) { return NULL; } + const ModeID mode = findModeID(mode_name); + if (band0) { bands[0] = band0->image; } @@ -3685,7 +3733,7 @@ static struct PyMethodDef methods[] = { static PyObject * _getattr_mode(ImagingObject *self, void *closure) { - return PyUnicode_FromString(self->image->mode); + return PyUnicode_FromString(getModeData(self->image->mode)->name); } static PyObject * @@ -4329,8 +4377,6 @@ setup_module(PyObject *m) { return -1; } - ImagingAccessInit(); - #ifdef HAVE_LIBJPEG { extern const char *ImagingJpegVersion(void); diff --git a/src/_imagingcms.c b/src/_imagingcms.c index 1823bcf0371..9137c12ee84 100644 --- a/src/_imagingcms.c +++ b/src/_imagingcms.c @@ -212,32 +212,44 @@ cms_transform_dealloc(CmsTransformObject *self) { /* internal functions */ static cmsUInt32Number -findLCMStype(char *PILmode) { - if (strcmp(PILmode, "RGB") == 0 || strcmp(PILmode, "RGBA") == 0 || - strcmp(PILmode, "RGBX") == 0) { - return TYPE_RGBA_8; +findLCMStype(const char *const mode_name) { + const ModeID mode = findModeID(mode_name); + switch (mode) { + case IMAGING_MODE_RGB: + case IMAGING_MODE_RGBA: + case IMAGING_MODE_RGBX: + return TYPE_RGBA_8; + case IMAGING_MODE_CMYK: + return TYPE_CMYK_8; + case IMAGING_MODE_I_16: + case IMAGING_MODE_I_16L: + return TYPE_GRAY_16; + case IMAGING_MODE_I_16B: + return TYPE_GRAY_16_SE; + case IMAGING_MODE_YCbCr: + return TYPE_YCbCr_8; + case IMAGING_MODE_LAB: + // LabX equivalent like ALab, but not reversed -- no #define in lcms2 + return ( + COLORSPACE_SH(PT_LabV2) | CHANNELS_SH(3) | BYTES_SH(1) | EXTRA_SH(1) + ); + default: + // This function only accepts a subset of the imaging modes Pillow has. + break; } - if (strcmp(PILmode, "RGBA;16B") == 0) { + // The following modes are not valid PIL Image modes. + if (strcmp(mode_name, "RGBA;16B") == 0) { return TYPE_RGBA_16; } - if (strcmp(PILmode, "CMYK") == 0) { - return TYPE_CMYK_8; - } - if (strcmp(PILmode, "I;16") == 0 || strcmp(PILmode, "I;16L") == 0 || - strcmp(PILmode, "L;16") == 0) { + if (strcmp(mode_name, "L;16") == 0) { return TYPE_GRAY_16; } - if (strcmp(PILmode, "I;16B") == 0 || strcmp(PILmode, "L;16B") == 0) { + if (strcmp(mode_name, "L;16B") == 0) { return TYPE_GRAY_16_SE; } - if (strcmp(PILmode, "YCbCr") == 0 || strcmp(PILmode, "YCCA") == 0 || - strcmp(PILmode, "YCC") == 0) { + if (strcmp(mode_name, "YCCA") == 0 || strcmp(mode_name, "YCC") == 0) { return TYPE_YCbCr_8; } - if (strcmp(PILmode, "LAB") == 0) { - // LabX equivalent like ALab, but not reversed -- no #define in lcms2 - return (COLORSPACE_SH(PT_LabV2) | CHANNELS_SH(3) | BYTES_SH(1) | EXTRA_SH(1)); - } /* presume "1" or "L" by default */ return TYPE_GRAY_8; } diff --git a/src/_imagingft.c b/src/_imagingft.c index d38279f3e4b..b41efe25fe4 100644 --- a/src/_imagingft.c +++ b/src/_imagingft.c @@ -529,7 +529,7 @@ font_getlength(FontObject *self, PyObject *args) { int horizontal_dir; /* is primary axis horizontal? */ int mask = 0; /* is FT_LOAD_TARGET_MONO enabled? */ int color = 0; /* is FT_LOAD_COLOR enabled? */ - const char *mode = NULL; + const char *mode_name = NULL; const char *dir = NULL; const char *lang = NULL; PyObject *features = Py_None; @@ -538,15 +538,16 @@ font_getlength(FontObject *self, PyObject *args) { /* calculate size and bearing for a given string */ if (!PyArg_ParseTuple( - args, "O|zzOz:getlength", &string, &mode, &dir, &features, &lang + args, "O|zzOz:getlength", &string, &mode_name, &dir, &features, &lang )) { return NULL; } horizontal_dir = dir && strcmp(dir, "ttb") == 0 ? 0 : 1; - mask = mode && strcmp(mode, "1") == 0; - color = mode && strcmp(mode, "RGBA") == 0; + const ModeID mode = findModeID(mode_name); + mask = mode == IMAGING_MODE_1; + color = mode == IMAGING_MODE_RGBA; count = text_layout(string, self, dir, features, lang, &glyph_info, mask, color); if (PyErr_Occurred()) { @@ -758,7 +759,7 @@ font_getsize(FontObject *self, PyObject *args) { int horizontal_dir; /* is primary axis horizontal? */ int mask = 0; /* is FT_LOAD_TARGET_MONO enabled? */ int color = 0; /* is FT_LOAD_COLOR enabled? */ - const char *mode = NULL; + const char *mode_name = NULL; const char *dir = NULL; const char *lang = NULL; const char *anchor = NULL; @@ -768,15 +769,23 @@ font_getsize(FontObject *self, PyObject *args) { /* calculate size and bearing for a given string */ if (!PyArg_ParseTuple( - args, "O|zzOzz:getsize", &string, &mode, &dir, &features, &lang, &anchor + args, + "O|zzOzz:getsize", + &string, + &mode_name, + &dir, + &features, + &lang, + &anchor )) { return NULL; } horizontal_dir = dir && strcmp(dir, "ttb") == 0 ? 0 : 1; - mask = mode && strcmp(mode, "1") == 0; - color = mode && strcmp(mode, "RGBA") == 0; + const ModeID mode = findModeID(mode_name); + mask = mode == IMAGING_MODE_1; + color = mode == IMAGING_MODE_RGBA; count = text_layout(string, self, dir, features, lang, &glyph_info, mask, color); if (PyErr_Occurred()) { @@ -842,7 +851,7 @@ font_render(FontObject *self, PyObject *args) { float stroke_width = 0; PY_LONG_LONG foreground_ink_long = 0; unsigned int foreground_ink; - const char *mode = NULL; + const char *mode_name = NULL; const char *dir = NULL; const char *lang = NULL; const char *anchor = NULL; @@ -862,7 +871,7 @@ font_render(FontObject *self, PyObject *args) { "OO|zzOzfzLffO:render", &string, &fill, - &mode, + &mode_name, &dir, &features, &lang, @@ -875,8 +884,9 @@ font_render(FontObject *self, PyObject *args) { return NULL; } - mask = mode && strcmp(mode, "1") == 0; - color = mode && strcmp(mode, "RGBA") == 0; + const ModeID mode = findModeID(mode_name); + mask = mode == IMAGING_MODE_1; + color = mode == IMAGING_MODE_RGBA; foreground_ink = foreground_ink_long; diff --git a/src/_webp.c b/src/_webp.c index dfda7048de4..5cbf48f68a1 100644 --- a/src/_webp.c +++ b/src/_webp.c @@ -89,8 +89,8 @@ HandleMuxError(WebPMuxError err, char *chunk) { static int import_frame_libwebp(WebPPicture *frame, Imaging im) { - if (strcmp(im->mode, "RGBA") && strcmp(im->mode, "RGB") && - strcmp(im->mode, "RGBX")) { + if (im->mode != IMAGING_MODE_RGBA && im->mode != IMAGING_MODE_RGB && + im->mode != IMAGING_MODE_RGBX) { PyErr_SetString(PyExc_ValueError, "unsupported image mode"); return -1; } @@ -104,7 +104,7 @@ import_frame_libwebp(WebPPicture *frame, Imaging im) { return -2; } - int ignore_fourth_channel = strcmp(im->mode, "RGBA"); + int ignore_fourth_channel = im->mode != IMAGING_MODE_RGBA; for (int y = 0; y < im->ysize; ++y) { UINT8 *src = (UINT8 *)im->image32[y]; UINT32 *dst = frame->argb + frame->argb_stride * y; @@ -143,7 +143,7 @@ typedef struct { PyObject_HEAD WebPAnimDecoder *dec; WebPAnimInfo info; WebPData data; - char *mode; + ModeID mode; } WebPAnimDecoderObject; static PyTypeObject WebPAnimDecoder_Type; @@ -396,7 +396,7 @@ _anim_decoder_new(PyObject *self, PyObject *args) { const uint8_t *webp; Py_ssize_t size; WebPData webp_src; - char *mode; + ModeID mode; WebPDecoderConfig config; WebPAnimDecoderObject *decp = NULL; WebPAnimDecoder *dec = NULL; @@ -409,10 +409,10 @@ _anim_decoder_new(PyObject *self, PyObject *args) { webp_src.size = size; // Sniff the mode, since the decoder API doesn't tell us - mode = "RGBA"; + mode = IMAGING_MODE_RGBA; if (WebPGetFeatures(webp, size, &config.input) == VP8_STATUS_OK) { if (!config.input.has_alpha) { - mode = "RGBX"; + mode = IMAGING_MODE_RGBX; } } @@ -455,7 +455,7 @@ _anim_decoder_get_info(PyObject *self) { info->loop_count, info->bgcolor, info->frame_count, - decp->mode + getModeData(decp->mode)->name ); } diff --git a/src/decode.c b/src/decode.c index 51d0aced2bd..85cd25bd52b 100644 --- a/src/decode.c +++ b/src/decode.c @@ -293,7 +293,9 @@ static PyTypeObject ImagingDecoderType = { /* -------------------------------------------------------------------- */ int -get_unpacker(ImagingDecoderObject *decoder, const char *mode, const char *rawmode) { +get_unpacker( + ImagingDecoderObject *decoder, const ModeID mode, const RawModeID rawmode +) { int bits; ImagingShuffler unpack; @@ -318,17 +320,20 @@ PyObject * PyImaging_BitDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; + const char *mode_name; int bits = 8; int pad = 8; int fill = 0; int sign = 0; int ystep = 1; - if (!PyArg_ParseTuple(args, "s|iiiii", &mode, &bits, &pad, &fill, &sign, &ystep)) { + if (!PyArg_ParseTuple( + args, "s|iiiii", &mode_name, &bits, &pad, &fill, &sign, &ystep + )) { return NULL; } - if (strcmp(mode, "F") != 0) { + const ModeID mode = findModeID(mode_name); + if (mode != IMAGING_MODE_F) { PyErr_SetString(PyExc_ValueError, "bad image mode"); return NULL; } @@ -358,34 +363,36 @@ PyObject * PyImaging_BcnDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *actual; + char *mode_name; int n = 0; char *pixel_format = ""; - if (!PyArg_ParseTuple(args, "si|s", &mode, &n, &pixel_format)) { + if (!PyArg_ParseTuple(args, "si|s", &mode_name, &n, &pixel_format)) { return NULL; } + const ModeID mode = findModeID(mode_name); + ModeID actual; + switch (n) { case 1: /* BC1: 565 color, 1-bit alpha */ case 2: /* BC2: 565 color, 4-bit alpha */ case 3: /* BC3: 565 color, 2-endpoint 8-bit interpolated alpha */ case 7: /* BC7: 4-channel 8-bit via everything */ - actual = "RGBA"; + actual = IMAGING_MODE_RGBA; break; case 4: /* BC4: 1-channel 8-bit via 1 BC3 alpha block */ - actual = "L"; + actual = IMAGING_MODE_L; break; case 5: /* BC5: 2-channel 8-bit via 2 BC3 alpha blocks */ case 6: /* BC6: 3-channel 16-bit float */ - actual = "RGB"; + actual = IMAGING_MODE_RGB; break; default: PyErr_SetString(PyExc_ValueError, "block compression type unknown"); return NULL; } - if (strcmp(mode, actual) != 0) { + if (mode != actual) { PyErr_SetString(PyExc_ValueError, "bad image mode"); return NULL; } @@ -428,15 +435,18 @@ PyObject * PyImaging_GifDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; + const char *mode_name; int bits = 8; int interlace = 0; int transparency = -1; - if (!PyArg_ParseTuple(args, "s|iii", &mode, &bits, &interlace, &transparency)) { + if (!PyArg_ParseTuple( + args, "s|iii", &mode_name, &bits, &interlace, &transparency + )) { return NULL; } - if (strcmp(mode, "L") != 0 && strcmp(mode, "P") != 0) { + const ModeID mode = findModeID(mode_name); + if (mode != IMAGING_MODE_L && mode != IMAGING_MODE_P) { PyErr_SetString(PyExc_ValueError, "bad image mode"); return NULL; } @@ -463,12 +473,14 @@ PyObject * PyImaging_HexDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; - if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) { + char *mode_name, *rawmode_name; + if (!PyArg_ParseTuple(args, "ss", &mode_name, &rawmode_name)) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + decoder = PyImaging_DecoderNew(0); if (decoder == NULL) { return NULL; @@ -496,16 +508,21 @@ PyImaging_HexDecoderNew(PyObject *self, PyObject *args) { PyObject * PyImaging_LibTiffDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; char *compname; int fp; uint32_t ifdoffset; - if (!PyArg_ParseTuple(args, "sssiI", &mode, &rawmode, &compname, &fp, &ifdoffset)) { + if (!PyArg_ParseTuple( + args, "sssiI", &mode_name, &rawmode_name, &compname, &fp, &ifdoffset + )) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + TRACE(("new tiff decoder %s\n", compname)); decoder = PyImaging_DecoderNew(sizeof(TIFFSTATE)); @@ -538,12 +555,15 @@ PyObject * PyImaging_PackbitsDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; - if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) { + char *mode_name; + char *rawmode_name; + if (!PyArg_ParseTuple(args, "ss", &mode_name, &rawmode_name)) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + decoder = PyImaging_DecoderNew(0); if (decoder == NULL) { return NULL; @@ -572,7 +592,7 @@ PyImaging_PcdDecoderNew(PyObject *self, PyObject *args) { } /* Unpack from PhotoYCC to RGB */ - if (get_unpacker(decoder, "RGB", "YCC;P") < 0) { + if (get_unpacker(decoder, IMAGING_MODE_RGB, IMAGING_RAWMODE_YCC_P) < 0) { return NULL; } @@ -589,13 +609,15 @@ PyObject * PyImaging_PcxDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name, *rawmode_name; int stride; - if (!PyArg_ParseTuple(args, "ssi", &mode, &rawmode, &stride)) { + if (!PyArg_ParseTuple(args, "ssi", &mode_name, &rawmode_name, &stride)) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + decoder = PyImaging_DecoderNew(0); if (decoder == NULL) { return NULL; @@ -620,14 +642,16 @@ PyObject * PyImaging_RawDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name, *rawmode_name; int stride = 0; int ystep = 1; - if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &stride, &ystep)) { + if (!PyArg_ParseTuple(args, "ss|ii", &mode_name, &rawmode_name, &stride, &ystep)) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + decoder = PyImaging_DecoderNew(sizeof(RAWSTATE)); if (decoder == NULL) { return NULL; @@ -654,14 +678,16 @@ PyObject * PyImaging_SgiRleDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name, *rawmode_name; int ystep = 1; int bpc = 1; - if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &ystep, &bpc)) { + if (!PyArg_ParseTuple(args, "ss|ii", &mode_name, &rawmode_name, &ystep, &bpc)) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + decoder = PyImaging_DecoderNew(sizeof(SGISTATE)); if (decoder == NULL) { return NULL; @@ -688,12 +714,14 @@ PyObject * PyImaging_SunRleDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; - if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) { + char *mode_name, *rawmode_name; + if (!PyArg_ParseTuple(args, "ss", &mode_name, &rawmode_name)) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + decoder = PyImaging_DecoderNew(0); if (decoder == NULL) { return NULL; @@ -716,14 +744,16 @@ PyObject * PyImaging_TgaRleDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name, *rawmode_name; int ystep = 1; int depth = 8; - if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &ystep, &depth)) { + if (!PyArg_ParseTuple(args, "ss|ii", &mode_name, &rawmode_name, &ystep, &depth)) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + decoder = PyImaging_DecoderNew(0); if (decoder == NULL) { return NULL; @@ -754,7 +784,7 @@ PyImaging_XbmDecoderNew(PyObject *self, PyObject *args) { return NULL; } - if (get_unpacker(decoder, "1", "1;R") < 0) { + if (get_unpacker(decoder, IMAGING_MODE_1, IMAGING_RAWMODE_1_R) < 0) { return NULL; } @@ -775,13 +805,15 @@ PyObject * PyImaging_ZipDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; + char *mode_name, *rawmode_name; int interlaced = 0; - if (!PyArg_ParseTuple(args, "ss|i", &mode, &rawmode, &interlaced)) { + if (!PyArg_ParseTuple(args, "ss|i", &mode_name, &rawmode_name, &interlaced)) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + decoder = PyImaging_DecoderNew(sizeof(ZIPSTATE)); if (decoder == NULL) { return NULL; @@ -825,19 +857,21 @@ PyObject * PyImaging_JpegDecoderNew(PyObject *self, PyObject *args) { ImagingDecoderObject *decoder; - char *mode; - char *rawmode; /* what we want from the decoder */ - char *jpegmode; /* what's in the file */ + char *mode_name; + char *rawmode_name; /* what we want from the decoder */ + char *jpegmode_name; /* what's in the file */ int scale = 1; int draft = 0; - if (!PyArg_ParseTuple(args, "ssz|ii", &mode, &rawmode, &jpegmode, &scale, &draft)) { + if (!PyArg_ParseTuple( + args, "ssz|ii", &mode_name, &rawmode_name, &jpegmode_name, &scale, &draft + )) { return NULL; } - if (!jpegmode) { - jpegmode = ""; - } + const ModeID mode = findModeID(mode_name); + RawModeID rawmode = findRawModeID(rawmode_name); + const RawModeID jpegmode = findRawModeID(jpegmode_name); decoder = PyImaging_DecoderNew(sizeof(JPEGSTATE)); if (decoder == NULL) { @@ -847,8 +881,8 @@ PyImaging_JpegDecoderNew(PyObject *self, PyObject *args) { // libjpeg-turbo supports different output formats. // We are choosing Pillow's native format (3 color bytes + 1 padding) // to avoid extra conversion in Unpack.c. - if (ImagingJpegUseJCSExtensions() && strcmp(rawmode, "RGB") == 0) { - rawmode = "RGBX"; + if (ImagingJpegUseJCSExtensions() && rawmode == IMAGING_RAWMODE_RGB) { + rawmode = IMAGING_RAWMODE_RGBX; } if (get_unpacker(decoder, mode, rawmode) < 0) { @@ -858,11 +892,13 @@ PyImaging_JpegDecoderNew(PyObject *self, PyObject *args) { decoder->decode = ImagingJpegDecode; decoder->cleanup = ImagingJpegDecodeCleanup; - strncpy(((JPEGSTATE *)decoder->state.context)->rawmode, rawmode, 8); - strncpy(((JPEGSTATE *)decoder->state.context)->jpegmode, jpegmode, 8); + JPEGSTATE *jpeg_decoder_state_context = (JPEGSTATE *)decoder->state.context; + + jpeg_decoder_state_context->rawmode = rawmode; + jpeg_decoder_state_context->jpegmode = jpegmode; - ((JPEGSTATE *)decoder->state.context)->scale = scale; - ((JPEGSTATE *)decoder->state.context)->draft = draft; + jpeg_decoder_state_context->scale = scale; + jpeg_decoder_state_context->draft = draft; return (PyObject *)decoder; } diff --git a/src/display.c b/src/display.c index b4e2e38991a..ea5a637188e 100644 --- a/src/display.c +++ b/src/display.c @@ -47,7 +47,7 @@ typedef struct { static PyTypeObject ImagingDisplayType; static ImagingDisplayObject * -_new(const char *mode, int xsize, int ysize) { +_new(const ModeID mode, int xsize, int ysize) { ImagingDisplayObject *display; if (PyType_Ready(&ImagingDisplayType) < 0) { @@ -240,7 +240,7 @@ static struct PyMethodDef methods[] = { static PyObject * _getattr_mode(ImagingDisplayObject *self, void *closure) { - return Py_BuildValue("s", self->dib->mode); + return Py_BuildValue("s", getModeData(self->dib->mode)->name); } static PyObject * @@ -288,13 +288,14 @@ static PyTypeObject ImagingDisplayType = { PyObject * PyImaging_DisplayWin32(PyObject *self, PyObject *args) { ImagingDisplayObject *display; - char *mode; + char *mode_name; int xsize, ysize; - if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) { + if (!PyArg_ParseTuple(args, "s(ii)", &mode_name, &xsize, &ysize)) { return NULL; } + const ModeID mode = findModeID(mode_name); display = _new(mode, xsize, ysize); if (display == NULL) { return NULL; @@ -305,12 +306,9 @@ PyImaging_DisplayWin32(PyObject *self, PyObject *args) { PyObject * PyImaging_DisplayModeWin32(PyObject *self, PyObject *args) { - char *mode; int size[2]; - - mode = ImagingGetModeDIB(size); - - return Py_BuildValue("s(ii)", mode, size[0], size[1]); + const ModeID mode = ImagingGetModeDIB(size); + return Py_BuildValue("s(ii)", getModeData(mode)->name, size[0], size[1]); } /* -------------------------------------------------------------------- */ diff --git a/src/encode.c b/src/encode.c index 1a4cd489da2..3f4f4319b28 100644 --- a/src/encode.c +++ b/src/encode.c @@ -360,14 +360,19 @@ static PyTypeObject ImagingEncoderType = { /* -------------------------------------------------------------------- */ int -get_packer(ImagingEncoderObject *encoder, const char *mode, const char *rawmode) { +get_packer(ImagingEncoderObject *encoder, const ModeID mode, const RawModeID rawmode) { int bits; ImagingShuffler pack; pack = ImagingFindPacker(mode, rawmode, &bits); if (!pack) { Py_DECREF(encoder); - PyErr_Format(PyExc_ValueError, "No packer found from %s to %s", mode, rawmode); + PyErr_Format( + PyExc_ValueError, + "No packer found from %s to %s", + getModeData(mode)->name, + getRawModeData(rawmode)->name + ); return -1; } @@ -403,11 +408,13 @@ PyObject * PyImaging_GifEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t bits = 8; Py_ssize_t interlace = 0; - if (!PyArg_ParseTuple(args, "ss|nn", &mode, &rawmode, &bits, &interlace)) { + if (!PyArg_ParseTuple( + args, "ss|nn", &mode_name, &rawmode_name, &bits, &interlace + )) { return NULL; } @@ -416,6 +423,9 @@ PyImaging_GifEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { return NULL; } @@ -436,11 +446,11 @@ PyObject * PyImaging_PcxEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t bits = 8; - if (!PyArg_ParseTuple(args, "ss|n", &mode, &rawmode, &bits)) { + if (!PyArg_ParseTuple(args, "ss|n", &mode_name, &rawmode_name, &bits)) { return NULL; } @@ -449,6 +459,9 @@ PyImaging_PcxEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { return NULL; } @@ -466,12 +479,12 @@ PyObject * PyImaging_RawEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t stride = 0; Py_ssize_t ystep = 1; - if (!PyArg_ParseTuple(args, "ss|nn", &mode, &rawmode, &stride, &ystep)) { + if (!PyArg_ParseTuple(args, "ss|nn", &mode_name, &rawmode_name, &stride, &ystep)) { return NULL; } @@ -480,6 +493,9 @@ PyImaging_RawEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { return NULL; } @@ -500,11 +516,11 @@ PyObject * PyImaging_TgaRleEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t ystep = 1; - if (!PyArg_ParseTuple(args, "ss|n", &mode, &rawmode, &ystep)) { + if (!PyArg_ParseTuple(args, "ss|n", &mode_name, &rawmode_name, &ystep)) { return NULL; } @@ -513,6 +529,9 @@ PyImaging_TgaRleEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { return NULL; } @@ -537,7 +556,7 @@ PyImaging_XbmEncoderNew(PyObject *self, PyObject *args) { return NULL; } - if (get_packer(encoder, "1", "1;R") < 0) { + if (get_packer(encoder, IMAGING_MODE_1, IMAGING_RAWMODE_1_R) < 0) { return NULL; } @@ -558,8 +577,8 @@ PyObject * PyImaging_ZipEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t optimize = 0; Py_ssize_t compress_level = -1; Py_ssize_t compress_type = -1; @@ -568,8 +587,8 @@ PyImaging_ZipEncoderNew(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple( args, "ss|nnny#", - &mode, - &rawmode, + &mode_name, + &rawmode_name, &optimize, &compress_level, &compress_type, @@ -598,6 +617,9 @@ PyImaging_ZipEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { free(dictionary); return NULL; @@ -606,7 +628,7 @@ PyImaging_ZipEncoderNew(PyObject *self, PyObject *args) { encoder->encode = ImagingZipEncode; encoder->cleanup = ImagingZipEncodeCleanup; - if (rawmode[0] == 'P') { + if (rawmode == IMAGING_RAWMODE_P || rawmode == IMAGING_RAWMODE_PA) { /* disable filtering */ ((ZIPSTATE *)encoder->state.context)->mode = ZIP_PNG_PALETTE; } @@ -635,8 +657,8 @@ PyObject * PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; char *compname; char *filename; Py_ssize_t fp; @@ -656,7 +678,15 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) { PyObject *item; if (!PyArg_ParseTuple( - args, "sssnsOO", &mode, &rawmode, &compname, &fp, &filename, &tags, &types + args, + "sssnsOO", + &mode_name, + &rawmode_name, + &compname, + &fp, + &filename, + &tags, + &types )) { return NULL; } @@ -694,6 +724,9 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const ModeID mode = findModeID(mode_name); + const RawModeID rawmode = findRawModeID(rawmode_name); + if (get_packer(encoder, mode, rawmode) < 0) { return NULL; } @@ -1071,8 +1104,8 @@ PyObject * PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) { ImagingEncoderObject *encoder; - char *mode; - char *rawmode; + char *mode_name; + char *rawmode_name; Py_ssize_t quality = 0; Py_ssize_t progressive = 0; Py_ssize_t smooth = 0; @@ -1096,8 +1129,8 @@ PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple( args, "ss|nnnnpnnnnnnOz#y#y#", - &mode, - &rawmode, + &mode_name, + &rawmode_name, &quality, &progressive, &smooth, @@ -1125,11 +1158,14 @@ PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) { return NULL; } + const ModeID mode = findModeID(mode_name); + RawModeID rawmode = findRawModeID(rawmode_name); + // libjpeg-turbo supports different output formats. // We are choosing Pillow's native format (3 color bytes + 1 padding) // to avoid extra conversion in Pack.c. - if (ImagingJpegUseJCSExtensions() && strcmp(rawmode, "RGB") == 0) { - rawmode = "RGBX"; + if (ImagingJpegUseJCSExtensions() && rawmode == IMAGING_RAWMODE_RGB) { + rawmode = IMAGING_RAWMODE_RGBX; } if (get_packer(encoder, mode, rawmode) < 0) { @@ -1187,7 +1223,7 @@ PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) { encoder->encode = ImagingJpegEncode; JPEGENCODERSTATE *jpeg_encoder_state = (JPEGENCODERSTATE *)encoder->state.context; - strncpy(jpeg_encoder_state->rawmode, rawmode, 8); + jpeg_encoder_state->rawmode = rawmode; jpeg_encoder_state->keep_rgb = keep_rgb; jpeg_encoder_state->quality = quality; jpeg_encoder_state->qtables = qarrays; diff --git a/src/libImaging/Access.c b/src/libImaging/Access.c index 1c193710531..a4829ebb4bd 100644 --- a/src/libImaging/Access.c +++ b/src/libImaging/Access.c @@ -11,39 +11,6 @@ #include "Imaging.h" -/* use make_hash.py from the pillow-scripts repository to calculate these values */ -#define ACCESS_TABLE_SIZE 35 -#define ACCESS_TABLE_HASH 8940 - -static struct ImagingAccessInstance access_table[ACCESS_TABLE_SIZE]; - -static inline UINT32 -hash(const char *mode) { - UINT32 i = ACCESS_TABLE_HASH; - while (*mode) { - i = ((i << 5) + i) ^ (UINT8)*mode++; - } - return i % ACCESS_TABLE_SIZE; -} - -static ImagingAccess -add_item(const char *mode) { - UINT32 i = hash(mode); - /* printf("hash %s => %d\n", mode, i); */ - if (access_table[i].mode && strcmp(access_table[i].mode, mode) != 0) { - fprintf( - stderr, - "AccessInit: hash collision: %d for both %s and %s\n", - i, - mode, - access_table[i].mode - ); - exit(1); - } - access_table[i].mode = mode; - return &access_table[i]; -} - /* fetch individual pixel */ static void @@ -184,54 +151,46 @@ put_pixel_32(Imaging im, int x, int y, const void *color) { memcpy(&im->image32[y][x], color, sizeof(INT32)); } -void -ImagingAccessInit(void) { -#define ADD(mode_, get_pixel_, put_pixel_) \ - { \ - ImagingAccess access = add_item(mode_); \ - access->get_pixel = get_pixel_; \ - access->put_pixel = put_pixel_; \ - } - - /* populate access table */ - ADD("1", get_pixel_8, put_pixel_8); - ADD("L", get_pixel_8, put_pixel_8); - ADD("LA", get_pixel_32_2bands, put_pixel_32); - ADD("La", get_pixel_32_2bands, put_pixel_32); - ADD("I", get_pixel_32, put_pixel_32); - ADD("I;16", get_pixel_16L, put_pixel_16L); - ADD("I;16L", get_pixel_16L, put_pixel_16L); - ADD("I;16B", get_pixel_16B, put_pixel_16B); +static struct ImagingAccessInstance accessors[] = { + {IMAGING_MODE_1, get_pixel_8, put_pixel_8}, + {IMAGING_MODE_L, get_pixel_8, put_pixel_8}, + {IMAGING_MODE_LA, get_pixel_32_2bands, put_pixel_32}, + {IMAGING_MODE_La, get_pixel_32_2bands, put_pixel_32}, + {IMAGING_MODE_I, get_pixel_32, put_pixel_32}, + {IMAGING_MODE_I_16, get_pixel_16L, put_pixel_16L}, + {IMAGING_MODE_I_16L, get_pixel_16L, put_pixel_16L}, + {IMAGING_MODE_I_16B, get_pixel_16B, put_pixel_16B}, #ifdef WORDS_BIGENDIAN - ADD("I;16N", get_pixel_16B, put_pixel_16B); + {IMAGING_MODE_I_16N, get_pixel_16B, put_pixel_16B}, #else - ADD("I;16N", get_pixel_16L, put_pixel_16L); + {IMAGING_MODE_I_16N, get_pixel_16L, put_pixel_16L}, #endif - ADD("I;32L", get_pixel_32L, put_pixel_32L); - ADD("I;32B", get_pixel_32B, put_pixel_32B); - ADD("F", get_pixel_32, put_pixel_32); - ADD("P", get_pixel_8, put_pixel_8); - ADD("PA", get_pixel_32_2bands, put_pixel_32); - ADD("BGR;15", get_pixel_BGR15, put_pixel_BGR1516); - ADD("BGR;16", get_pixel_BGR16, put_pixel_BGR1516); - ADD("BGR;24", get_pixel_BGR24, put_pixel_BGR24); - ADD("RGB", get_pixel_32, put_pixel_32); - ADD("RGBA", get_pixel_32, put_pixel_32); - ADD("RGBa", get_pixel_32, put_pixel_32); - ADD("RGBX", get_pixel_32, put_pixel_32); - ADD("CMYK", get_pixel_32, put_pixel_32); - ADD("YCbCr", get_pixel_32, put_pixel_32); - ADD("LAB", get_pixel_32, put_pixel_32); - ADD("HSV", get_pixel_32, put_pixel_32); -} + {IMAGING_MODE_I_32L, get_pixel_32L, put_pixel_32L}, + {IMAGING_MODE_I_32B, get_pixel_32B, put_pixel_32B}, + {IMAGING_MODE_F, get_pixel_32, put_pixel_32}, + {IMAGING_MODE_P, get_pixel_8, put_pixel_8}, + {IMAGING_MODE_PA, get_pixel_32_2bands, put_pixel_32}, + {IMAGING_MODE_BGR_15, get_pixel_BGR15, put_pixel_BGR1516}, + {IMAGING_MODE_BGR_16, get_pixel_BGR16, put_pixel_BGR1516}, + {IMAGING_MODE_BGR_24, get_pixel_BGR24, put_pixel_BGR24}, + {IMAGING_MODE_RGB, get_pixel_32, put_pixel_32}, + {IMAGING_MODE_RGBA, get_pixel_32, put_pixel_32}, + {IMAGING_MODE_RGBa, get_pixel_32, put_pixel_32}, + {IMAGING_MODE_RGBX, get_pixel_32, put_pixel_32}, + {IMAGING_MODE_CMYK, get_pixel_32, put_pixel_32}, + {IMAGING_MODE_YCbCr, get_pixel_32, put_pixel_32}, + {IMAGING_MODE_LAB, get_pixel_32, put_pixel_32}, + {IMAGING_MODE_HSV, get_pixel_32, put_pixel_32} +}; ImagingAccess -ImagingAccessNew(Imaging im) { - ImagingAccess access = &access_table[hash(im->mode)]; - if (im->mode[0] != access->mode[0] || strcmp(im->mode, access->mode) != 0) { - return NULL; +ImagingAccessNew(const Imaging im) { + for (size_t i = 0; i < sizeof(accessors) / sizeof(*accessors); i++) { + if (im->mode == accessors[i].mode) { + return &accessors[i]; + } } - return access; + return NULL; } void diff --git a/src/libImaging/AlphaComposite.c b/src/libImaging/AlphaComposite.c index 6d728f9088b..8d6ee886210 100644 --- a/src/libImaging/AlphaComposite.c +++ b/src/libImaging/AlphaComposite.c @@ -25,12 +25,12 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) { int x, y; /* Check arguments */ - if (!imDst || !imSrc || strcmp(imDst->mode, "RGBA") || + if (!imDst || !imSrc || imDst->mode != IMAGING_MODE_RGBA || imDst->type != IMAGING_TYPE_UINT8 || imDst->bands != 4) { return ImagingError_ModeError(); } - if (strcmp(imDst->mode, imSrc->mode) || imDst->type != imSrc->type || + if (imDst->mode != imSrc->mode || imDst->type != imSrc->type || imDst->bands != imSrc->bands || imDst->xsize != imSrc->xsize || imDst->ysize != imSrc->ysize) { return ImagingError_Mismatch(); diff --git a/src/libImaging/Bands.c b/src/libImaging/Bands.c index e1b16b34ac0..d1b0ebc4ed8 100644 --- a/src/libImaging/Bands.c +++ b/src/libImaging/Bands.c @@ -41,7 +41,7 @@ ImagingGetBand(Imaging imIn, int band) { band = 3; } - imOut = ImagingNewDirty("L", imIn->xsize, imIn->ysize); + imOut = ImagingNewDirty(IMAGING_MODE_L, imIn->xsize, imIn->ysize); if (!imOut) { return NULL; } @@ -82,7 +82,7 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) { } for (i = 0; i < imIn->bands; i++) { - bands[i] = ImagingNewDirty("L", imIn->xsize, imIn->ysize); + bands[i] = ImagingNewDirty(IMAGING_MODE_L, imIn->xsize, imIn->ysize); if (!bands[i]) { for (j = 0; j < i; ++j) { ImagingDelete(bands[j]); @@ -240,7 +240,7 @@ ImagingFillBand(Imaging imOut, int band, int color) { } Imaging -ImagingMerge(const char *mode, Imaging bands[4]) { +ImagingMerge(const ModeID mode, Imaging bands[4]) { int i, x, y; int bandsCount = 0; Imaging imOut; diff --git a/src/libImaging/Blend.c b/src/libImaging/Blend.c index a53ae0fad53..df94920f62e 100644 --- a/src/libImaging/Blend.c +++ b/src/libImaging/Blend.c @@ -24,8 +24,8 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) { /* Check arguments */ if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8 || imIn1->palette || - strcmp(imIn1->mode, "1") == 0 || imIn2->palette || - strcmp(imIn2->mode, "1") == 0) { + imIn1->mode == IMAGING_MODE_1 || imIn2->palette || + imIn2->mode == IMAGING_MODE_1) { return ImagingError_ModeError(); } diff --git a/src/libImaging/BoxBlur.c b/src/libImaging/BoxBlur.c index ed91541fed4..4fea4fe44b8 100644 --- a/src/libImaging/BoxBlur.c +++ b/src/libImaging/BoxBlur.c @@ -248,7 +248,7 @@ ImagingBoxBlur(Imaging imOut, Imaging imIn, float xradius, float yradius, int n) return ImagingError_ValueError("radius must be >= 0"); } - if (strcmp(imIn->mode, imOut->mode) || imIn->type != imOut->type || + if (imIn->mode != imOut->mode || imIn->type != imOut->type || imIn->bands != imOut->bands || imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) { return ImagingError_Mismatch(); @@ -258,10 +258,10 @@ ImagingBoxBlur(Imaging imOut, Imaging imIn, float xradius, float yradius, int n) return ImagingError_ModeError(); } - if (!(strcmp(imIn->mode, "RGB") == 0 || strcmp(imIn->mode, "RGBA") == 0 || - strcmp(imIn->mode, "RGBa") == 0 || strcmp(imIn->mode, "RGBX") == 0 || - strcmp(imIn->mode, "CMYK") == 0 || strcmp(imIn->mode, "L") == 0 || - strcmp(imIn->mode, "LA") == 0 || strcmp(imIn->mode, "La") == 0)) { + if (imIn->mode != IMAGING_MODE_RGB && imIn->mode != IMAGING_MODE_RGBA && + imIn->mode != IMAGING_MODE_RGBa && imIn->mode != IMAGING_MODE_RGBX && + imIn->mode != IMAGING_MODE_CMYK && imIn->mode != IMAGING_MODE_L && + imIn->mode != IMAGING_MODE_LA && imIn->mode != IMAGING_MODE_La) { return ImagingError_ModeError(); } diff --git a/src/libImaging/Chops.c b/src/libImaging/Chops.c index f326d402f2c..331f2dfe64c 100644 --- a/src/libImaging/Chops.c +++ b/src/libImaging/Chops.c @@ -18,28 +18,28 @@ #include "Imaging.h" -#define CHOP(operation) \ - int x, y; \ - Imaging imOut; \ - imOut = create(imIn1, imIn2, NULL); \ - if (!imOut) { \ - return NULL; \ - } \ - for (y = 0; y < imOut->ysize; y++) { \ - UINT8 *out = (UINT8 *)imOut->image[y]; \ - UINT8 *in1 = (UINT8 *)imIn1->image[y]; \ - UINT8 *in2 = (UINT8 *)imIn2->image[y]; \ - for (x = 0; x < imOut->linesize; x++) { \ - int temp = operation; \ - if (temp <= 0) { \ - out[x] = 0; \ - } else if (temp >= 255) { \ - out[x] = 255; \ - } else { \ - out[x] = temp; \ - } \ - } \ - } \ +#define CHOP(operation) \ + int x, y; \ + Imaging imOut; \ + imOut = create(imIn1, imIn2, IMAGING_MODE_UNKNOWN); \ + if (!imOut) { \ + return NULL; \ + } \ + for (y = 0; y < imOut->ysize; y++) { \ + UINT8 *out = (UINT8 *)imOut->image[y]; \ + UINT8 *in1 = (UINT8 *)imIn1->image[y]; \ + UINT8 *in2 = (UINT8 *)imIn2->image[y]; \ + for (x = 0; x < imOut->linesize; x++) { \ + int temp = operation; \ + if (temp <= 0) { \ + out[x] = 0; \ + } else if (temp >= 255) { \ + out[x] = 255; \ + } else { \ + out[x] = temp; \ + } \ + } \ + } \ return imOut; #define CHOP2(operation, mode) \ @@ -60,11 +60,11 @@ return imOut; static Imaging -create(Imaging im1, Imaging im2, char *mode) { +create(Imaging im1, Imaging im2, const ModeID mode) { int xsize, ysize; if (!im1 || !im2 || im1->type != IMAGING_TYPE_UINT8 || - (mode != NULL && (strcmp(im1->mode, "1") || strcmp(im2->mode, "1")))) { + (mode != IMAGING_MODE_UNKNOWN && (im1->mode != mode || im2->mode != mode))) { return (Imaging)ImagingError_ModeError(); } if (im1->type != im2->type || im1->bands != im2->bands) { @@ -114,27 +114,27 @@ ImagingChopSubtract(Imaging imIn1, Imaging imIn2, float scale, int offset) { Imaging ImagingChopAnd(Imaging imIn1, Imaging imIn2) { - CHOP2((in1[x] && in2[x]) ? 255 : 0, "1"); + CHOP2((in1[x] && in2[x]) ? 255 : 0, IMAGING_MODE_1); } Imaging ImagingChopOr(Imaging imIn1, Imaging imIn2) { - CHOP2((in1[x] || in2[x]) ? 255 : 0, "1"); + CHOP2((in1[x] || in2[x]) ? 255 : 0, IMAGING_MODE_1); } Imaging ImagingChopXor(Imaging imIn1, Imaging imIn2) { - CHOP2(((in1[x] != 0) ^ (in2[x] != 0)) ? 255 : 0, "1"); + CHOP2(((in1[x] != 0) ^ (in2[x] != 0)) ? 255 : 0, IMAGING_MODE_1); } Imaging ImagingChopAddModulo(Imaging imIn1, Imaging imIn2) { - CHOP2(in1[x] + in2[x], NULL); + CHOP2(in1[x] + in2[x], IMAGING_MODE_UNKNOWN); } Imaging ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2) { - CHOP2(in1[x] - in2[x], NULL); + CHOP2(in1[x] - in2[x], IMAGING_MODE_UNKNOWN); } Imaging @@ -142,7 +142,7 @@ ImagingChopSoftLight(Imaging imIn1, Imaging imIn2) { CHOP2( (((255 - in1[x]) * (in1[x] * in2[x])) / 65536) + (in1[x] * (255 - ((255 - in1[x]) * (255 - in2[x]) / 255))) / 255, - NULL + IMAGING_MODE_UNKNOWN ); } @@ -151,7 +151,7 @@ ImagingChopHardLight(Imaging imIn1, Imaging imIn2) { CHOP2( (in2[x] < 128) ? ((in1[x] * in2[x]) / 127) : 255 - (((255 - in2[x]) * (255 - in1[x])) / 127), - NULL + IMAGING_MODE_UNKNOWN ); } @@ -160,6 +160,6 @@ ImagingOverlay(Imaging imIn1, Imaging imIn2) { CHOP2( (in1[x] < 128) ? ((in1[x] * in2[x]) / 127) : 255 - (((255 - in1[x]) * (255 - in2[x])) / 127), - NULL + IMAGING_MODE_UNKNOWN ); } diff --git a/src/libImaging/Convert.c b/src/libImaging/Convert.c index c8f23426105..b8ad5560337 100644 --- a/src/libImaging/Convert.c +++ b/src/libImaging/Convert.c @@ -909,150 +909,12 @@ I16_RGB(UINT8 *out, const UINT8 *in, int xsize) { } } -static struct { - const char *from; - const char *to; - ImagingShuffler convert; -} converters[] = { - - {"1", "L", bit2l}, - {"1", "I", bit2i}, - {"1", "F", bit2f}, - {"1", "RGB", bit2rgb}, - {"1", "RGBA", bit2rgb}, - {"1", "RGBX", bit2rgb}, - {"1", "CMYK", bit2cmyk}, - {"1", "YCbCr", bit2ycbcr}, - {"1", "HSV", bit2hsv}, - - {"L", "1", l2bit}, - {"L", "LA", l2la}, - {"L", "I", l2i}, - {"L", "F", l2f}, - {"L", "RGB", l2rgb}, - {"L", "RGBA", l2rgb}, - {"L", "RGBX", l2rgb}, - {"L", "CMYK", l2cmyk}, - {"L", "YCbCr", l2ycbcr}, - {"L", "HSV", l2hsv}, - - {"LA", "L", la2l}, - {"LA", "La", lA2la}, - {"LA", "RGB", la2rgb}, - {"LA", "RGBA", la2rgb}, - {"LA", "RGBX", la2rgb}, - {"LA", "CMYK", la2cmyk}, - {"LA", "YCbCr", la2ycbcr}, - {"LA", "HSV", la2hsv}, - - {"La", "LA", la2lA}, - - {"I", "L", i2l}, - {"I", "F", i2f}, - {"I", "RGB", i2rgb}, - {"I", "RGBA", i2rgb}, - {"I", "RGBX", i2rgb}, - {"I", "HSV", i2hsv}, - - {"F", "L", f2l}, - {"F", "I", f2i}, - - {"RGB", "1", rgb2bit}, - {"RGB", "L", rgb2l}, - {"RGB", "LA", rgb2la}, - {"RGB", "La", rgb2la}, - {"RGB", "I", rgb2i}, - {"RGB", "I;16", rgb2i16l}, - {"RGB", "I;16L", rgb2i16l}, - {"RGB", "I;16B", rgb2i16b}, -#ifdef WORDS_BIGENDIAN - {"RGB", "I;16N", rgb2i16b}, -#else - {"RGB", "I;16N", rgb2i16l}, -#endif - {"RGB", "F", rgb2f}, - {"RGB", "BGR;15", rgb2bgr15}, - {"RGB", "BGR;16", rgb2bgr16}, - {"RGB", "BGR;24", rgb2bgr24}, - {"RGB", "RGBA", rgb2rgba}, - {"RGB", "RGBa", rgb2rgba}, - {"RGB", "RGBX", rgb2rgba}, - {"RGB", "CMYK", rgb2cmyk}, - {"RGB", "YCbCr", ImagingConvertRGB2YCbCr}, - {"RGB", "HSV", rgb2hsv}, - - {"RGBA", "1", rgb2bit}, - {"RGBA", "L", rgb2l}, - {"RGBA", "LA", rgba2la}, - {"RGBA", "I", rgb2i}, - {"RGBA", "F", rgb2f}, - {"RGBA", "RGB", rgba2rgb}, - {"RGBA", "RGBa", rgbA2rgba}, - {"RGBA", "RGBX", rgb2rgba}, - {"RGBA", "CMYK", rgb2cmyk}, - {"RGBA", "YCbCr", ImagingConvertRGB2YCbCr}, - {"RGBA", "HSV", rgb2hsv}, - - {"RGBa", "RGBA", rgba2rgbA}, - {"RGBa", "RGB", rgba2rgb_}, - - {"RGBX", "1", rgb2bit}, - {"RGBX", "L", rgb2l}, - {"RGBX", "LA", rgb2la}, - {"RGBX", "I", rgb2i}, - {"RGBX", "F", rgb2f}, - {"RGBX", "RGB", rgba2rgb}, - {"RGBX", "CMYK", rgb2cmyk}, - {"RGBX", "YCbCr", ImagingConvertRGB2YCbCr}, - {"RGBX", "HSV", rgb2hsv}, - - {"CMYK", "RGB", cmyk2rgb}, - {"CMYK", "RGBA", cmyk2rgb}, - {"CMYK", "RGBX", cmyk2rgb}, - {"CMYK", "HSV", cmyk2hsv}, - - {"YCbCr", "L", ycbcr2l}, - {"YCbCr", "LA", ycbcr2la}, - {"YCbCr", "RGB", ImagingConvertYCbCr2RGB}, - - {"HSV", "RGB", hsv2rgb}, - - {"I", "I;16", I_I16L}, - {"I;16", "I", I16L_I}, - {"I;16", "RGB", I16_RGB}, - {"L", "I;16", L_I16L}, - {"I;16", "L", I16L_L}, - - {"I", "I;16L", I_I16L}, - {"I;16L", "I", I16L_I}, - {"I", "I;16B", I_I16B}, - {"I;16B", "I", I16B_I}, - - {"L", "I;16L", L_I16L}, - {"I;16L", "L", I16L_L}, - {"L", "I;16B", L_I16B}, - {"I;16B", "L", I16B_L}, -#ifdef WORDS_BIGENDIAN - {"L", "I;16N", L_I16B}, - {"I;16N", "L", I16B_L}, -#else - {"L", "I;16N", L_I16L}, - {"I;16N", "L", I16L_L}, -#endif - - {"I;16", "F", I16L_F}, - {"I;16L", "F", I16L_F}, - {"I;16B", "F", I16B_F}, - - {NULL} -}; - -/* FIXME: translate indexed versions to pointer versions below this line */ - /* ------------------- */ /* Palette conversions */ /* ------------------- */ +/* FIXME: translate indexed versions to pointer versions below this line */ + static void p2bit(UINT8 *out, const UINT8 *in, int xsize, ImagingPalette palette) { int x; @@ -1100,13 +962,13 @@ pa2p(UINT8 *out, const UINT8 *in, int xsize, ImagingPalette palette) { static void p2pa(UINT8 *out, const UINT8 *in, int xsize, ImagingPalette palette) { int x; - int rgb = strcmp(palette->mode, "RGB"); + const int rgb = palette->mode == IMAGING_MODE_RGB; for (x = 0; x < xsize; x++, in++) { const UINT8 *rgba = &palette->palette[in[0] * 4]; *out++ = in[0]; *out++ = in[0]; *out++ = in[0]; - *out++ = rgb == 0 ? 255 : rgba[3]; + *out++ = rgb ? 255 : rgba[3]; } } @@ -1260,7 +1122,7 @@ pa2ycbcr(UINT8 *out, const UINT8 *in, int xsize, ImagingPalette palette) { } static Imaging -frompalette(Imaging imOut, Imaging imIn, const char *mode) { +frompalette(Imaging imOut, Imaging imIn, const ModeID mode) { ImagingSectionCookie cookie; int alpha; int y; @@ -1272,31 +1134,31 @@ frompalette(Imaging imOut, Imaging imIn, const char *mode) { return (Imaging)ImagingError_ValueError("no palette"); } - alpha = !strcmp(imIn->mode, "PA"); + alpha = imIn->mode == IMAGING_MODE_PA; - if (strcmp(mode, "1") == 0) { + if (mode == IMAGING_MODE_1) { convert = alpha ? pa2bit : p2bit; - } else if (strcmp(mode, "L") == 0) { + } else if (mode == IMAGING_MODE_L) { convert = alpha ? pa2l : p2l; - } else if (strcmp(mode, "LA") == 0) { + } else if (mode == IMAGING_MODE_LA) { convert = alpha ? pa2la : p2la; - } else if (strcmp(mode, "P") == 0) { + } else if (mode == IMAGING_MODE_P) { convert = pa2p; - } else if (strcmp(mode, "PA") == 0) { + } else if (mode == IMAGING_MODE_PA) { convert = p2pa; - } else if (strcmp(mode, "I") == 0) { + } else if (mode == IMAGING_MODE_I) { convert = alpha ? pa2i : p2i; - } else if (strcmp(mode, "F") == 0) { + } else if (mode == IMAGING_MODE_F) { convert = alpha ? pa2f : p2f; - } else if (strcmp(mode, "RGB") == 0) { + } else if (mode == IMAGING_MODE_RGB) { convert = alpha ? pa2rgb : p2rgb; - } else if (strcmp(mode, "RGBA") == 0 || strcmp(mode, "RGBX") == 0) { + } else if (mode == IMAGING_MODE_RGBA || mode == IMAGING_MODE_RGBX) { convert = alpha ? pa2rgba : p2rgba; - } else if (strcmp(mode, "CMYK") == 0) { + } else if (mode == IMAGING_MODE_CMYK) { convert = alpha ? pa2cmyk : p2cmyk; - } else if (strcmp(mode, "YCbCr") == 0) { + } else if (mode == IMAGING_MODE_YCbCr) { convert = alpha ? pa2ycbcr : p2ycbcr; - } else if (strcmp(mode, "HSV") == 0) { + } else if (mode == IMAGING_MODE_HSV) { convert = alpha ? pa2hsv : p2hsv; } else { return (Imaging)ImagingError_ValueError("conversion not supported"); @@ -1306,7 +1168,7 @@ frompalette(Imaging imOut, Imaging imIn, const char *mode) { if (!imOut) { return NULL; } - if (strcmp(mode, "P") == 0 || strcmp(mode, "PA") == 0) { + if (mode == IMAGING_MODE_P || mode == IMAGING_MODE_PA) { ImagingPaletteDelete(imOut->palette); imOut->palette = ImagingPaletteDuplicate(imIn->palette); } @@ -1330,24 +1192,26 @@ frompalette(Imaging imOut, Imaging imIn, const char *mode) { #endif static Imaging topalette( - Imaging imOut, Imaging imIn, const char *mode, ImagingPalette inpalette, int dither + Imaging imOut, Imaging imIn, const ModeID mode, ImagingPalette inpalette, int dither ) { ImagingSectionCookie cookie; int alpha; int x, y; ImagingPalette palette = inpalette; - /* Map L or RGB/RGBX/RGBA to palette image */ - if (strcmp(imIn->mode, "L") != 0 && strncmp(imIn->mode, "RGB", 3) != 0) { + /* Map L or RGB/RGBX/RGBA/RGBa to palette image */ + if (imIn->mode != IMAGING_MODE_L && imIn->mode != IMAGING_MODE_RGB && + imIn->mode != IMAGING_MODE_RGBX && imIn->mode != IMAGING_MODE_RGBA && + imIn->mode != IMAGING_MODE_RGBa) { return (Imaging)ImagingError_ValueError("conversion not supported"); } - alpha = !strcmp(mode, "PA"); + alpha = mode == IMAGING_MODE_PA; if (palette == NULL) { /* FIXME: make user configurable */ if (imIn->bands == 1) { - palette = ImagingPaletteNew("RGB"); + palette = ImagingPaletteNew(IMAGING_MODE_RGB); palette->size = 256; int i; @@ -1534,11 +1398,11 @@ tobilevel(Imaging imOut, Imaging imIn) { int *errors; /* Map L or RGB to dithered 1 image */ - if (strcmp(imIn->mode, "L") != 0 && strcmp(imIn->mode, "RGB") != 0) { + if (imIn->mode != IMAGING_MODE_L && imIn->mode != IMAGING_MODE_RGB) { return (Imaging)ImagingError_ValueError("conversion not supported"); } - imOut = ImagingNew2Dirty("1", imOut, imIn); + imOut = ImagingNew2Dirty(IMAGING_MODE_1, imOut, imIn); if (!imOut) { return NULL; } @@ -1620,19 +1484,155 @@ tobilevel(Imaging imOut, Imaging imIn) { #pragma optimize("", on) #endif +/* ------------------- */ +/* Conversion handlers */ +/* ------------------- */ + +static struct { + const ModeID from; + const ModeID to; + ImagingShuffler convert; +} converters[] = { + {IMAGING_MODE_1, IMAGING_MODE_L, bit2l}, + {IMAGING_MODE_1, IMAGING_MODE_I, bit2i}, + {IMAGING_MODE_1, IMAGING_MODE_F, bit2f}, + {IMAGING_MODE_1, IMAGING_MODE_RGB, bit2rgb}, + {IMAGING_MODE_1, IMAGING_MODE_RGBA, bit2rgb}, + {IMAGING_MODE_1, IMAGING_MODE_RGBX, bit2rgb}, + {IMAGING_MODE_1, IMAGING_MODE_CMYK, bit2cmyk}, + {IMAGING_MODE_1, IMAGING_MODE_YCbCr, bit2ycbcr}, + {IMAGING_MODE_1, IMAGING_MODE_HSV, bit2hsv}, + + {IMAGING_MODE_L, IMAGING_MODE_1, l2bit}, + {IMAGING_MODE_L, IMAGING_MODE_LA, l2la}, + {IMAGING_MODE_L, IMAGING_MODE_I, l2i}, + {IMAGING_MODE_L, IMAGING_MODE_F, l2f}, + {IMAGING_MODE_L, IMAGING_MODE_RGB, l2rgb}, + {IMAGING_MODE_L, IMAGING_MODE_RGBA, l2rgb}, + {IMAGING_MODE_L, IMAGING_MODE_RGBX, l2rgb}, + {IMAGING_MODE_L, IMAGING_MODE_CMYK, l2cmyk}, + {IMAGING_MODE_L, IMAGING_MODE_YCbCr, l2ycbcr}, + {IMAGING_MODE_L, IMAGING_MODE_HSV, l2hsv}, + + {IMAGING_MODE_LA, IMAGING_MODE_L, la2l}, + {IMAGING_MODE_LA, IMAGING_MODE_La, lA2la}, + {IMAGING_MODE_LA, IMAGING_MODE_RGB, la2rgb}, + {IMAGING_MODE_LA, IMAGING_MODE_RGBA, la2rgb}, + {IMAGING_MODE_LA, IMAGING_MODE_RGBX, la2rgb}, + {IMAGING_MODE_LA, IMAGING_MODE_CMYK, la2cmyk}, + {IMAGING_MODE_LA, IMAGING_MODE_YCbCr, la2ycbcr}, + {IMAGING_MODE_LA, IMAGING_MODE_HSV, la2hsv}, + + {IMAGING_MODE_La, IMAGING_MODE_LA, la2lA}, + + {IMAGING_MODE_I, IMAGING_MODE_L, i2l}, + {IMAGING_MODE_I, IMAGING_MODE_F, i2f}, + {IMAGING_MODE_I, IMAGING_MODE_RGB, i2rgb}, + {IMAGING_MODE_I, IMAGING_MODE_RGBA, i2rgb}, + {IMAGING_MODE_I, IMAGING_MODE_RGBX, i2rgb}, + {IMAGING_MODE_I, IMAGING_MODE_HSV, i2hsv}, + + {IMAGING_MODE_F, IMAGING_MODE_L, f2l}, + {IMAGING_MODE_F, IMAGING_MODE_I, f2i}, + + {IMAGING_MODE_RGB, IMAGING_MODE_1, rgb2bit}, + {IMAGING_MODE_RGB, IMAGING_MODE_L, rgb2l}, + {IMAGING_MODE_RGB, IMAGING_MODE_LA, rgb2la}, + {IMAGING_MODE_RGB, IMAGING_MODE_La, rgb2la}, + {IMAGING_MODE_RGB, IMAGING_MODE_I, rgb2i}, + {IMAGING_MODE_RGB, IMAGING_MODE_I_16, rgb2i16l}, + {IMAGING_MODE_RGB, IMAGING_MODE_I_16L, rgb2i16l}, + {IMAGING_MODE_RGB, IMAGING_MODE_I_16B, rgb2i16b}, +#ifdef WORDS_BIGENDIAN + {IMAGING_MODE_RGB, IMAGING_MODE_I_16N, rgb2i16b}, +#else + {IMAGING_MODE_RGB, IMAGING_MODE_I_16N, rgb2i16l}, +#endif + {IMAGING_MODE_RGB, IMAGING_MODE_F, rgb2f}, + {IMAGING_MODE_RGB, IMAGING_MODE_BGR_15, rgb2bgr15}, + {IMAGING_MODE_RGB, IMAGING_MODE_BGR_16, rgb2bgr16}, + {IMAGING_MODE_RGB, IMAGING_MODE_BGR_24, rgb2bgr24}, + {IMAGING_MODE_RGB, IMAGING_MODE_RGBA, rgb2rgba}, + {IMAGING_MODE_RGB, IMAGING_MODE_RGBa, rgb2rgba}, + {IMAGING_MODE_RGB, IMAGING_MODE_RGBX, rgb2rgba}, + {IMAGING_MODE_RGB, IMAGING_MODE_CMYK, rgb2cmyk}, + {IMAGING_MODE_RGB, IMAGING_MODE_YCbCr, ImagingConvertRGB2YCbCr}, + {IMAGING_MODE_RGB, IMAGING_MODE_HSV, rgb2hsv}, + + {IMAGING_MODE_RGBA, IMAGING_MODE_1, rgb2bit}, + {IMAGING_MODE_RGBA, IMAGING_MODE_L, rgb2l}, + {IMAGING_MODE_RGBA, IMAGING_MODE_LA, rgba2la}, + {IMAGING_MODE_RGBA, IMAGING_MODE_I, rgb2i}, + {IMAGING_MODE_RGBA, IMAGING_MODE_F, rgb2f}, + {IMAGING_MODE_RGBA, IMAGING_MODE_RGB, rgba2rgb}, + {IMAGING_MODE_RGBA, IMAGING_MODE_RGBa, rgbA2rgba}, + {IMAGING_MODE_RGBA, IMAGING_MODE_RGBX, rgb2rgba}, + {IMAGING_MODE_RGBA, IMAGING_MODE_CMYK, rgb2cmyk}, + {IMAGING_MODE_RGBA, IMAGING_MODE_YCbCr, ImagingConvertRGB2YCbCr}, + {IMAGING_MODE_RGBA, IMAGING_MODE_HSV, rgb2hsv}, + + {IMAGING_MODE_RGBa, IMAGING_MODE_RGBA, rgba2rgbA}, + {IMAGING_MODE_RGBa, IMAGING_MODE_RGB, rgba2rgb_}, + + {IMAGING_MODE_RGBX, IMAGING_MODE_1, rgb2bit}, + {IMAGING_MODE_RGBX, IMAGING_MODE_L, rgb2l}, + {IMAGING_MODE_RGBX, IMAGING_MODE_LA, rgb2la}, + {IMAGING_MODE_RGBX, IMAGING_MODE_I, rgb2i}, + {IMAGING_MODE_RGBX, IMAGING_MODE_F, rgb2f}, + {IMAGING_MODE_RGBX, IMAGING_MODE_RGB, rgba2rgb}, + {IMAGING_MODE_RGBX, IMAGING_MODE_CMYK, rgb2cmyk}, + {IMAGING_MODE_RGBX, IMAGING_MODE_YCbCr, ImagingConvertRGB2YCbCr}, + {IMAGING_MODE_RGBX, IMAGING_MODE_HSV, rgb2hsv}, + + {IMAGING_MODE_CMYK, IMAGING_MODE_RGB, cmyk2rgb}, + {IMAGING_MODE_CMYK, IMAGING_MODE_RGBA, cmyk2rgb}, + {IMAGING_MODE_CMYK, IMAGING_MODE_RGBX, cmyk2rgb}, + {IMAGING_MODE_CMYK, IMAGING_MODE_HSV, cmyk2hsv}, + + {IMAGING_MODE_YCbCr, IMAGING_MODE_L, ycbcr2l}, + {IMAGING_MODE_YCbCr, IMAGING_MODE_LA, ycbcr2la}, + {IMAGING_MODE_YCbCr, IMAGING_MODE_RGB, ImagingConvertYCbCr2RGB}, + + {IMAGING_MODE_HSV, IMAGING_MODE_RGB, hsv2rgb}, + + {IMAGING_MODE_I, IMAGING_MODE_I_16, I_I16L}, + {IMAGING_MODE_I_16, IMAGING_MODE_I, I16L_I}, + {IMAGING_MODE_I_16, IMAGING_MODE_RGB, I16_RGB}, + {IMAGING_MODE_L, IMAGING_MODE_I_16, L_I16L}, + {IMAGING_MODE_I_16, IMAGING_MODE_L, I16L_L}, + + {IMAGING_MODE_I, IMAGING_MODE_I_16L, I_I16L}, + {IMAGING_MODE_I_16L, IMAGING_MODE_I, I16L_I}, + {IMAGING_MODE_I, IMAGING_MODE_I_16B, I_I16B}, + {IMAGING_MODE_I_16B, IMAGING_MODE_I, I16B_I}, + + {IMAGING_MODE_L, IMAGING_MODE_I_16L, L_I16L}, + {IMAGING_MODE_I_16L, IMAGING_MODE_L, I16L_L}, + {IMAGING_MODE_L, IMAGING_MODE_I_16B, L_I16B}, + {IMAGING_MODE_I_16B, IMAGING_MODE_L, I16B_L}, +#ifdef WORDS_BIGENDIAN + {IMAGING_MODE_L, IMAGING_MODE_I_16N, L_I16B}, + {IMAGING_MODE_I_16N, IMAGING_MODE_L, I16B_L}, +#else + {IMAGING_MODE_L, IMAGING_MODE_I_16N, L_I16L}, + {IMAGING_MODE_I_16N, IMAGING_MODE_L, I16L_L}, +#endif + + {IMAGING_MODE_I_16, IMAGING_MODE_F, I16L_F}, + {IMAGING_MODE_I_16L, IMAGING_MODE_F, I16L_F}, + {IMAGING_MODE_I_16B, IMAGING_MODE_F, I16B_F} +}; + static Imaging -convert( - Imaging imOut, Imaging imIn, const char *mode, ImagingPalette palette, int dither -) { +convert(Imaging imOut, Imaging imIn, ModeID mode, ImagingPalette palette, int dither) { ImagingSectionCookie cookie; ImagingShuffler convert; - int y; if (!imIn) { return (Imaging)ImagingError_ModeError(); } - if (!mode) { + if (mode == IMAGING_MODE_UNKNOWN) { /* Map palette image to full depth */ if (!imIn->palette) { return (Imaging)ImagingError_ModeError(); @@ -1640,33 +1640,31 @@ convert( mode = imIn->palette->mode; } else { /* Same mode? */ - if (!strcmp(imIn->mode, mode)) { + if (imIn->mode == mode) { return ImagingCopy2(imOut, imIn); } } /* test for special conversions */ - if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "PA") == 0) { + if (imIn->mode == IMAGING_MODE_P || imIn->mode == IMAGING_MODE_PA) { return frompalette(imOut, imIn, mode); } - if (strcmp(mode, "P") == 0 || strcmp(mode, "PA") == 0) { + if (mode == IMAGING_MODE_P || mode == IMAGING_MODE_PA) { return topalette(imOut, imIn, mode, palette, dither); } - if (dither && strcmp(mode, "1") == 0) { + if (dither && mode == IMAGING_MODE_1) { return tobilevel(imOut, imIn); } /* standard conversion machinery */ convert = NULL; - - for (y = 0; converters[y].from; y++) { - if (!strcmp(imIn->mode, converters[y].from) && - !strcmp(mode, converters[y].to)) { - convert = converters[y].convert; + for (size_t i = 0; i < sizeof(converters) / sizeof(*converters); i++) { + if (imIn->mode == converters[i].from && mode == converters[i].to) { + convert = converters[i].convert; break; } } @@ -1677,7 +1675,11 @@ convert( #else static char buf[100]; snprintf( - buf, 100, "conversion from %.10s to %.10s not supported", imIn->mode, mode + buf, + 100, + "conversion from %.10s to %.10s not supported", + getModeData(imIn->mode)->name, + getModeData(mode)->name ); return (Imaging)ImagingError_ValueError(buf); #endif @@ -1689,7 +1691,7 @@ convert( } ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) { + for (int y = 0; y < imIn->ysize; y++) { (*convert)((UINT8 *)imOut->image[y], (UINT8 *)imIn->image[y], imIn->xsize); } ImagingSectionLeave(&cookie); @@ -1698,7 +1700,7 @@ convert( } Imaging -ImagingConvert(Imaging imIn, const char *mode, ImagingPalette palette, int dither) { +ImagingConvert(Imaging imIn, const ModeID mode, ImagingPalette palette, int dither) { return convert(NULL, imIn, mode, palette, dither); } @@ -1708,7 +1710,7 @@ ImagingConvert2(Imaging imOut, Imaging imIn) { } Imaging -ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) { +ImagingConvertTransparent(Imaging imIn, const ModeID mode, int r, int g, int b) { ImagingSectionCookie cookie; ImagingShuffler convert; Imaging imOut = NULL; @@ -1722,27 +1724,27 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) { return (Imaging)ImagingError_ModeError(); } - if (strcmp(imIn->mode, "RGB") == 0 && - (strcmp(mode, "RGBA") == 0 || strcmp(mode, "RGBa") == 0)) { + if (imIn->mode == IMAGING_MODE_RGB && + (mode == IMAGING_MODE_RGBA || mode == IMAGING_MODE_RGBa)) { convert = rgb2rgba; - if (strcmp(mode, "RGBa") == 0) { + if (mode == IMAGING_MODE_RGBa) { premultiplied = 1; } - } else if (strcmp(imIn->mode, "RGB") == 0 && - (strcmp(mode, "LA") == 0 || strcmp(mode, "La") == 0)) { + } else if (imIn->mode == IMAGING_MODE_RGB && + (mode == IMAGING_MODE_LA || mode == IMAGING_MODE_La)) { convert = rgb2la; source_transparency = 1; - if (strcmp(mode, "La") == 0) { + if (mode == IMAGING_MODE_La) { premultiplied = 1; } - } else if ((strcmp(imIn->mode, "1") == 0 || strcmp(imIn->mode, "I") == 0 || - strcmp(imIn->mode, "I;16") == 0 || strcmp(imIn->mode, "L") == 0) && - (strcmp(mode, "RGBA") == 0 || strcmp(mode, "LA") == 0)) { - if (strcmp(imIn->mode, "1") == 0) { + } else if ((imIn->mode == IMAGING_MODE_1 || imIn->mode == IMAGING_MODE_I || + imIn->mode == IMAGING_MODE_I_16 || imIn->mode == IMAGING_MODE_L) && + (mode == IMAGING_MODE_RGBA || mode == IMAGING_MODE_LA)) { + if (imIn->mode == IMAGING_MODE_1) { convert = bit2rgb; - } else if (strcmp(imIn->mode, "I") == 0) { + } else if (imIn->mode == IMAGING_MODE_I) { convert = i2rgb; - } else if (strcmp(imIn->mode, "I;16") == 0) { + } else if (imIn->mode == IMAGING_MODE_I_16) { convert = I16_RGB; } else { convert = l2rgb; @@ -1754,8 +1756,8 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) { buf, 100, "conversion from %.10s to %.10s not supported in convert_transparent", - imIn->mode, - mode + getModeData(imIn->mode)->name, + getModeData(mode)->name ); return (Imaging)ImagingError_ValueError(buf); } @@ -1778,15 +1780,15 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) { } Imaging -ImagingConvertInPlace(Imaging imIn, const char *mode) { +ImagingConvertInPlace(Imaging imIn, const ModeID mode) { ImagingSectionCookie cookie; ImagingShuffler convert; int y; /* limited support for inplace conversion */ - if (strcmp(imIn->mode, "L") == 0 && strcmp(mode, "1") == 0) { + if (imIn->mode == IMAGING_MODE_L && mode == IMAGING_MODE_1) { convert = l2bit; - } else if (strcmp(imIn->mode, "1") == 0 && strcmp(mode, "L") == 0) { + } else if (imIn->mode == IMAGING_MODE_1 && mode == IMAGING_MODE_L) { convert = bit2l; } else { return ImagingError_ModeError(); diff --git a/src/libImaging/Dib.c b/src/libImaging/Dib.c index c69e9e552ae..2afe71d4ac9 100644 --- a/src/libImaging/Dib.c +++ b/src/libImaging/Dib.c @@ -25,20 +25,17 @@ #include "ImDib.h" -char * +ModeID ImagingGetModeDIB(int size_out[2]) { /* Get device characteristics */ - HDC dc; - char *mode; + const HDC dc = CreateCompatibleDC(NULL); - dc = CreateCompatibleDC(NULL); - - mode = "P"; + ModeID mode = IMAGING_MODE_P; if (!(GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE)) { - mode = "RGB"; + mode = IMAGING_MODE_RGB; if (GetDeviceCaps(dc, BITSPIXEL) == 1) { - mode = "1"; + mode = IMAGING_MODE_1; } } @@ -53,7 +50,7 @@ ImagingGetModeDIB(int size_out[2]) { } ImagingDIB -ImagingNewDIB(const char *mode, int xsize, int ysize) { +ImagingNewDIB(const ModeID mode, int xsize, int ysize) { /* Create a Windows bitmap */ ImagingDIB dib; @@ -61,10 +58,12 @@ ImagingNewDIB(const char *mode, int xsize, int ysize) { int i; /* Check mode */ - if (strcmp(mode, "1") != 0 && strcmp(mode, "L") != 0 && strcmp(mode, "RGB") != 0) { + if (mode != IMAGING_MODE_1 && mode != IMAGING_MODE_L && mode != IMAGING_MODE_RGB) { return (ImagingDIB)ImagingError_ModeError(); } + const int pixelsize = mode == IMAGING_MODE_RGB ? 3 : 1; + /* Create DIB context and info header */ /* malloc check ok, small constant allocation */ dib = (ImagingDIB)malloc(sizeof(*dib)); @@ -83,7 +82,7 @@ ImagingNewDIB(const char *mode, int xsize, int ysize) { dib->info->bmiHeader.biWidth = xsize; dib->info->bmiHeader.biHeight = ysize; dib->info->bmiHeader.biPlanes = 1; - dib->info->bmiHeader.biBitCount = strlen(mode) * 8; + dib->info->bmiHeader.biBitCount = pixelsize * 8; dib->info->bmiHeader.biCompression = BI_RGB; /* Create DIB */ @@ -103,12 +102,12 @@ ImagingNewDIB(const char *mode, int xsize, int ysize) { return (ImagingDIB)ImagingError_MemoryError(); } - strcpy(dib->mode, mode); + dib->mode = mode; dib->xsize = xsize; dib->ysize = ysize; - dib->pixelsize = strlen(mode); - dib->linesize = (xsize * dib->pixelsize + 3) & -4; + dib->pixelsize = pixelsize; + dib->linesize = (xsize * pixelsize + 3) & -4; if (dib->pixelsize == 1) { dib->pack = dib->unpack = (ImagingShuffler)memcpy; @@ -132,7 +131,7 @@ ImagingNewDIB(const char *mode, int xsize, int ysize) { } /* Create an associated palette (for 8-bit displays only) */ - if (strcmp(ImagingGetModeDIB(NULL), "P") == 0) { + if (ImagingGetModeDIB(NULL) == IMAGING_MODE_P) { char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)]; LPLOGPALETTE pal = (LPLOGPALETTE)palbuf; int i, r, g, b; @@ -142,7 +141,7 @@ ImagingNewDIB(const char *mode, int xsize, int ysize) { pal->palNumEntries = 256; GetSystemPaletteEntries(dib->dc, 0, 256, pal->palPalEntry); - if (strcmp(mode, "L") == 0) { + if (mode == IMAGING_MODE_L) { /* Grayscale DIB. Fill all 236 slots with a grayscale ramp * (this is usually overkill on Windows since VGA only offers * 6 bits grayscale resolution). Ignore the slots already @@ -156,8 +155,7 @@ ImagingNewDIB(const char *mode, int xsize, int ysize) { } dib->palette = CreatePalette(pal); - - } else if (strcmp(mode, "RGB") == 0) { + } else if (mode == IMAGING_MODE_RGB) { #ifdef CUBE216 /* Colour DIB. Create a 6x6x6 colour cube (216 entries) and diff --git a/src/libImaging/Draw.c b/src/libImaging/Draw.c index f1c8ffcff8d..0b4fc4d2b6b 100644 --- a/src/libImaging/Draw.c +++ b/src/libImaging/Draw.c @@ -68,7 +68,7 @@ typedef void (*hline_handler)(Imaging, int, int, int, int); static inline void point8(Imaging im, int x, int y, int ink) { if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) { - if (strncmp(im->mode, "I;16", 4) == 0) { + if (isModeI16(im->mode)) { #ifdef WORDS_BIGENDIAN im->image8[y][x * 2] = (UINT8)(ink >> 8); im->image8[y][x * 2 + 1] = (UINT8)ink; @@ -118,7 +118,7 @@ hline8(Imaging im, int x0, int y0, int x1, int ink) { x1 = im->xsize - 1; } if (x0 <= x1) { - pixelwidth = strncmp(im->mode, "I;16", 4) == 0 ? 2 : 1; + pixelwidth = isModeI16(im->mode) ? 2 : 1; memset( im->image8[y0] + x0 * pixelwidth, (UINT8)ink, (x1 - x0 + 1) * pixelwidth ); @@ -659,17 +659,17 @@ DRAW draw32rgba = {point32rgba, hline32rgba, line32rgba, polygon32rgba}; /* Interface */ /* -------------------------------------------------------------------- */ -#define DRAWINIT() \ - if (im->image8) { \ - draw = &draw8; \ - if (strncmp(im->mode, "I;16", 4) == 0) { \ - ink = INK16(ink_); \ - } else { \ - ink = INK8(ink_); \ - } \ - } else { \ - draw = (op) ? &draw32rgba : &draw32; \ - memcpy(&ink, ink_, sizeof(ink)); \ +#define DRAWINIT() \ + if (im->image8) { \ + draw = &draw8; \ + if (isModeI16(im->mode)) { \ + ink = INK16(ink_); \ + } else { \ + ink = INK8(ink_); \ + } \ + } else { \ + draw = (op) ? &draw32rgba : &draw32; \ + memcpy(&ink, ink_, sizeof(ink)); \ } int diff --git a/src/libImaging/Effects.c b/src/libImaging/Effects.c index 93e7af0bce9..c05c5764e44 100644 --- a/src/libImaging/Effects.c +++ b/src/libImaging/Effects.c @@ -36,7 +36,7 @@ ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality) { return (Imaging)ImagingError_ValueError(NULL); } - im = ImagingNewDirty("L", xsize, ysize); + im = ImagingNewDirty(IMAGING_MODE_L, xsize, ysize); if (!im) { return NULL; } @@ -80,7 +80,7 @@ ImagingEffectNoise(int xsize, int ysize, float sigma) { int nextok; double this, next; - imOut = ImagingNewDirty("L", xsize, ysize); + imOut = ImagingNewDirty(IMAGING_MODE_L, xsize, ysize); if (!imOut) { return NULL; } diff --git a/src/libImaging/File.c b/src/libImaging/File.c index 76d0abccc4f..b1158a801a4 100644 --- a/src/libImaging/File.c +++ b/src/libImaging/File.c @@ -23,14 +23,13 @@ int ImagingSaveRaw(Imaging im, FILE *fp) { int x, y, i; - if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) { + if (im->mode == IMAGING_MODE_1 || im->mode == IMAGING_MODE_L) { /* @PIL227: FIXME: for mode "1", map != 0 to 255 */ /* PGM "L" */ for (y = 0; y < im->ysize; y++) { fwrite(im->image[y], 1, im->xsize, fp); } - } else { /* PPM "RGB" or other internal format */ for (y = 0; y < im->ysize; y++) { @@ -58,10 +57,10 @@ ImagingSavePPM(Imaging im, const char *outfile) { return 0; } - if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) { + if (im->mode == IMAGING_MODE_1 || im->mode == IMAGING_MODE_L) { /* Write "PGM" */ fprintf(fp, "P5\n%d %d\n255\n", im->xsize, im->ysize); - } else if (strcmp(im->mode, "RGB") == 0) { + } else if (im->mode == IMAGING_MODE_RGB) { /* Write "PPM" */ fprintf(fp, "P6\n%d %d\n255\n", im->xsize, im->ysize); } else { diff --git a/src/libImaging/Fill.c b/src/libImaging/Fill.c index 8fb481e7e4d..a8dae87f4c4 100644 --- a/src/libImaging/Fill.c +++ b/src/libImaging/Fill.c @@ -68,11 +68,12 @@ ImagingFill(Imaging im, const void *colour) { } Imaging -ImagingFillLinearGradient(const char *mode) { +ImagingFillLinearGradient(const ModeID mode) { Imaging im; int y; - if (strlen(mode) != 1) { + if (mode != IMAGING_MODE_1 && mode != IMAGING_MODE_F && mode != IMAGING_MODE_I && + mode != IMAGING_MODE_L && mode != IMAGING_MODE_P) { return (Imaging)ImagingError_ModeError(); } @@ -102,12 +103,13 @@ ImagingFillLinearGradient(const char *mode) { } Imaging -ImagingFillRadialGradient(const char *mode) { +ImagingFillRadialGradient(const ModeID mode) { Imaging im; int x, y; int d; - if (strlen(mode) != 1) { + if (mode != IMAGING_MODE_1 && mode != IMAGING_MODE_F && mode != IMAGING_MODE_I && + mode != IMAGING_MODE_L && mode != IMAGING_MODE_P) { return (Imaging)ImagingError_ModeError(); } diff --git a/src/libImaging/Filter.c b/src/libImaging/Filter.c index 7b7b2e4292d..48f21080906 100644 --- a/src/libImaging/Filter.c +++ b/src/libImaging/Filter.c @@ -155,9 +155,9 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float *kernel, float offset) { } else { int bigendian = 0; if (im->type == IMAGING_TYPE_SPECIAL) { - if (strcmp(im->mode, "I;16B") == 0 + if (im->mode == IMAGING_MODE_I_16B #ifdef WORDS_BIGENDIAN - || strcmp(im->mode, "I;16N") == 0 + || im->mode == IMAGING_MODE_I_16N #endif ) { bigendian = 1; @@ -308,9 +308,9 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float *kernel, float offset) { } else { int bigendian = 0; if (im->type == IMAGING_TYPE_SPECIAL) { - if (strcmp(im->mode, "I;16B") == 0 + if (im->mode == IMAGING_MODE_I_16B #ifdef WORDS_BIGENDIAN - || strcmp(im->mode, "I;16N") == 0 + || im->mode == IMAGING_MODE_I_16N #endif ) { bigendian = 1; diff --git a/src/libImaging/Geometry.c b/src/libImaging/Geometry.c index 1e2abd7e75c..80ecd7cb6b3 100644 --- a/src/libImaging/Geometry.c +++ b/src/libImaging/Geometry.c @@ -19,7 +19,7 @@ ImagingFlipLeftRight(Imaging imOut, Imaging imIn) { ImagingSectionCookie cookie; int x, y, xr; - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) { + if (!imOut || !imIn || imIn->mode != imOut->mode) { return (Imaging)ImagingError_ModeError(); } if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) { @@ -41,7 +41,7 @@ ImagingFlipLeftRight(Imaging imOut, Imaging imIn) { ImagingSectionEnter(&cookie); if (imIn->image8) { - if (strncmp(imIn->mode, "I;16", 4) == 0) { + if (isModeI16(imIn->mode)) { FLIP_LEFT_RIGHT(UINT16, image8) } else { FLIP_LEFT_RIGHT(UINT8, image8) @@ -62,7 +62,7 @@ ImagingFlipTopBottom(Imaging imOut, Imaging imIn) { ImagingSectionCookie cookie; int y, yr; - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) { + if (!imOut || !imIn || imIn->mode != imOut->mode) { return (Imaging)ImagingError_ModeError(); } if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) { @@ -89,7 +89,7 @@ ImagingRotate90(Imaging imOut, Imaging imIn) { int x, y, xx, yy, xr, xxsize, yysize; int xxx, yyy, xxxsize, yyysize; - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) { + if (!imOut || !imIn || imIn->mode != imOut->mode) { return (Imaging)ImagingError_ModeError(); } if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) { @@ -127,7 +127,7 @@ ImagingRotate90(Imaging imOut, Imaging imIn) { ImagingSectionEnter(&cookie); if (imIn->image8) { - if (strncmp(imIn->mode, "I;16", 4) == 0) { + if (isModeI16(imIn->mode)) { ROTATE_90(UINT16, image8); } else { ROTATE_90(UINT8, image8); @@ -149,7 +149,7 @@ ImagingTranspose(Imaging imOut, Imaging imIn) { int x, y, xx, yy, xxsize, yysize; int xxx, yyy, xxxsize, yyysize; - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) { + if (!imOut || !imIn || imIn->mode != imOut->mode) { return (Imaging)ImagingError_ModeError(); } if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) { @@ -186,7 +186,7 @@ ImagingTranspose(Imaging imOut, Imaging imIn) { ImagingSectionEnter(&cookie); if (imIn->image8) { - if (strncmp(imIn->mode, "I;16", 4) == 0) { + if (isModeI16(imIn->mode)) { TRANSPOSE(UINT16, image8); } else { TRANSPOSE(UINT8, image8); @@ -208,7 +208,7 @@ ImagingTransverse(Imaging imOut, Imaging imIn) { int x, y, xr, yr, xx, yy, xxsize, yysize; int xxx, yyy, xxxsize, yyysize; - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) { + if (!imOut || !imIn || imIn->mode != imOut->mode) { return (Imaging)ImagingError_ModeError(); } if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) { @@ -247,7 +247,7 @@ ImagingTransverse(Imaging imOut, Imaging imIn) { ImagingSectionEnter(&cookie); if (imIn->image8) { - if (strncmp(imIn->mode, "I;16", 4) == 0) { + if (isModeI16(imIn->mode)) { TRANSVERSE(UINT16, image8); } else { TRANSVERSE(UINT8, image8); @@ -268,7 +268,7 @@ ImagingRotate180(Imaging imOut, Imaging imIn) { ImagingSectionCookie cookie; int x, y, xr, yr; - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) { + if (!imOut || !imIn || imIn->mode != imOut->mode) { return (Imaging)ImagingError_ModeError(); } if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) { @@ -291,7 +291,7 @@ ImagingRotate180(Imaging imOut, Imaging imIn) { yr = imIn->ysize - 1; if (imIn->image8) { - if (strncmp(imIn->mode, "I;16", 4) == 0) { + if (isModeI16(imIn->mode)) { ROTATE_180(UINT16, image8) } else { ROTATE_180(UINT8, image8) @@ -313,7 +313,7 @@ ImagingRotate270(Imaging imOut, Imaging imIn) { int x, y, xx, yy, yr, xxsize, yysize; int xxx, yyy, xxxsize, yyysize; - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) { + if (!imOut || !imIn || imIn->mode != imOut->mode) { return (Imaging)ImagingError_ModeError(); } if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) { @@ -351,7 +351,7 @@ ImagingRotate270(Imaging imOut, Imaging imIn) { ImagingSectionEnter(&cookie); if (imIn->image8) { - if (strncmp(imIn->mode, "I;16", 4) == 0) { + if (isModeI16(imIn->mode)) { ROTATE_270(UINT16, image8); } else { ROTATE_270(UINT8, image8); @@ -791,7 +791,7 @@ ImagingGenericTransform( char *out; double xx, yy; - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) { + if (!imOut || !imIn || imIn->mode != imOut->mode) { return (Imaging)ImagingError_ModeError(); } @@ -848,7 +848,7 @@ ImagingScaleAffine( int xmin, xmax; int *xintab; - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) { + if (!imOut || !imIn || imIn->mode != imOut->mode) { return (Imaging)ImagingError_ModeError(); } @@ -1035,7 +1035,7 @@ ImagingTransformAffine( double xx, yy; double xo, yo; - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) { + if (!imOut || !imIn || imIn->mode != imOut->mode) { return (Imaging)ImagingError_ModeError(); } diff --git a/src/libImaging/GetBBox.c b/src/libImaging/GetBBox.c index d430893ddb2..f94cf2a0e5f 100644 --- a/src/libImaging/GetBBox.c +++ b/src/libImaging/GetBBox.c @@ -90,9 +90,9 @@ ImagingGetBBox(Imaging im, int bbox[4], int alpha_only) { if (im->bands == 3) { ((UINT8 *)&mask)[3] = 0; } else if (alpha_only && - (strcmp(im->mode, "RGBa") == 0 || strcmp(im->mode, "RGBA") == 0 || - strcmp(im->mode, "La") == 0 || strcmp(im->mode, "LA") == 0 || - strcmp(im->mode, "PA") == 0)) { + (im->mode == IMAGING_MODE_RGBa || im->mode == IMAGING_MODE_RGBA || + im->mode == IMAGING_MODE_La || im->mode == IMAGING_MODE_LA || + im->mode == IMAGING_MODE_PA)) { #ifdef WORDS_BIGENDIAN mask = 0x000000ff; #else @@ -208,7 +208,7 @@ ImagingGetExtrema(Imaging im, void *extrema) { memcpy(((char *)extrema) + sizeof(fmin), &fmax, sizeof(fmax)); break; case IMAGING_TYPE_SPECIAL: - if (strcmp(im->mode, "I;16") == 0) { + if (im->mode == IMAGING_MODE_I_16) { UINT16 v; UINT8 *pixel = *im->image8; #ifdef WORDS_BIGENDIAN diff --git a/src/libImaging/Histo.c b/src/libImaging/Histo.c index c5a547a647b..cfbf8333d24 100644 --- a/src/libImaging/Histo.c +++ b/src/libImaging/Histo.c @@ -43,10 +43,10 @@ ImagingHistogramNew(Imaging im) { if (!h) { return (ImagingHistogram)ImagingError_MemoryError(); } - strncpy(h->mode, im->mode, IMAGING_MODE_LENGTH - 1); - h->mode[IMAGING_MODE_LENGTH - 1] = 0; + h->mode = im->mode; h->bands = im->bands; + h->histogram = calloc(im->pixelsize, 256 * sizeof(long)); if (!h->histogram) { free(h); @@ -73,7 +73,7 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) { if (im->xsize != imMask->xsize || im->ysize != imMask->ysize) { return ImagingError_Mismatch(); } - if (strcmp(imMask->mode, "1") != 0 && strcmp(imMask->mode, "L") != 0) { + if (imMask->mode != IMAGING_MODE_1 && imMask->mode != IMAGING_MODE_L) { return ImagingError_ValueError("bad transparency mask"); } } diff --git a/src/libImaging/ImDib.h b/src/libImaging/ImDib.h index 91ff3f322ff..65f090f928a 100644 --- a/src/libImaging/ImDib.h +++ b/src/libImaging/ImDib.h @@ -27,7 +27,7 @@ struct ImagingDIBInstance { UINT8 *bits; HPALETTE palette; /* Used by cut and paste */ - char mode[4]; + ModeID mode; int xsize, ysize; int pixelsize; int linesize; @@ -37,11 +37,11 @@ struct ImagingDIBInstance { typedef struct ImagingDIBInstance *ImagingDIB; -extern char * +extern ModeID ImagingGetModeDIB(int size_out[2]); extern ImagingDIB -ImagingNewDIB(const char *mode, int xsize, int ysize); +ImagingNewDIB(ModeID mode, int xsize, int ysize); extern void ImagingDeleteDIB(ImagingDIB im); diff --git a/src/libImaging/Imaging.h b/src/libImaging/Imaging.h index 31052c68a97..5bede5818ae 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. */ + 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. */ 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; + ModeID 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) */ + ModeID mode; /* Mode ID 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 */ + ModeID mode; /* Data */ int size; @@ -176,21 +173,21 @@ extern void ImagingMemoryClearCache(ImagingMemoryArena arena, int new_size); extern Imaging -ImagingNew(const char *mode, int xsize, int ysize); +ImagingNew(ModeID mode, int xsize, int ysize); extern Imaging -ImagingNewDirty(const char *mode, int xsize, int ysize); +ImagingNewDirty(ModeID mode, int xsize, int ysize); extern Imaging -ImagingNew2Dirty(const char *mode, Imaging imOut, Imaging imIn); +ImagingNew2Dirty(ModeID mode, Imaging imOut, Imaging imIn); extern void ImagingDelete(Imaging im); extern Imaging -ImagingNewBlock(const char *mode, int xsize, int ysize); +ImagingNewBlock(ModeID mode, int xsize, int ysize); extern Imaging -ImagingNewPrologue(const char *mode, int xsize, int ysize); +ImagingNewPrologue(ModeID mode, int xsize, int ysize); extern Imaging -ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int structure_size); +ImagingNewPrologueSubtype(ModeID mode, int xsize, int ysize, int structure_size); extern void ImagingCopyPalette(Imaging destination, Imaging source); @@ -198,8 +195,6 @@ ImagingCopyPalette(Imaging destination, Imaging source); extern void ImagingHistogramDelete(ImagingHistogram histogram); -extern void -ImagingAccessInit(void); extern ImagingAccess ImagingAccessNew(Imaging im); extern void @@ -207,7 +202,7 @@ _ImagingAccessDelete(Imaging im, ImagingAccess access); #define ImagingAccessDelete(im, access) /* nop, for now */ extern ImagingPalette -ImagingPaletteNew(const char *mode); +ImagingPaletteNew(ModeID mode); extern ImagingPalette ImagingPaletteNewBrowser(void); extern ImagingPalette @@ -283,13 +278,13 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha); extern Imaging ImagingCopy(Imaging im); extern Imaging -ImagingConvert(Imaging im, const char *mode, ImagingPalette palette, int dither); +ImagingConvert(Imaging im, ModeID mode, ImagingPalette palette, int dither); extern Imaging -ImagingConvertInPlace(Imaging im, const char *mode); +ImagingConvertInPlace(Imaging im, ModeID mode); extern Imaging -ImagingConvertMatrix(Imaging im, const char *mode, float m[]); +ImagingConvertMatrix(Imaging im, ModeID mode, float m[]); extern Imaging -ImagingConvertTransparent(Imaging im, const char *mode, int r, int g, int b); +ImagingConvertTransparent(Imaging im, ModeID mode, int r, int g, int b); extern Imaging ImagingCrop(Imaging im, int x0, int y0, int x1, int y1); extern Imaging @@ -303,9 +298,9 @@ ImagingFill2( extern Imaging ImagingFillBand(Imaging im, int band, int color); extern Imaging -ImagingFillLinearGradient(const char *mode); +ImagingFillLinearGradient(ModeID mode); extern Imaging -ImagingFillRadialGradient(const char *mode); +ImagingFillRadialGradient(ModeID mode); extern Imaging ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32 *kernel, FLOAT32 offset); extern Imaging @@ -319,7 +314,7 @@ ImagingGaussianBlur( extern Imaging ImagingGetBand(Imaging im, int band); extern Imaging -ImagingMerge(const char *mode, Imaging bands[4]); +ImagingMerge(ModeID mode, Imaging bands[4]); extern int ImagingSplit(Imaging im, Imaging bands[4]); extern int @@ -346,7 +341,7 @@ ImagingOffset(Imaging im, int xoffset, int yoffset); extern int ImagingPaste(Imaging into, Imaging im, Imaging mask, int x0, int y0, int x1, int y1); extern Imaging -ImagingPoint(Imaging im, const char *tablemode, const void *table); +ImagingPoint(Imaging im, ModeID tablemode, const void *table); extern Imaging ImagingPointTransform(Imaging imIn, double scale, double offset); extern Imaging @@ -674,9 +669,9 @@ extern void ImagingConvertYCbCr2RGB(UINT8 *out, const UINT8 *in, int pixels); extern ImagingShuffler -ImagingFindUnpacker(const char *mode, const char *rawmode, int *bits_out); +ImagingFindUnpacker(ModeID mode, RawModeID rawmode, int *bits_out); extern ImagingShuffler -ImagingFindPacker(const char *mode, const char *rawmode, int *bits_out); +ImagingFindPacker(ModeID mode, RawModeID rawmode, int *bits_out); struct ImagingCodecStateInstance { int count; diff --git a/src/libImaging/Jpeg.h b/src/libImaging/Jpeg.h index 7cdba902281..e07904fc70c 100644 --- a/src/libImaging/Jpeg.h +++ b/src/libImaging/Jpeg.h @@ -28,12 +28,12 @@ typedef struct { typedef struct { /* CONFIGURATION */ - /* Jpeg file mode (empty if not known) */ - char jpegmode[8 + 1]; + /* Jpeg file mode */ + RawModeID jpegmode; - /* Converter output mode (input to the shuffler). If empty, - convert conversions are disabled */ - char rawmode[8 + 1]; + /* Converter output mode (input to the shuffler) */ + /* If not a valid mode, convert conversions are disabled */ + RawModeID rawmode; /* If set, trade quality for speed */ int draft; @@ -91,7 +91,7 @@ typedef struct { unsigned int restart_marker_rows; /* Converter input mode (input to the shuffler) */ - char rawmode[8 + 1]; + RawModeID rawmode; /* Custom quantization tables () */ unsigned int *qtables; diff --git a/src/libImaging/Jpeg2KDecode.c b/src/libImaging/Jpeg2KDecode.c index fc927d2f0c0..7c46d246eeb 100644 --- a/src/libImaging/Jpeg2KDecode.c +++ b/src/libImaging/Jpeg2KDecode.c @@ -71,7 +71,7 @@ typedef void (*j2k_unpacker_t)( ); struct j2k_decode_unpacker { - const char *mode; + const ModeID mode; OPJ_COLOR_SPACE color_space; unsigned components; /* bool indicating if unpacker supports subsampling */ @@ -599,25 +599,25 @@ j2ku_sycca_rgba( } static const struct j2k_decode_unpacker j2k_unpackers[] = { - {"L", OPJ_CLRSPC_GRAY, 1, 0, j2ku_gray_l}, - {"P", OPJ_CLRSPC_SRGB, 1, 0, j2ku_gray_l}, - {"PA", OPJ_CLRSPC_SRGB, 2, 0, j2ku_graya_la}, - {"I;16", OPJ_CLRSPC_GRAY, 1, 0, j2ku_gray_i}, - {"I;16B", OPJ_CLRSPC_GRAY, 1, 0, j2ku_gray_i}, - {"LA", OPJ_CLRSPC_GRAY, 2, 0, j2ku_graya_la}, - {"RGB", OPJ_CLRSPC_GRAY, 1, 0, j2ku_gray_rgb}, - {"RGB", OPJ_CLRSPC_GRAY, 2, 0, j2ku_gray_rgb}, - {"RGB", OPJ_CLRSPC_SRGB, 3, 1, j2ku_srgb_rgb}, - {"RGB", OPJ_CLRSPC_SYCC, 3, 1, j2ku_sycc_rgb}, - {"RGB", OPJ_CLRSPC_SRGB, 4, 1, j2ku_srgb_rgb}, - {"RGB", OPJ_CLRSPC_SYCC, 4, 1, j2ku_sycc_rgb}, - {"RGBA", OPJ_CLRSPC_GRAY, 1, 0, j2ku_gray_rgb}, - {"RGBA", OPJ_CLRSPC_GRAY, 2, 0, j2ku_graya_la}, - {"RGBA", OPJ_CLRSPC_SRGB, 3, 1, j2ku_srgb_rgb}, - {"RGBA", OPJ_CLRSPC_SYCC, 3, 1, j2ku_sycc_rgb}, - {"RGBA", OPJ_CLRSPC_SRGB, 4, 1, j2ku_srgba_rgba}, - {"RGBA", OPJ_CLRSPC_SYCC, 4, 1, j2ku_sycca_rgba}, - {"CMYK", OPJ_CLRSPC_CMYK, 4, 1, j2ku_srgba_rgba}, + {IMAGING_MODE_L, OPJ_CLRSPC_GRAY, 1, 0, j2ku_gray_l}, + {IMAGING_MODE_P, OPJ_CLRSPC_SRGB, 1, 0, j2ku_gray_l}, + {IMAGING_MODE_PA, OPJ_CLRSPC_SRGB, 2, 0, j2ku_graya_la}, + {IMAGING_MODE_I_16, OPJ_CLRSPC_GRAY, 1, 0, j2ku_gray_i}, + {IMAGING_MODE_I_16B, OPJ_CLRSPC_GRAY, 1, 0, j2ku_gray_i}, + {IMAGING_MODE_LA, OPJ_CLRSPC_GRAY, 2, 0, j2ku_graya_la}, + {IMAGING_MODE_RGB, OPJ_CLRSPC_GRAY, 1, 0, j2ku_gray_rgb}, + {IMAGING_MODE_RGB, OPJ_CLRSPC_GRAY, 2, 0, j2ku_gray_rgb}, + {IMAGING_MODE_RGB, OPJ_CLRSPC_SRGB, 3, 1, j2ku_srgb_rgb}, + {IMAGING_MODE_RGB, OPJ_CLRSPC_SYCC, 3, 1, j2ku_sycc_rgb}, + {IMAGING_MODE_RGB, OPJ_CLRSPC_SRGB, 4, 1, j2ku_srgb_rgb}, + {IMAGING_MODE_RGB, OPJ_CLRSPC_SYCC, 4, 1, j2ku_sycc_rgb}, + {IMAGING_MODE_RGBA, OPJ_CLRSPC_GRAY, 1, 0, j2ku_gray_rgb}, + {IMAGING_MODE_RGBA, OPJ_CLRSPC_GRAY, 2, 0, j2ku_graya_la}, + {IMAGING_MODE_RGBA, OPJ_CLRSPC_SRGB, 3, 1, j2ku_srgb_rgb}, + {IMAGING_MODE_RGBA, OPJ_CLRSPC_SYCC, 3, 1, j2ku_sycc_rgb}, + {IMAGING_MODE_RGBA, OPJ_CLRSPC_SRGB, 4, 1, j2ku_srgba_rgba}, + {IMAGING_MODE_RGBA, OPJ_CLRSPC_SYCC, 4, 1, j2ku_sycca_rgba}, + {IMAGING_MODE_CMYK, OPJ_CLRSPC_CMYK, 4, 1, j2ku_srgba_rgba}, }; /* -------------------------------------------------------------------- */ @@ -770,7 +770,7 @@ j2k_decode_entry(Imaging im, ImagingCodecState state) { if (color_space == j2k_unpackers[n].color_space && image->numcomps == j2k_unpackers[n].components && (j2k_unpackers[n].subsampling || (subsampling == -1)) && - strcmp(im->mode, j2k_unpackers[n].mode) == 0) { + im->mode == j2k_unpackers[n].mode) { unpack = j2k_unpackers[n].unpacker; break; } diff --git a/src/libImaging/Jpeg2KEncode.c b/src/libImaging/Jpeg2KEncode.c index d30ccde603e..d0a45964820 100644 --- a/src/libImaging/Jpeg2KEncode.c +++ b/src/libImaging/Jpeg2KEncode.c @@ -305,28 +305,28 @@ j2k_encode_entry(Imaging im, ImagingCodecState state) { #endif /* Setup an opj_image */ - if (strcmp(im->mode, "L") == 0) { + if (im->mode == IMAGING_MODE_L) { components = 1; color_space = OPJ_CLRSPC_GRAY; pack = j2k_pack_l; - } else if (strcmp(im->mode, "I;16") == 0 || strcmp(im->mode, "I;16B") == 0) { + } else if (im->mode == IMAGING_MODE_I_16 || im->mode == IMAGING_MODE_I_16B) { components = 1; color_space = OPJ_CLRSPC_GRAY; pack = j2k_pack_i16; prec = 16; - } else if (strcmp(im->mode, "LA") == 0) { + } else if (im->mode == IMAGING_MODE_LA) { components = 2; color_space = OPJ_CLRSPC_GRAY; pack = j2k_pack_la; - } else if (strcmp(im->mode, "RGB") == 0) { + } else if (im->mode == IMAGING_MODE_RGB) { components = 3; color_space = OPJ_CLRSPC_SRGB; pack = j2k_pack_rgb; - } else if (strcmp(im->mode, "YCbCr") == 0) { + } else if (im->mode == IMAGING_MODE_YCbCr) { components = 3; color_space = OPJ_CLRSPC_SYCC; pack = j2k_pack_rgb; - } else if (strcmp(im->mode, "RGBA") == 0) { + } else if (im->mode == IMAGING_MODE_RGBA) { components = 4; color_space = OPJ_CLRSPC_SRGB; pack = j2k_pack_rgba; @@ -490,9 +490,9 @@ j2k_encode_entry(Imaging im, ImagingCodecState state) { goto quick_exit; } - if (strcmp(im->mode, "RGBA") == 0) { + if (im->mode == IMAGING_MODE_RGBA) { image->comps[3].alpha = 1; - } else if (strcmp(im->mode, "LA") == 0) { + } else if (im->mode == IMAGING_MODE_LA) { image->comps[1].alpha = 1; } diff --git a/src/libImaging/JpegDecode.c b/src/libImaging/JpegDecode.c index 2970f56d1af..ae3274456d3 100644 --- a/src/libImaging/JpegDecode.c +++ b/src/libImaging/JpegDecode.c @@ -180,41 +180,41 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t by /* Decoder settings */ - /* jpegmode indicates what's in the file; if not set, we'll - trust the decoder */ - if (strcmp(context->jpegmode, "L") == 0) { + /* jpegmode indicates what's in the file. */ + /* If not valid, we'll trust the decoder. */ + if (context->jpegmode == IMAGING_RAWMODE_L) { context->cinfo.jpeg_color_space = JCS_GRAYSCALE; - } else if (strcmp(context->jpegmode, "RGB") == 0) { + } else if (context->jpegmode == IMAGING_RAWMODE_RGB) { context->cinfo.jpeg_color_space = JCS_RGB; - } else if (strcmp(context->jpegmode, "CMYK") == 0) { + } else if (context->jpegmode == IMAGING_RAWMODE_CMYK) { context->cinfo.jpeg_color_space = JCS_CMYK; - } else if (strcmp(context->jpegmode, "YCbCr") == 0) { + } else if (context->jpegmode == IMAGING_RAWMODE_YCbCr) { context->cinfo.jpeg_color_space = JCS_YCbCr; - } else if (strcmp(context->jpegmode, "YCbCrK") == 0) { + } else if (context->jpegmode == IMAGING_RAWMODE_YCbCrK) { context->cinfo.jpeg_color_space = JCS_YCCK; } - /* rawmode indicates what we want from the decoder. if not - set, conversions are disabled */ - if (strcmp(context->rawmode, "L") == 0) { + /* rawmode indicates what we want from the decoder. */ + /* If not valid, conversions are disabled. */ + if (context->rawmode == IMAGING_RAWMODE_L) { context->cinfo.out_color_space = JCS_GRAYSCALE; - } else if (strcmp(context->rawmode, "RGB") == 0) { + } else if (context->rawmode == IMAGING_RAWMODE_RGB) { context->cinfo.out_color_space = JCS_RGB; } #ifdef JCS_EXTENSIONS - else if (strcmp(context->rawmode, "RGBX") == 0) { + else if (context->rawmode == IMAGING_RAWMODE_RGBX) { context->cinfo.out_color_space = JCS_EXT_RGBX; } #endif - else if (strcmp(context->rawmode, "CMYK") == 0 || - strcmp(context->rawmode, "CMYK;I") == 0) { + else if (context->rawmode == IMAGING_RAWMODE_CMYK || + context->rawmode == IMAGING_RAWMODE_CMYK_I) { context->cinfo.out_color_space = JCS_CMYK; - } else if (strcmp(context->rawmode, "YCbCr") == 0) { + } else if (context->rawmode == IMAGING_RAWMODE_YCbCr) { context->cinfo.out_color_space = JCS_YCbCr; - } else if (strcmp(context->rawmode, "YCbCrK") == 0) { + } else if (context->rawmode == IMAGING_RAWMODE_YCbCrK) { context->cinfo.out_color_space = JCS_YCCK; } else { - /* Disable decoder conversions */ + /* Disable decoder conversions. */ context->cinfo.jpeg_color_space = JCS_UNKNOWN; context->cinfo.out_color_space = JCS_UNKNOWN; } diff --git a/src/libImaging/JpegEncode.c b/src/libImaging/JpegEncode.c index 4372d51d5c3..ba187ecdc38 100644 --- a/src/libImaging/JpegEncode.c +++ b/src/libImaging/JpegEncode.c @@ -114,7 +114,7 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) { break; case 24: context->cinfo.input_components = 3; - if (strcmp(im->mode, "YCbCr") == 0) { + if (im->mode == IMAGING_MODE_YCbCr) { context->cinfo.in_color_space = JCS_YCbCr; } else { context->cinfo.in_color_space = JCS_RGB; @@ -124,7 +124,7 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) { context->cinfo.input_components = 4; context->cinfo.in_color_space = JCS_CMYK; #ifdef JCS_EXTENSIONS - if (strcmp(context->rawmode, "RGBX") == 0) { + if (context->rawmode == IMAGING_RAWMODE_RGBX) { context->cinfo.in_color_space = JCS_EXT_RGBX; } #endif diff --git a/src/libImaging/Matrix.c b/src/libImaging/Matrix.c index ec7f4d93e06..d28e04edfaa 100644 --- a/src/libImaging/Matrix.c +++ b/src/libImaging/Matrix.c @@ -18,7 +18,7 @@ #define CLIPF(v) ((v <= 0.0) ? 0 : (v >= 255.0F) ? 255 : (UINT8)v) Imaging -ImagingConvertMatrix(Imaging im, const char *mode, float m[]) { +ImagingConvertMatrix(Imaging im, const ModeID mode, float m[]) { Imaging imOut; int x, y; ImagingSectionCookie cookie; @@ -28,8 +28,8 @@ ImagingConvertMatrix(Imaging im, const char *mode, float m[]) { return (Imaging)ImagingError_ModeError(); } - if (strcmp(mode, "L") == 0) { - imOut = ImagingNewDirty("L", im->xsize, im->ysize); + if (mode == IMAGING_MODE_L) { + imOut = ImagingNewDirty(IMAGING_MODE_L, im->xsize, im->ysize); if (!imOut) { return NULL; } @@ -46,8 +46,8 @@ ImagingConvertMatrix(Imaging im, const char *mode, float m[]) { } } ImagingSectionLeave(&cookie); - - } else if (strlen(mode) == 3) { + } else if (mode == IMAGING_MODE_HSV || mode == IMAGING_MODE_LAB || + mode == IMAGING_MODE_RGB) { imOut = ImagingNewDirty(mode, im->xsize, im->ysize); if (!imOut) { return NULL; diff --git a/src/libImaging/Mode.c b/src/libImaging/Mode.c new file mode 100644 index 00000000000..8222c585b68 --- /dev/null +++ b/src/libImaging/Mode.c @@ -0,0 +1,264 @@ +#include "Mode.h" +#include + +#ifdef NDEBUG +#include +#include +#endif + +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_BGR_15] = {"BGR;15"}, [IMAGING_MODE_BGR_16] = {"BGR;16"}, + [IMAGING_MODE_BGR_24] = {"BGR;24"}, + + [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"}, +}; + +const ModeID +findModeID(const char *const name) { + if (name == NULL) { + return IMAGING_MODE_UNKNOWN; + } + for (size_t i = 0; i < sizeof(MODES) / sizeof(*MODES); i++) { +#ifdef NDEBUG + if (MODES[i].name == NULL) { + fprintf(stderr, "Mode ID %zu is not defined.\n", (size_t)i); + } else +#endif + if (strcmp(MODES[i].name, name) == 0) { + return (ModeID)i; + } + } + return IMAGING_MODE_UNKNOWN; +} + +const ModeData *const +getModeData(const ModeID id) { + if (id < 0 || id > sizeof(MODES) / sizeof(*MODES)) { + return &MODES[IMAGING_MODE_UNKNOWN]; + } + return &MODES[id]; +} + +const RawModeData RAWMODES[] = { + [IMAGING_RAWMODE_UNKNOWN] = {""}, + + [IMAGING_RAWMODE_1] = {"1"}, + [IMAGING_RAWMODE_CMYK] = {"CMYK"}, + [IMAGING_RAWMODE_F] = {"F"}, + [IMAGING_RAWMODE_HSV] = {"HSV"}, + [IMAGING_RAWMODE_I] = {"I"}, + [IMAGING_RAWMODE_L] = {"L"}, + [IMAGING_RAWMODE_LA] = {"LA"}, + [IMAGING_RAWMODE_LAB] = {"LAB"}, + [IMAGING_RAWMODE_La] = {"La"}, + [IMAGING_RAWMODE_P] = {"P"}, + [IMAGING_RAWMODE_PA] = {"PA"}, + [IMAGING_RAWMODE_RGB] = {"RGB"}, + [IMAGING_RAWMODE_RGBA] = {"RGBA"}, + [IMAGING_RAWMODE_RGBX] = {"RGBX"}, + [IMAGING_RAWMODE_RGBa] = {"RGBa"}, + [IMAGING_RAWMODE_YCbCr] = {"YCbCr"}, + + [IMAGING_RAWMODE_BGR_15] = {"BGR;15"}, + [IMAGING_RAWMODE_BGR_16] = {"BGR;16"}, + [IMAGING_RAWMODE_BGR_24] = {"BGR;24"}, + [IMAGING_RAWMODE_BGR_32] = {"BGR;32"}, + + [IMAGING_RAWMODE_I_16] = {"I;16"}, + [IMAGING_RAWMODE_I_16L] = {"I;16L"}, + [IMAGING_RAWMODE_I_16B] = {"I;16B"}, + [IMAGING_RAWMODE_I_16N] = {"I;16N"}, + [IMAGING_RAWMODE_I_32L] = {"I;32L"}, + [IMAGING_RAWMODE_I_32B] = {"I;32B"}, + + [IMAGING_RAWMODE_1_8] = {"1;8"}, + [IMAGING_RAWMODE_1_I] = {"1;I"}, + [IMAGING_RAWMODE_1_IR] = {"1;IR"}, + [IMAGING_RAWMODE_1_R] = {"1;R"}, + [IMAGING_RAWMODE_A] = {"A"}, + [IMAGING_RAWMODE_ABGR] = {"ABGR"}, + [IMAGING_RAWMODE_ARGB] = {"ARGB"}, + [IMAGING_RAWMODE_A_16B] = {"A;16B"}, + [IMAGING_RAWMODE_A_16L] = {"A;16L"}, + [IMAGING_RAWMODE_A_16N] = {"A;16N"}, + [IMAGING_RAWMODE_B] = {"B"}, + [IMAGING_RAWMODE_BGAR] = {"BGAR"}, + [IMAGING_RAWMODE_BGR] = {"BGR"}, + [IMAGING_RAWMODE_BGRA] = {"BGRA"}, + [IMAGING_RAWMODE_BGRA_15] = {"BGRA;15"}, + [IMAGING_RAWMODE_BGRA_15Z] = {"BGRA;15Z"}, + [IMAGING_RAWMODE_BGRA_16B] = {"BGRA;16B"}, + [IMAGING_RAWMODE_BGRA_16L] = {"BGRA;16L"}, + [IMAGING_RAWMODE_BGRX] = {"BGRX"}, + [IMAGING_RAWMODE_BGR_5] = {"BGR;5"}, + [IMAGING_RAWMODE_BGRa] = {"BGRa"}, + [IMAGING_RAWMODE_BGXR] = {"BGXR"}, + [IMAGING_RAWMODE_B_16B] = {"B;16B"}, + [IMAGING_RAWMODE_B_16L] = {"B;16L"}, + [IMAGING_RAWMODE_B_16N] = {"B;16N"}, + [IMAGING_RAWMODE_C] = {"C"}, + [IMAGING_RAWMODE_CMYKX] = {"CMYKX"}, + [IMAGING_RAWMODE_CMYKXX] = {"CMYKXX"}, + [IMAGING_RAWMODE_CMYK_16B] = {"CMYK;16B"}, + [IMAGING_RAWMODE_CMYK_16L] = {"CMYK;16L"}, + [IMAGING_RAWMODE_CMYK_16N] = {"CMYK;16N"}, + [IMAGING_RAWMODE_CMYK_I] = {"CMYK;I"}, + [IMAGING_RAWMODE_CMYK_L] = {"CMYK;L"}, + [IMAGING_RAWMODE_C_I] = {"C;I"}, + [IMAGING_RAWMODE_Cb] = {"Cb"}, + [IMAGING_RAWMODE_Cr] = {"Cr"}, + [IMAGING_RAWMODE_F_16] = {"F;16"}, + [IMAGING_RAWMODE_F_16B] = {"F;16B"}, + [IMAGING_RAWMODE_F_16BS] = {"F;16BS"}, + [IMAGING_RAWMODE_F_16N] = {"F;16N"}, + [IMAGING_RAWMODE_F_16NS] = {"F;16NS"}, + [IMAGING_RAWMODE_F_16S] = {"F;16S"}, + [IMAGING_RAWMODE_F_32] = {"F;32"}, + [IMAGING_RAWMODE_F_32B] = {"F;32B"}, + [IMAGING_RAWMODE_F_32BF] = {"F;32BF"}, + [IMAGING_RAWMODE_F_32BS] = {"F;32BS"}, + [IMAGING_RAWMODE_F_32F] = {"F;32F"}, + [IMAGING_RAWMODE_F_32N] = {"F;32N"}, + [IMAGING_RAWMODE_F_32NF] = {"F;32NF"}, + [IMAGING_RAWMODE_F_32NS] = {"F;32NS"}, + [IMAGING_RAWMODE_F_32S] = {"F;32S"}, + [IMAGING_RAWMODE_F_64BF] = {"F;64BF"}, + [IMAGING_RAWMODE_F_64F] = {"F;64F"}, + [IMAGING_RAWMODE_F_64NF] = {"F;64NF"}, + [IMAGING_RAWMODE_F_8] = {"F;8"}, + [IMAGING_RAWMODE_F_8S] = {"F;8S"}, + [IMAGING_RAWMODE_G] = {"G"}, + [IMAGING_RAWMODE_G_16B] = {"G;16B"}, + [IMAGING_RAWMODE_G_16L] = {"G;16L"}, + [IMAGING_RAWMODE_G_16N] = {"G;16N"}, + [IMAGING_RAWMODE_H] = {"H"}, + [IMAGING_RAWMODE_I_12] = {"I;12"}, + [IMAGING_RAWMODE_I_16BS] = {"I;16BS"}, + [IMAGING_RAWMODE_I_16NS] = {"I;16NS"}, + [IMAGING_RAWMODE_I_16R] = {"I;16R"}, + [IMAGING_RAWMODE_I_16S] = {"I;16S"}, + [IMAGING_RAWMODE_I_32] = {"I;32"}, + [IMAGING_RAWMODE_I_32BS] = {"I;32BS"}, + [IMAGING_RAWMODE_I_32N] = {"I;32N"}, + [IMAGING_RAWMODE_I_32NS] = {"I;32NS"}, + [IMAGING_RAWMODE_I_32S] = {"I;32S"}, + [IMAGING_RAWMODE_I_8] = {"I;8"}, + [IMAGING_RAWMODE_I_8S] = {"I;8S"}, + [IMAGING_RAWMODE_K] = {"K"}, + [IMAGING_RAWMODE_K_I] = {"K;I"}, + [IMAGING_RAWMODE_LA_16B] = {"LA;16B"}, + [IMAGING_RAWMODE_LA_L] = {"LA;L"}, + [IMAGING_RAWMODE_L_16] = {"L;16"}, + [IMAGING_RAWMODE_L_16B] = {"L;16B"}, + [IMAGING_RAWMODE_L_2] = {"L;2"}, + [IMAGING_RAWMODE_L_2I] = {"L;2I"}, + [IMAGING_RAWMODE_L_2IR] = {"L;2IR"}, + [IMAGING_RAWMODE_L_2R] = {"L;2R"}, + [IMAGING_RAWMODE_L_4] = {"L;4"}, + [IMAGING_RAWMODE_L_4I] = {"L;4I"}, + [IMAGING_RAWMODE_L_4IR] = {"L;4IR"}, + [IMAGING_RAWMODE_L_4R] = {"L;4R"}, + [IMAGING_RAWMODE_L_I] = {"L;I"}, + [IMAGING_RAWMODE_L_R] = {"L;R"}, + [IMAGING_RAWMODE_M] = {"M"}, + [IMAGING_RAWMODE_M_I] = {"M;I"}, + [IMAGING_RAWMODE_PA_L] = {"PA;L"}, + [IMAGING_RAWMODE_PX] = {"PX"}, + [IMAGING_RAWMODE_P_1] = {"P;1"}, + [IMAGING_RAWMODE_P_2] = {"P;2"}, + [IMAGING_RAWMODE_P_2L] = {"P;2L"}, + [IMAGING_RAWMODE_P_4] = {"P;4"}, + [IMAGING_RAWMODE_P_4L] = {"P;4L"}, + [IMAGING_RAWMODE_P_R] = {"P;R"}, + [IMAGING_RAWMODE_R] = {"R"}, + [IMAGING_RAWMODE_RGBAX] = {"RGBAX"}, + [IMAGING_RAWMODE_RGBAXX] = {"RGBAXX"}, + [IMAGING_RAWMODE_RGBA_15] = {"RGBA;15"}, + [IMAGING_RAWMODE_RGBA_16B] = {"RGBA;16B"}, + [IMAGING_RAWMODE_RGBA_16L] = {"RGBA;16L"}, + [IMAGING_RAWMODE_RGBA_16N] = {"RGBA;16N"}, + [IMAGING_RAWMODE_RGBA_4B] = {"RGBA;4B"}, + [IMAGING_RAWMODE_RGBA_I] = {"RGBA;I"}, + [IMAGING_RAWMODE_RGBA_L] = {"RGBA;L"}, + [IMAGING_RAWMODE_RGBXX] = {"RGBXX"}, + [IMAGING_RAWMODE_RGBXXX] = {"RGBXXX"}, + [IMAGING_RAWMODE_RGBX_16B] = {"RGBX;16B"}, + [IMAGING_RAWMODE_RGBX_16L] = {"RGBX;16L"}, + [IMAGING_RAWMODE_RGBX_16N] = {"RGBX;16N"}, + [IMAGING_RAWMODE_RGBX_L] = {"RGBX;L"}, + [IMAGING_RAWMODE_RGB_15] = {"RGB;15"}, + [IMAGING_RAWMODE_RGB_16] = {"RGB;16"}, + [IMAGING_RAWMODE_RGB_16B] = {"RGB;16B"}, + [IMAGING_RAWMODE_RGB_16L] = {"RGB;16L"}, + [IMAGING_RAWMODE_RGB_16N] = {"RGB;16N"}, + [IMAGING_RAWMODE_RGB_4B] = {"RGB;4B"}, + [IMAGING_RAWMODE_RGB_L] = {"RGB;L"}, + [IMAGING_RAWMODE_RGB_R] = {"RGB;R"}, + [IMAGING_RAWMODE_RGBaX] = {"RGBaX"}, + [IMAGING_RAWMODE_RGBaXX] = {"RGBaXX"}, + [IMAGING_RAWMODE_RGBa_16B] = {"RGBa;16B"}, + [IMAGING_RAWMODE_RGBa_16L] = {"RGBa;16L"}, + [IMAGING_RAWMODE_RGBa_16N] = {"RGBa;16N"}, + [IMAGING_RAWMODE_R_16B] = {"R;16B"}, + [IMAGING_RAWMODE_R_16L] = {"R;16L"}, + [IMAGING_RAWMODE_R_16N] = {"R;16N"}, + [IMAGING_RAWMODE_S] = {"S"}, + [IMAGING_RAWMODE_V] = {"V"}, + [IMAGING_RAWMODE_X] = {"X"}, + [IMAGING_RAWMODE_XBGR] = {"XBGR"}, + [IMAGING_RAWMODE_XRGB] = {"XRGB"}, + [IMAGING_RAWMODE_Y] = {"Y"}, + [IMAGING_RAWMODE_YCCA_P] = {"YCCA;P"}, + [IMAGING_RAWMODE_YCC_P] = {"YCC;P"}, + [IMAGING_RAWMODE_YCbCrK] = {"YCbCrK"}, + [IMAGING_RAWMODE_YCbCrX] = {"YCbCrX"}, + [IMAGING_RAWMODE_YCbCr_L] = {"YCbCr;L"}, + [IMAGING_RAWMODE_Y_I] = {"Y;I"}, + [IMAGING_RAWMODE_aBGR] = {"aBGR"}, + [IMAGING_RAWMODE_aRGB] = {"aRGB"}, +}; + +const RawModeID +findRawModeID(const char *const name) { + if (name == NULL) { + return IMAGING_RAWMODE_UNKNOWN; + } + for (size_t i = 0; i < sizeof(RAWMODES) / sizeof(*RAWMODES); i++) { +#ifdef NDEBUG + if (RAWMODES[i].name == NULL) { + fprintf(stderr, "Rawmode ID %zu is not defined.\n", (size_t)i); + } else +#endif + if (strcmp(RAWMODES[i].name, name) == 0) { + return (RawModeID)i; + } + } + return IMAGING_RAWMODE_UNKNOWN; +} + +const RawModeData *const +getRawModeData(const RawModeID id) { + if (id < 0 || id > sizeof(RAWMODES) / sizeof(*RAWMODES)) { + return &RAWMODES[IMAGING_RAWMODE_UNKNOWN]; + } + return &RAWMODES[id]; +} + +int +isModeI16(const ModeID mode) { + return mode == IMAGING_MODE_I_16 || mode == IMAGING_MODE_I_16L || + mode == IMAGING_MODE_I_16B || mode == IMAGING_MODE_I_16N; +} diff --git a/src/libImaging/Mode.h b/src/libImaging/Mode.h new file mode 100644 index 00000000000..a20ad0cb68d --- /dev/null +++ b/src/libImaging/Mode.h @@ -0,0 +1,240 @@ +#ifndef __MODE_H__ +#define __MODE_H__ + +typedef enum { + IMAGING_MODE_UNKNOWN, + + 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, + + IMAGING_MODE_BGR_15, + IMAGING_MODE_BGR_16, + IMAGING_MODE_BGR_24, + + IMAGING_MODE_I_16, + IMAGING_MODE_I_16L, + IMAGING_MODE_I_16B, + IMAGING_MODE_I_16N, + IMAGING_MODE_I_32L, + IMAGING_MODE_I_32B, +} ModeID; + +typedef struct { + const char *const name; +} ModeData; + +const ModeID +findModeID(const char *const name); +const ModeData *const +getModeData(const ModeID id); + +typedef enum { + IMAGING_RAWMODE_UNKNOWN, + + // Non-rawmode aliases. + 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, + + // BGR modes. + IMAGING_RAWMODE_BGR_15, + IMAGING_RAWMODE_BGR_16, + IMAGING_RAWMODE_BGR_24, + IMAGING_RAWMODE_BGR_32, + + // I;* modes. + IMAGING_RAWMODE_I_16, + IMAGING_RAWMODE_I_16L, + IMAGING_RAWMODE_I_16B, + IMAGING_RAWMODE_I_16N, + IMAGING_RAWMODE_I_32L, + IMAGING_RAWMODE_I_32B, + + // Rawmodes + IMAGING_RAWMODE_1_8, + IMAGING_RAWMODE_1_I, + IMAGING_RAWMODE_1_IR, + IMAGING_RAWMODE_1_R, + IMAGING_RAWMODE_A, + IMAGING_RAWMODE_ABGR, + IMAGING_RAWMODE_ARGB, + IMAGING_RAWMODE_A_16B, + IMAGING_RAWMODE_A_16L, + IMAGING_RAWMODE_A_16N, + IMAGING_RAWMODE_B, + IMAGING_RAWMODE_BGAR, + IMAGING_RAWMODE_BGR, + IMAGING_RAWMODE_BGRA, + IMAGING_RAWMODE_BGRA_15, + IMAGING_RAWMODE_BGRA_15Z, + IMAGING_RAWMODE_BGRA_16B, + IMAGING_RAWMODE_BGRA_16L, + IMAGING_RAWMODE_BGRX, + IMAGING_RAWMODE_BGR_5, + IMAGING_RAWMODE_BGRa, + IMAGING_RAWMODE_BGXR, + IMAGING_RAWMODE_B_16B, + IMAGING_RAWMODE_B_16L, + IMAGING_RAWMODE_B_16N, + IMAGING_RAWMODE_C, + IMAGING_RAWMODE_CMYKX, + IMAGING_RAWMODE_CMYKXX, + IMAGING_RAWMODE_CMYK_16B, + IMAGING_RAWMODE_CMYK_16L, + IMAGING_RAWMODE_CMYK_16N, + IMAGING_RAWMODE_CMYK_I, + IMAGING_RAWMODE_CMYK_L, + IMAGING_RAWMODE_C_I, + IMAGING_RAWMODE_Cb, + IMAGING_RAWMODE_Cr, + IMAGING_RAWMODE_F_16, + IMAGING_RAWMODE_F_16B, + IMAGING_RAWMODE_F_16BS, + IMAGING_RAWMODE_F_16N, + IMAGING_RAWMODE_F_16NS, + IMAGING_RAWMODE_F_16S, + IMAGING_RAWMODE_F_32, + IMAGING_RAWMODE_F_32B, + IMAGING_RAWMODE_F_32BF, + IMAGING_RAWMODE_F_32BS, + IMAGING_RAWMODE_F_32F, + IMAGING_RAWMODE_F_32N, + IMAGING_RAWMODE_F_32NF, + IMAGING_RAWMODE_F_32NS, + IMAGING_RAWMODE_F_32S, + IMAGING_RAWMODE_F_64BF, + IMAGING_RAWMODE_F_64F, + IMAGING_RAWMODE_F_64NF, + IMAGING_RAWMODE_F_8, + IMAGING_RAWMODE_F_8S, + IMAGING_RAWMODE_G, + IMAGING_RAWMODE_G_16B, + IMAGING_RAWMODE_G_16L, + IMAGING_RAWMODE_G_16N, + IMAGING_RAWMODE_H, + IMAGING_RAWMODE_I_12, + IMAGING_RAWMODE_I_16BS, + IMAGING_RAWMODE_I_16NS, + IMAGING_RAWMODE_I_16R, + IMAGING_RAWMODE_I_16S, + IMAGING_RAWMODE_I_32, + IMAGING_RAWMODE_I_32BS, + IMAGING_RAWMODE_I_32N, + IMAGING_RAWMODE_I_32NS, + IMAGING_RAWMODE_I_32S, + IMAGING_RAWMODE_I_8, + IMAGING_RAWMODE_I_8S, + IMAGING_RAWMODE_K, + IMAGING_RAWMODE_K_I, + IMAGING_RAWMODE_LA_16B, + IMAGING_RAWMODE_LA_L, + IMAGING_RAWMODE_L_16, + IMAGING_RAWMODE_L_16B, + IMAGING_RAWMODE_L_2, + IMAGING_RAWMODE_L_2I, + IMAGING_RAWMODE_L_2IR, + IMAGING_RAWMODE_L_2R, + IMAGING_RAWMODE_L_4, + IMAGING_RAWMODE_L_4I, + IMAGING_RAWMODE_L_4IR, + IMAGING_RAWMODE_L_4R, + IMAGING_RAWMODE_L_I, + IMAGING_RAWMODE_L_R, + IMAGING_RAWMODE_M, + IMAGING_RAWMODE_M_I, + IMAGING_RAWMODE_PA_L, + IMAGING_RAWMODE_PX, + IMAGING_RAWMODE_P_1, + IMAGING_RAWMODE_P_2, + IMAGING_RAWMODE_P_2L, + IMAGING_RAWMODE_P_4, + IMAGING_RAWMODE_P_4L, + IMAGING_RAWMODE_P_R, + IMAGING_RAWMODE_R, + IMAGING_RAWMODE_RGBAX, + IMAGING_RAWMODE_RGBAXX, + IMAGING_RAWMODE_RGBA_15, + IMAGING_RAWMODE_RGBA_16B, + IMAGING_RAWMODE_RGBA_16L, + IMAGING_RAWMODE_RGBA_16N, + IMAGING_RAWMODE_RGBA_4B, + IMAGING_RAWMODE_RGBA_I, + IMAGING_RAWMODE_RGBA_L, + IMAGING_RAWMODE_RGBXX, + IMAGING_RAWMODE_RGBXXX, + IMAGING_RAWMODE_RGBX_16B, + IMAGING_RAWMODE_RGBX_16L, + IMAGING_RAWMODE_RGBX_16N, + IMAGING_RAWMODE_RGBX_L, + IMAGING_RAWMODE_RGB_15, + IMAGING_RAWMODE_RGB_16, + IMAGING_RAWMODE_RGB_16B, + IMAGING_RAWMODE_RGB_16L, + IMAGING_RAWMODE_RGB_16N, + IMAGING_RAWMODE_RGB_4B, + IMAGING_RAWMODE_RGB_L, + IMAGING_RAWMODE_RGB_R, + IMAGING_RAWMODE_RGBaX, + IMAGING_RAWMODE_RGBaXX, + IMAGING_RAWMODE_RGBa_16B, + IMAGING_RAWMODE_RGBa_16L, + IMAGING_RAWMODE_RGBa_16N, + IMAGING_RAWMODE_R_16B, + IMAGING_RAWMODE_R_16L, + IMAGING_RAWMODE_R_16N, + IMAGING_RAWMODE_S, + IMAGING_RAWMODE_V, + IMAGING_RAWMODE_X, + IMAGING_RAWMODE_XBGR, + IMAGING_RAWMODE_XRGB, + IMAGING_RAWMODE_Y, + IMAGING_RAWMODE_YCCA_P, + IMAGING_RAWMODE_YCC_P, + IMAGING_RAWMODE_YCbCrK, + IMAGING_RAWMODE_YCbCrX, + IMAGING_RAWMODE_YCbCr_L, + IMAGING_RAWMODE_Y_I, + IMAGING_RAWMODE_aBGR, + IMAGING_RAWMODE_aRGB, +} RawModeID; + +typedef struct { + const char *const name; +} RawModeData; + +const RawModeID +findRawModeID(const char *const name); +const RawModeData *const +getRawModeData(const RawModeID id); + +int +isModeI16(const ModeID mode); + +#endif // __MODE_H__ diff --git a/src/libImaging/Pack.c b/src/libImaging/Pack.c index c29473d90db..8f21eab3aad 100644 --- a/src/libImaging/Pack.c +++ b/src/libImaging/Pack.c @@ -525,153 +525,147 @@ band3(UINT8 *out, const UINT8 *in, int pixels) { } static struct { - const char *mode; - const char *rawmode; + const ModeID mode; + const RawModeID rawmode; int bits; ImagingShuffler pack; } packers[] = { - /* bilevel */ - {"1", "1", 1, pack1}, - {"1", "1;I", 1, pack1I}, - {"1", "1;R", 1, pack1R}, - {"1", "1;IR", 1, pack1IR}, - {"1", "L", 8, pack1L}, + {IMAGING_MODE_1, IMAGING_RAWMODE_1, 1, pack1}, + {IMAGING_MODE_1, IMAGING_RAWMODE_1_I, 1, pack1I}, + {IMAGING_MODE_1, IMAGING_RAWMODE_1_R, 1, pack1R}, + {IMAGING_MODE_1, IMAGING_RAWMODE_1_IR, 1, pack1IR}, + {IMAGING_MODE_1, IMAGING_RAWMODE_L, 8, pack1L}, /* grayscale */ - {"L", "L", 8, copy1}, - {"L", "L;16", 16, packL16}, - {"L", "L;16B", 16, packL16B}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L, 8, copy1}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_16, 16, packL16}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_16B, 16, packL16B}, /* grayscale w. alpha */ - {"LA", "LA", 16, packLA}, - {"LA", "LA;L", 16, packLAL}, + {IMAGING_MODE_LA, IMAGING_RAWMODE_LA, 16, packLA}, + {IMAGING_MODE_LA, IMAGING_RAWMODE_LA_L, 16, packLAL}, /* grayscale w. alpha premultiplied */ - {"La", "La", 16, packLA}, + {IMAGING_MODE_La, IMAGING_RAWMODE_La, 16, packLA}, /* palette */ - {"P", "P;1", 1, pack1}, - {"P", "P;2", 2, packP2}, - {"P", "P;4", 4, packP4}, - {"P", "P", 8, copy1}, + {IMAGING_MODE_P, IMAGING_RAWMODE_P_1, 1, pack1}, + {IMAGING_MODE_P, IMAGING_RAWMODE_P_2, 2, packP2}, + {IMAGING_MODE_P, IMAGING_RAWMODE_P_4, 4, packP4}, + {IMAGING_MODE_P, IMAGING_RAWMODE_P, 8, copy1}, /* palette w. alpha */ - {"PA", "PA", 16, packLA}, - {"PA", "PA;L", 16, packLAL}, + {IMAGING_MODE_PA, IMAGING_RAWMODE_PA, 16, packLA}, + {IMAGING_MODE_PA, IMAGING_RAWMODE_PA_L, 16, packLAL}, /* true colour */ - {"RGB", "RGB", 24, ImagingPackRGB}, - {"RGB", "RGBX", 32, copy4}, - {"RGB", "RGBA", 32, copy4}, - {"RGB", "XRGB", 32, ImagingPackXRGB}, - {"RGB", "BGR", 24, ImagingPackBGR}, - {"RGB", "BGRX", 32, ImagingPackBGRX}, - {"RGB", "XBGR", 32, ImagingPackXBGR}, - {"RGB", "RGB;L", 24, packRGBL}, - {"RGB", "R", 8, band0}, - {"RGB", "G", 8, band1}, - {"RGB", "B", 8, band2}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB, 24, ImagingPackRGB}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBX, 32, copy4}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBA, 32, copy4}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_XRGB, 32, ImagingPackXRGB}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_BGR, 24, ImagingPackBGR}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_BGRX, 32, ImagingPackBGRX}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_XBGR, 32, ImagingPackXBGR}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB_L, 24, packRGBL}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_R, 8, band0}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_G, 8, band1}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_B, 8, band2}, /* true colour w. alpha */ - {"RGBA", "RGBA", 32, copy4}, - {"RGBA", "RGBA;L", 32, packRGBXL}, - {"RGBA", "RGB", 24, ImagingPackRGB}, - {"RGBA", "BGR", 24, ImagingPackBGR}, - {"RGBA", "BGRA", 32, ImagingPackBGRA}, - {"RGBA", "ABGR", 32, ImagingPackABGR}, - {"RGBA", "BGRa", 32, ImagingPackBGRa}, - {"RGBA", "R", 8, band0}, - {"RGBA", "G", 8, band1}, - {"RGBA", "B", 8, band2}, - {"RGBA", "A", 8, band3}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA, 32, copy4}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA_L, 32, packRGBXL}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGB, 24, ImagingPackRGB}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGR, 24, ImagingPackBGR}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGRA, 32, ImagingPackBGRA}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_ABGR, 32, ImagingPackABGR}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGRa, 32, ImagingPackBGRa}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_R, 8, band0}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_G, 8, band1}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_B, 8, band2}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_A, 8, band3}, /* true colour w. alpha premultiplied */ - {"RGBa", "RGBa", 32, copy4}, - {"RGBa", "BGRa", 32, ImagingPackBGRA}, - {"RGBa", "aBGR", 32, ImagingPackABGR}, + {IMAGING_MODE_RGBa, IMAGING_RAWMODE_RGBa, 32, copy4}, + {IMAGING_MODE_RGBa, IMAGING_RAWMODE_BGRa, 32, ImagingPackBGRA}, + {IMAGING_MODE_RGBa, IMAGING_RAWMODE_aBGR, 32, ImagingPackABGR}, /* true colour w. padding */ - {"RGBX", "RGBX", 32, copy4}, - {"RGBX", "RGBX;L", 32, packRGBXL}, - {"RGBX", "RGB", 24, ImagingPackRGB}, - {"RGBX", "BGR", 24, ImagingPackBGR}, - {"RGBX", "BGRX", 32, ImagingPackBGRX}, - {"RGBX", "XBGR", 32, ImagingPackXBGR}, - {"RGBX", "R", 8, band0}, - {"RGBX", "G", 8, band1}, - {"RGBX", "B", 8, band2}, - {"RGBX", "X", 8, band3}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBX, 32, copy4}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBX_L, 32, packRGBXL}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGB, 24, ImagingPackRGB}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_BGR, 24, ImagingPackBGR}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_BGRX, 32, ImagingPackBGRX}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_XBGR, 32, ImagingPackXBGR}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_R, 8, band0}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_G, 8, band1}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_B, 8, band2}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_X, 8, band3}, /* colour separation */ - {"CMYK", "CMYK", 32, copy4}, - {"CMYK", "CMYK;I", 32, copy4I}, - {"CMYK", "CMYK;L", 32, packRGBXL}, - {"CMYK", "C", 8, band0}, - {"CMYK", "M", 8, band1}, - {"CMYK", "Y", 8, band2}, - {"CMYK", "K", 8, band3}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK, 32, copy4}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK_I, 32, copy4I}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK_L, 32, packRGBXL}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_C, 8, band0}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_M, 8, band1}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_Y, 8, band2}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_K, 8, band3}, /* video (YCbCr) */ - {"YCbCr", "YCbCr", 24, ImagingPackRGB}, - {"YCbCr", "YCbCr;L", 24, packRGBL}, - {"YCbCr", "YCbCrX", 32, copy4}, - {"YCbCr", "YCbCrK", 32, copy4}, - {"YCbCr", "Y", 8, band0}, - {"YCbCr", "Cb", 8, band1}, - {"YCbCr", "Cr", 8, band2}, + {IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCr, 24, ImagingPackRGB}, + {IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCr_L, 24, packRGBL}, + {IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCrX, 32, copy4}, + {IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCrK, 32, copy4}, + {IMAGING_MODE_YCbCr, IMAGING_RAWMODE_Y, 8, band0}, + {IMAGING_MODE_YCbCr, IMAGING_RAWMODE_Cb, 8, band1}, + {IMAGING_MODE_YCbCr, IMAGING_RAWMODE_Cr, 8, band2}, /* LAB Color */ - {"LAB", "LAB", 24, ImagingPackLAB}, - {"LAB", "L", 8, band0}, - {"LAB", "A", 8, band1}, - {"LAB", "B", 8, band2}, + {IMAGING_MODE_LAB, IMAGING_RAWMODE_LAB, 24, ImagingPackLAB}, + {IMAGING_MODE_LAB, IMAGING_RAWMODE_L, 8, band0}, + {IMAGING_MODE_LAB, IMAGING_RAWMODE_A, 8, band1}, + {IMAGING_MODE_LAB, IMAGING_RAWMODE_B, 8, band2}, /* HSV */ - {"HSV", "HSV", 24, ImagingPackRGB}, - {"HSV", "H", 8, band0}, - {"HSV", "S", 8, band1}, - {"HSV", "V", 8, band2}, + {IMAGING_MODE_HSV, IMAGING_RAWMODE_HSV, 24, ImagingPackRGB}, + {IMAGING_MODE_HSV, IMAGING_RAWMODE_H, 8, band0}, + {IMAGING_MODE_HSV, IMAGING_RAWMODE_S, 8, band1}, + {IMAGING_MODE_HSV, IMAGING_RAWMODE_V, 8, band2}, /* integer */ - {"I", "I", 32, copy4}, - {"I", "I;16B", 16, packI16B}, - {"I", "I;32S", 32, packI32S}, - {"I", "I;32NS", 32, copy4}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I, 32, copy4}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_16B, 16, packI16B}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_32S, 32, packI32S}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_32NS, 32, copy4}, /* floating point */ - {"F", "F", 32, copy4}, - {"F", "F;32F", 32, packI32S}, - {"F", "F;32NF", 32, copy4}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F, 32, copy4}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_32F, 32, packI32S}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_32NF, 32, copy4}, /* storage modes */ - {"I;16", "I;16", 16, copy2}, + {IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16, 16, copy2}, #ifdef WORDS_BIGENDIAN - {"I;16", "I;16B", 16, packI16N_I16}, + {IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16B, 16, packI16N_I16}, #else - {"I;16", "I;16B", 16, packI16N_I16B}, + {IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16B, 16, packI16N_I16B}, #endif - {"I;16B", "I;16B", 16, copy2}, - {"I;16L", "I;16L", 16, copy2}, - {"I;16N", "I;16N", 16, copy2}, - {"I;16", "I;16N", 16, packI16N_I16}, // LibTiff native->image endian. - {"I;16L", "I;16N", 16, packI16N_I16}, - {"I;16B", "I;16N", 16, packI16N_I16B}, - {"BGR;15", "BGR;15", 16, copy2}, - {"BGR;16", "BGR;16", 16, copy2}, - {"BGR;24", "BGR;24", 24, copy3}, - - {NULL} /* sentinel */ + {IMAGING_MODE_I_16B, IMAGING_RAWMODE_I_16B, 16, copy2}, + {IMAGING_MODE_I_16L, IMAGING_RAWMODE_I_16L, 16, copy2}, + {IMAGING_MODE_I_16N, IMAGING_RAWMODE_I_16N, 16, copy2}, + {IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16N, 16, packI16N_I16 + }, // LibTiff native->image endian. + {IMAGING_MODE_I_16L, IMAGING_RAWMODE_I_16N, 16, packI16N_I16}, + {IMAGING_MODE_I_16B, IMAGING_RAWMODE_I_16N, 16, packI16N_I16B}, + {IMAGING_MODE_BGR_15, IMAGING_RAWMODE_BGR_15, 16, copy2}, + {IMAGING_MODE_BGR_16, IMAGING_RAWMODE_BGR_16, 16, copy2}, + {IMAGING_MODE_BGR_24, IMAGING_RAWMODE_BGR_24, 24, copy3} }; ImagingShuffler -ImagingFindPacker(const char *mode, const char *rawmode, int *bits_out) { - int i; - - /* find a suitable pixel packer */ - for (i = 0; packers[i].rawmode; i++) { - if (strcmp(packers[i].mode, mode) == 0 && - strcmp(packers[i].rawmode, rawmode) == 0) { +ImagingFindPacker(const ModeID mode, const RawModeID rawmode, int *bits_out) { + for (size_t i = 0; i < sizeof(packers) / sizeof(*packers); i++) { + if (packers[i].mode == mode && packers[i].rawmode == rawmode) { if (bits_out) { *bits_out = packers[i].bits; } diff --git a/src/libImaging/Palette.c b/src/libImaging/Palette.c index 78916bca52b..2bbdb69ef65 100644 --- a/src/libImaging/Palette.c +++ b/src/libImaging/Palette.c @@ -21,13 +21,13 @@ #include ImagingPalette -ImagingPaletteNew(const char *mode) { +ImagingPaletteNew(const ModeID mode) { /* Create a palette object */ int i; ImagingPalette palette; - if (strcmp(mode, "RGB") && strcmp(mode, "RGBA")) { + if (mode != IMAGING_MODE_RGB && mode != IMAGING_MODE_RGBA) { return (ImagingPalette)ImagingError_ModeError(); } @@ -36,8 +36,7 @@ ImagingPaletteNew(const char *mode) { return (ImagingPalette)ImagingError_MemoryError(); } - strncpy(palette->mode, mode, IMAGING_MODE_LENGTH - 1); - palette->mode[IMAGING_MODE_LENGTH - 1] = 0; + palette->mode = mode; palette->size = 0; for (i = 0; i < 256; i++) { @@ -54,7 +53,7 @@ ImagingPaletteNewBrowser(void) { int i, r, g, b; ImagingPalette palette; - palette = ImagingPaletteNew("RGB"); + palette = ImagingPaletteNew(IMAGING_MODE_RGB); if (!palette) { return NULL; } diff --git a/src/libImaging/Paste.c b/src/libImaging/Paste.c index 86085942a2e..d4b973abc4d 100644 --- a/src/libImaging/Paste.c +++ b/src/libImaging/Paste.c @@ -67,8 +67,8 @@ paste_mask_1( int x, y; if (imOut->image8) { - int in_i16 = strncmp(imIn->mode, "I;16", 4) == 0; - int out_i16 = strncmp(imOut->mode, "I;16", 4) == 0; + int in_i16 = isModeI16(imIn->mode); + int out_i16 = isModeI16(imOut->mode); for (y = 0; y < ysize; y++) { UINT8 *out = imOut->image8[y + dy] + dx; if (out_i16) { @@ -307,31 +307,26 @@ ImagingPaste( ImagingSectionEnter(&cookie); paste(imOut, imIn, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "1") == 0) { + } else if (imMask->mode == IMAGING_MODE_1) { ImagingSectionEnter(&cookie); paste_mask_1(imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "L") == 0) { + } else if (imMask->mode == IMAGING_MODE_L) { ImagingSectionEnter(&cookie); paste_mask_L(imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "LA") == 0 || strcmp(imMask->mode, "RGBA") == 0) { + } else if (imMask->mode == IMAGING_MODE_LA || imMask->mode == IMAGING_MODE_RGBA) { ImagingSectionEnter(&cookie); paste_mask_RGBA( imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize ); ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "RGBa") == 0) { + } else if (imMask->mode == IMAGING_MODE_RGBa) { ImagingSectionEnter(&cookie); paste_mask_RGBa( imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize ); ImagingSectionLeave(&cookie); - } else { (void)ImagingError_ValueError("bad transparency mask"); return -1; @@ -437,7 +432,7 @@ fill_mask_L( unsigned int tmp1; if (imOut->image8) { - int i16 = strncmp(imOut->mode, "I;16", 4) == 0; + int i16 = isModeI16(imOut->mode); for (y = 0; y < ysize; y++) { UINT8 *out = imOut->image8[y + dy] + dx; if (i16) { @@ -456,9 +451,9 @@ fill_mask_L( } else { int alpha_channel = - strcmp(imOut->mode, "RGBa") == 0 || strcmp(imOut->mode, "RGBA") == 0 || - strcmp(imOut->mode, "La") == 0 || strcmp(imOut->mode, "LA") == 0 || - strcmp(imOut->mode, "PA") == 0; + imOut->mode == IMAGING_MODE_RGBa || imOut->mode == IMAGING_MODE_RGBA || + imOut->mode == IMAGING_MODE_La || imOut->mode == IMAGING_MODE_LA || + imOut->mode == IMAGING_MODE_PA; for (y = 0; y < ysize; y++) { UINT8 *out = (UINT8 *)imOut->image[y + dy] + dx * pixelsize; UINT8 *mask = (UINT8 *)imMask->image[y + sy] + sx; @@ -617,27 +612,22 @@ ImagingFill2( ImagingSectionEnter(&cookie); fill(imOut, ink, dx0, dy0, xsize, ysize, pixelsize); ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "1") == 0) { + } else if (imMask->mode == IMAGING_MODE_1) { ImagingSectionEnter(&cookie); fill_mask_1(imOut, ink, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "L") == 0) { + } else if (imMask->mode == IMAGING_MODE_L) { ImagingSectionEnter(&cookie); fill_mask_L(imOut, ink, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "RGBA") == 0) { + } else if (imMask->mode == IMAGING_MODE_RGBA) { ImagingSectionEnter(&cookie); fill_mask_RGBA(imOut, ink, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "RGBa") == 0) { + } else if (imMask->mode == IMAGING_MODE_RGBa) { ImagingSectionEnter(&cookie); fill_mask_RGBa(imOut, ink, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); ImagingSectionLeave(&cookie); - } else { (void)ImagingError_ValueError("bad transparency mask"); return -1; diff --git a/src/libImaging/Point.c b/src/libImaging/Point.c index 6a4060b4bc1..b78873e0cf9 100644 --- a/src/libImaging/Point.c +++ b/src/libImaging/Point.c @@ -128,7 +128,7 @@ im_point_32_8(Imaging imOut, Imaging imIn, im_point_context *context) { } Imaging -ImagingPoint(Imaging imIn, const char *mode, const void *table) { +ImagingPoint(Imaging imIn, ModeID mode, const void *table) { /* lookup table transform */ ImagingSectionCookie cookie; @@ -140,15 +140,15 @@ ImagingPoint(Imaging imIn, const char *mode, const void *table) { return (Imaging)ImagingError_ModeError(); } - if (!mode) { + if (mode == IMAGING_MODE_UNKNOWN) { mode = imIn->mode; } if (imIn->type != IMAGING_TYPE_UINT8) { - if (imIn->type != IMAGING_TYPE_INT32 || strcmp(mode, "L") != 0) { + if (imIn->type != IMAGING_TYPE_INT32 || mode != IMAGING_MODE_L) { goto mode_mismatch; } - } else if (!imIn->image8 && strcmp(imIn->mode, mode) != 0) { + } else if (!imIn->image8 && imIn->mode != mode) { goto mode_mismatch; } @@ -209,8 +209,8 @@ ImagingPointTransform(Imaging imIn, double scale, double offset) { Imaging imOut; int x, y; - if (!imIn || (strcmp(imIn->mode, "I") != 0 && strcmp(imIn->mode, "I;16") != 0 && - strcmp(imIn->mode, "F") != 0)) { + if (!imIn || (imIn->mode != IMAGING_MODE_I && imIn->mode != IMAGING_MODE_I_16 && + imIn->mode != IMAGING_MODE_F)) { return (Imaging)ImagingError_ModeError(); } @@ -244,7 +244,7 @@ ImagingPointTransform(Imaging imIn, double scale, double offset) { ImagingSectionLeave(&cookie); break; case IMAGING_TYPE_SPECIAL: - if (strcmp(imIn->mode, "I;16") == 0) { + if (imIn->mode == IMAGING_MODE_I_16) { ImagingSectionEnter(&cookie); for (y = 0; y < imIn->ysize; y++) { char *in = (char *)imIn->image[y]; diff --git a/src/libImaging/Quant.c b/src/libImaging/Quant.c index a489a882db2..b1397c5f054 100644 --- a/src/libImaging/Quant.c +++ b/src/libImaging/Quant.c @@ -1684,13 +1684,13 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) { return (Imaging)ImagingError_ValueError("bad number of colors"); } - if (strcmp(im->mode, "L") != 0 && strcmp(im->mode, "P") != 0 && - strcmp(im->mode, "RGB") != 0 && strcmp(im->mode, "RGBA") != 0) { + if (im->mode != IMAGING_MODE_L && im->mode != IMAGING_MODE_P && + im->mode != IMAGING_MODE_RGB && im->mode != IMAGING_MODE_RGBA) { return ImagingError_ModeError(); } /* only octree and imagequant supports RGBA */ - if (!strcmp(im->mode, "RGBA") && mode != 2 && mode != 3) { + if (im->mode == IMAGING_MODE_RGBA && mode != 2 && mode != 3) { return ImagingError_ModeError(); } @@ -1708,7 +1708,7 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) { /* FIXME: maybe we could load the hash tables directly from the image data? */ - if (!strcmp(im->mode, "L")) { + if (im->mode == IMAGING_MODE_L) { /* grayscale */ /* FIXME: converting a "L" image to "P" with 256 colors @@ -1721,7 +1721,7 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) { } } - } else if (!strcmp(im->mode, "P")) { + } else if (im->mode == IMAGING_MODE_P) { /* palette */ pp = im->palette->palette; @@ -1736,10 +1736,10 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) { } } - } else if (!strcmp(im->mode, "RGB") || !strcmp(im->mode, "RGBA")) { + } else if (im->mode == IMAGING_MODE_RGB || im->mode == IMAGING_MODE_RGBA) { /* true colour */ - withAlpha = !strcmp(im->mode, "RGBA"); + withAlpha = im->mode == IMAGING_MODE_RGBA; int transparency = 0; unsigned char r = 0, g = 0, b = 0; for (i = y = 0; y < im->ysize; y++) { @@ -1830,7 +1830,7 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) { ImagingSectionLeave(&cookie); if (result > 0) { - imOut = ImagingNewDirty("P", im->xsize, im->ysize); + imOut = ImagingNewDirty(IMAGING_MODE_P, im->xsize, im->ysize); ImagingSectionEnter(&cookie); for (i = y = 0; y < im->ysize; y++) { @@ -1855,7 +1855,7 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) { } if (withAlpha) { - strcpy(imOut->palette->mode, "RGBA"); + imOut->palette->mode = IMAGING_MODE_RGBA; } free(palette); diff --git a/src/libImaging/Reduce.c b/src/libImaging/Reduce.c index 022daa0003f..a4e58ced81b 100644 --- a/src/libImaging/Reduce.c +++ b/src/libImaging/Reduce.c @@ -1452,7 +1452,7 @@ ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4]) { ImagingSectionCookie cookie; Imaging imOut = NULL; - if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "1") == 0) { + if (imIn->mode == IMAGING_MODE_P || imIn->mode == IMAGING_MODE_1) { return (Imaging)ImagingError_ModeError(); } diff --git a/src/libImaging/Resample.c b/src/libImaging/Resample.c index f5e386dc2ba..3ab43a8955a 100644 --- a/src/libImaging/Resample.c +++ b/src/libImaging/Resample.c @@ -470,9 +470,9 @@ ImagingResampleHorizontal_16bpc( double *k; int bigendian = 0; - if (strcmp(imIn->mode, "I;16N") == 0 + if (imIn->mode == IMAGING_MODE_I_16N #ifdef WORDS_BIGENDIAN - || strcmp(imIn->mode, "I;16B") == 0 + || imIn->mode == IMAGING_MODE_I_16B #endif ) { bigendian = 1; @@ -509,9 +509,9 @@ ImagingResampleVertical_16bpc( double *k; int bigendian = 0; - if (strcmp(imIn->mode, "I;16N") == 0 + if (imIn->mode == IMAGING_MODE_I_16N #ifdef WORDS_BIGENDIAN - || strcmp(imIn->mode, "I;16B") == 0 + || imIn->mode == IMAGING_MODE_I_16B #endif ) { bigendian = 1; @@ -646,12 +646,12 @@ ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) { ResampleFunction ResampleHorizontal; ResampleFunction ResampleVertical; - if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "1") == 0) { + if (imIn->mode == IMAGING_MODE_P || imIn->mode == IMAGING_MODE_1) { return (Imaging)ImagingError_ModeError(); } if (imIn->type == IMAGING_TYPE_SPECIAL) { - if (strncmp(imIn->mode, "I;16", 4) == 0) { + if (isModeI16(imIn->mode)) { ResampleHorizontal = ImagingResampleHorizontal_16bpc; ResampleVertical = ImagingResampleVertical_16bpc; } else { diff --git a/src/libImaging/Storage.c b/src/libImaging/Storage.c index 522e9f37557..bc51fb6827b 100644 --- a/src/libImaging/Storage.c +++ b/src/libImaging/Storage.c @@ -42,7 +42,7 @@ */ Imaging -ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) { +ImagingNewPrologueSubtype(const ModeID mode, int xsize, int ysize, int size) { Imaging im; /* linesize overflow check, roughly the current largest space req'd */ @@ -61,57 +61,56 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) { im->type = IMAGING_TYPE_UINT8; - if (strcmp(mode, "1") == 0) { + if (mode == IMAGING_MODE_1) { /* 1-bit images */ im->bands = im->pixelsize = 1; im->linesize = xsize; - } else if (strcmp(mode, "P") == 0) { + } else if (mode == IMAGING_MODE_P) { /* 8-bit palette mapped images */ im->bands = im->pixelsize = 1; im->linesize = xsize; - im->palette = ImagingPaletteNew("RGB"); + im->palette = ImagingPaletteNew(IMAGING_MODE_RGB); - } else if (strcmp(mode, "PA") == 0) { + } 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("RGB"); + im->palette = ImagingPaletteNew(IMAGING_MODE_RGB); - } else if (strcmp(mode, "L") == 0) { + } else if (mode == IMAGING_MODE_L) { /* 8-bit grayscale (luminance) images */ im->bands = im->pixelsize = 1; im->linesize = xsize; - } else if (strcmp(mode, "LA") == 0) { + } 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; - } else if (strcmp(mode, "La") == 0) { + } 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; - } else if (strcmp(mode, "F") == 0) { + } 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; - } else if (strcmp(mode, "I") == 0) { + } 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; - } else if (strcmp(mode, "I;16") == 0 || strcmp(mode, "I;16L") == 0 || - strcmp(mode, "I;16B") == 0 || strcmp(mode, "I;16N") == 0) { + } else if (isModeI16(mode)) { /* EXPERIMENTAL */ /* 16-bit raw integer images */ im->bands = 1; @@ -119,13 +118,13 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) { im->linesize = xsize * 2; im->type = IMAGING_TYPE_SPECIAL; - } else if (strcmp(mode, "RGB") == 0) { + } else if (mode == IMAGING_MODE_RGB) { /* 24-bit true colour images */ im->bands = 3; im->pixelsize = 4; im->linesize = xsize * 4; - } else if (strcmp(mode, "BGR;15") == 0) { + } else if (mode == IMAGING_MODE_BGR_15) { /* EXPERIMENTAL */ /* 15-bit reversed true colour */ im->bands = 3; @@ -133,7 +132,7 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) { im->linesize = (xsize * 2 + 3) & -4; im->type = IMAGING_TYPE_SPECIAL; - } else if (strcmp(mode, "BGR;16") == 0) { + } else if (mode == IMAGING_MODE_BGR_16) { /* EXPERIMENTAL */ /* 16-bit reversed true colour */ im->bands = 3; @@ -141,7 +140,7 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) { im->linesize = (xsize * 2 + 3) & -4; im->type = IMAGING_TYPE_SPECIAL; - } else if (strcmp(mode, "BGR;24") == 0) { + } else if (mode == IMAGING_MODE_BGR_24) { /* EXPERIMENTAL */ /* 24-bit reversed true colour */ im->bands = 3; @@ -149,40 +148,40 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) { im->linesize = (xsize * 3 + 3) & -4; im->type = IMAGING_TYPE_SPECIAL; - } else if (strcmp(mode, "RGBX") == 0) { + } else if (mode == IMAGING_MODE_RGBX) { /* 32-bit true colour images with padding */ im->bands = im->pixelsize = 4; im->linesize = xsize * 4; - } else if (strcmp(mode, "RGBA") == 0) { + } else if (mode == IMAGING_MODE_RGBA) { /* 32-bit true colour images with alpha */ im->bands = im->pixelsize = 4; im->linesize = xsize * 4; - } else if (strcmp(mode, "RGBa") == 0) { + } else if (mode == IMAGING_MODE_RGBa) { /* 32-bit true colour images with premultiplied alpha */ im->bands = im->pixelsize = 4; im->linesize = xsize * 4; - } else if (strcmp(mode, "CMYK") == 0) { + } else if (mode == IMAGING_MODE_CMYK) { /* 32-bit colour separation */ im->bands = im->pixelsize = 4; im->linesize = xsize * 4; - } else if (strcmp(mode, "YCbCr") == 0) { + } else if (mode == IMAGING_MODE_YCbCr) { /* 24-bit video format */ im->bands = 3; im->pixelsize = 4; im->linesize = xsize * 4; - } else if (strcmp(mode, "LAB") == 0) { + } 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; - } else if (strcmp(mode, "HSV") == 0) { + } else if (mode == IMAGING_MODE_HSV) { /* 24-bit color, luminance, + 2 color channels */ /* L is uint8, a,b are int8 */ im->bands = 3; @@ -195,7 +194,7 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) { } /* Setup image descriptor */ - strcpy(im->mode, mode); + im->mode = mode; /* Pointer array (allocate at least one line, to avoid MemoryError exceptions on platforms where calloc(0, x) returns NULL) */ @@ -226,7 +225,7 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) { } Imaging -ImagingNewPrologue(const char *mode, int xsize, int ysize) { +ImagingNewPrologue(const ModeID mode, int xsize, int ysize) { return ImagingNewPrologueSubtype( mode, xsize, ysize, sizeof(struct ImagingMemoryInstance) ); @@ -492,7 +491,7 @@ ImagingAllocateBlock(Imaging im) { */ Imaging -ImagingNewInternal(const char *mode, int xsize, int ysize, int dirty) { +ImagingNewInternal(const ModeID mode, int xsize, int ysize, int dirty) { Imaging im; if (xsize < 0 || ysize < 0) { @@ -528,17 +527,17 @@ ImagingNewInternal(const char *mode, int xsize, int ysize, int dirty) { } Imaging -ImagingNew(const char *mode, int xsize, int ysize) { +ImagingNew(const ModeID mode, int xsize, int ysize) { return ImagingNewInternal(mode, xsize, ysize, 0); } Imaging -ImagingNewDirty(const char *mode, int xsize, int ysize) { +ImagingNewDirty(const ModeID mode, int xsize, int ysize) { return ImagingNewInternal(mode, xsize, ysize, 1); } Imaging -ImagingNewBlock(const char *mode, int xsize, int ysize) { +ImagingNewBlock(const ModeID mode, int xsize, int ysize) { Imaging im; if (xsize < 0 || ysize < 0) { @@ -559,12 +558,12 @@ ImagingNewBlock(const char *mode, int xsize, int ysize) { } Imaging -ImagingNew2Dirty(const char *mode, Imaging imOut, Imaging imIn) { +ImagingNew2Dirty(const ModeID mode, Imaging imOut, Imaging imIn) { /* allocate or validate output image */ if (imOut) { /* make sure images match */ - if (strcmp(imOut->mode, mode) != 0 || imOut->xsize != imIn->xsize || + if (imOut->mode != mode || imOut->xsize != imIn->xsize || imOut->ysize != imIn->ysize) { return ImagingError_Mismatch(); } diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c index e4da9162dc9..fdbe1c1b3ec 100644 --- a/src/libImaging/TiffDecode.c +++ b/src/libImaging/TiffDecode.c @@ -246,14 +246,26 @@ _pickUnpackers( // We'll pick appropriate set of unpackers depending on planar_configuration // It does not matter if data is RGB(A), CMYK or LUV really, // we just copy it plane by plane - unpackers[0] = - ImagingFindUnpacker("RGBA", bits_per_sample == 16 ? "R;16N" : "R", NULL); - unpackers[1] = - ImagingFindUnpacker("RGBA", bits_per_sample == 16 ? "G;16N" : "G", NULL); - unpackers[2] = - ImagingFindUnpacker("RGBA", bits_per_sample == 16 ? "B;16N" : "B", NULL); - unpackers[3] = - ImagingFindUnpacker("RGBA", bits_per_sample == 16 ? "A;16N" : "A", NULL); + unpackers[0] = ImagingFindUnpacker( + IMAGING_MODE_RGBA, + bits_per_sample == 16 ? IMAGING_RAWMODE_R_16N : IMAGING_RAWMODE_R, + NULL + ); + unpackers[1] = ImagingFindUnpacker( + IMAGING_MODE_RGBA, + bits_per_sample == 16 ? IMAGING_RAWMODE_G_16N : IMAGING_RAWMODE_G, + NULL + ); + unpackers[2] = ImagingFindUnpacker( + IMAGING_MODE_RGBA, + bits_per_sample == 16 ? IMAGING_RAWMODE_B_16N : IMAGING_RAWMODE_B, + NULL + ); + unpackers[3] = ImagingFindUnpacker( + IMAGING_MODE_RGBA, + bits_per_sample == 16 ? IMAGING_RAWMODE_A_16N : IMAGING_RAWMODE_A, + NULL + ); return im->bands; } else { @@ -642,7 +654,7 @@ ImagingLibTiffDecode( ); TRACE( ("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n", - im->mode, + getModeData(im->mode)->name, im->type, im->bands, im->xsize, @@ -753,7 +765,7 @@ ImagingLibTiffDecode( if (!state->errcode) { // Check if raw mode was RGBa and it was stored on separate planes // so we have to convert it to RGBA - if (planes > 3 && strcmp(im->mode, "RGBA") == 0) { + if (planes > 3 && im->mode == IMAGING_MODE_RGBA) { uint16_t extrasamples; uint16_t *sampleinfo; ImagingShuffler shuffle; @@ -765,7 +777,9 @@ ImagingLibTiffDecode( if (extrasamples >= 1 && (sampleinfo[0] == EXTRASAMPLE_UNSPECIFIED || sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA)) { - shuffle = ImagingFindUnpacker("RGBA", "RGBa", NULL); + shuffle = ImagingFindUnpacker( + IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBa, NULL + ); for (y = state->yoff; y < state->ysize; y++) { UINT8 *ptr = (UINT8 *)im->image[y + state->yoff] + @@ -976,7 +990,7 @@ ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int byt ); TRACE( ("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n", - im->mode, + getModeData(im->mode)->name, im->type, im->bands, im->xsize, diff --git a/src/libImaging/Unpack.c b/src/libImaging/Unpack.c index c23d5d889f6..cee5177fd85 100644 --- a/src/libImaging/Unpack.c +++ b/src/libImaging/Unpack.c @@ -1548,12 +1548,11 @@ band316L(UINT8 *out, const UINT8 *in, int pixels) { } static struct { - const char *mode; - const char *rawmode; + const ModeID mode; + const RawModeID rawmode; int bits; ImagingShuffler unpack; } unpackers[] = { - /* raw mode syntax is ";" where "bits" defaults depending on mode (1 for "1", 8 for "P" and "L", etc), and "flags" should be given in alphabetical order. if both bits @@ -1566,300 +1565,297 @@ static struct { /* exception: rawmodes "I" and "F" are always native endian byte order */ /* bilevel */ - {"1", "1", 1, unpack1}, - {"1", "1;I", 1, unpack1I}, - {"1", "1;R", 1, unpack1R}, - {"1", "1;IR", 1, unpack1IR}, - {"1", "1;8", 8, unpack18}, + {IMAGING_MODE_1, IMAGING_RAWMODE_1, 1, unpack1}, + {IMAGING_MODE_1, IMAGING_RAWMODE_1_I, 1, unpack1I}, + {IMAGING_MODE_1, IMAGING_RAWMODE_1_R, 1, unpack1R}, + {IMAGING_MODE_1, IMAGING_RAWMODE_1_IR, 1, unpack1IR}, + {IMAGING_MODE_1, IMAGING_RAWMODE_1_8, 8, unpack18}, /* grayscale */ - {"L", "L;2", 2, unpackL2}, - {"L", "L;2I", 2, unpackL2I}, - {"L", "L;2R", 2, unpackL2R}, - {"L", "L;2IR", 2, unpackL2IR}, - - {"L", "L;4", 4, unpackL4}, - {"L", "L;4I", 4, unpackL4I}, - {"L", "L;4R", 4, unpackL4R}, - {"L", "L;4IR", 4, unpackL4IR}, - - {"L", "L", 8, copy1}, - {"L", "L;I", 8, unpackLI}, - {"L", "L;R", 8, unpackLR}, - {"L", "L;16", 16, unpackL16}, - {"L", "L;16B", 16, unpackL16B}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_2, 2, unpackL2}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_2I, 2, unpackL2I}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_2R, 2, unpackL2R}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_2IR, 2, unpackL2IR}, + + {IMAGING_MODE_L, IMAGING_RAWMODE_L_4, 4, unpackL4}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_4I, 4, unpackL4I}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_4R, 4, unpackL4R}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_4IR, 4, unpackL4IR}, + + {IMAGING_MODE_L, IMAGING_RAWMODE_L, 8, copy1}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_I, 8, unpackLI}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_R, 8, unpackLR}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_16, 16, unpackL16}, + {IMAGING_MODE_L, IMAGING_RAWMODE_L_16B, 16, unpackL16B}, /* grayscale w. alpha */ - {"LA", "LA", 16, unpackLA}, - {"LA", "LA;L", 16, unpackLAL}, + {IMAGING_MODE_LA, IMAGING_RAWMODE_LA, 16, unpackLA}, + {IMAGING_MODE_LA, IMAGING_RAWMODE_LA_L, 16, unpackLAL}, /* grayscale w. alpha premultiplied */ - {"La", "La", 16, unpackLA}, + {IMAGING_MODE_La, IMAGING_RAWMODE_La, 16, unpackLA}, /* palette */ - {"P", "P;1", 1, unpackP1}, - {"P", "P;2", 2, unpackP2}, - {"P", "P;2L", 2, unpackP2L}, - {"P", "P;4", 4, unpackP4}, - {"P", "P;4L", 4, unpackP4L}, - {"P", "P", 8, copy1}, - {"P", "P;R", 8, unpackLR}, - {"P", "L", 8, copy1}, - {"P", "PX", 16, unpackL16B}, + {IMAGING_MODE_P, IMAGING_RAWMODE_P_1, 1, unpackP1}, + {IMAGING_MODE_P, IMAGING_RAWMODE_P_2, 2, unpackP2}, + {IMAGING_MODE_P, IMAGING_RAWMODE_P_2L, 2, unpackP2L}, + {IMAGING_MODE_P, IMAGING_RAWMODE_P_4, 4, unpackP4}, + {IMAGING_MODE_P, IMAGING_RAWMODE_P_4L, 4, unpackP4L}, + {IMAGING_MODE_P, IMAGING_RAWMODE_P, 8, copy1}, + {IMAGING_MODE_P, IMAGING_RAWMODE_P_R, 8, unpackLR}, + {IMAGING_MODE_P, IMAGING_RAWMODE_L, 8, copy1}, + {IMAGING_MODE_P, IMAGING_RAWMODE_PX, 16, unpackL16B}, /* palette w. alpha */ - {"PA", "PA", 16, unpackLA}, - {"PA", "PA;L", 16, unpackLAL}, - {"PA", "LA", 16, unpackLA}, + {IMAGING_MODE_PA, IMAGING_RAWMODE_PA, 16, unpackLA}, + {IMAGING_MODE_PA, IMAGING_RAWMODE_PA_L, 16, unpackLAL}, + {IMAGING_MODE_PA, IMAGING_RAWMODE_LA, 16, unpackLA}, /* true colour */ - {"RGB", "RGB", 24, ImagingUnpackRGB}, - {"RGB", "RGB;L", 24, unpackRGBL}, - {"RGB", "RGB;R", 24, unpackRGBR}, - {"RGB", "RGB;16L", 48, unpackRGB16L}, - {"RGB", "RGB;16B", 48, unpackRGB16B}, - {"RGB", "BGR", 24, ImagingUnpackBGR}, - {"RGB", "RGB;15", 16, ImagingUnpackRGB15}, - {"RGB", "BGR;15", 16, ImagingUnpackBGR15}, - {"RGB", "RGB;16", 16, ImagingUnpackRGB16}, - {"RGB", "BGR;16", 16, ImagingUnpackBGR16}, - {"RGB", "RGBX;16L", 64, unpackRGBA16L}, - {"RGB", "RGBX;16B", 64, unpackRGBA16B}, - {"RGB", "RGB;4B", 16, ImagingUnpackRGB4B}, - {"RGB", "BGR;5", 16, ImagingUnpackBGR15}, /* compat */ - {"RGB", "RGBX", 32, copy4}, - {"RGB", "RGBX;L", 32, unpackRGBAL}, - {"RGB", "RGBXX", 40, copy4skip1}, - {"RGB", "RGBXXX", 48, copy4skip2}, - {"RGB", "RGBA;L", 32, unpackRGBAL}, - {"RGB", "RGBA;15", 16, ImagingUnpackRGBA15}, - {"RGB", "BGRX", 32, ImagingUnpackBGRX}, - {"RGB", "BGXR", 32, ImagingUnpackBGXR}, - {"RGB", "XRGB", 32, ImagingUnpackXRGB}, - {"RGB", "XBGR", 32, ImagingUnpackXBGR}, - {"RGB", "YCC;P", 24, ImagingUnpackYCC}, - {"RGB", "R", 8, band0}, - {"RGB", "G", 8, band1}, - {"RGB", "B", 8, band2}, - {"RGB", "R;16L", 16, band016L}, - {"RGB", "G;16L", 16, band116L}, - {"RGB", "B;16L", 16, band216L}, - {"RGB", "R;16B", 16, band016B}, - {"RGB", "G;16B", 16, band116B}, - {"RGB", "B;16B", 16, band216B}, - {"RGB", "CMYK", 32, cmyk2rgb}, - - {"BGR;15", "BGR;15", 16, copy2}, - {"BGR;16", "BGR;16", 16, copy2}, - {"BGR;24", "BGR;24", 24, copy3}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB, 24, ImagingUnpackRGB}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB_L, 24, unpackRGBL}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB_R, 24, unpackRGBR}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB_16L, 48, unpackRGB16L}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB_16B, 48, unpackRGB16B}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_BGR, 24, ImagingUnpackBGR}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB_15, 16, ImagingUnpackRGB15}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_BGR_15, 16, ImagingUnpackBGR15}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB_16, 16, ImagingUnpackRGB16}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_BGR_16, 16, ImagingUnpackBGR16}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBX_16L, 64, unpackRGBA16L}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBX_16B, 64, unpackRGBA16B}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB_4B, 16, ImagingUnpackRGB4B}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_BGR_5, 16, ImagingUnpackBGR15}, /* compat */ + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBX, 32, copy4}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBX_L, 32, unpackRGBAL}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBXX, 40, copy4skip1}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBXXX, 48, copy4skip2}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBA_L, 32, unpackRGBAL}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGBA_15, 16, ImagingUnpackRGBA15}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_BGRX, 32, ImagingUnpackBGRX}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_BGXR, 32, ImagingUnpackBGXR}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_XRGB, 32, ImagingUnpackXRGB}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_XBGR, 32, ImagingUnpackXBGR}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_YCC_P, 24, ImagingUnpackYCC}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_R, 8, band0}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_G, 8, band1}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_B, 8, band2}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_R_16L, 16, band016L}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_G_16L, 16, band116L}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_B_16L, 16, band216L}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_R_16B, 16, band016B}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_G_16B, 16, band116B}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_B_16B, 16, band216B}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_CMYK, 32, cmyk2rgb}, + + {IMAGING_MODE_BGR_15, IMAGING_RAWMODE_BGR_15, 16, copy2}, + {IMAGING_MODE_BGR_16, IMAGING_RAWMODE_BGR_16, 16, copy2}, + {IMAGING_MODE_BGR_24, IMAGING_RAWMODE_BGR_24, 24, copy3}, /* true colour w. alpha */ - {"RGBA", "LA", 16, unpackRGBALA}, - {"RGBA", "LA;16B", 32, unpackRGBALA16B}, - {"RGBA", "RGBA", 32, copy4}, - {"RGBA", "RGBAX", 40, copy4skip1}, - {"RGBA", "RGBAXX", 48, copy4skip2}, - {"RGBA", "RGBa", 32, unpackRGBa}, - {"RGBA", "RGBaX", 40, unpackRGBaskip1}, - {"RGBA", "RGBaXX", 48, unpackRGBaskip2}, - {"RGBA", "RGBa;16L", 64, unpackRGBa16L}, - {"RGBA", "RGBa;16B", 64, unpackRGBa16B}, - {"RGBA", "BGRa", 32, unpackBGRa}, - {"RGBA", "RGBA;I", 32, unpackRGBAI}, - {"RGBA", "RGBA;L", 32, unpackRGBAL}, - {"RGBA", "RGBA;15", 16, ImagingUnpackRGBA15}, - {"RGBA", "BGRA;15", 16, ImagingUnpackBGRA15}, - {"RGBA", "BGRA;15Z", 16, ImagingUnpackBGRA15Z}, - {"RGBA", "RGBA;4B", 16, ImagingUnpackRGBA4B}, - {"RGBA", "RGBA;16L", 64, unpackRGBA16L}, - {"RGBA", "RGBA;16B", 64, unpackRGBA16B}, - {"RGBA", "BGRA", 32, unpackBGRA}, - {"RGBA", "BGRA;16L", 64, unpackBGRA16L}, - {"RGBA", "BGRA;16B", 64, unpackBGRA16B}, - {"RGBA", "BGAR", 32, unpackBGAR}, - {"RGBA", "ARGB", 32, unpackARGB}, - {"RGBA", "ABGR", 32, unpackABGR}, - {"RGBA", "YCCA;P", 32, ImagingUnpackYCCA}, - {"RGBA", "R", 8, band0}, - {"RGBA", "G", 8, band1}, - {"RGBA", "B", 8, band2}, - {"RGBA", "A", 8, band3}, - {"RGBA", "R;16L", 16, band016L}, - {"RGBA", "G;16L", 16, band116L}, - {"RGBA", "B;16L", 16, band216L}, - {"RGBA", "A;16L", 16, band316L}, - {"RGBA", "R;16B", 16, band016B}, - {"RGBA", "G;16B", 16, band116B}, - {"RGBA", "B;16B", 16, band216B}, - {"RGBA", "A;16B", 16, band316B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_LA, 16, unpackRGBALA}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_LA_16B, 32, unpackRGBALA16B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA, 32, copy4}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBAX, 40, copy4skip1}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBAXX, 48, copy4skip2}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBa, 32, unpackRGBa}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBaX, 40, unpackRGBaskip1}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBaXX, 48, unpackRGBaskip2}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBa_16L, 64, unpackRGBa16L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBa_16B, 64, unpackRGBa16B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGRa, 32, unpackBGRa}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA_I, 32, unpackRGBAI}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA_L, 32, unpackRGBAL}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA_15, 16, ImagingUnpackRGBA15}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGRA_15, 16, ImagingUnpackBGRA15}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGRA_15Z, 16, ImagingUnpackBGRA15Z}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA_4B, 16, ImagingUnpackRGBA4B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA_16L, 64, unpackRGBA16L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA_16B, 64, unpackRGBA16B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGRA, 32, unpackBGRA}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGRA_16L, 64, unpackBGRA16L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGRA_16B, 64, unpackBGRA16B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_BGAR, 32, unpackBGAR}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_ARGB, 32, unpackARGB}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_ABGR, 32, unpackABGR}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_YCCA_P, 32, ImagingUnpackYCCA}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_R, 8, band0}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_G, 8, band1}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_B, 8, band2}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_A, 8, band3}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_R_16L, 16, band016L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_G_16L, 16, band116L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_B_16L, 16, band216L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_A_16L, 16, band316L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_R_16B, 16, band016B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_G_16B, 16, band116B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_B_16B, 16, band216B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_A_16B, 16, band316B}, #ifdef WORDS_BIGENDIAN - {"RGB", "RGB;16N", 48, unpackRGB16B}, - {"RGBA", "RGBa;16N", 64, unpackRGBa16B}, - {"RGBA", "RGBA;16N", 64, unpackRGBA16B}, - {"RGBX", "RGBX;16N", 64, unpackRGBA16B}, - {"RGB", "R;16N", 16, band016B}, - {"RGB", "G;16N", 16, band116B}, - {"RGB", "B;16N", 16, band216B}, - - {"RGBA", "R;16N", 16, band016B}, - {"RGBA", "G;16N", 16, band116B}, - {"RGBA", "B;16N", 16, band216B}, - {"RGBA", "A;16N", 16, band316B}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB_16N, 48, unpackRGB16B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBa_16N, 64, unpackRGBa16B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA_16N, 64, unpackRGBA16B}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBX_16N, 64, unpackRGBA16B}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_R_16N, 16, band016B}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_G_16N, 16, band116B}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_B_16N, 16, band216B}, + + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_R_16N, 16, band016B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_G_16N, 16, band116B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_B_16N, 16, band216B}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_A_16N, 16, band316B}, #else - {"RGB", "RGB;16N", 48, unpackRGB16L}, - {"RGBA", "RGBa;16N", 64, unpackRGBa16L}, - {"RGBA", "RGBA;16N", 64, unpackRGBA16L}, - {"RGBX", "RGBX;16N", 64, unpackRGBA16L}, - {"RGB", "R;16N", 16, band016L}, - {"RGB", "G;16N", 16, band116L}, - {"RGB", "B;16N", 16, band216L}, - - {"RGBA", "R;16N", 16, band016L}, - {"RGBA", "G;16N", 16, band116L}, - {"RGBA", "B;16N", 16, band216L}, - {"RGBA", "A;16N", 16, band316L}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_RGB_16N, 48, unpackRGB16L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBa_16N, 64, unpackRGBa16L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_RGBA_16N, 64, unpackRGBA16L}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBX_16N, 64, unpackRGBA16L}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_R_16N, 16, band016L}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_G_16N, 16, band116L}, + {IMAGING_MODE_RGB, IMAGING_RAWMODE_B_16N, 16, band216L}, + + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_R_16N, 16, band016L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_G_16N, 16, band116L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_B_16N, 16, band216L}, + {IMAGING_MODE_RGBA, IMAGING_RAWMODE_A_16N, 16, band316L}, #endif /* true colour w. alpha premultiplied */ - {"RGBa", "RGBa", 32, copy4}, - {"RGBa", "BGRa", 32, unpackBGRA}, - {"RGBa", "aRGB", 32, unpackARGB}, - {"RGBa", "aBGR", 32, unpackABGR}, + {IMAGING_MODE_RGBa, IMAGING_RAWMODE_RGBa, 32, copy4}, + {IMAGING_MODE_RGBa, IMAGING_RAWMODE_BGRa, 32, unpackBGRA}, + {IMAGING_MODE_RGBa, IMAGING_RAWMODE_aRGB, 32, unpackARGB}, + {IMAGING_MODE_RGBa, IMAGING_RAWMODE_aBGR, 32, unpackABGR}, /* true colour w. padding */ - {"RGBX", "RGB", 24, ImagingUnpackRGB}, - {"RGBX", "RGB;L", 24, unpackRGBL}, - {"RGBX", "RGB;16B", 48, unpackRGB16B}, - {"RGBX", "BGR", 24, ImagingUnpackBGR}, - {"RGBX", "RGB;15", 16, ImagingUnpackRGB15}, - {"RGBX", "BGR;15", 16, ImagingUnpackBGR15}, - {"RGBX", "RGB;4B", 16, ImagingUnpackRGB4B}, - {"RGBX", "BGR;5", 16, ImagingUnpackBGR15}, /* compat */ - {"RGBX", "RGBX", 32, copy4}, - {"RGBX", "RGBXX", 40, copy4skip1}, - {"RGBX", "RGBXXX", 48, copy4skip2}, - {"RGBX", "RGBX;L", 32, unpackRGBAL}, - {"RGBX", "RGBX;16L", 64, unpackRGBA16L}, - {"RGBX", "RGBX;16B", 64, unpackRGBA16B}, - {"RGBX", "BGRX", 32, ImagingUnpackBGRX}, - {"RGBX", "XRGB", 32, ImagingUnpackXRGB}, - {"RGBX", "XBGR", 32, ImagingUnpackXBGR}, - {"RGBX", "YCC;P", 24, ImagingUnpackYCC}, - {"RGBX", "R", 8, band0}, - {"RGBX", "G", 8, band1}, - {"RGBX", "B", 8, band2}, - {"RGBX", "X", 8, band3}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGB, 24, ImagingUnpackRGB}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGB_L, 24, unpackRGBL}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGB_16B, 48, unpackRGB16B}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_BGR, 24, ImagingUnpackBGR}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGB_15, 16, ImagingUnpackRGB15}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_BGR_15, 16, ImagingUnpackBGR15}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGB_4B, 16, ImagingUnpackRGB4B}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_BGR_5, 16, ImagingUnpackBGR15}, /* compat */ + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBX, 32, copy4}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBXX, 40, copy4skip1}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBXXX, 48, copy4skip2}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBX_L, 32, unpackRGBAL}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBX_16L, 64, unpackRGBA16L}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_RGBX_16B, 64, unpackRGBA16B}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_BGRX, 32, ImagingUnpackBGRX}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_XRGB, 32, ImagingUnpackXRGB}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_XBGR, 32, ImagingUnpackXBGR}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_YCC_P, 24, ImagingUnpackYCC}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_R, 8, band0}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_G, 8, band1}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_B, 8, band2}, + {IMAGING_MODE_RGBX, IMAGING_RAWMODE_X, 8, band3}, /* colour separation */ - {"CMYK", "CMYK", 32, copy4}, - {"CMYK", "CMYKX", 40, copy4skip1}, - {"CMYK", "CMYKXX", 48, copy4skip2}, - {"CMYK", "CMYK;I", 32, unpackCMYKI}, - {"CMYK", "CMYK;L", 32, unpackRGBAL}, - {"CMYK", "CMYK;16L", 64, unpackRGBA16L}, - {"CMYK", "CMYK;16B", 64, unpackRGBA16B}, - {"CMYK", "C", 8, band0}, - {"CMYK", "M", 8, band1}, - {"CMYK", "Y", 8, band2}, - {"CMYK", "K", 8, band3}, - {"CMYK", "C;I", 8, band0I}, - {"CMYK", "M;I", 8, band1I}, - {"CMYK", "Y;I", 8, band2I}, - {"CMYK", "K;I", 8, band3I}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK, 32, copy4}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYKX, 40, copy4skip1}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYKXX, 48, copy4skip2}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK_I, 32, unpackCMYKI}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK_L, 32, unpackRGBAL}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK_16L, 64, unpackRGBA16L}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK_16B, 64, unpackRGBA16B}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_C, 8, band0}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_M, 8, band1}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_Y, 8, band2}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_K, 8, band3}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_C_I, 8, band0I}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_M_I, 8, band1I}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_Y_I, 8, band2I}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_K_I, 8, band3I}, #ifdef WORDS_BIGENDIAN - {"CMYK", "CMYK;16N", 64, unpackRGBA16B}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK_16N, 64, unpackRGBA16B}, #else - {"CMYK", "CMYK;16N", 64, unpackRGBA16L}, + {IMAGING_MODE_CMYK, IMAGING_RAWMODE_CMYK_16N, 64, unpackRGBA16L}, #endif /* video (YCbCr) */ - {"YCbCr", "YCbCr", 24, ImagingUnpackRGB}, - {"YCbCr", "YCbCr;L", 24, unpackRGBL}, - {"YCbCr", "YCbCrX", 32, copy4}, - {"YCbCr", "YCbCrK", 32, copy4}, + {IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCr, 24, ImagingUnpackRGB}, + {IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCr_L, 24, unpackRGBL}, + {IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCrX, 32, copy4}, + {IMAGING_MODE_YCbCr, IMAGING_RAWMODE_YCbCrK, 32, copy4}, /* LAB Color */ - {"LAB", "LAB", 24, ImagingUnpackLAB}, - {"LAB", "L", 8, band0}, - {"LAB", "A", 8, band1}, - {"LAB", "B", 8, band2}, + {IMAGING_MODE_LAB, IMAGING_RAWMODE_LAB, 24, ImagingUnpackLAB}, + {IMAGING_MODE_LAB, IMAGING_RAWMODE_L, 8, band0}, + {IMAGING_MODE_LAB, IMAGING_RAWMODE_A, 8, band1}, + {IMAGING_MODE_LAB, IMAGING_RAWMODE_B, 8, band2}, /* HSV Color */ - {"HSV", "HSV", 24, ImagingUnpackRGB}, - {"HSV", "H", 8, band0}, - {"HSV", "S", 8, band1}, - {"HSV", "V", 8, band2}, + {IMAGING_MODE_HSV, IMAGING_RAWMODE_HSV, 24, ImagingUnpackRGB}, + {IMAGING_MODE_HSV, IMAGING_RAWMODE_H, 8, band0}, + {IMAGING_MODE_HSV, IMAGING_RAWMODE_S, 8, band1}, + {IMAGING_MODE_HSV, IMAGING_RAWMODE_V, 8, band2}, /* integer variations */ - {"I", "I", 32, copy4}, - {"I", "I;8", 8, unpackI8}, - {"I", "I;8S", 8, unpackI8S}, - {"I", "I;16", 16, unpackI16}, - {"I", "I;16S", 16, unpackI16S}, - {"I", "I;16B", 16, unpackI16B}, - {"I", "I;16BS", 16, unpackI16BS}, - {"I", "I;16N", 16, unpackI16N}, - {"I", "I;16NS", 16, unpackI16NS}, - {"I", "I;32", 32, unpackI32}, - {"I", "I;32S", 32, unpackI32S}, - {"I", "I;32B", 32, unpackI32B}, - {"I", "I;32BS", 32, unpackI32BS}, - {"I", "I;32N", 32, unpackI32N}, - {"I", "I;32NS", 32, unpackI32NS}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I, 32, copy4}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_8, 8, unpackI8}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_8S, 8, unpackI8S}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_16, 16, unpackI16}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_16S, 16, unpackI16S}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_16B, 16, unpackI16B}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_16BS, 16, unpackI16BS}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_16N, 16, unpackI16N}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_16NS, 16, unpackI16NS}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_32, 32, unpackI32}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_32S, 32, unpackI32S}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_32B, 32, unpackI32B}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_32BS, 32, unpackI32BS}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_32N, 32, unpackI32N}, + {IMAGING_MODE_I, IMAGING_RAWMODE_I_32NS, 32, unpackI32NS}, /* floating point variations */ - {"F", "F", 32, copy4}, - {"F", "F;8", 8, unpackF8}, - {"F", "F;8S", 8, unpackF8S}, - {"F", "F;16", 16, unpackF16}, - {"F", "F;16S", 16, unpackF16S}, - {"F", "F;16B", 16, unpackF16B}, - {"F", "F;16BS", 16, unpackF16BS}, - {"F", "F;16N", 16, unpackF16N}, - {"F", "F;16NS", 16, unpackF16NS}, - {"F", "F;32", 32, unpackF32}, - {"F", "F;32S", 32, unpackF32S}, - {"F", "F;32B", 32, unpackF32B}, - {"F", "F;32BS", 32, unpackF32BS}, - {"F", "F;32N", 32, unpackF32N}, - {"F", "F;32NS", 32, unpackF32NS}, - {"F", "F;32F", 32, unpackF32F}, - {"F", "F;32BF", 32, unpackF32BF}, - {"F", "F;32NF", 32, unpackF32NF}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F, 32, copy4}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_8, 8, unpackF8}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_8S, 8, unpackF8S}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_16, 16, unpackF16}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_16S, 16, unpackF16S}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_16B, 16, unpackF16B}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_16BS, 16, unpackF16BS}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_16N, 16, unpackF16N}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_16NS, 16, unpackF16NS}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_32, 32, unpackF32}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_32S, 32, unpackF32S}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_32B, 32, unpackF32B}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_32BS, 32, unpackF32BS}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_32N, 32, unpackF32N}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_32NS, 32, unpackF32NS}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_32F, 32, unpackF32F}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_32BF, 32, unpackF32BF}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_32NF, 32, unpackF32NF}, #ifdef FLOAT64 - {"F", "F;64F", 64, unpackF64F}, - {"F", "F;64BF", 64, unpackF64BF}, - {"F", "F;64NF", 64, unpackF64NF}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_64F, 64, unpackF64F}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_64BF, 64, unpackF64BF}, + {IMAGING_MODE_F, IMAGING_RAWMODE_F_64NF, 64, unpackF64NF}, #endif /* storage modes */ - {"I;16", "I;16", 16, copy2}, - {"I;16B", "I;16B", 16, copy2}, - {"I;16L", "I;16L", 16, copy2}, - {"I;16N", "I;16N", 16, copy2}, - - {"I;16", "I;16B", 16, unpackI16B_I16}, - {"I;16", "I;16N", 16, unpackI16N_I16}, // LibTiff native->image endian. - {"I;16L", "I;16N", 16, unpackI16N_I16}, // LibTiff native->image endian. - {"I;16B", "I;16N", 16, unpackI16N_I16B}, - - {"I;16", "I;16R", 16, unpackI16R_I16}, - - {"I;16", "I;12", 12, unpackI12_I16}, // 12 bit Tiffs stored in 16bits. - - {NULL} /* sentinel */ + {IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16, 16, copy2}, + {IMAGING_MODE_I_16B, IMAGING_RAWMODE_I_16B, 16, copy2}, + {IMAGING_MODE_I_16L, IMAGING_RAWMODE_I_16L, 16, copy2}, + {IMAGING_MODE_I_16N, IMAGING_RAWMODE_I_16N, 16, copy2}, + + {IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16B, 16, unpackI16B_I16}, + {IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16N, 16, unpackI16N_I16 + }, // LibTiff native->image endian. + {IMAGING_MODE_I_16L, IMAGING_RAWMODE_I_16N, 16, unpackI16N_I16 + }, // LibTiff native->image endian. + {IMAGING_MODE_I_16B, IMAGING_RAWMODE_I_16N, 16, unpackI16N_I16B}, + + {IMAGING_MODE_I_16, IMAGING_RAWMODE_I_16R, 16, unpackI16R_I16}, + + {IMAGING_MODE_I_16, IMAGING_RAWMODE_I_12, 12, unpackI12_I16 + } // 12 bit Tiffs stored in 16bits. }; ImagingShuffler -ImagingFindUnpacker(const char *mode, const char *rawmode, int *bits_out) { - int i; - - /* find a suitable pixel unpacker */ - for (i = 0; unpackers[i].rawmode; i++) { - if (strcmp(unpackers[i].mode, mode) == 0 && - strcmp(unpackers[i].rawmode, rawmode) == 0) { +ImagingFindUnpacker(const ModeID mode, const RawModeID rawmode, int *bits_out) { + for (size_t i = 0; i < sizeof(unpackers) / sizeof(*unpackers); i++) { + if (unpackers[i].mode == mode && unpackers[i].rawmode == rawmode) { if (bits_out) { *bits_out = unpackers[i].bits; } diff --git a/src/map.c b/src/map.c index c66702981d3..d347f6c0d23 100644 --- a/src/map.c +++ b/src/map.c @@ -55,7 +55,7 @@ PyImaging_MapBuffer(PyObject *self, PyObject *args) { PyObject *target; Py_buffer view; - char *mode; + char *mode_name; char *codec; Py_ssize_t offset; int xsize, ysize; @@ -70,7 +70,7 @@ PyImaging_MapBuffer(PyObject *self, PyObject *args) { &ysize, &codec, &offset, - &mode, + &mode_name, &stride, &ystep )) { @@ -82,10 +82,12 @@ PyImaging_MapBuffer(PyObject *self, PyObject *args) { return NULL; } + const ModeID mode = findModeID(mode_name); + if (stride <= 0) { - if (!strcmp(mode, "L") || !strcmp(mode, "P")) { + if (mode == IMAGING_MODE_L || mode == IMAGING_MODE_P) { stride = xsize; - } else if (!strncmp(mode, "I;16", 4)) { + } else if (isModeI16(mode)) { stride = xsize * 2; } else { stride = xsize * 4;