Merge branch 'main' into types/fromarray

This commit is contained in:
Andrew Murray 2024-04-07 08:32:48 +10:00 committed by GitHub
commit 84238bd459
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 96 additions and 86 deletions

View File

@ -1,9 +1,9 @@
skip_commits: skip_commits:
files: files:
- ".github/**" - ".github/**/*"
- ".gitmodules" - ".gitmodules"
- "docs/**" - "docs/**/*"
- "wheels/**" - "wheels/**/*"
version: '{build}' version: '{build}'
clone_folder: c:\pillow clone_folder: c:\pillow

View File

@ -289,6 +289,16 @@ def test_rgba(ext: str) -> None:
assert im.mode == "RGBA" assert im.mode == "RGBA"
@pytest.mark.skipif(
not os.path.exists(EXTRA_DIR), reason="Extra image files not installed"
)
@skip_unless_feature_version("jpg_2000", "2.5.1")
def test_cmyk() -> None:
with Image.open(f"{EXTRA_DIR}/issue205.jp2") as im:
assert im.mode == "CMYK"
assert im.getpixel((0, 0)) == (185, 134, 0, 0)
@pytest.mark.parametrize("ext", (".j2k", ".jp2")) @pytest.mark.parametrize("ext", (".j2k", ".jp2"))
def test_16bit_monochrome_has_correct_mode(ext: str) -> None: def test_16bit_monochrome_has_correct_mode(ext: str) -> None:
with Image.open("Tests/images/16bit.cropped" + ext) as im: with Image.open("Tests/images/16bit.cropped" + ext) as im:

View File

@ -14,7 +14,7 @@ def test_sanity() -> None:
assert data[0] == (20, 20, 70) assert data[0] == (20, 20, 70)
def test_roundtrip() -> None: def test_mode() -> None:
def getdata(mode: str) -> tuple[float | tuple[int, ...], int, int]: def getdata(mode: str) -> tuple[float | tuple[int, ...], int, int]:
im = hopper(mode).resize((32, 30), Image.Resampling.NEAREST) im = hopper(mode).resize((32, 30), Image.Resampling.NEAREST)
data = im.getdata() data = im.getdata()

View File

@ -1488,7 +1488,9 @@ QOI
.. versionadded:: 9.5.0 .. versionadded:: 9.5.0
Pillow identifies and reads images in Quite OK Image format. Pillow reads images in Quite OK Image format using a Python decoder. If you wish to
write code specifically for this format, :pypi:`qoi` is an alternative library that
uses C to decode the image and interfaces with NumPy.
SUN SUN
^^^ ^^^

View File

@ -241,7 +241,7 @@ class BLPFormatError(NotImplementedError):
pass pass
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] in (b"BLP1", b"BLP2") return prefix[:4] in (b"BLP1", b"BLP2")

View File

@ -48,7 +48,7 @@ BIT2MODE = {
} }
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:2] == b"BM" return prefix[:2] == b"BM"

View File

@ -29,7 +29,7 @@ def register_handler(handler):
# Image adapter # Image adapter
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] == b"BUFR" or prefix[:4] == b"ZCZC" return prefix[:4] == b"BUFR" or prefix[:4] == b"ZCZC"

View File

@ -25,7 +25,7 @@ from ._binary import i32le as i32
# -------------------------------------------------------------------- # --------------------------------------------------------------------
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] == b"\0\0\2\0" return prefix[:4] == b"\0\0\2\0"

View File

@ -29,7 +29,7 @@ from .PcxImagePlugin import PcxImageFile
MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then? MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then?
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return len(prefix) >= 4 and i32(prefix) == MAGIC return len(prefix) >= 4 and i32(prefix) == MAGIC

View File

@ -562,7 +562,7 @@ def _save(im, fp, filename):
) )
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] == b"DDS " return prefix[:4] == b"DDS "

View File

@ -195,7 +195,7 @@ class PSFile:
return b"".join(s).decode("latin-1") return b"".join(s).decode("latin-1")
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] == b"%!PS" or (len(prefix) >= 4 and i32(prefix) == 0xC6D3D0C5) return prefix[:4] == b"%!PS" or (len(prefix) >= 4 and i32(prefix) == 0xC6D3D0C5)

View File

@ -27,7 +27,7 @@ from ._binary import o8
# decoder # decoder
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return ( return (
len(prefix) >= 6 len(prefix) >= 6
and i16(prefix, 4) in [0xAF11, 0xAF12] and i16(prefix, 4) in [0xAF11, 0xAF12]

View File

@ -41,7 +41,7 @@ MODES = {
# -------------------------------------------------------------------- # --------------------------------------------------------------------
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:8] == olefile.MAGIC return prefix[:8] == olefile.MAGIC

View File

@ -107,7 +107,7 @@ class FtexImageFile(ImageFile.ImageFile):
pass pass
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] == MAGIC return prefix[:4] == MAGIC

View File

@ -29,7 +29,7 @@ from . import Image, ImageFile
from ._binary import i32be as i32 from ._binary import i32be as i32
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return len(prefix) >= 8 and i32(prefix, 0) >= 20 and i32(prefix, 4) in (1, 2) return len(prefix) >= 8 and i32(prefix, 0) >= 20 and i32(prefix, 4) in (1, 2)

View File

@ -60,7 +60,7 @@ LOADING_STRATEGY = LoadingStrategy.RGB_AFTER_FIRST
# Identify/read GIF files # Identify/read GIF files
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:6] in [b"GIF87a", b"GIF89a"] return prefix[:6] in [b"GIF87a", b"GIF89a"]

View File

@ -29,7 +29,7 @@ def register_handler(handler):
# Image adapter # Image adapter
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] == b"GRIB" and prefix[7] == 1 return prefix[:4] == b"GRIB" and prefix[7] == 1

View File

@ -29,7 +29,7 @@ def register_handler(handler):
# Image adapter # Image adapter
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:8] == b"\x89HDF\r\n\x1a\n" return prefix[:8] == b"\x89HDF\r\n\x1a\n"

View File

@ -374,7 +374,7 @@ def _save(im, fp, filename):
fp.flush() fp.flush()
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] == MAGIC return prefix[:4] == MAGIC

View File

@ -114,7 +114,7 @@ def _save(im, fp, filename):
fp.seek(current) fp.seek(current)
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] == _MAGIC return prefix[:4] == _MAGIC

View File

@ -41,7 +41,7 @@ import warnings
from collections.abc import Callable, MutableMapping from collections.abc import Callable, MutableMapping
from enum import IntEnum from enum import IntEnum
from types import ModuleType from types import ModuleType
from typing import IO, TYPE_CHECKING, Any, Protocol from typing import IO, TYPE_CHECKING, Any, Literal, Protocol, cast
# VERSION was removed in Pillow 6.0.0. # VERSION was removed in Pillow 6.0.0.
# PILLOW_VERSION was removed in Pillow 9.0.0. # PILLOW_VERSION was removed in Pillow 9.0.0.
@ -55,7 +55,7 @@ from . import (
_plugins, _plugins,
) )
from ._binary import i32le, o32be, o32le from ._binary import i32le, o32be, o32le
from ._typing import TypeGuard from ._typing import StrOrBytesPath, TypeGuard
from ._util import DeferredError, is_path from ._util import DeferredError, is_path
ElementTree: ModuleType | None ElementTree: ModuleType | None
@ -223,7 +223,7 @@ OPEN: dict[
str, str,
tuple[ tuple[
Callable[[IO[bytes], str | bytes], ImageFile.ImageFile], Callable[[IO[bytes], str | bytes], ImageFile.ImageFile],
Callable[[bytes], bool] | None, Callable[[bytes], bool | str] | None,
], ],
] = {} ] = {}
MIME: dict[str, str] = {} MIME: dict[str, str] = {}
@ -357,7 +357,7 @@ def preinit() -> None:
_initialized = 1 _initialized = 1
def init(): def init() -> bool:
""" """
Explicitly initializes the Python Imaging Library. This function Explicitly initializes the Python Imaging Library. This function
loads all available file format drivers. loads all available file format drivers.
@ -368,7 +368,7 @@ def init():
global _initialized global _initialized
if _initialized >= 2: if _initialized >= 2:
return 0 return False
parent_name = __name__.rpartition(".")[0] parent_name = __name__.rpartition(".")[0]
for plugin in _plugins: for plugin in _plugins:
@ -380,7 +380,8 @@ def init():
if OPEN or SAVE: if OPEN or SAVE:
_initialized = 2 _initialized = 2
return 1 return True
return False
# -------------------------------------------------------------------- # --------------------------------------------------------------------
@ -2373,7 +2374,9 @@ class Image:
(w, h), Transform.AFFINE, matrix, resample, fillcolor=fillcolor (w, h), Transform.AFFINE, matrix, resample, fillcolor=fillcolor
) )
def save(self, fp, format=None, **params) -> None: def save(
self, fp: StrOrBytesPath | IO[bytes], format: str | None = None, **params: Any
) -> None:
""" """
Saves this image under the given filename. If no format is Saves this image under the given filename. If no format is
specified, the format to use is determined from the filename specified, the format to use is determined from the filename
@ -2454,6 +2457,8 @@ class Image:
fp = builtins.open(filename, "r+b") fp = builtins.open(filename, "r+b")
else: else:
fp = builtins.open(filename, "w+b") fp = builtins.open(filename, "w+b")
else:
fp = cast(IO[bytes], fp)
try: try:
save_handler(self, fp, filename) save_handler(self, fp, filename)
@ -3233,7 +3238,11 @@ def _decompression_bomb_check(size: tuple[int, int]) -> None:
) )
def open(fp, mode="r", formats=None) -> Image: def open(
fp: StrOrBytesPath | IO[bytes],
mode: Literal["r"] = "r",
formats: list[str] | tuple[str, ...] | None = None,
) -> ImageFile.ImageFile:
""" """
Opens and identifies the given image file. Opens and identifies the given image file.
@ -3264,10 +3273,10 @@ def open(fp, mode="r", formats=None) -> Image:
""" """
if mode != "r": if mode != "r":
msg = f"bad mode {repr(mode)}" msg = f"bad mode {repr(mode)}" # type: ignore[unreachable]
raise ValueError(msg) raise ValueError(msg)
elif isinstance(fp, io.StringIO): elif isinstance(fp, io.StringIO):
msg = ( msg = ( # type: ignore[unreachable]
"StringIO cannot be used to open an image. " "StringIO cannot be used to open an image. "
"Binary data must be used instead." "Binary data must be used instead."
) )
@ -3276,7 +3285,7 @@ def open(fp, mode="r", formats=None) -> Image:
if formats is None: if formats is None:
formats = ID formats = ID
elif not isinstance(formats, (list, tuple)): elif not isinstance(formats, (list, tuple)):
msg = "formats must be a list or tuple" msg = "formats must be a list or tuple" # type: ignore[unreachable]
raise TypeError(msg) raise TypeError(msg)
exclusive_fp = False exclusive_fp = False
@ -3287,6 +3296,8 @@ def open(fp, mode="r", formats=None) -> Image:
if filename: if filename:
fp = builtins.open(filename, "rb") fp = builtins.open(filename, "rb")
exclusive_fp = True exclusive_fp = True
else:
fp = cast(IO[bytes], fp)
try: try:
fp.seek(0) fp.seek(0)
@ -3298,9 +3309,14 @@ def open(fp, mode="r", formats=None) -> Image:
preinit() preinit()
accept_warnings = [] accept_warnings: list[str] = []
def _open_core(fp, filename, prefix, formats): def _open_core(
fp: IO[bytes],
filename: str | bytes,
prefix: bytes,
formats: list[str] | tuple[str, ...],
) -> ImageFile.ImageFile | None:
for i in formats: for i in formats:
i = i.upper() i = i.upper()
if i not in OPEN: if i not in OPEN:
@ -3308,7 +3324,7 @@ def open(fp, mode="r", formats=None) -> Image:
try: try:
factory, accept = OPEN[i] factory, accept = OPEN[i]
result = not accept or accept(prefix) result = not accept or accept(prefix)
if type(result) in [str, bytes]: if isinstance(result, str):
accept_warnings.append(result) accept_warnings.append(result)
elif result: elif result:
fp.seek(0) fp.seek(0)
@ -3329,7 +3345,7 @@ def open(fp, mode="r", formats=None) -> Image:
im = _open_core(fp, filename, prefix, formats) im = _open_core(fp, filename, prefix, formats)
if im is None and formats is ID: if im is None and formats is ID:
checked_formats = formats.copy() checked_formats = ID.copy()
if init(): if init():
im = _open_core( im = _open_core(
fp, fp,
@ -3459,7 +3475,7 @@ def merge(mode, bands):
def register_open( def register_open(
id, id,
factory: Callable[[IO[bytes], str | bytes], ImageFile.ImageFile], factory: Callable[[IO[bytes], str | bytes], ImageFile.ImageFile],
accept: Callable[[bytes], bool] | None = None, accept: Callable[[bytes], bool | str] | None = None,
) -> None: ) -> None:
""" """
Register an image file plugin. This function should not be used Register an image file plugin. This function should not be used

View File

@ -704,12 +704,12 @@ def applyTransform(
""" """
(pyCMS) Applies a transform to a given image. (pyCMS) Applies a transform to a given image.
If ``im.mode != transform.inMode``, a :exc:`PyCMSError` is raised. If ``im.mode != transform.input_mode``, a :exc:`PyCMSError` is raised.
If ``inPlace`` is ``True`` and ``transform.inMode != transform.outMode``, a If ``inPlace`` is ``True`` and ``transform.input_mode != transform.output_mode``, a
:exc:`PyCMSError` is raised. :exc:`PyCMSError` is raised.
If ``im.mode``, ``transform.inMode`` or ``transform.outMode`` is not If ``im.mode``, ``transform.input_mode`` or ``transform.output_mode`` is not
supported by pyCMSdll or the profiles you used for the transform, a supported by pyCMSdll or the profiles you used for the transform, a
:exc:`PyCMSError` is raised. :exc:`PyCMSError` is raised.
@ -723,13 +723,13 @@ def applyTransform(
If you want to modify im in-place instead of receiving a new image as If you want to modify im in-place instead of receiving a new image as
the return value, set ``inPlace`` to ``True``. This can only be done if the return value, set ``inPlace`` to ``True``. This can only be done if
``transform.inMode`` and ``transform.outMode`` are the same, because we can't ``transform.input_mode`` and ``transform.output_mode`` are the same, because we
change the mode in-place (the buffer sizes for some modes are can't change the mode in-place (the buffer sizes for some modes are
different). The default behavior is to return a new :py:class:`~PIL.Image.Image` different). The default behavior is to return a new :py:class:`~PIL.Image.Image`
object of the same dimensions in mode ``transform.outMode``. object of the same dimensions in mode ``transform.output_mode``.
:param im: An :py:class:`~PIL.Image.Image` object, and im.mode must be the same :param im: An :py:class:`~PIL.Image.Image` object, and ``im.mode`` must be the same
as the ``inMode`` supported by the transform. as the ``input_mode`` supported by the transform.
:param transform: A valid CmsTransform class object :param transform: A valid CmsTransform class object
:param inPlace: Bool. If ``True``, ``im`` is modified in place and ``None`` is :param inPlace: Bool. If ``True``, ``im`` is modified in place and ``None`` is
returned, if ``False``, a new :py:class:`~PIL.Image.Image` object with the returned, if ``False``, a new :py:class:`~PIL.Image.Image` object with the

View File

@ -176,6 +176,10 @@ def _parse_jp2_header(fp):
mode = "RGB" mode = "RGB"
elif nc == 4: elif nc == 4:
mode = "RGBA" mode = "RGBA"
elif tbox == b"colr" and nc == 4:
meth, _, _, enumcs = header.read_fields(">BBBI")
if meth == 1 and enumcs == 12:
mode = "CMYK"
elif tbox == b"pclr" and mode in ("L", "LA"): elif tbox == b"pclr" and mode in ("L", "LA"):
ne, npc = header.read_fields(">HB") ne, npc = header.read_fields(">HB")
bitdepths = header.read_fields(">" + ("B" * npc)) bitdepths = header.read_fields(">" + ("B" * npc))
@ -313,7 +317,7 @@ class Jpeg2KImageFile(ImageFile.ImageFile):
return ImageFile.ImageFile.load(self) return ImageFile.ImageFile.load(self)
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return ( return (
prefix[:4] == b"\xff\x4f\xff\x51" prefix[:4] == b"\xff\x4f\xff\x51"
or prefix[:12] == b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a" or prefix[:12] == b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a"

View File

@ -344,7 +344,7 @@ MARKER = {
} }
def _accept(prefix): def _accept(prefix: bytes) -> bool:
# Magic number was taken from https://en.wikipedia.org/wiki/JPEG # Magic number was taken from https://en.wikipedia.org/wiki/JPEG
return prefix[:3] == b"\xFF\xD8\xFF" return prefix[:3] == b"\xFF\xD8\xFF"

View File

@ -25,7 +25,7 @@ from . import Image, TiffImagePlugin
# -------------------------------------------------------------------- # --------------------------------------------------------------------
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:8] == olefile.MAGIC return prefix[:8] == olefile.MAGIC

View File

@ -689,7 +689,7 @@ class PngStream(ChunkStream):
# PNG reader # PNG reader
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:8] == _MAGIC return prefix[:8] == _MAGIC

View File

@ -44,7 +44,7 @@ MODES = {
# read PSD images # read PSD images
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] == b"8BPS" return prefix[:4] == b"8BPS"

View File

@ -13,7 +13,7 @@ from . import Image, ImageFile
from ._binary import i32be as i32 from ._binary import i32be as i32
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] == b"qoif" return prefix[:4] == b"qoif"

View File

@ -277,7 +277,7 @@ PREFIXES = [
] ]
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:4] in PREFIXES return prefix[:4] in PREFIXES

View File

@ -23,7 +23,7 @@ _VP8_MODES_BY_IDENTIFIER = {
} }
def _accept(prefix): def _accept(prefix: bytes) -> bool | str:
is_riff_file_format = prefix[:4] == b"RIFF" is_riff_file_format = prefix[:4] == b"RIFF"
is_webp_file = prefix[8:12] == b"WEBP" is_webp_file = prefix[8:12] == b"WEBP"
is_valid_vp8_mode = prefix[12:16] in _VP8_MODES_BY_IDENTIFIER is_valid_vp8_mode = prefix[12:16] in _VP8_MODES_BY_IDENTIFIER
@ -34,6 +34,7 @@ def _accept(prefix):
"image file could not be identified because WEBP support not installed" "image file could not be identified because WEBP support not installed"
) )
return True return True
return False
class WebPImageFile(ImageFile.ImageFile): class WebPImageFile(ImageFile.ImageFile):

View File

@ -65,7 +65,7 @@ if hasattr(Image.core, "drawwmf"):
# Read WMF file # Read WMF file
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return ( return (
prefix[:6] == b"\xd7\xcd\xc6\x9a\x00\x00" or prefix[:4] == b"\x01\x00\x00\x00" prefix[:6] == b"\xd7\xcd\xc6\x9a\x00\x00" or prefix[:4] == b"\x01\x00\x00\x00"
) )

View File

@ -24,7 +24,7 @@ from ._binary import o8
xpm_head = re.compile(b'"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)') xpm_head = re.compile(b'"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)')
def _accept(prefix): def _accept(prefix: bytes) -> bool:
return prefix[:9] == b"/* XPM */" return prefix[:9] == b"/* XPM */"

View File

@ -108,10 +108,6 @@ class CmsProfile:
def is_intent_supported(self, intent: int, direction: int, /) -> int: ... def is_intent_supported(self, intent: int, direction: int, /) -> int: ...
class CmsTransform: class CmsTransform:
@property
def inputMode(self) -> str: ...
@property
def outputMode(self) -> str: ...
def apply(self, id_in: int, id_out: int) -> int: ... def apply(self, id_in: int, id_out: int) -> int: ...
def profile_open(profile: str, /) -> CmsProfile: ... def profile_open(profile: str, /) -> CmsProfile: ...

View File

@ -181,9 +181,7 @@ cms_profile_dealloc(CmsProfileObject *self) {
/* a transform represents the mapping between two profiles */ /* a transform represents the mapping between two profiles */
typedef struct { typedef struct {
PyObject_HEAD char mode_in[8]; PyObject_HEAD cmsHTRANSFORM transform;
char mode_out[8];
cmsHTRANSFORM transform;
} CmsTransformObject; } CmsTransformObject;
static PyTypeObject CmsTransform_Type; static PyTypeObject CmsTransform_Type;
@ -191,7 +189,7 @@ static PyTypeObject CmsTransform_Type;
#define CmsTransform_Check(op) (Py_TYPE(op) == &CmsTransform_Type) #define CmsTransform_Check(op) (Py_TYPE(op) == &CmsTransform_Type)
static PyObject * static PyObject *
cms_transform_new(cmsHTRANSFORM transform, char *mode_in, char *mode_out) { cms_transform_new(cmsHTRANSFORM transform) {
CmsTransformObject *self; CmsTransformObject *self;
self = PyObject_New(CmsTransformObject, &CmsTransform_Type); self = PyObject_New(CmsTransformObject, &CmsTransform_Type);
@ -201,9 +199,6 @@ cms_transform_new(cmsHTRANSFORM transform, char *mode_in, char *mode_out) {
self->transform = transform; self->transform = transform;
strncpy(self->mode_in, mode_in, 8);
strncpy(self->mode_out, mode_out, 8);
return (PyObject *)self; return (PyObject *)self;
} }
@ -476,7 +471,7 @@ buildTransform(PyObject *self, PyObject *args) {
return NULL; return NULL;
} }
return cms_transform_new(transform, sInMode, sOutMode); return cms_transform_new(transform);
} }
static PyObject * static PyObject *
@ -523,7 +518,7 @@ buildProofTransform(PyObject *self, PyObject *args) {
return NULL; return NULL;
} }
return cms_transform_new(transform, sInMode, sOutMode); return cms_transform_new(transform);
} }
static PyObject * static PyObject *
@ -1456,21 +1451,6 @@ static struct PyMethodDef cms_transform_methods[] = {
{"apply", (PyCFunction)cms_transform_apply, 1}, {NULL, NULL} /* sentinel */ {"apply", (PyCFunction)cms_transform_apply, 1}, {NULL, NULL} /* sentinel */
}; };
static PyObject *
cms_transform_getattr_inputMode(CmsTransformObject *self, void *closure) {
return PyUnicode_FromString(self->mode_in);
}
static PyObject *
cms_transform_getattr_outputMode(CmsTransformObject *self, void *closure) {
return PyUnicode_FromString(self->mode_out);
}
static struct PyGetSetDef cms_transform_getsetters[] = {
{"inputMode", (getter)cms_transform_getattr_inputMode},
{"outputMode", (getter)cms_transform_getattr_outputMode},
{NULL}};
static PyTypeObject CmsTransform_Type = { static PyTypeObject CmsTransform_Type = {
PyVarObject_HEAD_INIT(NULL, 0) "PIL.ImageCms.core.CmsTransform", /*tp_name*/ PyVarObject_HEAD_INIT(NULL, 0) "PIL.ImageCms.core.CmsTransform", /*tp_name*/
sizeof(CmsTransformObject), /*tp_basicsize*/ sizeof(CmsTransformObject), /*tp_basicsize*/
@ -1501,7 +1481,7 @@ static PyTypeObject CmsTransform_Type = {
0, /*tp_iternext*/ 0, /*tp_iternext*/
cms_transform_methods, /*tp_methods*/ cms_transform_methods, /*tp_methods*/
0, /*tp_members*/ 0, /*tp_members*/
cms_transform_getsetters, /*tp_getset*/ 0, /*tp_getset*/
}; };
static int static int

View File

@ -632,6 +632,7 @@ static const struct j2k_decode_unpacker j2k_unpackers[] = {
{"RGBA", OPJ_CLRSPC_SYCC, 3, 1, j2ku_sycc_rgb}, {"RGBA", OPJ_CLRSPC_SYCC, 3, 1, j2ku_sycc_rgb},
{"RGBA", OPJ_CLRSPC_SRGB, 4, 1, j2ku_srgba_rgba}, {"RGBA", OPJ_CLRSPC_SRGB, 4, 1, j2ku_srgba_rgba},
{"RGBA", OPJ_CLRSPC_SYCC, 4, 1, j2ku_sycca_rgba}, {"RGBA", OPJ_CLRSPC_SYCC, 4, 1, j2ku_sycca_rgba},
{"CMYK", OPJ_CLRSPC_CMYK, 4, 1, j2ku_srgba_rgba},
}; };
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */