Merge branch 'main' into multiband

This commit is contained in:
Andrew Murray 2024-07-19 22:28:46 +10:00 committed by GitHub
commit b6ce6ab137
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
95 changed files with 3083 additions and 957 deletions

View File

@ -3,7 +3,7 @@
BasedOnStyle: Google BasedOnStyle: Google
AlwaysBreakAfterReturnType: All AlwaysBreakAfterReturnType: All
AllowShortIfStatementsOnASingleLine: false AllowShortIfStatementsOnASingleLine: false
AlignAfterOpenBracket: AlwaysBreak AlignAfterOpenBracket: BlockIndent
BinPackArguments: false BinPackArguments: false
BinPackParameters: false BinPackParameters: false
BreakBeforeBraces: Attach BreakBeforeBraces: Attach

View File

@ -24,6 +24,8 @@ concurrency:
jobs: jobs:
Fuzzing: Fuzzing:
# Disabled until google/oss-fuzz#11419 upgrades Python to 3.9+
if: false
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Build Fuzzers - name: Build Fuzzers

View File

@ -12,8 +12,14 @@ elif [ "${AUDITWHEEL_POLICY::9}" == "musllinux" ]; then
else else
yum install -y fribidi yum install -y fribidi
fi fi
if [ "${AUDITWHEEL_POLICY::9}" != "musllinux" ]; then if [ "${AUDITWHEEL_POLICY::9}" != "musllinux" ]; then
# TODO Update condition when NumPy supports free-threading
if [ $(python3 -c "import sysconfig;print(sysconfig.get_config_var('Py_GIL_DISABLED'))") == "1" ]; then
python3 -m pip install numpy --index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple
else
python3 -m pip install numpy python3 -m pip install numpy
fi
fi fi
if [ ! -d "test-images-main" ]; then if [ ! -d "test-images-main" ]; then

View File

@ -1,6 +1,14 @@
name: Wheels name: Wheels
on: on:
schedule:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
# │ │ │ │ │
- cron: "42 1 * * 0,3"
push: push:
paths: paths:
- ".ci/requirements-cibw.txt" - ".ci/requirements-cibw.txt"
@ -33,6 +41,7 @@ env:
jobs: jobs:
build-1-QEMU-emulated-wheels: build-1-QEMU-emulated-wheels:
if: github.event_name != 'schedule' && github.event_name != 'workflow_dispatch'
name: aarch64 ${{ matrix.python-version }} ${{ matrix.spec }} name: aarch64 ${{ matrix.python-version }} ${{ matrix.spec }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
@ -129,6 +138,7 @@ jobs:
env: env:
CIBW_ARCHS: ${{ matrix.cibw_arch }} CIBW_ARCHS: ${{ matrix.cibw_arch }}
CIBW_BUILD: ${{ matrix.build }} CIBW_BUILD: ${{ matrix.build }}
CIBW_FREE_THREADED_SUPPORT: True
CIBW_MANYLINUX_PYPY_X86_64_IMAGE: ${{ matrix.manylinux }} CIBW_MANYLINUX_PYPY_X86_64_IMAGE: ${{ matrix.manylinux }}
CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux }} CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux }}
CIBW_PRERELEASE_PYTHONS: True CIBW_PRERELEASE_PYTHONS: True
@ -201,6 +211,7 @@ jobs:
CIBW_ARCHS: ${{ matrix.cibw_arch }} CIBW_ARCHS: ${{ matrix.cibw_arch }}
CIBW_BEFORE_ALL: "{package}\\winbuild\\build\\build_dep_all.cmd" CIBW_BEFORE_ALL: "{package}\\winbuild\\build\\build_dep_all.cmd"
CIBW_CACHE_PATH: "C:\\cibw" CIBW_CACHE_PATH: "C:\\cibw"
CIBW_FREE_THREADED_SUPPORT: True
CIBW_PRERELEASE_PYTHONS: True CIBW_PRERELEASE_PYTHONS: True
CIBW_TEST_SKIP: "*-win_arm64" CIBW_TEST_SKIP: "*-win_arm64"
CIBW_TEST_COMMAND: 'docker run --rm CIBW_TEST_COMMAND: 'docker run --rm
@ -225,6 +236,7 @@ jobs:
path: winbuild\build\bin\fribidi* path: winbuild\build\bin\fribidi*
sdist: sdist:
if: github.event_name != 'schedule'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -243,6 +255,23 @@ jobs:
name: dist-sdist name: dist-sdist
path: dist/*.tar.gz path: dist/*.tar.gz
scientific-python-nightly-wheels-publish:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
needs: [build-2-native-wheels, windows]
runs-on: ubuntu-latest
name: Upload wheels to scientific-python-nightly-wheels
steps:
- uses: actions/download-artifact@v4
with:
pattern: dist-*
path: dist
merge-multiple: true
- name: Upload wheels to scientific-python-nightly-wheels
uses: scientific-python/upload-nightly-action@b67d7fcc0396e1128a474d1ab2b48aa94680f9fc # 0.5.0
with:
artifacts_path: dist
anaconda_nightly_upload_token: ${{ secrets.ANACONDA_ORG_UPLOAD_TOKEN }}
pypi-publish: pypi-publish:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
needs: [build-1-QEMU-emulated-wheels, build-2-native-wheels, windows, sdist] needs: [build-1-QEMU-emulated-wheels, build-2-native-wheels, windows, sdist]

View File

@ -5,6 +5,18 @@ Changelog (Pillow)
11.0.0 (unreleased) 11.0.0 (unreleased)
------------------- -------------------
- Deprecate ImageMath lambda_eval and unsafe_eval options argument #8242
[radarhere]
- Changed ContainerIO to subclass IO #8240
[radarhere]
- Move away from APIs that use borrowed references under the free-threaded build #8216
[hugovk, lysnikolaou]
- Allow size argument to resize() to be a NumPy array #8201
[radarhere]
- Drop support for Python 3.8 #8183 - Drop support for Python 3.8 #8183
[hugovk, radarhere] [hugovk, radarhere]

View File

@ -1,7 +1,5 @@
from __future__ import annotations from __future__ import annotations
from typing import Literal
import pytest import pytest
from PIL import ContainerIO, Image from PIL import ContainerIO, Image
@ -23,6 +21,13 @@ def test_isatty() -> None:
assert container.isatty() is False assert container.isatty() is False
def test_seekable() -> None:
with hopper() as im:
container = ContainerIO.ContainerIO(im, 0, 0)
assert container.seekable() is True
@pytest.mark.parametrize( @pytest.mark.parametrize(
"mode, expected_position", "mode, expected_position",
( (
@ -31,7 +36,7 @@ def test_isatty() -> None:
(2, 100), (2, 100),
), ),
) )
def test_seek_mode(mode: Literal[0, 1, 2], expected_position: int) -> None: def test_seek_mode(mode: int, expected_position: int) -> None:
# Arrange # Arrange
with open(TEST_FILE, "rb") as fh: with open(TEST_FILE, "rb") as fh:
container = ContainerIO.ContainerIO(fh, 22, 100) container = ContainerIO.ContainerIO(fh, 22, 100)
@ -44,6 +49,14 @@ def test_seek_mode(mode: Literal[0, 1, 2], expected_position: int) -> None:
assert container.tell() == expected_position assert container.tell() == expected_position
@pytest.mark.parametrize("bytesmode", (True, False))
def test_readable(bytesmode: bool) -> None:
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
container = ContainerIO.ContainerIO(fh, 0, 120)
assert container.readable() is True
@pytest.mark.parametrize("bytesmode", (True, False)) @pytest.mark.parametrize("bytesmode", (True, False))
def test_read_n0(bytesmode: bool) -> None: def test_read_n0(bytesmode: bool) -> None:
# Arrange # Arrange
@ -51,7 +64,7 @@ def test_read_n0(bytesmode: bool) -> None:
container = ContainerIO.ContainerIO(fh, 22, 100) container = ContainerIO.ContainerIO(fh, 22, 100)
# Act # Act
container.seek(81) assert container.seek(81) == 81
data = container.read() data = container.read()
# Assert # Assert
@ -67,7 +80,7 @@ def test_read_n(bytesmode: bool) -> None:
container = ContainerIO.ContainerIO(fh, 22, 100) container = ContainerIO.ContainerIO(fh, 22, 100)
# Act # Act
container.seek(81) assert container.seek(81) == 81
data = container.read(3) data = container.read(3)
# Assert # Assert
@ -83,7 +96,7 @@ def test_read_eof(bytesmode: bool) -> None:
container = ContainerIO.ContainerIO(fh, 22, 100) container = ContainerIO.ContainerIO(fh, 22, 100)
# Act # Act
container.seek(100) assert container.seek(100) == 100
data = container.read() data = container.read()
# Assert # Assert
@ -94,21 +107,65 @@ def test_read_eof(bytesmode: bool) -> None:
@pytest.mark.parametrize("bytesmode", (True, False)) @pytest.mark.parametrize("bytesmode", (True, False))
def test_readline(bytesmode: bool) -> None: def test_readline(bytesmode: bool) -> None:
# Arrange
with open(TEST_FILE, "rb" if bytesmode else "r") as fh: with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
container = ContainerIO.ContainerIO(fh, 0, 120) container = ContainerIO.ContainerIO(fh, 0, 120)
# Act
data = container.readline() data = container.readline()
# Assert
if bytesmode: if bytesmode:
data = data.decode() data = data.decode()
assert data == "This is line 1\n" assert data == "This is line 1\n"
data = container.readline(4)
if bytesmode:
data = data.decode()
assert data == "This"
@pytest.mark.parametrize("bytesmode", (True, False)) @pytest.mark.parametrize("bytesmode", (True, False))
def test_readlines(bytesmode: bool) -> None: def test_readlines(bytesmode: bool) -> None:
expected = [
"This is line 1\n",
"This is line 2\n",
"This is line 3\n",
"This is line 4\n",
"This is line 5\n",
"This is line 6\n",
"This is line 7\n",
"This is line 8\n",
]
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
container = ContainerIO.ContainerIO(fh, 0, 120)
data = container.readlines()
if bytesmode:
data = [line.decode() for line in data]
assert data == expected
assert container.seek(0) == 0
data = container.readlines(2)
if bytesmode:
data = [line.decode() for line in data]
assert data == expected[:2]
@pytest.mark.parametrize("bytesmode", (True, False))
def test_write(bytesmode: bool) -> None:
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
container = ContainerIO.ContainerIO(fh, 0, 120)
assert container.writable() is False
with pytest.raises(NotImplementedError):
container.write(b"" if bytesmode else "")
with pytest.raises(NotImplementedError):
container.writelines([])
with pytest.raises(NotImplementedError):
container.truncate()
@pytest.mark.parametrize("bytesmode", (True, False))
def test_iter(bytesmode: bool) -> None:
# Arrange # Arrange
expected = [ expected = [
"This is line 1\n", "This is line 1\n",
@ -124,9 +181,21 @@ def test_readlines(bytesmode: bool) -> None:
container = ContainerIO.ContainerIO(fh, 0, 120) container = ContainerIO.ContainerIO(fh, 0, 120)
# Act # Act
data = container.readlines() data = []
for line in container:
data.append(line)
# Assert # Assert
if bytesmode: if bytesmode:
data = [line.decode() for line in data] data = [line.decode() for line in data]
assert data == expected assert data == expected
@pytest.mark.parametrize("bytesmode", (True, False))
def test_file(bytesmode: bool) -> None:
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
container = ContainerIO.ContainerIO(fh, 0, 120)
assert isinstance(container.fileno(), int)
container.flush()
container.close()

View File

@ -41,7 +41,7 @@ MAGIC = PngImagePlugin._MAGIC
def chunk(cid: bytes, *data: bytes) -> bytes: def chunk(cid: bytes, *data: bytes) -> bytes:
test_file = BytesIO() test_file = BytesIO()
PngImagePlugin.putchunk(*(test_file, cid) + data) PngImagePlugin.putchunk(test_file, cid, *data)
return test_file.getvalue() return test_file.getvalue()

View File

@ -127,7 +127,7 @@ class TestImageFile:
def test_raise_typeerror(self) -> None: def test_raise_typeerror(self) -> None:
with pytest.raises(TypeError): with pytest.raises(TypeError):
parser = ImageFile.Parser() parser = ImageFile.Parser()
parser.feed(1) parser.feed(1) # type: ignore[arg-type]
def test_negative_stride(self) -> None: def test_negative_stride(self) -> None:
with open("Tests/images/raw_negative_stride.bin", "rb") as f: with open("Tests/images/raw_negative_stride.bin", "rb") as f:
@ -305,7 +305,7 @@ class TestPyDecoder(CodecsTest):
im.load() im.load()
def test_decode(self) -> None: def test_decode(self) -> None:
decoder = ImageFile.PyDecoder(None) decoder = ImageFile.PyDecoder("")
with pytest.raises(NotImplementedError): with pytest.raises(NotImplementedError):
decoder.decode(b"") decoder.decode(b"")
@ -383,7 +383,7 @@ class TestPyEncoder(CodecsTest):
) )
def test_encode(self) -> None: def test_encode(self) -> None:
encoder = ImageFile.PyEncoder(None) encoder = ImageFile.PyEncoder("")
with pytest.raises(NotImplementedError): with pytest.raises(NotImplementedError):
encoder.encode(0) encoder.encode(0)

View File

@ -1,5 +1,9 @@
from __future__ import annotations from __future__ import annotations
from typing import Any
import pytest
from PIL import Image, ImageMath from PIL import Image, ImageMath
@ -19,7 +23,7 @@ I = Image.new("I", (1, 1), 4) # noqa: E741
A2 = A.resize((2, 2)) A2 = A.resize((2, 2))
B2 = B.resize((2, 2)) B2 = B.resize((2, 2))
images = {"A": A, "B": B, "F": F, "I": I} images: dict[str, Any] = {"A": A, "B": B, "F": F, "I": I}
def test_sanity() -> None: def test_sanity() -> None:
@ -30,13 +34,13 @@ def test_sanity() -> None:
== "I 3" == "I 3"
) )
assert ( assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] + args["B"], images)) pixel(ImageMath.lambda_eval(lambda args: args["A"] + args["B"], **images))
== "I 3" == "I 3"
) )
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval( ImageMath.lambda_eval(
lambda args: args["float"](args["A"]) + args["B"], images lambda args: args["float"](args["A"]) + args["B"], **images
) )
) )
== "F 3.0" == "F 3.0"
@ -44,42 +48,47 @@ def test_sanity() -> None:
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval( ImageMath.lambda_eval(
lambda args: args["int"](args["float"](args["A"]) + args["B"]), images lambda args: args["int"](args["float"](args["A"]) + args["B"]), **images
) )
) )
== "I 3" == "I 3"
) )
def test_options_deprecated() -> None:
with pytest.warns(DeprecationWarning):
assert ImageMath.lambda_eval(lambda args: 1, images) == 1
def test_ops() -> None: def test_ops() -> None:
assert pixel(ImageMath.lambda_eval(lambda args: args["A"] * -1, images)) == "I -1" assert pixel(ImageMath.lambda_eval(lambda args: args["A"] * -1, **images)) == "I -1"
assert ( assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] + args["B"], images)) pixel(ImageMath.lambda_eval(lambda args: args["A"] + args["B"], **images))
== "I 3" == "I 3"
) )
assert ( assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] - args["B"], images)) pixel(ImageMath.lambda_eval(lambda args: args["A"] - args["B"], **images))
== "I -1" == "I -1"
) )
assert ( assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] * args["B"], images)) pixel(ImageMath.lambda_eval(lambda args: args["A"] * args["B"], **images))
== "I 2" == "I 2"
) )
assert ( assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] / args["B"], images)) pixel(ImageMath.lambda_eval(lambda args: args["A"] / args["B"], **images))
== "I 0" == "I 0"
) )
assert pixel(ImageMath.lambda_eval(lambda args: args["B"] ** 2, images)) == "I 4" assert pixel(ImageMath.lambda_eval(lambda args: args["B"] ** 2, **images)) == "I 4"
assert ( assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] ** 33, images)) pixel(ImageMath.lambda_eval(lambda args: args["B"] ** 33, **images))
== "I 2147483647" == "I 2147483647"
) )
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval( ImageMath.lambda_eval(
lambda args: args["float"](args["A"]) + args["B"], images lambda args: args["float"](args["A"]) + args["B"], **images
) )
) )
== "F 3.0" == "F 3.0"
@ -87,7 +96,7 @@ def test_ops() -> None:
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval( ImageMath.lambda_eval(
lambda args: args["float"](args["A"]) - args["B"], images lambda args: args["float"](args["A"]) - args["B"], **images
) )
) )
== "F -1.0" == "F -1.0"
@ -95,7 +104,7 @@ def test_ops() -> None:
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval( ImageMath.lambda_eval(
lambda args: args["float"](args["A"]) * args["B"], images lambda args: args["float"](args["A"]) * args["B"], **images
) )
) )
== "F 2.0" == "F 2.0"
@ -103,31 +112,33 @@ def test_ops() -> None:
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval( ImageMath.lambda_eval(
lambda args: args["float"](args["A"]) / args["B"], images lambda args: args["float"](args["A"]) / args["B"], **images
) )
) )
== "F 0.5" == "F 0.5"
) )
assert ( assert (
pixel(ImageMath.lambda_eval(lambda args: args["float"](args["B"]) ** 2, images)) pixel(
ImageMath.lambda_eval(lambda args: args["float"](args["B"]) ** 2, **images)
)
== "F 4.0" == "F 4.0"
) )
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval(lambda args: args["float"](args["B"]) ** 33, images) ImageMath.lambda_eval(lambda args: args["float"](args["B"]) ** 33, **images)
) )
== "F 8589934592.0" == "F 8589934592.0"
) )
def test_logical() -> None: def test_logical() -> None:
assert pixel(ImageMath.lambda_eval(lambda args: not args["A"], images)) == 0 assert pixel(ImageMath.lambda_eval(lambda args: not args["A"], **images)) == 0
assert ( assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] and args["B"], images)) pixel(ImageMath.lambda_eval(lambda args: args["A"] and args["B"], **images))
== "L 2" == "L 2"
) )
assert ( assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] or args["B"], images)) pixel(ImageMath.lambda_eval(lambda args: args["A"] or args["B"], **images))
== "L 1" == "L 1"
) )
@ -136,7 +147,7 @@ def test_convert() -> None:
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval( ImageMath.lambda_eval(
lambda args: args["convert"](args["A"] + args["B"], "L"), images lambda args: args["convert"](args["A"] + args["B"], "L"), **images
) )
) )
== "L 3" == "L 3"
@ -144,7 +155,7 @@ def test_convert() -> None:
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval( ImageMath.lambda_eval(
lambda args: args["convert"](args["A"] + args["B"], "1"), images lambda args: args["convert"](args["A"] + args["B"], "1"), **images
) )
) )
== "1 0" == "1 0"
@ -152,7 +163,7 @@ def test_convert() -> None:
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval( ImageMath.lambda_eval(
lambda args: args["convert"](args["A"] + args["B"], "RGB"), images lambda args: args["convert"](args["A"] + args["B"], "RGB"), **images
) )
) )
== "RGB (3, 3, 3)" == "RGB (3, 3, 3)"
@ -163,7 +174,7 @@ def test_compare() -> None:
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval( ImageMath.lambda_eval(
lambda args: args["min"](args["A"], args["B"]), images lambda args: args["min"](args["A"], args["B"]), **images
) )
) )
== "I 1" == "I 1"
@ -171,13 +182,13 @@ def test_compare() -> None:
assert ( assert (
pixel( pixel(
ImageMath.lambda_eval( ImageMath.lambda_eval(
lambda args: args["max"](args["A"], args["B"]), images lambda args: args["max"](args["A"], args["B"]), **images
) )
) )
== "I 2" == "I 2"
) )
assert pixel(ImageMath.lambda_eval(lambda args: args["A"] == 1, images)) == "I 1" assert pixel(ImageMath.lambda_eval(lambda args: args["A"] == 1, **images)) == "I 1"
assert pixel(ImageMath.lambda_eval(lambda args: args["A"] == 2, images)) == "I 0" assert pixel(ImageMath.lambda_eval(lambda args: args["A"] == 2, **images)) == "I 0"
def test_one_image_larger() -> None: def test_one_image_larger() -> None:

View File

@ -1,5 +1,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Any
import pytest import pytest
from PIL import Image, ImageMath from PIL import Image, ImageMath
@ -21,16 +23,16 @@ I = Image.new("I", (1, 1), 4) # noqa: E741
A2 = A.resize((2, 2)) A2 = A.resize((2, 2))
B2 = B.resize((2, 2)) B2 = B.resize((2, 2))
images = {"A": A, "B": B, "F": F, "I": I} images: dict[str, Any] = {"A": A, "B": B, "F": F, "I": I}
def test_sanity() -> None: def test_sanity() -> None:
assert ImageMath.unsafe_eval("1") == 1 assert ImageMath.unsafe_eval("1") == 1
assert ImageMath.unsafe_eval("1+A", A=2) == 3 assert ImageMath.unsafe_eval("1+A", A=2) == 3
assert pixel(ImageMath.unsafe_eval("A+B", A=A, B=B)) == "I 3" assert pixel(ImageMath.unsafe_eval("A+B", A=A, B=B)) == "I 3"
assert pixel(ImageMath.unsafe_eval("A+B", images)) == "I 3" assert pixel(ImageMath.unsafe_eval("A+B", **images)) == "I 3"
assert pixel(ImageMath.unsafe_eval("float(A)+B", images)) == "F 3.0" assert pixel(ImageMath.unsafe_eval("float(A)+B", **images)) == "F 3.0"
assert pixel(ImageMath.unsafe_eval("int(float(A)+B)", images)) == "I 3" assert pixel(ImageMath.unsafe_eval("int(float(A)+B)", **images)) == "I 3"
def test_eval_deprecated() -> None: def test_eval_deprecated() -> None:
@ -38,23 +40,28 @@ def test_eval_deprecated() -> None:
assert ImageMath.eval("1") == 1 assert ImageMath.eval("1") == 1
def test_options_deprecated() -> None:
with pytest.warns(DeprecationWarning):
assert ImageMath.unsafe_eval("1", images) == 1
def test_ops() -> None: def test_ops() -> None:
assert pixel(ImageMath.unsafe_eval("-A", images)) == "I -1" assert pixel(ImageMath.unsafe_eval("-A", **images)) == "I -1"
assert pixel(ImageMath.unsafe_eval("+B", images)) == "L 2" assert pixel(ImageMath.unsafe_eval("+B", **images)) == "L 2"
assert pixel(ImageMath.unsafe_eval("A+B", images)) == "I 3" assert pixel(ImageMath.unsafe_eval("A+B", **images)) == "I 3"
assert pixel(ImageMath.unsafe_eval("A-B", images)) == "I -1" assert pixel(ImageMath.unsafe_eval("A-B", **images)) == "I -1"
assert pixel(ImageMath.unsafe_eval("A*B", images)) == "I 2" assert pixel(ImageMath.unsafe_eval("A*B", **images)) == "I 2"
assert pixel(ImageMath.unsafe_eval("A/B", images)) == "I 0" assert pixel(ImageMath.unsafe_eval("A/B", **images)) == "I 0"
assert pixel(ImageMath.unsafe_eval("B**2", images)) == "I 4" assert pixel(ImageMath.unsafe_eval("B**2", **images)) == "I 4"
assert pixel(ImageMath.unsafe_eval("B**33", images)) == "I 2147483647" assert pixel(ImageMath.unsafe_eval("B**33", **images)) == "I 2147483647"
assert pixel(ImageMath.unsafe_eval("float(A)+B", images)) == "F 3.0" assert pixel(ImageMath.unsafe_eval("float(A)+B", **images)) == "F 3.0"
assert pixel(ImageMath.unsafe_eval("float(A)-B", images)) == "F -1.0" assert pixel(ImageMath.unsafe_eval("float(A)-B", **images)) == "F -1.0"
assert pixel(ImageMath.unsafe_eval("float(A)*B", images)) == "F 2.0" assert pixel(ImageMath.unsafe_eval("float(A)*B", **images)) == "F 2.0"
assert pixel(ImageMath.unsafe_eval("float(A)/B", images)) == "F 0.5" assert pixel(ImageMath.unsafe_eval("float(A)/B", **images)) == "F 0.5"
assert pixel(ImageMath.unsafe_eval("float(B)**2", images)) == "F 4.0" assert pixel(ImageMath.unsafe_eval("float(B)**2", **images)) == "F 4.0"
assert pixel(ImageMath.unsafe_eval("float(B)**33", images)) == "F 8589934592.0" assert pixel(ImageMath.unsafe_eval("float(B)**33", **images)) == "F 8589934592.0"
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -72,33 +79,33 @@ def test_prevent_exec(expression: str) -> None:
def test_prevent_double_underscores() -> None: def test_prevent_double_underscores() -> None:
with pytest.raises(ValueError): with pytest.raises(ValueError):
ImageMath.unsafe_eval("1", {"__": None}) ImageMath.unsafe_eval("1", __=None)
def test_prevent_builtins() -> None: def test_prevent_builtins() -> None:
with pytest.raises(ValueError): with pytest.raises(ValueError):
ImageMath.unsafe_eval("(lambda: exec('exit()'))()", {"exec": None}) ImageMath.unsafe_eval("(lambda: exec('exit()'))()", exec=None)
def test_logical() -> None: def test_logical() -> None:
assert pixel(ImageMath.unsafe_eval("not A", images)) == 0 assert pixel(ImageMath.unsafe_eval("not A", **images)) == 0
assert pixel(ImageMath.unsafe_eval("A and B", images)) == "L 2" assert pixel(ImageMath.unsafe_eval("A and B", **images)) == "L 2"
assert pixel(ImageMath.unsafe_eval("A or B", images)) == "L 1" assert pixel(ImageMath.unsafe_eval("A or B", **images)) == "L 1"
def test_convert() -> None: def test_convert() -> None:
assert pixel(ImageMath.unsafe_eval("convert(A+B, 'L')", images)) == "L 3" assert pixel(ImageMath.unsafe_eval("convert(A+B, 'L')", **images)) == "L 3"
assert pixel(ImageMath.unsafe_eval("convert(A+B, '1')", images)) == "1 0" assert pixel(ImageMath.unsafe_eval("convert(A+B, '1')", **images)) == "1 0"
assert ( assert (
pixel(ImageMath.unsafe_eval("convert(A+B, 'RGB')", images)) == "RGB (3, 3, 3)" pixel(ImageMath.unsafe_eval("convert(A+B, 'RGB')", **images)) == "RGB (3, 3, 3)"
) )
def test_compare() -> None: def test_compare() -> None:
assert pixel(ImageMath.unsafe_eval("min(A, B)", images)) == "I 1" assert pixel(ImageMath.unsafe_eval("min(A, B)", **images)) == "I 1"
assert pixel(ImageMath.unsafe_eval("max(A, B)", images)) == "I 2" assert pixel(ImageMath.unsafe_eval("max(A, B)", **images)) == "I 2"
assert pixel(ImageMath.unsafe_eval("A == 1", images)) == "I 1" assert pixel(ImageMath.unsafe_eval("A == 1", **images)) == "I 1"
assert pixel(ImageMath.unsafe_eval("A == 2", images)) == "I 0" assert pixel(ImageMath.unsafe_eval("A == 2", **images)) == "I 0"
def test_one_image_larger() -> None: def test_one_image_larger() -> None:

View File

@ -57,6 +57,9 @@ class TestImageWinDib:
# Assert # Assert
assert dib.size == (128, 128) assert dib.size == (128, 128)
with pytest.raises(ValueError):
ImageWin.Dib(mode)
def test_dib_paste(self) -> None: def test_dib_paste(self) -> None:
# Arrange # Arrange
im = hopper() im = hopper()

View File

@ -109,6 +109,15 @@ ImageDraw.getdraw hints parameter
The ``hints`` parameter in :py:meth:`~PIL.ImageDraw.getdraw()` has been deprecated. The ``hints`` parameter in :py:meth:`~PIL.ImageDraw.getdraw()` has been deprecated.
ImageMath.lambda_eval and ImageMath.unsafe_eval options parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
The ``options`` parameter in :py:meth:`~PIL.ImageMath.lambda_eval()` and
:py:meth:`~PIL.ImageMath.unsafe_eval()` has been deprecated. One or more keyword
arguments can be used instead.
Removed features Removed features
---------------- ----------------

View File

@ -31,20 +31,21 @@ Example: Using the :py:mod:`~PIL.ImageMath` module
b=im2 b=im2
) )
.. py:function:: lambda_eval(expression, options) .. py:function:: lambda_eval(expression, options, **kw)
Returns the result of an image function. Returns the result of an image function.
:param expression: A function that receives a dictionary. :param expression: A function that receives a dictionary.
:param options: Values to add to the function's dictionary, mapping image :param options: Values to add to the function's dictionary. Note that the names
names to Image instances. You can use one or more keyword must be valid Python identifiers. Deprecated.
arguments instead of a dictionary, as shown in the above You can instead use one or more keyword arguments, as
example. Note that the names must be valid Python shown in the above example.
identifiers. :param \**kw: Values to add to the function's dictionary, mapping image names to
Image instances.
:return: An image, an integer value, a floating point value, :return: An image, an integer value, a floating point value,
or a pixel tuple, depending on the expression. or a pixel tuple, depending on the expression.
.. py:function:: unsafe_eval(expression, options) .. py:function:: unsafe_eval(expression, options, **kw)
Evaluates an image expression. Evaluates an image expression.
@ -61,11 +62,12 @@ Example: Using the :py:mod:`~PIL.ImageMath` module
:param expression: A string which uses the standard Python expression :param expression: A string which uses the standard Python expression
syntax. In addition to the standard operators, you can syntax. In addition to the standard operators, you can
also use the functions described below. also use the functions described below.
:param options: Values to add to the function's dictionary, mapping image :param options: Values to add to the evaluation context. Note that the names must
names to Image instances. You can use one or more keyword be valid Python identifiers. Deprecated.
arguments instead of a dictionary, as shown in the above You can instead use one or more keyword arguments, as
example. Note that the names must be valid Python shown in the above example.
identifiers. :param \**kw: Values to add to the evaluation context, mapping image names to Image
instances.
:return: An image, an integer value, a floating point value, :return: An image, an integer value, a floating point value,
or a pixel tuple, depending on the expression. or a pixel tuple, depending on the expression.

View File

@ -43,10 +43,12 @@ similarly removed.
Deprecations Deprecations
============ ============
TODO ImageMath.lambda_eval and ImageMath.unsafe_eval options parameter
^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TODO The ``options`` parameter in :py:meth:`~PIL.ImageMath.lambda_eval()` and
:py:meth:`~PIL.ImageMath.unsafe_eval()` has been deprecated. One or more
keyword arguments can be used instead.
API Changes API Changes
=========== ===========

View File

@ -161,5 +161,4 @@ exclude = [
'^Tests/test_qt_image_qapplication.py$', '^Tests/test_qt_image_qapplication.py$',
'^Tests/test_font_pcf_charsets.py$', '^Tests/test_font_pcf_charsets.py$',
'^Tests/test_font_pcf.py$', '^Tests/test_font_pcf.py$',
'^Tests/test_file_tar.py$',
] ]

View File

@ -16,10 +16,11 @@
from __future__ import annotations from __future__ import annotations
import io import io
from typing import IO, AnyStr, Generic, Literal from collections.abc import Iterable
from typing import IO, AnyStr, NoReturn
class ContainerIO(Generic[AnyStr]): class ContainerIO(IO[AnyStr]):
""" """
A file object that provides read access to a part of an existing A file object that provides read access to a part of an existing
file (for example a TAR file). file (for example a TAR file).
@ -45,7 +46,10 @@ class ContainerIO(Generic[AnyStr]):
def isatty(self) -> bool: def isatty(self) -> bool:
return False return False
def seek(self, offset: int, mode: Literal[0, 1, 2] = io.SEEK_SET) -> None: def seekable(self) -> bool:
return True
def seek(self, offset: int, mode: int = io.SEEK_SET) -> int:
""" """
Move file pointer. Move file pointer.
@ -53,6 +57,7 @@ class ContainerIO(Generic[AnyStr]):
:param mode: Starting position. Use 0 for beginning of region, 1 :param mode: Starting position. Use 0 for beginning of region, 1
for current offset, and 2 for end of region. You cannot move for current offset, and 2 for end of region. You cannot move
the pointer outside the defined region. the pointer outside the defined region.
:returns: Offset from start of region, in bytes.
""" """
if mode == 1: if mode == 1:
self.pos = self.pos + offset self.pos = self.pos + offset
@ -63,6 +68,7 @@ class ContainerIO(Generic[AnyStr]):
# clamp # clamp
self.pos = max(0, min(self.pos, self.length)) self.pos = max(0, min(self.pos, self.length))
self.fh.seek(self.offset + self.pos) self.fh.seek(self.offset + self.pos)
return self.pos
def tell(self) -> int: def tell(self) -> int:
""" """
@ -72,27 +78,32 @@ class ContainerIO(Generic[AnyStr]):
""" """
return self.pos return self.pos
def read(self, n: int = 0) -> AnyStr: def readable(self) -> bool:
return True
def read(self, n: int = -1) -> AnyStr:
""" """
Read data. Read data.
:param n: Number of bytes to read. If omitted or zero, :param n: Number of bytes to read. If omitted, zero or negative,
read until end of region. read until end of region.
:returns: An 8-bit string. :returns: An 8-bit string.
""" """
if n: if n > 0:
n = min(n, self.length - self.pos) n = min(n, self.length - self.pos)
else: else:
n = self.length - self.pos n = self.length - self.pos
if not n: # EOF if n <= 0: # EOF
return b"" if "b" in self.fh.mode else "" # type: ignore[return-value] return b"" if "b" in self.fh.mode else "" # type: ignore[return-value]
self.pos = self.pos + n self.pos = self.pos + n
return self.fh.read(n) return self.fh.read(n)
def readline(self) -> AnyStr: def readline(self, n: int = -1) -> AnyStr:
""" """
Read a line of text. Read a line of text.
:param n: Number of bytes to read. If omitted, zero or negative,
read until end of line.
:returns: An 8-bit string. :returns: An 8-bit string.
""" """
s: AnyStr = b"" if "b" in self.fh.mode else "" # type: ignore[assignment] s: AnyStr = b"" if "b" in self.fh.mode else "" # type: ignore[assignment]
@ -102,14 +113,16 @@ class ContainerIO(Generic[AnyStr]):
if not c: if not c:
break break
s = s + c s = s + c
if c == newline_character: if c == newline_character or len(s) == n:
break break
return s return s
def readlines(self) -> list[AnyStr]: def readlines(self, n: int | None = -1) -> list[AnyStr]:
""" """
Read multiple lines of text. Read multiple lines of text.
:param n: Number of lines to read. If omitted, zero, negative or None,
read until end of region.
:returns: A list of 8-bit strings. :returns: A list of 8-bit strings.
""" """
lines = [] lines = []
@ -118,4 +131,43 @@ class ContainerIO(Generic[AnyStr]):
if not s: if not s:
break break
lines.append(s) lines.append(s)
if len(lines) == n:
break
return lines return lines
def writable(self) -> bool:
return False
def write(self, b: AnyStr) -> NoReturn:
raise NotImplementedError()
def writelines(self, lines: Iterable[AnyStr]) -> NoReturn:
raise NotImplementedError()
def truncate(self, size: int | None = None) -> int:
raise NotImplementedError()
def __enter__(self) -> ContainerIO[AnyStr]:
return self
def __exit__(self, *args: object) -> None:
self.close()
def __iter__(self) -> ContainerIO[AnyStr]:
return self
def __next__(self) -> AnyStr:
line = self.readline()
if not line:
msg = "end of region"
raise StopIteration(msg)
return line
def fileno(self) -> int:
return self.fh.fileno()
def flush(self) -> None:
self.fh.flush()
def close(self) -> None:
self.fh.close()

View File

@ -65,7 +65,7 @@ def has_ghostscript() -> bool:
return gs_binary is not False return gs_binary is not False
def Ghostscript(tile, size, fp, scale=1, transparency=False): def Ghostscript(tile, size, fp, scale=1, transparency: bool = False) -> Image.Image:
"""Render an image using Ghostscript""" """Render an image using Ghostscript"""
global gs_binary global gs_binary
if not has_ghostscript(): if not has_ghostscript():

View File

@ -25,7 +25,7 @@ from __future__ import annotations
import warnings import warnings
from io import BytesIO from io import BytesIO
from math import ceil, log from math import ceil, log
from typing import IO from typing import IO, NamedTuple
from . import BmpImagePlugin, Image, ImageFile, PngImagePlugin from . import BmpImagePlugin, Image, ImageFile, PngImagePlugin
from ._binary import i16le as i16 from ._binary import i16le as i16
@ -119,8 +119,22 @@ def _accept(prefix: bytes) -> bool:
return prefix[:4] == _MAGIC return prefix[:4] == _MAGIC
class IconHeader(NamedTuple):
width: int
height: int
nb_color: int
reserved: int
planes: int
bpp: int
size: int
offset: int
dim: tuple[int, int]
square: int
color_depth: int
class IcoFile: class IcoFile:
def __init__(self, buf) -> None: def __init__(self, buf: IO[bytes]) -> None:
""" """
Parse image from file-like object containing ico file data Parse image from file-like object containing ico file data
""" """
@ -141,51 +155,44 @@ class IcoFile:
for i in range(self.nb_items): for i in range(self.nb_items):
s = buf.read(16) s = buf.read(16)
icon_header = {
"width": s[0],
"height": s[1],
"nb_color": s[2], # No. of colors in image (0 if >=8bpp)
"reserved": s[3],
"planes": i16(s, 4),
"bpp": i16(s, 6),
"size": i32(s, 8),
"offset": i32(s, 12),
}
# See Wikipedia # See Wikipedia
for j in ("width", "height"): width = s[0] or 256
if not icon_header[j]: height = s[1] or 256
icon_header[j] = 256
# See Wikipedia notes about color depth. # No. of colors in image (0 if >=8bpp)
# We need this just to differ images with equal sizes nb_color = s[2]
icon_header["color_depth"] = ( bpp = i16(s, 6)
icon_header["bpp"] icon_header = IconHeader(
or ( width=width,
icon_header["nb_color"] != 0 height=height,
and ceil(log(icon_header["nb_color"], 2)) nb_color=nb_color,
) reserved=s[3],
or 256 planes=i16(s, 4),
bpp=i16(s, 6),
size=i32(s, 8),
offset=i32(s, 12),
dim=(width, height),
square=width * height,
# See Wikipedia notes about color depth.
# We need this just to differ images with equal sizes
color_depth=bpp or (nb_color != 0 and ceil(log(nb_color, 2))) or 256,
) )
icon_header["dim"] = (icon_header["width"], icon_header["height"])
icon_header["square"] = icon_header["width"] * icon_header["height"]
self.entry.append(icon_header) self.entry.append(icon_header)
self.entry = sorted(self.entry, key=lambda x: x["color_depth"]) self.entry = sorted(self.entry, key=lambda x: x.color_depth)
# ICO images are usually squares # ICO images are usually squares
self.entry = sorted(self.entry, key=lambda x: x["square"], reverse=True) self.entry = sorted(self.entry, key=lambda x: x.square, reverse=True)
def sizes(self) -> set[tuple[int, int]]: def sizes(self) -> set[tuple[int, int]]:
""" """
Get a list of all available icon sizes and color depths. Get a set of all available icon sizes and color depths.
""" """
return {(h["width"], h["height"]) for h in self.entry} return {(h.width, h.height) for h in self.entry}
def getentryindex(self, size: tuple[int, int], bpp: int | bool = False) -> int: def getentryindex(self, size: tuple[int, int], bpp: int | bool = False) -> int:
for i, h in enumerate(self.entry): for i, h in enumerate(self.entry):
if size == h["dim"] and (bpp is False or bpp == h["color_depth"]): if size == h.dim and (bpp is False or bpp == h.color_depth):
return i return i
return 0 return 0
@ -202,9 +209,9 @@ class IcoFile:
header = self.entry[idx] header = self.entry[idx]
self.buf.seek(header["offset"]) self.buf.seek(header.offset)
data = self.buf.read(8) data = self.buf.read(8)
self.buf.seek(header["offset"]) self.buf.seek(header.offset)
im: Image.Image im: Image.Image
if data[:8] == PngImagePlugin._MAGIC: if data[:8] == PngImagePlugin._MAGIC:
@ -222,8 +229,7 @@ class IcoFile:
im.tile[0] = d, (0, 0) + im.size, o, a im.tile[0] = d, (0, 0) + im.size, o, a
# figure out where AND mask image starts # figure out where AND mask image starts
bpp = header["bpp"] if header.bpp == 32:
if 32 == bpp:
# 32-bit color depth icon image allows semitransparent areas # 32-bit color depth icon image allows semitransparent areas
# PIL's DIB format ignores transparency bits, recover them. # PIL's DIB format ignores transparency bits, recover them.
# The DIB is packed in BGRX byte order where X is the alpha # The DIB is packed in BGRX byte order where X is the alpha
@ -253,7 +259,7 @@ class IcoFile:
# padded row size * height / bits per char # padded row size * height / bits per char
total_bytes = int((w * im.size[1]) / 8) total_bytes = int((w * im.size[1]) / 8)
and_mask_offset = header["offset"] + header["size"] - total_bytes and_mask_offset = header.offset + header.size - total_bytes
self.buf.seek(and_mask_offset) self.buf.seek(and_mask_offset)
mask_data = self.buf.read(total_bytes) mask_data = self.buf.read(total_bytes)
@ -307,7 +313,7 @@ class IcoImageFile(ImageFile.ImageFile):
def _open(self) -> None: def _open(self) -> None:
self.ico = IcoFile(self.fp) self.ico = IcoFile(self.fp)
self.info["sizes"] = self.ico.sizes() self.info["sizes"] = self.ico.sizes()
self.size = self.ico.entry[0]["dim"] self.size = self.ico.entry[0].dim
self.load() self.load()
@property @property

View File

@ -3286,7 +3286,7 @@ def fromarray(obj: SupportsArrayInterface, mode: str | None = None) -> Image:
return frombuffer(mode, size, obj, "raw", rawmode, 0, 1) return frombuffer(mode, size, obj, "raw", rawmode, 0, 1)
def fromqimage(im): def fromqimage(im) -> ImageFile.ImageFile:
"""Creates an image instance from a QImage image""" """Creates an image instance from a QImage image"""
from . import ImageQt from . import ImageQt
@ -3296,7 +3296,7 @@ def fromqimage(im):
return ImageQt.fromqimage(im) return ImageQt.fromqimage(im)
def fromqpixmap(im): def fromqpixmap(im) -> ImageFile.ImageFile:
"""Creates an image instance from a QPixmap image""" """Creates an image instance from a QPixmap image"""
from . import ImageQt from . import ImageQt
@ -3867,7 +3867,7 @@ class Exif(_ExifBase):
# returns a dict with any single item tuples/lists as individual values # returns a dict with any single item tuples/lists as individual values
return {k: self._fixup(v) for k, v in src_dict.items()} return {k: self._fixup(v) for k, v in src_dict.items()}
def _get_ifd_dict(self, offset, group=None): def _get_ifd_dict(self, offset: int, group=None):
try: try:
# an offset pointer to the location of the nested embedded IFD. # an offset pointer to the location of the nested embedded IFD.
# It should be a long, but may be corrupted. # It should be a long, but may be corrupted.
@ -3881,7 +3881,7 @@ class Exif(_ExifBase):
info.load(self.fp) info.load(self.fp)
return self._fixup_dict(info) return self._fixup_dict(info)
def _get_head(self): def _get_head(self) -> bytes:
version = b"\x2B" if self.bigtiff else b"\x2A" version = b"\x2B" if self.bigtiff else b"\x2A"
if self.endian == "<": if self.endian == "<":
head = b"II" + version + b"\x00" + o32le(8) head = b"II" + version + b"\x00" + o32le(8)
@ -4102,16 +4102,16 @@ class Exif(_ExifBase):
keys.update(self._info) keys.update(self._info)
return len(keys) return len(keys)
def __getitem__(self, tag): def __getitem__(self, tag: int):
if self._info is not None and tag not in self._data and tag in self._info: if self._info is not None and tag not in self._data and tag in self._info:
self._data[tag] = self._fixup(self._info[tag]) self._data[tag] = self._fixup(self._info[tag])
del self._info[tag] del self._info[tag]
return self._data[tag] return self._data[tag]
def __contains__(self, tag) -> bool: def __contains__(self, tag: object) -> bool:
return tag in self._data or (self._info is not None and tag in self._info) return tag in self._data or (self._info is not None and tag in self._info)
def __setitem__(self, tag, value) -> None: def __setitem__(self, tag: int, value) -> None:
if self._info is not None and tag in self._info: if self._info is not None and tag in self._info:
del self._info[tag] del self._info[tag]
self._data[tag] = value self._data[tag] = value

View File

@ -86,7 +86,7 @@ def raise_oserror(error: int) -> OSError:
raise _get_oserror(error, encoder=False) raise _get_oserror(error, encoder=False)
def _tilesort(t): def _tilesort(t) -> int:
# sort on offset # sort on offset
return t[2] return t[2]
@ -163,7 +163,7 @@ class ImageFile(Image.Image):
return Image.MIME.get(self.format.upper()) return Image.MIME.get(self.format.upper())
return None return None
def __setstate__(self, state): def __setstate__(self, state) -> None:
self.tile = [] self.tile = []
super().__setstate__(state) super().__setstate__(state)
@ -335,14 +335,14 @@ class ImageFile(Image.Image):
# def load_read(self, read_bytes: int) -> bytes: # def load_read(self, read_bytes: int) -> bytes:
# pass # pass
def _seek_check(self, frame): def _seek_check(self, frame: int) -> bool:
if ( if (
frame < self._min_frame frame < self._min_frame
# Only check upper limit on frames if additional seek operations # Only check upper limit on frames if additional seek operations
# are not required to do so # are not required to do so
or ( or (
not (hasattr(self, "_n_frames") and self._n_frames is None) not (hasattr(self, "_n_frames") and self._n_frames is None)
and frame >= self.n_frames + self._min_frame and frame >= getattr(self, "n_frames") + self._min_frame
) )
): ):
msg = "attempt to seek outside sequence" msg = "attempt to seek outside sequence"
@ -372,7 +372,7 @@ class StubImageFile(ImageFile):
msg = "StubImageFile subclass must implement _open" msg = "StubImageFile subclass must implement _open"
raise NotImplementedError(msg) raise NotImplementedError(msg)
def load(self): def load(self) -> Image.core.PixelAccess | None:
loader = self._load() loader = self._load()
if loader is None: if loader is None:
msg = f"cannot find loader for this {self.format} file" msg = f"cannot find loader for this {self.format} file"
@ -380,7 +380,7 @@ class StubImageFile(ImageFile):
image = loader.load(self) image = loader.load(self)
assert image is not None assert image is not None
# become the other object (!) # become the other object (!)
self.__class__ = image.__class__ self.__class__ = image.__class__ # type: ignore[assignment]
self.__dict__ = image.__dict__ self.__dict__ = image.__dict__
return image.load() return image.load()
@ -398,8 +398,8 @@ class Parser:
incremental = None incremental = None
image: Image.Image | None = None image: Image.Image | None = None
data = None data: bytes | None = None
decoder = None decoder: Image.core.ImagingDecoder | PyDecoder | None = None
offset = 0 offset = 0
finished = 0 finished = 0
@ -411,7 +411,7 @@ class Parser:
""" """
assert self.data is None, "cannot reuse parsers" assert self.data is None, "cannot reuse parsers"
def feed(self, data): def feed(self, data: bytes) -> None:
""" """
(Consumer) Feed data to the parser. (Consumer) Feed data to the parser.
@ -493,7 +493,7 @@ class Parser:
def __exit__(self, *args: object) -> None: def __exit__(self, *args: object) -> None:
self.close() self.close()
def close(self): def close(self) -> Image.Image:
""" """
(Consumer) Close the stream. (Consumer) Close the stream.
@ -527,7 +527,7 @@ class Parser:
# -------------------------------------------------------------------- # --------------------------------------------------------------------
def _save(im, fp, tile, bufsize=0) -> None: def _save(im, fp, tile, bufsize: int = 0) -> None:
"""Helper to save image based on tile list """Helper to save image based on tile list
:param im: Image object. :param im: Image object.
@ -555,7 +555,9 @@ def _save(im, fp, tile, bufsize=0) -> None:
fp.flush() fp.flush()
def _encode_tile(im, fp, tile: list[_Tile], bufsize, fh, exc=None): def _encode_tile(
im, fp: IO[bytes], tile: list[_Tile], bufsize: int, fh, exc=None
) -> None:
for encoder_name, extents, offset, args in tile: for encoder_name, extents, offset, args in tile:
if offset > 0: if offset > 0:
fp.seek(offset) fp.seek(offset)
@ -631,18 +633,18 @@ class PyCodecState:
class PyCodec: class PyCodec:
fd: IO[bytes] | None fd: IO[bytes] | None
def __init__(self, mode, *args): def __init__(self, mode: str, *args: Any) -> None:
self.im = None self.im: Image.core.ImagingCore | None = None
self.state = PyCodecState() self.state = PyCodecState()
self.fd = None self.fd = None
self.mode = mode self.mode = mode
self.init(args) self.init(args)
def init(self, args) -> None: def init(self, args: tuple[Any, ...]) -> None:
""" """
Override to perform codec specific initialization Override to perform codec specific initialization
:param args: Array of args items from the tile entry :param args: Tuple of arg items from the tile entry
:returns: None :returns: None
""" """
self.args = args self.args = args
@ -655,7 +657,7 @@ class PyCodec:
""" """
pass pass
def setfd(self, fd) -> None: def setfd(self, fd: IO[bytes]) -> None:
""" """
Called from ImageFile to set the Python file-like object Called from ImageFile to set the Python file-like object
@ -664,7 +666,7 @@ class PyCodec:
""" """
self.fd = fd self.fd = fd
def setimage(self, im, extents: tuple[int, int, int, int] | None = None) -> None: def setimage(self, im, extents=None):
""" """
Called from ImageFile to set the core output image for the codec Called from ImageFile to set the core output image for the codec

View File

@ -249,14 +249,21 @@ def lambda_eval(
:py:func:`~PIL.Image.merge` function. :py:func:`~PIL.Image.merge` function.
:param expression: A function that receives a dictionary. :param expression: A function that receives a dictionary.
:param options: Values to add to the function's dictionary. You :param options: Values to add to the function's dictionary. Deprecated.
can either use a dictionary, or one or more keyword You can instead use one or more keyword arguments.
arguments. :param **kw: Values to add to the function's dictionary.
:return: The expression result. This is usually an image object, but can :return: The expression result. This is usually an image object, but can
also be an integer, a floating point value, or a pixel tuple, also be an integer, a floating point value, or a pixel tuple,
depending on the expression. depending on the expression.
""" """
if options:
deprecate(
"ImageMath.lambda_eval options",
12,
"ImageMath.lambda_eval keyword arguments",
)
args: dict[str, Any] = ops.copy() args: dict[str, Any] = ops.copy()
args.update(options) args.update(options)
args.update(kw) args.update(kw)
@ -287,14 +294,21 @@ def unsafe_eval(
:py:func:`~PIL.Image.merge` function. :py:func:`~PIL.Image.merge` function.
:param expression: A string containing a Python-style expression. :param expression: A string containing a Python-style expression.
:param options: Values to add to the evaluation context. You :param options: Values to add to the evaluation context. Deprecated.
can either use a dictionary, or one or more keyword You can instead use one or more keyword arguments.
arguments. :param **kw: Values to add to the evaluation context.
:return: The evaluated expression. This is usually an image object, but can :return: The evaluated expression. This is usually an image object, but can
also be an integer, a floating point value, or a pixel tuple, also be an integer, a floating point value, or a pixel tuple,
depending on the expression. depending on the expression.
""" """
if options:
deprecate(
"ImageMath.unsafe_eval options",
12,
"ImageMath.unsafe_eval keyword arguments",
)
# build execution namespace # build execution namespace
args: dict[str, Any] = ops.copy() args: dict[str, Any] = ops.copy()
for k in list(options.keys()) + list(kw.keys()): for k in list(options.keys()) + list(kw.keys()):

View File

@ -19,11 +19,14 @@ from __future__ import annotations
import sys import sys
from io import BytesIO from io import BytesIO
from typing import Callable from typing import TYPE_CHECKING, Callable
from . import Image from . import Image
from ._util import is_path from ._util import is_path
if TYPE_CHECKING:
from . import ImageFile
qt_version: str | None qt_version: str | None
qt_versions = [ qt_versions = [
["6", "PyQt6"], ["6", "PyQt6"],
@ -90,11 +93,11 @@ def fromqimage(im):
return Image.open(b) return Image.open(b)
def fromqpixmap(im): def fromqpixmap(im) -> ImageFile.ImageFile:
return fromqimage(im) return fromqimage(im)
def align8to32(bytes, width, mode): def align8to32(bytes: bytes, width: int, mode: str) -> bytes:
""" """
converts each scanline of data from 8 bit to 32 bit aligned converts each scanline of data from 8 bit to 32 bit aligned
""" """
@ -172,7 +175,7 @@ def _toqclass_helper(im):
if qt_is_installed: if qt_is_installed:
class ImageQt(QImage): class ImageQt(QImage):
def __init__(self, im): def __init__(self, im) -> None:
""" """
An PIL image wrapper for Qt. This is a subclass of PyQt's QImage An PIL image wrapper for Qt. This is a subclass of PyQt's QImage
class. class.

View File

@ -33,7 +33,7 @@ class Iterator:
:param im: An image object. :param im: An image object.
""" """
def __init__(self, im: Image.Image): def __init__(self, im: Image.Image) -> None:
if not hasattr(im, "seek"): if not hasattr(im, "seek"):
msg = "im must have seek method" msg = "im must have seek method"
raise AttributeError(msg) raise AttributeError(msg)

View File

@ -70,11 +70,14 @@ class Dib:
""" """
def __init__( def __init__(
self, image: Image.Image | str, size: tuple[int, int] | list[int] | None = None self, image: Image.Image | str, size: tuple[int, int] | None = None
) -> None: ) -> None:
if isinstance(image, str): if isinstance(image, str):
mode = image mode = image
image = "" image = ""
if size is None:
msg = "If first argument is mode, size is required"
raise ValueError(msg)
else: else:
mode = image.mode mode = image.mode
size = image.size size = image.size
@ -105,7 +108,12 @@ class Dib:
result = self.image.expose(handle) result = self.image.expose(handle)
return result return result
def draw(self, handle, dst, src=None): def draw(
self,
handle,
dst: tuple[int, int, int, int],
src: tuple[int, int, int, int] | None = None,
):
""" """
Same as expose, but allows you to specify where to draw the image, and Same as expose, but allows you to specify where to draw the image, and
what part of it to draw. what part of it to draw.
@ -115,7 +123,7 @@ class Dib:
the destination have different sizes, the image is resized as the destination have different sizes, the image is resized as
necessary. necessary.
""" """
if not src: if src is None:
src = (0, 0) + self.size src = (0, 0) + self.size
if isinstance(handle, HWND): if isinstance(handle, HWND):
dc = self.image.getdc(handle) dc = self.image.getdc(handle)
@ -202,22 +210,22 @@ class Window:
title, self.__dispatcher, width or 0, height or 0 title, self.__dispatcher, width or 0, height or 0
) )
def __dispatcher(self, action, *args): def __dispatcher(self, action: str, *args):
return getattr(self, f"ui_handle_{action}")(*args) return getattr(self, f"ui_handle_{action}")(*args)
def ui_handle_clear(self, dc, x0, y0, x1, y1): def ui_handle_clear(self, dc, x0, y0, x1, y1) -> None:
pass pass
def ui_handle_damage(self, x0, y0, x1, y1): def ui_handle_damage(self, x0, y0, x1, y1) -> None:
pass pass
def ui_handle_destroy(self) -> None: def ui_handle_destroy(self) -> None:
pass pass
def ui_handle_repair(self, dc, x0, y0, x1, y1): def ui_handle_repair(self, dc, x0, y0, x1, y1) -> None:
pass pass
def ui_handle_resize(self, width, height): def ui_handle_resize(self, width, height) -> None:
pass pass
def mainloop(self) -> None: def mainloop(self) -> None:
@ -227,12 +235,12 @@ class Window:
class ImageWindow(Window): class ImageWindow(Window):
"""Create an image window which displays the given image.""" """Create an image window which displays the given image."""
def __init__(self, image, title="PIL"): def __init__(self, image, title: str = "PIL") -> None:
if not isinstance(image, Dib): if not isinstance(image, Dib):
image = Dib(image) image = Dib(image)
self.image = image self.image = image
width, height = image.size width, height = image.size
super().__init__(title, width=width, height=height) super().__init__(title, width=width, height=height)
def ui_handle_repair(self, dc, x0, y0, x1, y1): def ui_handle_repair(self, dc, x0, y0, x1, y1) -> None:
self.image.draw(dc, (x0, y0, x1, y1)) self.image.draw(dc, (x0, y0, x1, y1))

View File

@ -18,6 +18,7 @@ from __future__ import annotations
from collections.abc import Sequence from collections.abc import Sequence
from io import BytesIO from io import BytesIO
from typing import cast
from . import Image, ImageFile from . import Image, ImageFile
from ._binary import i16be as i16 from ._binary import i16be as i16
@ -184,7 +185,7 @@ Image.register_open(IptcImageFile.format, IptcImageFile)
Image.register_extension(IptcImageFile.format, ".iim") Image.register_extension(IptcImageFile.format, ".iim")
def getiptcinfo(im): def getiptcinfo(im: ImageFile.ImageFile):
""" """
Get IPTC information from TIFF, JPEG, or IPTC file. Get IPTC information from TIFF, JPEG, or IPTC file.
@ -221,16 +222,17 @@ def getiptcinfo(im):
class FakeImage: class FakeImage:
pass pass
im = FakeImage() fake_im = FakeImage()
im.__class__ = IptcImageFile fake_im.__class__ = IptcImageFile # type: ignore[assignment]
iptc_im = cast(IptcImageFile, fake_im)
# parse the IPTC information chunk # parse the IPTC information chunk
im.info = {} iptc_im.info = {}
im.fp = BytesIO(data) iptc_im.fp = BytesIO(data)
try: try:
im._open() iptc_im._open()
except (IndexError, KeyError): except (IndexError, KeyError):
pass # expected failure pass # expected failure
return im.info return iptc_im.info

View File

@ -685,7 +685,11 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
raise ValueError(msg) raise ValueError(msg)
subsampling = get_sampling(im) subsampling = get_sampling(im)
def validate_qtables(qtables): def validate_qtables(
qtables: (
str | tuple[list[int], ...] | list[list[int]] | dict[int, list[int]] | None
)
) -> list[list[int]] | None:
if qtables is None: if qtables is None:
return qtables return qtables
if isinstance(qtables, str): if isinstance(qtables, str):
@ -715,12 +719,12 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
if len(table) != 64: if len(table) != 64:
msg = "Invalid quantization table" msg = "Invalid quantization table"
raise TypeError(msg) raise TypeError(msg)
table = array.array("H", table) table_array = array.array("H", table)
except TypeError as e: except TypeError as e:
msg = "Invalid quantization table" msg = "Invalid quantization table"
raise ValueError(msg) from e raise ValueError(msg) from e
else: else:
qtables[idx] = list(table) qtables[idx] = list(table_array)
return qtables return qtables
if qtables == "keep": if qtables == "keep":
@ -827,11 +831,11 @@ def _save_cjpeg(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
## ##
# Factory for making JPEG and MPO instances # Factory for making JPEG and MPO instances
def jpeg_factory(fp=None, filename=None): def jpeg_factory(fp: IO[bytes] | None = None, filename: str | bytes | None = None):
im = JpegImageFile(fp, filename) im = JpegImageFile(fp, filename)
try: try:
mpheader = im._getmp() mpheader = im._getmp()
if mpheader[45057] > 1: if mpheader is not None and mpheader[45057] > 1:
for segment, content in im.applist: for segment, content in im.applist:
if segment == "APP1" and b' hdrgm:Version="' in content: if segment == "APP1" and b' hdrgm:Version="' in content:
# Ultra HDR images are not yet supported # Ultra HDR images are not yet supported

View File

@ -174,12 +174,15 @@ def _write_image(im, filename, existing_pdf, image_refs):
return image_ref, procset return image_ref, procset
def _save(im, fp, filename, save_all=False): def _save(
im: Image.Image, fp: IO[bytes], filename: str | bytes, save_all: bool = False
) -> None:
is_appending = im.encoderinfo.get("append", False) is_appending = im.encoderinfo.get("append", False)
filename_str = filename.decode() if isinstance(filename, bytes) else filename
if is_appending: if is_appending:
existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode="r+b") existing_pdf = PdfParser.PdfParser(f=fp, filename=filename_str, mode="r+b")
else: else:
existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode="w+b") existing_pdf = PdfParser.PdfParser(f=fp, filename=filename_str, mode="w+b")
dpi = im.encoderinfo.get("dpi") dpi = im.encoderinfo.get("dpi")
if dpi: if dpi:
@ -228,12 +231,7 @@ def _save(im, fp, filename, save_all=False):
for im in ims: for im in ims:
im_number_of_pages = 1 im_number_of_pages = 1
if save_all: if save_all:
try: im_number_of_pages = getattr(im, "n_frames", 1)
im_number_of_pages = im.n_frames
except AttributeError:
# Image format does not have n_frames.
# It is a single frame image
pass
number_of_pages += im_number_of_pages number_of_pages += im_number_of_pages
for i in range(im_number_of_pages): for i in range(im_number_of_pages):
image_refs.append(existing_pdf.next_object_id(0)) image_refs.append(existing_pdf.next_object_id(0))
@ -250,7 +248,9 @@ def _save(im, fp, filename, save_all=False):
page_number = 0 page_number = 0
for im_sequence in ims: for im_sequence in ims:
im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence] im_pages: ImageSequence.Iterator | list[Image.Image] = (
ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]
)
for im in im_pages: for im in im_pages:
image_ref, procset = _write_image(im, filename, existing_pdf, image_refs) image_ref, procset = _write_image(im, filename, existing_pdf, image_refs)

View File

@ -39,7 +39,7 @@ import struct
import warnings import warnings
import zlib import zlib
from enum import IntEnum from enum import IntEnum
from typing import IO, TYPE_CHECKING, Any, NoReturn from typing import IO, TYPE_CHECKING, Any, NamedTuple, NoReturn
from . import Image, ImageChops, ImageFile, ImagePalette, ImageSequence from . import Image, ImageChops, ImageFile, ImagePalette, ImageSequence
from ._binary import i16be as i16 from ._binary import i16be as i16
@ -144,7 +144,7 @@ def _safe_zlib_decompress(s):
return plaintext return plaintext
def _crc32(data, seed=0): def _crc32(data: bytes, seed: int = 0) -> int:
return zlib.crc32(data, seed) & 0xFFFFFFFF return zlib.crc32(data, seed) & 0xFFFFFFFF
@ -191,7 +191,7 @@ class ChunkStream:
assert self.queue is not None assert self.queue is not None
self.queue.append((cid, pos, length)) self.queue.append((cid, pos, length))
def call(self, cid, pos, length): def call(self, cid: bytes, pos: int, length: int) -> bytes:
"""Call the appropriate chunk handler""" """Call the appropriate chunk handler"""
logger.debug("STREAM %r %s %s", cid, pos, length) logger.debug("STREAM %r %s %s", cid, pos, length)
@ -1091,21 +1091,21 @@ _OUTMODES = {
} }
def putchunk(fp, cid, *data): def putchunk(fp: IO[bytes], cid: bytes, *data: bytes) -> None:
"""Write a PNG chunk (including CRC field)""" """Write a PNG chunk (including CRC field)"""
data = b"".join(data) byte_data = b"".join(data)
fp.write(o32(len(data)) + cid) fp.write(o32(len(byte_data)) + cid)
fp.write(data) fp.write(byte_data)
crc = _crc32(data, _crc32(cid)) crc = _crc32(byte_data, _crc32(cid))
fp.write(o32(crc)) fp.write(o32(crc))
class _idat: class _idat:
# wrap output from the encoder in IDAT chunks # wrap output from the encoder in IDAT chunks
def __init__(self, fp, chunk): def __init__(self, fp, chunk) -> None:
self.fp = fp self.fp = fp
self.chunk = chunk self.chunk = chunk
@ -1116,7 +1116,7 @@ class _idat:
class _fdat: class _fdat:
# wrap encoder output in fdAT chunks # wrap encoder output in fdAT chunks
def __init__(self, fp, chunk, seq_num): def __init__(self, fp: IO[bytes], chunk, seq_num: int) -> None:
self.fp = fp self.fp = fp
self.chunk = chunk self.chunk = chunk
self.seq_num = seq_num self.seq_num = seq_num
@ -1126,7 +1126,21 @@ class _fdat:
self.seq_num += 1 self.seq_num += 1
def _write_multiple_frames(im, fp, chunk, mode, rawmode, default_image, append_images): class _Frame(NamedTuple):
im: Image.Image
bbox: tuple[int, int, int, int] | None
encoderinfo: dict[str, Any]
def _write_multiple_frames(
im: Image.Image,
fp: IO[bytes],
chunk,
mode: str,
rawmode: str,
default_image: Image.Image | None,
append_images: list[Image.Image],
) -> Image.Image | None:
duration = im.encoderinfo.get("duration") duration = im.encoderinfo.get("duration")
loop = im.encoderinfo.get("loop", im.info.get("loop", 0)) loop = im.encoderinfo.get("loop", im.info.get("loop", 0))
disposal = im.encoderinfo.get("disposal", im.info.get("disposal", Disposal.OP_NONE)) disposal = im.encoderinfo.get("disposal", im.info.get("disposal", Disposal.OP_NONE))
@ -1137,7 +1151,7 @@ def _write_multiple_frames(im, fp, chunk, mode, rawmode, default_image, append_i
else: else:
chain = itertools.chain([im], append_images) chain = itertools.chain([im], append_images)
im_frames = [] im_frames: list[_Frame] = []
frame_count = 0 frame_count = 0
for im_seq in chain: for im_seq in chain:
for im_frame in ImageSequence.Iterator(im_seq): for im_frame in ImageSequence.Iterator(im_seq):
@ -1158,24 +1172,24 @@ def _write_multiple_frames(im, fp, chunk, mode, rawmode, default_image, append_i
if im_frames: if im_frames:
previous = im_frames[-1] previous = im_frames[-1]
prev_disposal = previous["encoderinfo"].get("disposal") prev_disposal = previous.encoderinfo.get("disposal")
prev_blend = previous["encoderinfo"].get("blend") prev_blend = previous.encoderinfo.get("blend")
if prev_disposal == Disposal.OP_PREVIOUS and len(im_frames) < 2: if prev_disposal == Disposal.OP_PREVIOUS and len(im_frames) < 2:
prev_disposal = Disposal.OP_BACKGROUND prev_disposal = Disposal.OP_BACKGROUND
if prev_disposal == Disposal.OP_BACKGROUND: if prev_disposal == Disposal.OP_BACKGROUND:
base_im = previous["im"].copy() base_im = previous.im.copy()
dispose = Image.core.fill("RGBA", im.size, (0, 0, 0, 0)) dispose = Image.core.fill("RGBA", im.size, (0, 0, 0, 0))
bbox = previous["bbox"] bbox = previous.bbox
if bbox: if bbox:
dispose = dispose.crop(bbox) dispose = dispose.crop(bbox)
else: else:
bbox = (0, 0) + im.size bbox = (0, 0) + im.size
base_im.paste(dispose, bbox) base_im.paste(dispose, bbox)
elif prev_disposal == Disposal.OP_PREVIOUS: elif prev_disposal == Disposal.OP_PREVIOUS:
base_im = im_frames[-2]["im"] base_im = im_frames[-2].im
else: else:
base_im = previous["im"] base_im = previous.im
delta = ImageChops.subtract_modulo( delta = ImageChops.subtract_modulo(
im_frame.convert("RGBA"), base_im.convert("RGBA") im_frame.convert("RGBA"), base_im.convert("RGBA")
) )
@ -1186,14 +1200,14 @@ def _write_multiple_frames(im, fp, chunk, mode, rawmode, default_image, append_i
and prev_blend == encoderinfo.get("blend") and prev_blend == encoderinfo.get("blend")
and "duration" in encoderinfo and "duration" in encoderinfo
): ):
previous["encoderinfo"]["duration"] += encoderinfo["duration"] previous.encoderinfo["duration"] += encoderinfo["duration"]
continue continue
else: else:
bbox = None bbox = None
im_frames.append({"im": im_frame, "bbox": bbox, "encoderinfo": encoderinfo}) im_frames.append(_Frame(im_frame, bbox, encoderinfo))
if len(im_frames) == 1 and not default_image: if len(im_frames) == 1 and not default_image:
return im_frames[0]["im"] return im_frames[0].im
# animation control # animation control
chunk( chunk(
@ -1211,14 +1225,14 @@ def _write_multiple_frames(im, fp, chunk, mode, rawmode, default_image, append_i
seq_num = 0 seq_num = 0
for frame, frame_data in enumerate(im_frames): for frame, frame_data in enumerate(im_frames):
im_frame = frame_data["im"] im_frame = frame_data.im
if not frame_data["bbox"]: if not frame_data.bbox:
bbox = (0, 0) + im_frame.size bbox = (0, 0) + im_frame.size
else: else:
bbox = frame_data["bbox"] bbox = frame_data.bbox
im_frame = im_frame.crop(bbox) im_frame = im_frame.crop(bbox)
size = im_frame.size size = im_frame.size
encoderinfo = frame_data["encoderinfo"] encoderinfo = frame_data.encoderinfo
frame_duration = int(round(encoderinfo.get("duration", 0))) frame_duration = int(round(encoderinfo.get("duration", 0)))
frame_disposal = encoderinfo.get("disposal", disposal) frame_disposal = encoderinfo.get("disposal", disposal)
frame_blend = encoderinfo.get("blend", blend) frame_blend = encoderinfo.get("blend", blend)
@ -1253,13 +1267,16 @@ def _write_multiple_frames(im, fp, chunk, mode, rawmode, default_image, append_i
[("zip", (0, 0) + im_frame.size, 0, rawmode)], [("zip", (0, 0) + im_frame.size, 0, rawmode)],
) )
seq_num = fdat_chunks.seq_num seq_num = fdat_chunks.seq_num
return None
def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
_save(im, fp, filename, save_all=True) _save(im, fp, filename, save_all=True)
def _save(im, fp, filename, chunk=putchunk, save_all=False): def _save(
im: Image.Image, fp, filename: str | bytes, chunk=putchunk, save_all: bool = False
) -> None:
# save an image to disk (called by the save method) # save an image to disk (called by the save method)
if save_all: if save_all:
@ -1435,12 +1452,15 @@ def _save(im, fp, filename, chunk=putchunk, save_all=False):
exif = exif[6:] exif = exif[6:]
chunk(fp, b"eXIf", exif) chunk(fp, b"eXIf", exif)
single_im: Image.Image | None = im
if save_all: if save_all:
im = _write_multiple_frames( single_im = _write_multiple_frames(
im, fp, chunk, mode, rawmode, default_image, append_images im, fp, chunk, mode, rawmode, default_image, append_images
) )
if im: if single_im:
ImageFile._save(im, _idat(fp, chunk), [("zip", (0, 0) + im.size, 0, rawmode)]) ImageFile._save(
single_im, _idat(fp, chunk), [("zip", (0, 0) + single_im.size, 0, rawmode)]
)
if info: if info:
for info_chunk in info.chunks: for info_chunk in info.chunks:
@ -1461,7 +1481,7 @@ def _save(im, fp, filename, chunk=putchunk, save_all=False):
# PNG chunk converter # PNG chunk converter
def getchunks(im, **params): def getchunks(im: Image.Image, **params: Any) -> list[tuple[bytes, bytes, bytes]]:
"""Return a list of PNG chunks representing this image.""" """Return a list of PNG chunks representing this image."""
class collector: class collector:
@ -1470,19 +1490,19 @@ def getchunks(im, **params):
def write(self, data: bytes) -> None: def write(self, data: bytes) -> None:
pass pass
def append(self, chunk: bytes) -> None: def append(self, chunk: tuple[bytes, bytes, bytes]) -> None:
self.data.append(chunk) self.data.append(chunk)
def append(fp, cid, *data): def append(fp: collector, cid: bytes, *data: bytes) -> None:
data = b"".join(data) byte_data = b"".join(data)
crc = o32(_crc32(data, _crc32(cid))) crc = o32(_crc32(byte_data, _crc32(cid)))
fp.append((cid, data, crc)) fp.append((cid, byte_data, crc))
fp = collector() fp = collector()
try: try:
im.encoderinfo = params im.encoderinfo = params
_save(im, fp, None, append) _save(im, fp, "", append)
finally: finally:
del im.encoderinfo del im.encoderinfo

View File

@ -55,13 +55,3 @@ class TarIO(ContainerIO.ContainerIO[bytes]):
# Open region # Open region
super().__init__(self.fh, self.fh.tell(), size) super().__init__(self.fh, self.fh.tell(), size)
# Context manager support
def __enter__(self) -> TarIO:
return self
def __exit__(self, *args: object) -> None:
self.close()
def close(self) -> None:
self.fh.close()

View File

@ -380,12 +380,13 @@ class IFDRational(Rational):
__slots__ = ("_numerator", "_denominator", "_val") __slots__ = ("_numerator", "_denominator", "_val")
def __init__(self, value, denominator=1): def __init__(self, value, denominator: int = 1) -> None:
""" """
:param value: either an integer numerator, a :param value: either an integer numerator, a
float/rational/other number, or an IFDRational float/rational/other number, or an IFDRational
:param denominator: Optional integer denominator :param denominator: Optional integer denominator
""" """
self._val: Fraction | float
if isinstance(value, IFDRational): if isinstance(value, IFDRational):
self._numerator = value.numerator self._numerator = value.numerator
self._denominator = value.denominator self._denominator = value.denominator
@ -682,13 +683,13 @@ class ImageFileDirectory_v2(_IFDv2Base):
val = (val,) val = (val,)
return val return val
def __contains__(self, tag): def __contains__(self, tag: object) -> bool:
return tag in self._tags_v2 or tag in self._tagdata return tag in self._tags_v2 or tag in self._tagdata
def __setitem__(self, tag, value): def __setitem__(self, tag, value) -> None:
self._setitem(tag, value, self.legacy_api) self._setitem(tag, value, self.legacy_api)
def _setitem(self, tag, value, legacy_api): def _setitem(self, tag, value, legacy_api) -> None:
basetypes = (Number, bytes, str) basetypes = (Number, bytes, str)
info = TiffTags.lookup(tag, self.group) info = TiffTags.lookup(tag, self.group)
@ -804,7 +805,7 @@ class ImageFileDirectory_v2(_IFDv2Base):
return data return data
@_register_writer(1) # Basic type, except for the legacy API. @_register_writer(1) # Basic type, except for the legacy API.
def write_byte(self, data): def write_byte(self, data) -> bytes:
if isinstance(data, IFDRational): if isinstance(data, IFDRational):
data = int(data) data = int(data)
if isinstance(data, int): if isinstance(data, int):
@ -818,7 +819,7 @@ class ImageFileDirectory_v2(_IFDv2Base):
return data.decode("latin-1", "replace") return data.decode("latin-1", "replace")
@_register_writer(2) @_register_writer(2)
def write_string(self, value): def write_string(self, value) -> bytes:
# remerge of https://github.com/python-pillow/Pillow/pull/1416 # remerge of https://github.com/python-pillow/Pillow/pull/1416
if isinstance(value, int): if isinstance(value, int):
value = str(value) value = str(value)
@ -836,7 +837,7 @@ class ImageFileDirectory_v2(_IFDv2Base):
return tuple(combine(num, denom) for num, denom in zip(vals[::2], vals[1::2])) return tuple(combine(num, denom) for num, denom in zip(vals[::2], vals[1::2]))
@_register_writer(5) @_register_writer(5)
def write_rational(self, *values): def write_rational(self, *values) -> bytes:
return b"".join( return b"".join(
self._pack("2L", *_limit_rational(frac, 2**32 - 1)) for frac in values self._pack("2L", *_limit_rational(frac, 2**32 - 1)) for frac in values
) )
@ -846,7 +847,7 @@ class ImageFileDirectory_v2(_IFDv2Base):
return data return data
@_register_writer(7) @_register_writer(7)
def write_undefined(self, value): def write_undefined(self, value) -> bytes:
if isinstance(value, IFDRational): if isinstance(value, IFDRational):
value = int(value) value = int(value)
if isinstance(value, int): if isinstance(value, int):
@ -863,13 +864,13 @@ class ImageFileDirectory_v2(_IFDv2Base):
return tuple(combine(num, denom) for num, denom in zip(vals[::2], vals[1::2])) return tuple(combine(num, denom) for num, denom in zip(vals[::2], vals[1::2]))
@_register_writer(10) @_register_writer(10)
def write_signed_rational(self, *values): def write_signed_rational(self, *values) -> bytes:
return b"".join( return b"".join(
self._pack("2l", *_limit_signed_rational(frac, 2**31 - 1, -(2**31))) self._pack("2l", *_limit_signed_rational(frac, 2**31 - 1, -(2**31)))
for frac in values for frac in values
) )
def _ensure_read(self, fp, size): def _ensure_read(self, fp: IO[bytes], size: int) -> bytes:
ret = fp.read(size) ret = fp.read(size)
if len(ret) != size: if len(ret) != size:
msg = ( msg = (
@ -1023,7 +1024,7 @@ class ImageFileDirectory_v2(_IFDv2Base):
return result return result
def save(self, fp): def save(self, fp: IO[bytes]) -> int:
if fp.tell() == 0: # skip TIFF header on subsequent pages if fp.tell() == 0: # skip TIFF header on subsequent pages
# tiff header -- PIL always starts the first IFD at offset 8 # tiff header -- PIL always starts the first IFD at offset 8
fp.write(self._prefix + self._pack("HL", 42, 8)) fp.write(self._prefix + self._pack("HL", 42, 8))
@ -1063,7 +1064,7 @@ class ImageFileDirectory_v1(ImageFileDirectory_v2):
.. deprecated:: 3.0.0 .. deprecated:: 3.0.0
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self._legacy_api = True self._legacy_api = True
@ -1075,7 +1076,7 @@ class ImageFileDirectory_v1(ImageFileDirectory_v2):
"""Dictionary of tag types""" """Dictionary of tag types"""
@classmethod @classmethod
def from_v2(cls, original): def from_v2(cls, original) -> ImageFileDirectory_v1:
"""Returns an """Returns an
:py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`
instance with the same data as is contained in the original instance with the same data as is contained in the original
@ -1109,7 +1110,7 @@ class ImageFileDirectory_v1(ImageFileDirectory_v2):
ifd._tags_v2 = dict(self._tags_v2) ifd._tags_v2 = dict(self._tags_v2)
return ifd return ifd
def __contains__(self, tag): def __contains__(self, tag: object) -> bool:
return tag in self._tags_v1 or tag in self._tagdata return tag in self._tags_v1 or tag in self._tagdata
def __len__(self) -> int: def __len__(self) -> int:
@ -1118,7 +1119,7 @@ class ImageFileDirectory_v1(ImageFileDirectory_v2):
def __iter__(self): def __iter__(self):
return iter(set(self._tagdata) | set(self._tags_v1)) return iter(set(self._tagdata) | set(self._tags_v1))
def __setitem__(self, tag, value): def __setitem__(self, tag, value) -> None:
for legacy_api in (False, True): for legacy_api in (False, True):
self._setitem(tag, value, legacy_api) self._setitem(tag, value, legacy_api)
@ -1168,7 +1169,7 @@ class TiffImageFile(ImageFile.ImageFile):
self.tag_v2 = ImageFileDirectory_v2(ifh) self.tag_v2 = ImageFileDirectory_v2(ifh)
# legacy IFD entries will be filled in later # legacy IFD entries will be filled in later
self.ifd = None self.ifd: ImageFileDirectory_v1 | None = None
# setup frame pointers # setup frame pointers
self.__first = self.__next = self.tag_v2.next self.__first = self.__next = self.tag_v2.next
@ -1389,7 +1390,7 @@ class TiffImageFile(ImageFile.ImageFile):
return Image.Image.load(self) return Image.Image.load(self)
def _setup(self): def _setup(self) -> None:
"""Setup this image object based on current tags""" """Setup this image object based on current tags"""
if 0xBC01 in self.tag_v2: if 0xBC01 in self.tag_v2:
@ -1578,13 +1579,13 @@ class TiffImageFile(ImageFile.ImageFile):
# adjust stride width accordingly # adjust stride width accordingly
stride /= bps_count stride /= bps_count
a = (tile_rawmode, int(stride), 1) args = (tile_rawmode, int(stride), 1)
self.tile.append( self.tile.append(
( (
self._compression, self._compression,
(x, y, min(x + w, xsize), min(y + h, ysize)), (x, y, min(x + w, xsize), min(y + h, ysize)),
offset, offset,
a, args,
) )
) )
x = x + w x = x + w
@ -1979,7 +1980,7 @@ class AppendingTiffWriter:
521, # JPEGACTables 521, # JPEGACTables
} }
def __init__(self, fn, new=False): def __init__(self, fn, new: bool = False) -> None:
if hasattr(fn, "read"): if hasattr(fn, "read"):
self.f = fn self.f = fn
self.close_fp = False self.close_fp = False
@ -2056,7 +2057,7 @@ class AppendingTiffWriter:
def tell(self) -> int: def tell(self) -> int:
return self.f.tell() - self.offsetOfNewPage return self.f.tell() - self.offsetOfNewPage
def seek(self, offset, whence=io.SEEK_SET): def seek(self, offset: int, whence=io.SEEK_SET) -> int:
if whence == os.SEEK_SET: if whence == os.SEEK_SET:
offset += self.offsetOfNewPage offset += self.offsetOfNewPage

View File

@ -24,8 +24,11 @@ and has been tested with a few sample files found using google.
""" """
from __future__ import annotations from __future__ import annotations
from typing import IO
from . import Image, ImageFile from . import Image, ImageFile
from ._binary import i32le as i32 from ._binary import i32le as i32
from ._typing import StrOrBytesPath
class WalImageFile(ImageFile.ImageFile): class WalImageFile(ImageFile.ImageFile):
@ -58,7 +61,7 @@ class WalImageFile(ImageFile.ImageFile):
return Image.Image.load(self) return Image.Image.load(self)
def open(filename): def open(filename: StrOrBytesPath | IO[bytes]) -> WalImageFile:
""" """
Load texture from a Quake2 WAL texture file. Load texture from a Quake2 WAL texture file.

View File

@ -80,7 +80,8 @@ typedef struct Tcl_Command_ *Tcl_Command;
typedef void *ClientData; typedef void *ClientData;
typedef int(Tcl_CmdProc)( typedef int(Tcl_CmdProc)(
ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]); ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]
);
typedef void(Tcl_CmdDeleteProc)(ClientData clientData); typedef void(Tcl_CmdDeleteProc)(ClientData clientData);
/* Typedefs derived from function signatures in Tcl header */ /* Typedefs derived from function signatures in Tcl header */
@ -90,7 +91,8 @@ typedef Tcl_Command (*Tcl_CreateCommand_t)(
const char *cmdName, const char *cmdName,
Tcl_CmdProc *proc, Tcl_CmdProc *proc,
ClientData clientData, ClientData clientData,
Tcl_CmdDeleteProc *deleteProc); Tcl_CmdDeleteProc *deleteProc
);
/* Tcl_AppendResult */ /* Tcl_AppendResult */
typedef void (*Tcl_AppendResult_t)(Tcl_Interp *interp, ...); typedef void (*Tcl_AppendResult_t)(Tcl_Interp *interp, ...);
@ -127,7 +129,8 @@ typedef int (*Tk_PhotoPutBlock_t)(
int y, int y,
int width, int width,
int height, int height,
int compRule); int compRule
);
/* Tk_FindPhoto */ /* Tk_FindPhoto */
typedef Tk_PhotoHandle (*Tk_FindPhoto_t)(Tcl_Interp *interp, const char *imageName); typedef Tk_PhotoHandle (*Tk_FindPhoto_t)(Tcl_Interp *interp, const char *imageName);
/* Tk_PhotoGetImage */ /* Tk_PhotoGetImage */

View File

@ -73,14 +73,16 @@ ImagingFind(const char *name) {
static int static int
PyImagingPhotoPut( PyImagingPhotoPut(
ClientData clientdata, Tcl_Interp *interp, int argc, const char **argv) { ClientData clientdata, Tcl_Interp *interp, int argc, const char **argv
) {
Imaging im; Imaging im;
Tk_PhotoHandle photo; Tk_PhotoHandle photo;
Tk_PhotoImageBlock block; Tk_PhotoImageBlock block;
if (argc != 3) { if (argc != 3) {
TCL_APPEND_RESULT( TCL_APPEND_RESULT(
interp, "usage: ", argv[0], " destPhoto srcImage", (char *)NULL); interp, "usage: ", argv[0], " destPhoto srcImage", (char *)NULL
);
return TCL_ERROR; return TCL_ERROR;
} }
@ -128,14 +130,16 @@ PyImagingPhotoPut(
block.pixelPtr = (unsigned char *)im->block; block.pixelPtr = (unsigned char *)im->block;
TK_PHOTO_PUT_BLOCK( TK_PHOTO_PUT_BLOCK(
interp, photo, &block, 0, 0, block.width, block.height, TK_PHOTO_COMPOSITE_SET); interp, photo, &block, 0, 0, block.width, block.height, TK_PHOTO_COMPOSITE_SET
);
return TCL_OK; return TCL_OK;
} }
static int static int
PyImagingPhotoGet( PyImagingPhotoGet(
ClientData clientdata, Tcl_Interp *interp, int argc, const char **argv) { ClientData clientdata, Tcl_Interp *interp, int argc, const char **argv
) {
Imaging im; Imaging im;
Tk_PhotoHandle photo; Tk_PhotoHandle photo;
Tk_PhotoImageBlock block; Tk_PhotoImageBlock block;
@ -143,7 +147,8 @@ PyImagingPhotoGet(
if (argc != 3) { if (argc != 3) {
TCL_APPEND_RESULT( TCL_APPEND_RESULT(
interp, "usage: ", argv[0], " srcPhoto destImage", (char *)NULL); interp, "usage: ", argv[0], " srcPhoto destImage", (char *)NULL
);
return TCL_ERROR; return TCL_ERROR;
} }
@ -183,13 +188,15 @@ TkImaging_Init(Tcl_Interp *interp) {
"PyImagingPhoto", "PyImagingPhoto",
PyImagingPhotoPut, PyImagingPhotoPut,
(ClientData)0, (ClientData)0,
(Tcl_CmdDeleteProc *)NULL); (Tcl_CmdDeleteProc *)NULL
);
TCL_CREATE_COMMAND( TCL_CREATE_COMMAND(
interp, interp,
"PyImagingPhotoGet", "PyImagingPhotoGet",
PyImagingPhotoGet, PyImagingPhotoGet,
(ClientData)0, (ClientData)0,
(Tcl_CmdDeleteProc *)NULL); (Tcl_CmdDeleteProc *)NULL
);
} }
/* /*
@ -394,7 +401,8 @@ _func_loader(void *lib) {
} }
return ( return (
(TK_PHOTO_PUT_BLOCK = (Tk_PhotoPutBlock_t)_dfunc(lib, "Tk_PhotoPutBlock")) == (TK_PHOTO_PUT_BLOCK = (Tk_PhotoPutBlock_t)_dfunc(lib, "Tk_PhotoPutBlock")) ==
NULL); NULL
);
} }
int int

View File

@ -290,7 +290,8 @@ ImagingError_ModeError(void) {
void * void *
ImagingError_ValueError(const char *message) { ImagingError_ValueError(const char *message) {
PyErr_SetString( PyErr_SetString(
PyExc_ValueError, (message) ? (char *)message : "unrecognized argument value"); PyExc_ValueError, (message) ? (char *)message : "unrecognized argument value"
);
return NULL; return NULL;
} }
@ -501,7 +502,8 @@ getpixel(Imaging im, ImagingAccess access, int x, int y) {
return Py_BuildValue("BBB", pixel.b[0], pixel.b[1], pixel.b[2]); return Py_BuildValue("BBB", pixel.b[0], pixel.b[1], pixel.b[2]);
case 4: case 4:
return Py_BuildValue( return Py_BuildValue(
"BBBB", pixel.b[0], pixel.b[1], pixel.b[2], pixel.b[3]); "BBBB", pixel.b[0], pixel.b[1], pixel.b[2], pixel.b[3]
);
} }
break; break;
case IMAGING_TYPE_INT32: case IMAGING_TYPE_INT32:
@ -552,7 +554,8 @@ getink(PyObject *color, Imaging im, char *ink) {
rIsInt = 1; rIsInt = 1;
} else if (im->bands == 1) { } else if (im->bands == 1) {
PyErr_SetString( PyErr_SetString(
PyExc_TypeError, "color must be int or single-element tuple"); PyExc_TypeError, "color must be int or single-element tuple"
);
return NULL; return NULL;
} else if (tupleSize == -1) { } else if (tupleSize == -1) {
PyErr_SetString(PyExc_TypeError, "color must be int or tuple"); PyErr_SetString(PyExc_TypeError, "color must be int or tuple");
@ -568,8 +571,8 @@ getink(PyObject *color, Imaging im, char *ink) {
if (rIsInt != 1) { if (rIsInt != 1) {
if (tupleSize != 1) { if (tupleSize != 1) {
PyErr_SetString( PyErr_SetString(
PyExc_TypeError, PyExc_TypeError, "color must be int or single-element tuple"
"color must be int or single-element tuple"); );
return NULL; return NULL;
} else if (!PyArg_ParseTuple(color, "L", &r)) { } else if (!PyArg_ParseTuple(color, "L", &r)) {
return NULL; return NULL;
@ -590,7 +593,8 @@ getink(PyObject *color, Imaging im, char *ink) {
if (tupleSize != 1 && tupleSize != 2) { if (tupleSize != 1 && tupleSize != 2) {
PyErr_SetString( PyErr_SetString(
PyExc_TypeError, PyExc_TypeError,
"color must be int, or tuple of one or two elements"); "color must be int, or tuple of one or two elements"
);
return NULL; return NULL;
} else if (!PyArg_ParseTuple(color, "L|i", &r, &a)) { } else if (!PyArg_ParseTuple(color, "L|i", &r, &a)) {
return NULL; return NULL;
@ -601,7 +605,8 @@ getink(PyObject *color, Imaging im, char *ink) {
PyErr_SetString( PyErr_SetString(
PyExc_TypeError, PyExc_TypeError,
"color must be int, or tuple of one, three or four " "color must be int, or tuple of one, three or four "
"elements"); "elements"
);
return NULL; return NULL;
} else if (!PyArg_ParseTuple(color, "Lii|i", &r, &g, &b, &a)) { } else if (!PyArg_ParseTuple(color, "Lii|i", &r, &g, &b, &a)) {
return NULL; return NULL;
@ -642,7 +647,8 @@ getink(PyObject *color, Imaging im, char *ink) {
} else if (tupleSize != 3) { } else if (tupleSize != 3) {
PyErr_SetString( PyErr_SetString(
PyExc_TypeError, PyExc_TypeError,
"color must be int, or tuple of one or three elements"); "color must be int, or tuple of one or three elements"
);
return NULL; return NULL;
} else if (!PyArg_ParseTuple(color, "iiL", &b, &g, &r)) { } else if (!PyArg_ParseTuple(color, "iiL", &b, &g, &r)) {
return NULL; return NULL;
@ -768,7 +774,8 @@ _alpha_composite(ImagingObject *self, PyObject *args) {
ImagingObject *imagep2; ImagingObject *imagep2;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "O!O!", &Imaging_Type, &imagep1, &Imaging_Type, &imagep2)) { args, "O!O!", &Imaging_Type, &imagep1, &Imaging_Type, &imagep2
)) {
return NULL; return NULL;
} }
@ -783,7 +790,8 @@ _blend(ImagingObject *self, PyObject *args) {
alpha = 0.5; alpha = 0.5;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "O!O!|d", &Imaging_Type, &imagep1, &Imaging_Type, &imagep2, &alpha)) { args, "O!O!|d", &Imaging_Type, &imagep1, &Imaging_Type, &imagep2, &alpha
)) {
return NULL; return NULL;
} }
@ -862,7 +870,8 @@ _prepare_lut_table(PyObject *table, Py_ssize_t table_size) {
break; break;
case TYPE_FLOAT32: case TYPE_FLOAT32:
memcpy( memcpy(
&item, ((char *)table_data) + i * sizeof(FLOAT32), sizeof(FLOAT32)); &item, ((char *)table_data) + i * sizeof(FLOAT32), sizeof(FLOAT32)
);
break; break;
case TYPE_DOUBLE: case TYPE_DOUBLE:
memcpy(&dtmp, ((char *)table_data) + i * sizeof(dtmp), sizeof(dtmp)); memcpy(&dtmp, ((char *)table_data) + i * sizeof(dtmp), sizeof(dtmp));
@ -913,7 +922,8 @@ _color_lut_3d(ImagingObject *self, PyObject *args) {
&size1D, &size1D,
&size2D, &size2D,
&size3D, &size3D,
&table)) { &table
)) {
return NULL; return NULL;
} }
@ -931,7 +941,8 @@ _color_lut_3d(ImagingObject *self, PyObject *args) {
if (2 > size1D || size1D > 65 || 2 > size2D || size2D > 65 || 2 > size3D || if (2 > size1D || size1D > 65 || 2 > size2D || size2D > 65 || 2 > size3D ||
size3D > 65) { size3D > 65) {
PyErr_SetString( PyErr_SetString(
PyExc_ValueError, "Table size in any dimension should be from 2 to 65"); PyExc_ValueError, "Table size in any dimension should be from 2 to 65"
);
return NULL; return NULL;
} }
@ -949,13 +960,8 @@ _color_lut_3d(ImagingObject *self, PyObject *args) {
} }
if (!ImagingColorLUT3D_linear( if (!ImagingColorLUT3D_linear(
imOut, imOut, self->image, table_channels, size1D, size2D, size3D, prepared_table
self->image, )) {
table_channels,
size1D,
size2D,
size3D,
prepared_table)) {
free(prepared_table); free(prepared_table);
ImagingDelete(imOut); ImagingDelete(imOut);
return NULL; return NULL;
@ -979,7 +985,8 @@ _convert(ImagingObject *self, PyObject *args) {
if (!PyImaging_Check(paletteimage)) { if (!PyImaging_Check(paletteimage)) {
PyObject_Print((PyObject *)paletteimage, stderr, 0); PyObject_Print((PyObject *)paletteimage, stderr, 0);
PyErr_SetString( PyErr_SetString(
PyExc_ValueError, "palette argument must be image with mode 'P'"); PyExc_ValueError, "palette argument must be image with mode 'P'"
);
return NULL; return NULL;
} }
if (paletteimage->image->palette == NULL) { if (paletteimage->image->palette == NULL) {
@ -989,7 +996,8 @@ _convert(ImagingObject *self, PyObject *args) {
} }
return PyImagingNew(ImagingConvert( return PyImagingNew(ImagingConvert(
self->image, mode, paletteimage ? paletteimage->image->palette : NULL, dither)); self->image, mode, paletteimage ? paletteimage->image->palette : NULL, dither
));
} }
static PyObject * static PyObject *
@ -997,7 +1005,8 @@ _convert2(ImagingObject *self, PyObject *args) {
ImagingObject *imagep1; ImagingObject *imagep1;
ImagingObject *imagep2; ImagingObject *imagep2;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "O!O!", &Imaging_Type, &imagep1, &Imaging_Type, &imagep2)) { args, "O!O!", &Imaging_Type, &imagep1, &Imaging_Type, &imagep2
)) {
return NULL; return NULL;
} }
@ -1030,7 +1039,8 @@ _convert_matrix(ImagingObject *self, PyObject *args) {
m + 8, m + 8,
m + 9, m + 9,
m + 10, m + 10,
m + 11)) { m + 11
)) {
return NULL; return NULL;
} }
} }
@ -1091,7 +1101,8 @@ _filter(ImagingObject *self, PyObject *args) {
float divisor, offset; float divisor, offset;
PyObject *kernel = NULL; PyObject *kernel = NULL;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "(ii)ffO", &xsize, &ysize, &divisor, &offset, &kernel)) { args, "(ii)ffO", &xsize, &ysize, &divisor, &offset, &kernel
)) {
return NULL; return NULL;
} }
@ -1174,7 +1185,8 @@ _getpalette(ImagingObject *self, PyObject *args) {
} }
pack( pack(
(UINT8 *)PyBytes_AsString(palette), self->image->palette->palette, palettesize); (UINT8 *)PyBytes_AsString(palette), self->image->palette->palette, palettesize
);
return palette; return palette;
} }
@ -1268,7 +1280,8 @@ union hist_extrema {
static union hist_extrema * static union hist_extrema *
parse_histogram_extremap( parse_histogram_extremap(
ImagingObject *self, PyObject *extremap, union hist_extrema *ep) { ImagingObject *self, PyObject *extremap, union hist_extrema *ep
) {
int i0, i1; int i0, i1;
double f0, f1; double f0, f1;
@ -1428,7 +1441,8 @@ _paste(ImagingObject *self, PyObject *args) {
int x0, y0, x1, y1; int x0, y0, x1, y1;
ImagingObject *maskp = NULL; ImagingObject *maskp = NULL;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "O(iiii)|O!", &source, &x0, &y0, &x1, &y1, &Imaging_Type, &maskp)) { args, "O(iiii)|O!", &source, &x0, &y0, &x1, &y1, &Imaging_Type, &maskp
)) {
return NULL; return NULL;
} }
@ -1440,14 +1454,16 @@ _paste(ImagingObject *self, PyObject *args) {
x0, x0,
y0, y0,
x1, x1,
y1); y1
);
} else { } else {
if (!getink(source, self->image, ink)) { if (!getink(source, self->image, ink)) {
return NULL; return NULL;
} }
status = ImagingFill2( status = ImagingFill2(
self->image, ink, (maskp) ? maskp->image : NULL, x0, y0, x1, y1); self->image, ink, (maskp) ? maskp->image : NULL, x0, y0, x1, y1
);
} }
if (status < 0) { if (status < 0) {
@ -1766,7 +1782,8 @@ _putpalette(ImagingObject *self, PyObject *args) {
UINT8 *palette; UINT8 *palette;
Py_ssize_t palettesize; Py_ssize_t palettesize;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "ssy#", &palette_mode, &rawmode, &palette, &palettesize)) { args, "ssy#", &palette_mode, &rawmode, &palette, &palettesize
)) {
return NULL; return NULL;
} }
@ -1924,7 +1941,8 @@ _resize(ImagingObject *self, PyObject *args) {
&box[0], &box[0],
&box[1], &box[1],
&box[2], &box[2],
&box[3])) { &box[3]
)) {
return NULL; return NULL;
} }
@ -1960,7 +1978,8 @@ _resize(ImagingObject *self, PyObject *args) {
imOut = ImagingNewDirty(imIn->mode, (ImagingNewParams){xsize, ysize}); imOut = ImagingNewDirty(imIn->mode, (ImagingNewParams){xsize, ysize});
imOut = ImagingTransform( imOut = ImagingTransform(
imOut, imIn, IMAGING_TRANSFORM_AFFINE, 0, 0, xsize, ysize, a, filter, 1); imOut, imIn, IMAGING_TRANSFORM_AFFINE, 0, 0, xsize, ysize, a, filter, 1
);
} else { } else {
imOut = ImagingResample(imIn, xsize, ysize, filter, box); imOut = ImagingResample(imIn, xsize, ysize, filter, box);
} }
@ -1981,14 +2000,8 @@ _reduce(ImagingObject *self, PyObject *args) {
box[3] = imIn->ysize; box[3] = imIn->ysize;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, args, "(ii)|(iiii)", &xscale, &yscale, &box[0], &box[1], &box[2], &box[3]
"(ii)|(iiii)", )) {
&xscale,
&yscale,
&box[0],
&box[1],
&box[2],
&box[3])) {
return NULL; return NULL;
} }
@ -2090,7 +2103,8 @@ _transform(ImagingObject *self, PyObject *args) {
&method, &method,
&data, &data,
&filter, &filter,
&fill)) { &fill
)) {
return NULL; return NULL;
} }
@ -2114,7 +2128,8 @@ _transform(ImagingObject *self, PyObject *args) {
} }
imOut = ImagingTransform( imOut = ImagingTransform(
self->image, imagep->image, method, x0, y0, x1, y1, a, filter, fill); self->image, imagep->image, method, x0, y0, x1, y1, a, filter, fill
);
free(a); free(a);
@ -2291,7 +2306,13 @@ _getcolors(ImagingObject *self, PyObject *args) {
for (i = 0; i < colors; i++) { for (i = 0; i < colors; i++) {
ImagingColorItem *v = &items[i]; ImagingColorItem *v = &items[i];
PyObject *item = Py_BuildValue( PyObject *item = Py_BuildValue(
"iN", v->count, getpixel(self->image, self->access, v->x, v->y)); "iN", v->count, getpixel(self->image, self->access, v->x, v->y)
);
if (item == NULL) {
Py_DECREF(out);
free(items);
return NULL;
}
PyList_SetItem(out, i, item); PyList_SetItem(out, i, item);
} }
} }
@ -2352,14 +2373,16 @@ _getprojection(ImagingObject *self) {
} }
ImagingGetProjection( ImagingGetProjection(
self->image, (unsigned char *)xprofile, (unsigned char *)yprofile); self->image, (unsigned char *)xprofile, (unsigned char *)yprofile
);
result = Py_BuildValue( result = Py_BuildValue(
"y#y#", "y#y#",
xprofile, xprofile,
(Py_ssize_t)self->image->xsize, (Py_ssize_t)self->image->xsize,
yprofile, yprofile,
(Py_ssize_t)self->image->ysize); (Py_ssize_t)self->image->ysize
);
free(xprofile); free(xprofile);
free(yprofile); free(yprofile);
@ -2433,7 +2456,8 @@ _merge(PyObject *self, PyObject *args) {
&Imaging_Type, &Imaging_Type,
&band2, &band2,
&Imaging_Type, &Imaging_Type,
&band3)) { &band3
)) {
return NULL; return NULL;
} }
@ -2679,7 +2703,8 @@ _font_new(PyObject *self_, PyObject *args) {
unsigned char *glyphdata; unsigned char *glyphdata;
Py_ssize_t glyphdata_length; Py_ssize_t glyphdata_length;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "O!y#", &Imaging_Type, &imagep, &glyphdata, &glyphdata_length)) { args, "O!y#", &Imaging_Type, &imagep, &glyphdata, &glyphdata_length
)) {
return NULL; return NULL;
} }
@ -2838,7 +2863,8 @@ _font_getmask(ImagingFontObject *self, PyObject *args) {
if (i == 0 || text[i] != text[i - 1]) { if (i == 0 || text[i] != text[i - 1]) {
ImagingDelete(bitmap); ImagingDelete(bitmap);
bitmap = ImagingCrop( bitmap = ImagingCrop(
self->bitmap, glyph->sx0, glyph->sy0, glyph->sx1, glyph->sy1); self->bitmap, glyph->sx0, glyph->sy0, glyph->sx1, glyph->sy1
);
if (!bitmap) { if (!bitmap) {
goto failed; goto failed;
} }
@ -2850,7 +2876,8 @@ _font_getmask(ImagingFontObject *self, PyObject *args) {
glyph->dx0 + x, glyph->dx0 + x,
glyph->dy0 + b, glyph->dy0 + b,
glyph->dx1 + x, glyph->dx1 + x,
glyph->dy1 + b); glyph->dy1 + b
);
if (status < 0) { if (status < 0) {
goto failed; goto failed;
} }
@ -2989,7 +3016,8 @@ _draw_arc(ImagingDrawObject *self, PyObject *args) {
end, end,
&ink, &ink,
width, width,
self->blend); self->blend
);
free(xy); free(xy);
@ -3019,13 +3047,15 @@ _draw_bitmap(ImagingDrawObject *self, PyObject *args) {
} }
if (n != 1) { if (n != 1) {
PyErr_SetString( PyErr_SetString(
PyExc_TypeError, "coordinate list must contain exactly 1 coordinate"); PyExc_TypeError, "coordinate list must contain exactly 1 coordinate"
);
free(xy); free(xy);
return NULL; return NULL;
} }
n = ImagingDrawBitmap( n = ImagingDrawBitmap(
self->image->image, (int)xy[0], (int)xy[1], bitmap->image, &ink, self->blend); self->image->image, (int)xy[0], (int)xy[1], bitmap->image, &ink, self->blend
);
free(xy); free(xy);
@ -3081,7 +3111,8 @@ _draw_chord(ImagingDrawObject *self, PyObject *args) {
&ink, &ink,
fill, fill,
width, width,
self->blend); self->blend
);
free(xy); free(xy);
@ -3135,7 +3166,8 @@ _draw_ellipse(ImagingDrawObject *self, PyObject *args) {
&ink, &ink,
fill, fill,
width, width,
self->blend); self->blend
);
free(xy); free(xy);
@ -3175,14 +3207,16 @@ _draw_lines(ImagingDrawObject *self, PyObject *args) {
(int)p[2], (int)p[2],
(int)p[3], (int)p[3],
&ink, &ink,
self->blend) < 0) { self->blend
) < 0) {
free(xy); free(xy);
return NULL; return NULL;
} }
} }
if (p) { /* draw last point */ if (p) { /* draw last point */
ImagingDrawPoint( ImagingDrawPoint(
self->image->image, (int)p[2], (int)p[3], &ink, self->blend); self->image->image, (int)p[2], (int)p[3], &ink, self->blend
);
} }
} else { } else {
for (i = 0; i < n - 1; i++) { for (i = 0; i < n - 1; i++) {
@ -3195,7 +3229,8 @@ _draw_lines(ImagingDrawObject *self, PyObject *args) {
(int)p[3], (int)p[3],
&ink, &ink,
width, width,
self->blend) < 0) { self->blend
) < 0) {
free(xy); free(xy);
return NULL; return NULL;
} }
@ -3227,7 +3262,8 @@ _draw_points(ImagingDrawObject *self, PyObject *args) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
double *p = &xy[i + i]; double *p = &xy[i + i];
if (ImagingDrawPoint( if (ImagingDrawPoint(
self->image->image, (int)p[0], (int)p[1], &ink, self->blend) < 0) { self->image->image, (int)p[0], (int)p[1], &ink, self->blend
) < 0) {
free(xy); free(xy);
return NULL; return NULL;
} }
@ -3316,7 +3352,8 @@ _draw_pieslice(ImagingDrawObject *self, PyObject *args) {
&ink, &ink,
fill, fill,
width, width,
self->blend); self->blend
);
free(xy); free(xy);
@ -3348,7 +3385,8 @@ _draw_polygon(ImagingDrawObject *self, PyObject *args) {
} }
if (n < 2) { if (n < 2) {
PyErr_SetString( PyErr_SetString(
PyExc_TypeError, "coordinate list must contain at least 2 coordinates"); PyExc_TypeError, "coordinate list must contain at least 2 coordinates"
);
free(xy); free(xy);
return NULL; return NULL;
} }
@ -3421,7 +3459,8 @@ _draw_rectangle(ImagingDrawObject *self, PyObject *args) {
&ink, &ink,
fill, fill,
width, width,
self->blend); self->blend
);
free(xy); free(xy);
@ -3561,7 +3600,8 @@ _effect_mandelbrot(ImagingObject *self, PyObject *args) {
&extent[1], &extent[1],
&extent[2], &extent[2],
&extent[3], &extent[3],
&quality)) { &quality
)) {
return NULL; return NULL;
} }
@ -3789,7 +3829,8 @@ _getattr_unsafe_ptrs(ImagingObject *self, void *closure) {
"image32", "image32",
self->image->image32, self->image->image32,
"image", "image",
self->image->image); self->image->image
);
} }
static struct PyGetSetDef getsetters[] = { static struct PyGetSetDef getsetters[] = {
@ -3799,7 +3840,8 @@ static struct PyGetSetDef getsetters[] = {
{"id", (getter)_getattr_id}, {"id", (getter)_getattr_id},
{"ptr", (getter)_getattr_ptr}, {"ptr", (getter)_getattr_ptr},
{"unsafe_ptrs", (getter)_getattr_unsafe_ptrs}, {"unsafe_ptrs", (getter)_getattr_unsafe_ptrs},
{NULL}}; {NULL}
};
/* basic sequence semantics */ /* basic sequence semantics */
@ -4108,9 +4150,8 @@ _set_blocks_max(PyObject *self, PyObject *args) {
if (blocks_max < 0) { if (blocks_max < 0) {
PyErr_SetString(PyExc_ValueError, "blocks_max should be greater than 0"); PyErr_SetString(PyExc_ValueError, "blocks_max should be greater than 0");
return NULL; return NULL;
} else if ( } else if ((unsigned long)blocks_max >
(unsigned long)blocks_max > SIZE_MAX / sizeof(ImagingDefaultArena.blocks_pool[0])) {
SIZE_MAX / sizeof(ImagingDefaultArena.blocks_pool[0])) {
PyErr_SetString(PyExc_ValueError, "blocks_max is too large"); PyErr_SetString(PyExc_ValueError, "blocks_max is too large");
return NULL; return NULL;
} }
@ -4465,7 +4506,8 @@ setup_module(PyObject *m) {
PyObject *pillow_version = PyUnicode_FromString(version); PyObject *pillow_version = PyUnicode_FromString(version);
PyDict_SetItemString( PyDict_SetItemString(
d, "PILLOW_VERSION", pillow_version ? pillow_version : Py_None); d, "PILLOW_VERSION", pillow_version ? pillow_version : Py_None
);
Py_XDECREF(pillow_version); Py_XDECREF(pillow_version);
return 0; return 0;
@ -4490,5 +4532,9 @@ PyInit__imaging(void) {
return NULL; return NULL;
} }
#ifdef Py_GIL_DISABLED
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
#endif
return m; return m;
} }

View File

@ -331,7 +331,8 @@ pyCMScopyAux(cmsHTRANSFORM hTransform, Imaging imDst, const Imaging imSrc) {
memcpy( memcpy(
pDstExtras + x * dstChunkSize, pDstExtras + x * dstChunkSize,
pSrcExtras + x * srcChunkSize, pSrcExtras + x * srcChunkSize,
channelSize); channelSize
);
} }
} }
} }
@ -373,7 +374,8 @@ _buildTransform(
char *sInMode, char *sInMode,
char *sOutMode, char *sOutMode,
int iRenderingIntent, int iRenderingIntent,
cmsUInt32Number cmsFLAGS) { cmsUInt32Number cmsFLAGS
) {
cmsHTRANSFORM hTransform; cmsHTRANSFORM hTransform;
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
@ -385,7 +387,8 @@ _buildTransform(
hOutputProfile, hOutputProfile,
findLCMStype(sOutMode), findLCMStype(sOutMode),
iRenderingIntent, iRenderingIntent,
cmsFLAGS); cmsFLAGS
);
Py_END_ALLOW_THREADS; Py_END_ALLOW_THREADS;
@ -405,7 +408,8 @@ _buildProofTransform(
char *sOutMode, char *sOutMode,
int iRenderingIntent, int iRenderingIntent,
int iProofIntent, int iProofIntent,
cmsUInt32Number cmsFLAGS) { cmsUInt32Number cmsFLAGS
) {
cmsHTRANSFORM hTransform; cmsHTRANSFORM hTransform;
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
@ -419,7 +423,8 @@ _buildProofTransform(
hProofProfile, hProofProfile,
iRenderingIntent, iRenderingIntent,
iProofIntent, iProofIntent,
cmsFLAGS); cmsFLAGS
);
Py_END_ALLOW_THREADS; Py_END_ALLOW_THREADS;
@ -454,7 +459,8 @@ buildTransform(PyObject *self, PyObject *args) {
&sInMode, &sInMode,
&sOutMode, &sOutMode,
&iRenderingIntent, &iRenderingIntent,
&cmsFLAGS)) { &cmsFLAGS
)) {
return NULL; return NULL;
} }
@ -464,7 +470,8 @@ buildTransform(PyObject *self, PyObject *args) {
sInMode, sInMode,
sOutMode, sOutMode,
iRenderingIntent, iRenderingIntent,
cmsFLAGS); cmsFLAGS
);
if (!transform) { if (!transform) {
return NULL; return NULL;
@ -499,7 +506,8 @@ buildProofTransform(PyObject *self, PyObject *args) {
&sOutMode, &sOutMode,
&iRenderingIntent, &iRenderingIntent,
&iProofIntent, &iProofIntent,
&cmsFLAGS)) { &cmsFLAGS
)) {
return NULL; return NULL;
} }
@ -511,7 +519,8 @@ buildProofTransform(PyObject *self, PyObject *args) {
sOutMode, sOutMode,
iRenderingIntent, iRenderingIntent,
iProofIntent, iProofIntent,
cmsFLAGS); cmsFLAGS
);
if (!transform) { if (!transform) {
return NULL; return NULL;
@ -563,7 +572,8 @@ createProfile(PyObject *self, PyObject *args) {
PyErr_SetString( PyErr_SetString(
PyExc_ValueError, PyExc_ValueError,
"ERROR: Could not calculate white point from color temperature " "ERROR: Could not calculate white point from color temperature "
"provided, must be float in degrees Kelvin"); "provided, must be float in degrees Kelvin"
);
return NULL; return NULL;
} }
hProfile = cmsCreateLab2Profile(&whitePoint); hProfile = cmsCreateLab2Profile(&whitePoint);
@ -624,7 +634,8 @@ cms_get_display_profile_win32(PyObject *self, PyObject *args) {
HANDLE handle = 0; HANDLE handle = 0;
int is_dc = 0; int is_dc = 0;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "|" F_HANDLE "i:get_display_profile", &handle, &is_dc)) { args, "|" F_HANDLE "i:get_display_profile", &handle, &is_dc
)) {
return NULL; return NULL;
} }
@ -729,7 +740,8 @@ _xyz_py(cmsCIEXYZ *XYZ) {
cmsCIExyY xyY; cmsCIExyY xyY;
cmsXYZ2xyY(&xyY, XYZ); cmsXYZ2xyY(&xyY, XYZ);
return Py_BuildValue( return Py_BuildValue(
"((d,d,d),(d,d,d))", XYZ->X, XYZ->Y, XYZ->Z, xyY.x, xyY.y, xyY.Y); "((d,d,d),(d,d,d))", XYZ->X, XYZ->Y, XYZ->Z, xyY.x, xyY.y, xyY.Y
);
} }
static PyObject * static PyObject *
@ -758,7 +770,8 @@ _xyz3_py(cmsCIEXYZ *XYZ) {
xyY[1].Y, xyY[1].Y,
xyY[2].x, xyY[2].x,
xyY[2].y, xyY[2].y,
xyY[2].Y); xyY[2].Y
);
} }
static PyObject * static PyObject *
@ -809,7 +822,8 @@ _profile_read_ciexyy_triple(CmsProfileObject *self, cmsTagSignature info) {
triple->Green.Y, triple->Green.Y,
triple->Blue.x, triple->Blue.x,
triple->Blue.y, triple->Blue.y,
triple->Blue.Y); triple->Blue.Y
);
} }
static PyObject * static PyObject *
@ -873,7 +887,8 @@ _calculate_rgb_primaries(CmsProfileObject *self, cmsCIEXYZTRIPLE *result) {
hXYZ, hXYZ,
TYPE_XYZ_DBL, TYPE_XYZ_DBL,
INTENT_RELATIVE_COLORIMETRIC, INTENT_RELATIVE_COLORIMETRIC,
cmsFLAGS_NOCACHE | cmsFLAGS_NOOPTIMIZE); cmsFLAGS_NOCACHE | cmsFLAGS_NOOPTIMIZE
);
cmsCloseProfile(hXYZ); cmsCloseProfile(hXYZ);
if (hTransform == NULL) { if (hTransform == NULL) {
return 0; return 0;
@ -889,7 +904,8 @@ _check_intent(
int clut, int clut,
cmsHPROFILE hProfile, cmsHPROFILE hProfile,
cmsUInt32Number Intent, cmsUInt32Number Intent,
cmsUInt32Number UsedDirection) { cmsUInt32Number UsedDirection
) {
if (clut) { if (clut) {
return cmsIsCLUT(hProfile, Intent, UsedDirection); return cmsIsCLUT(hProfile, Intent, UsedDirection);
} else { } else {
@ -934,7 +950,8 @@ _is_intent_supported(CmsProfileObject *self, int clut) {
_check_intent(clut, self->profile, intent, LCMS_USED_AS_OUTPUT) ? Py_True _check_intent(clut, self->profile, intent, LCMS_USED_AS_OUTPUT) ? Py_True
: Py_False, : Py_False,
_check_intent(clut, self->profile, intent, LCMS_USED_AS_PROOF) ? Py_True _check_intent(clut, self->profile, intent, LCMS_USED_AS_PROOF) ? Py_True
: Py_False); : Py_False
);
if (id == NULL || entry == NULL) { if (id == NULL || entry == NULL) {
Py_XDECREF(id); Py_XDECREF(id);
Py_XDECREF(entry); Py_XDECREF(entry);
@ -968,7 +985,8 @@ static PyMethodDef pyCMSdll_methods[] = {
{"get_display_profile_win32", cms_get_display_profile_win32, METH_VARARGS}, {"get_display_profile_win32", cms_get_display_profile_win32, METH_VARARGS},
#endif #endif
{NULL, NULL}}; {NULL, NULL}
};
static struct PyMethodDef cms_profile_methods[] = { static struct PyMethodDef cms_profile_methods[] = {
{"is_intent_supported", (PyCFunction)cms_profile_is_intent_supported, METH_VARARGS}, {"is_intent_supported", (PyCFunction)cms_profile_is_intent_supported, METH_VARARGS},
@ -1028,7 +1046,8 @@ cms_profile_getattr_creation_date(CmsProfileObject *self, void *closure) {
} }
return PyDateTime_FromDateAndTime( return PyDateTime_FromDateAndTime(
1900 + ct.tm_year, ct.tm_mon, ct.tm_mday, ct.tm_hour, ct.tm_min, ct.tm_sec, 0); 1900 + ct.tm_year, ct.tm_mon, ct.tm_mday, ct.tm_hour, ct.tm_min, ct.tm_sec, 0
);
} }
static PyObject * static PyObject *
@ -1106,13 +1125,15 @@ cms_profile_getattr_colorimetric_intent(CmsProfileObject *self, void *closure) {
static PyObject * static PyObject *
cms_profile_getattr_perceptual_rendering_intent_gamut( cms_profile_getattr_perceptual_rendering_intent_gamut(
CmsProfileObject *self, void *closure) { CmsProfileObject *self, void *closure
) {
return _profile_read_signature(self, cmsSigPerceptualRenderingIntentGamutTag); return _profile_read_signature(self, cmsSigPerceptualRenderingIntentGamutTag);
} }
static PyObject * static PyObject *
cms_profile_getattr_saturation_rendering_intent_gamut( cms_profile_getattr_saturation_rendering_intent_gamut(
CmsProfileObject *self, void *closure) { CmsProfileObject *self, void *closure
) {
return _profile_read_signature(self, cmsSigSaturationRenderingIntentGamutTag); return _profile_read_signature(self, cmsSigSaturationRenderingIntentGamutTag);
} }
@ -1145,7 +1166,8 @@ cms_profile_getattr_blue_colorant(CmsProfileObject *self, void *closure) {
static PyObject * static PyObject *
cms_profile_getattr_media_white_point_temperature( cms_profile_getattr_media_white_point_temperature(
CmsProfileObject *self, void *closure) { CmsProfileObject *self, void *closure
) {
cmsCIEXYZ *XYZ; cmsCIEXYZ *XYZ;
cmsCIExyY xyY; cmsCIExyY xyY;
cmsFloat64Number tempK; cmsFloat64Number tempK;
@ -1329,7 +1351,8 @@ cms_profile_getattr_icc_measurement_condition(CmsProfileObject *self, void *clos
"flare", "flare",
mc->Flare, mc->Flare,
"illuminant_type", "illuminant_type",
_illu_map(mc->IlluminantType)); _illu_map(mc->IlluminantType)
);
} }
static PyObject * static PyObject *
@ -1359,7 +1382,8 @@ cms_profile_getattr_icc_viewing_condition(CmsProfileObject *self, void *closure)
vc->SurroundXYZ.Y, vc->SurroundXYZ.Y,
vc->SurroundXYZ.Z, vc->SurroundXYZ.Z,
"illuminant_type", "illuminant_type",
_illu_map(vc->IlluminantType)); _illu_map(vc->IlluminantType)
);
} }
static struct PyGetSetDef cms_profile_getsetters[] = { static struct PyGetSetDef cms_profile_getsetters[] = {
@ -1407,11 +1431,12 @@ static struct PyGetSetDef cms_profile_getsetters[] = {
{"colorant_table_out", (getter)cms_profile_getattr_colorant_table_out}, {"colorant_table_out", (getter)cms_profile_getattr_colorant_table_out},
{"intent_supported", (getter)cms_profile_getattr_is_intent_supported}, {"intent_supported", (getter)cms_profile_getattr_is_intent_supported},
{"clut", (getter)cms_profile_getattr_is_clut}, {"clut", (getter)cms_profile_getattr_is_clut},
{"icc_measurement_condition", {"icc_measurement_condition", (getter)cms_profile_getattr_icc_measurement_condition
(getter)cms_profile_getattr_icc_measurement_condition}, },
{"icc_viewing_condition", (getter)cms_profile_getattr_icc_viewing_condition}, {"icc_viewing_condition", (getter)cms_profile_getattr_icc_viewing_condition},
{NULL}}; {NULL}
};
static PyTypeObject CmsProfile_Type = { static PyTypeObject CmsProfile_Type = {
PyVarObject_HEAD_INIT(NULL, 0) "PIL.ImageCms.core.CmsProfile", /*tp_name*/ PyVarObject_HEAD_INIT(NULL, 0) "PIL.ImageCms.core.CmsProfile", /*tp_name*/
@ -1538,5 +1563,9 @@ PyInit__imagingcms(void) {
PyDateTime_IMPORT; PyDateTime_IMPORT;
#ifdef Py_GIL_DISABLED
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
#endif
return m; return m;
} }

View File

@ -20,6 +20,7 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include "Python.h" #include "Python.h"
#include "thirdparty/pythoncapi_compat.h"
#include "libImaging/Imaging.h" #include "libImaging/Imaging.h"
#include <ft2build.h> #include <ft2build.h>
@ -125,7 +126,8 @@ getfont(PyObject *self_, PyObject *args, PyObject *kw) {
unsigned char *font_bytes; unsigned char *font_bytes;
Py_ssize_t font_bytes_size = 0; Py_ssize_t font_bytes_size = 0;
static char *kwlist[] = { static char *kwlist[] = {
"filename", "size", "index", "encoding", "font_bytes", "layout_engine", NULL}; "filename", "size", "index", "encoding", "font_bytes", "layout_engine", NULL
};
if (!library) { if (!library) {
PyErr_SetString(PyExc_OSError, "failed to initialize FreeType library"); PyErr_SetString(PyExc_OSError, "failed to initialize FreeType library");
@ -147,7 +149,8 @@ getfont(PyObject *self_, PyObject *args, PyObject *kw) {
&encoding, &encoding,
&font_bytes, &font_bytes,
&font_bytes_size, &font_bytes_size,
&layout_engine)) { &layout_engine
)) {
PyConfig_Clear(&config); PyConfig_Clear(&config);
return NULL; return NULL;
} }
@ -165,7 +168,8 @@ getfont(PyObject *self_, PyObject *args, PyObject *kw) {
&encoding, &encoding,
&font_bytes, &font_bytes,
&font_bytes_size, &font_bytes_size,
&layout_engine)) { &layout_engine
)) {
return NULL; return NULL;
} }
#endif #endif
@ -198,7 +202,8 @@ getfont(PyObject *self_, PyObject *args, PyObject *kw) {
(FT_Byte *)self->font_bytes, (FT_Byte *)self->font_bytes,
font_bytes_size, font_bytes_size,
index, index,
&self->face); &self->face
);
} }
} }
@ -242,7 +247,8 @@ text_layout_raqm(
const char *dir, const char *dir,
PyObject *features, PyObject *features,
const char *lang, const char *lang,
GlyphInfo **glyph_info) { GlyphInfo **glyph_info
) {
size_t i = 0, count = 0, start = 0; size_t i = 0, count = 0, start = 0;
raqm_t *rq; raqm_t *rq;
raqm_glyph_t *glyphs = NULL; raqm_glyph_t *glyphs = NULL;
@ -296,13 +302,14 @@ text_layout_raqm(
#if !defined(RAQM_VERSION_ATLEAST) #if !defined(RAQM_VERSION_ATLEAST)
/* RAQM_VERSION_ATLEAST was added in Raqm 0.7.0 */ /* RAQM_VERSION_ATLEAST was added in Raqm 0.7.0 */
PyErr_SetString( PyErr_SetString(
PyExc_ValueError, PyExc_ValueError, "libraqm 0.7 or greater required for 'ttb' direction"
"libraqm 0.7 or greater required for 'ttb' direction"); );
goto failed; goto failed;
#endif #endif
} else { } else {
PyErr_SetString( PyErr_SetString(
PyExc_ValueError, "direction must be either 'rtl', 'ltr' or 'ttb'"); PyExc_ValueError, "direction must be either 'rtl', 'ltr' or 'ttb'"
);
goto failed; goto failed;
} }
} }
@ -398,7 +405,8 @@ text_layout_fallback(
const char *lang, const char *lang,
GlyphInfo **glyph_info, GlyphInfo **glyph_info,
int mask, int mask,
int color) { int color
) {
int error, load_flags, i; int error, load_flags, i;
char *buffer = NULL; char *buffer = NULL;
FT_ULong ch; FT_ULong ch;
@ -411,7 +419,8 @@ text_layout_fallback(
PyErr_SetString( PyErr_SetString(
PyExc_KeyError, PyExc_KeyError,
"setting text direction, language or font features is not supported " "setting text direction, language or font features is not supported "
"without libraqm"); "without libraqm"
);
} }
if (PyUnicode_Check(string)) { if (PyUnicode_Check(string)) {
@ -458,7 +467,8 @@ text_layout_fallback(
last_index, last_index,
(*glyph_info)[i].index, (*glyph_info)[i].index,
ft_kerning_default, ft_kerning_default,
&delta) == 0) { &delta
) == 0) {
(*glyph_info)[i - 1].x_advance += PIXEL(delta.x); (*glyph_info)[i - 1].x_advance += PIXEL(delta.x);
(*glyph_info)[i - 1].y_advance += PIXEL(delta.y); (*glyph_info)[i - 1].y_advance += PIXEL(delta.y);
} }
@ -482,7 +492,8 @@ text_layout(
const char *lang, const char *lang,
GlyphInfo **glyph_info, GlyphInfo **glyph_info,
int mask, int mask,
int color) { int color
) {
size_t count; size_t count;
#ifdef HAVE_RAQM #ifdef HAVE_RAQM
if (have_raqm && self->layout_engine == LAYOUT_RAQM) { if (have_raqm && self->layout_engine == LAYOUT_RAQM) {
@ -491,7 +502,8 @@ text_layout(
#endif #endif
{ {
count = text_layout_fallback( count = text_layout_fallback(
string, self, dir, features, lang, glyph_info, mask, color); string, self, dir, features, lang, glyph_info, mask, color
);
} }
return count; return count;
} }
@ -513,7 +525,8 @@ font_getlength(FontObject *self, PyObject *args) {
/* calculate size and bearing for a given string */ /* calculate size and bearing for a given string */
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "O|zzOz:getlength", &string, &mode, &dir, &features, &lang)) { args, "O|zzOz:getlength", &string, &mode, &dir, &features, &lang
)) {
return NULL; return NULL;
} }
@ -555,7 +568,8 @@ bounding_box_and_anchors(
int *width, int *width,
int *height, int *height,
int *x_offset, int *x_offset,
int *y_offset) { int *y_offset
) {
int position; /* pen position along primary axis, in 26.6 precision */ int position; /* pen position along primary axis, in 26.6 precision */
int advanced; /* pen position along primary axis, in pixels */ int advanced; /* pen position along primary axis, in pixels */
int px, py; /* position of current glyph, in pixels */ int px, py; /* position of current glyph, in pixels */
@ -660,7 +674,8 @@ bounding_box_and_anchors(
case 'm': // middle (ascender + descender) / 2 case 'm': // middle (ascender + descender) / 2
y_anchor = PIXEL( y_anchor = PIXEL(
(face->size->metrics.ascender + face->size->metrics.descender) / (face->size->metrics.ascender + face->size->metrics.descender) /
2); 2
);
break; break;
case 's': // horizontal baseline case 's': // horizontal baseline
y_anchor = 0; y_anchor = 0;
@ -740,7 +755,8 @@ font_getsize(FontObject *self, PyObject *args) {
/* calculate size and bearing for a given string */ /* calculate size and bearing for a given string */
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "O|zzOzz:getsize", &string, &mode, &dir, &features, &lang, &anchor)) { args, "O|zzOzz:getsize", &string, &mode, &dir, &features, &lang, &anchor
)) {
return NULL; return NULL;
} }
@ -772,7 +788,8 @@ font_getsize(FontObject *self, PyObject *args) {
&width, &width,
&height, &height,
&x_offset, &x_offset,
&y_offset); &y_offset
);
if (glyph_info) { if (glyph_info) {
PyMem_Free(glyph_info); PyMem_Free(glyph_info);
glyph_info = NULL; glyph_info = NULL;
@ -841,7 +858,8 @@ font_render(FontObject *self, PyObject *args) {
&anchor, &anchor,
&foreground_ink_long, &foreground_ink_long,
&x_start, &x_start,
&y_start)) { &y_start
)) {
return NULL; return NULL;
} }
@ -888,7 +906,8 @@ font_render(FontObject *self, PyObject *args) {
&width, &width,
&height, &height,
&x_offset, &x_offset,
&y_offset); &y_offset
);
if (error) { if (error) {
PyMem_Del(glyph_info); PyMem_Del(glyph_info);
return NULL; return NULL;
@ -928,7 +947,8 @@ font_render(FontObject *self, PyObject *args) {
(FT_Fixed)stroke_width * 64, (FT_Fixed)stroke_width * 64,
FT_STROKER_LINECAP_ROUND, FT_STROKER_LINECAP_ROUND,
FT_STROKER_LINEJOIN_ROUND, FT_STROKER_LINEJOIN_ROUND,
0); 0
);
} }
/* /*
@ -1103,8 +1123,8 @@ font_render(FontObject *self, PyObject *args) {
BLEND(src_alpha, target[k * 4 + 2], src_blue, tmp); BLEND(src_alpha, target[k * 4 + 2], src_blue, tmp);
target[k * 4 + 3] = CLIP8( target[k * 4 + 3] = CLIP8(
src_alpha + src_alpha +
MULDIV255( MULDIV255(target[k * 4 + 3], (255 - src_alpha), tmp)
target[k * 4 + 3], (255 - src_alpha), tmp)); );
} else { } else {
/* paste unpremultiplied RGBA values */ /* paste unpremultiplied RGBA values */
target[k * 4 + 0] = src_red; target[k * 4 + 0] = src_red;
@ -1122,15 +1142,20 @@ font_render(FontObject *self, PyObject *args) {
if (src_alpha > 0) { if (src_alpha > 0) {
if (target[k * 4 + 3] > 0) { if (target[k * 4 + 3] > 0) {
target[k * 4 + 0] = BLEND( target[k * 4 + 0] = BLEND(
src_alpha, target[k * 4 + 0], ink[0], tmp); src_alpha, target[k * 4 + 0], ink[0], tmp
);
target[k * 4 + 1] = BLEND( target[k * 4 + 1] = BLEND(
src_alpha, target[k * 4 + 1], ink[1], tmp); src_alpha, target[k * 4 + 1], ink[1], tmp
);
target[k * 4 + 2] = BLEND( target[k * 4 + 2] = BLEND(
src_alpha, target[k * 4 + 2], ink[2], tmp); src_alpha, target[k * 4 + 2], ink[2], tmp
);
target[k * 4 + 3] = CLIP8( target[k * 4 + 3] = CLIP8(
src_alpha + src_alpha +
MULDIV255( MULDIV255(
target[k * 4 + 3], (255 - src_alpha), tmp)); target[k * 4 + 3], (255 - src_alpha), tmp
)
);
} else { } else {
target[k * 4 + 0] = ink[0]; target[k * 4 + 0] = ink[0];
target[k * 4 + 1] = ink[1]; target[k * 4 + 1] = ink[1];
@ -1148,7 +1173,9 @@ font_render(FontObject *self, PyObject *args) {
? CLIP8( ? CLIP8(
src_alpha + src_alpha +
MULDIV255( MULDIV255(
target[k], (255 - src_alpha), tmp)) target[k], (255 - src_alpha), tmp
)
)
: src_alpha; : src_alpha;
} }
} }
@ -1209,30 +1236,49 @@ font_getvarnames(FontObject *self) {
return NULL; return NULL;
} }
int *list_names_filled = PyMem_Malloc(num_namedstyles * sizeof(int));
if (list_names_filled == NULL) {
Py_DECREF(list_names);
FT_Done_MM_Var(library, master);
return PyErr_NoMemory();
}
for (int i = 0; i < num_namedstyles; i++) {
list_names_filled[i] = 0;
}
name_count = FT_Get_Sfnt_Name_Count(self->face); name_count = FT_Get_Sfnt_Name_Count(self->face);
for (i = 0; i < name_count; i++) { for (i = 0; i < name_count; i++) {
error = FT_Get_Sfnt_Name(self->face, i, &name); error = FT_Get_Sfnt_Name(self->face, i, &name);
if (error) { if (error) {
PyMem_Free(list_names_filled);
Py_DECREF(list_names); Py_DECREF(list_names);
FT_Done_MM_Var(library, master); FT_Done_MM_Var(library, master);
return geterror(error); return geterror(error);
} }
for (j = 0; j < num_namedstyles; j++) { for (j = 0; j < num_namedstyles; j++) {
if (PyList_GetItem(list_names, j) != NULL) { if (list_names_filled[j]) {
continue; continue;
} }
if (master->namedstyle[j].strid == name.name_id) { if (master->namedstyle[j].strid == name.name_id) {
list_name = Py_BuildValue("y#", name.string, name.string_len); list_name = Py_BuildValue("y#", name.string, name.string_len);
if (list_name == NULL) {
PyMem_Free(list_names_filled);
Py_DECREF(list_names);
FT_Done_MM_Var(library, master);
return NULL;
}
PyList_SetItem(list_names, j, list_name); PyList_SetItem(list_names, j, list_name);
list_names_filled[j] = 1;
break; break;
} }
} }
} }
PyMem_Free(list_names_filled);
FT_Done_MM_Var(library, master); FT_Done_MM_Var(library, master);
return list_names; return list_names;
} }
@ -1289,9 +1335,14 @@ font_getvaraxes(FontObject *self) {
if (name.name_id == axis.strid) { if (name.name_id == axis.strid) {
axis_name = Py_BuildValue("y#", name.string, name.string_len); axis_name = Py_BuildValue("y#", name.string, name.string_len);
PyDict_SetItemString( if (axis_name == NULL) {
list_axis, "name", axis_name ? axis_name : Py_None); Py_DECREF(list_axis);
Py_XDECREF(axis_name); Py_DECREF(list_axes);
FT_Done_MM_Var(library, master);
return NULL;
}
PyDict_SetItemString(list_axis, "name", axis_name);
Py_DECREF(axis_name);
break; break;
} }
} }
@ -1345,7 +1396,12 @@ font_setvaraxes(FontObject *self, PyObject *args) {
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
for (i = 0; i < num_coords; i++) { for (i = 0; i < num_coords; i++) {
item = PyList_GET_ITEM(axes, i); item = PyList_GetItemRef(axes, i);
if (item == NULL) {
free(coords);
return NULL;
}
if (PyFloat_Check(item)) { if (PyFloat_Check(item)) {
coord = PyFloat_AS_DOUBLE(item); coord = PyFloat_AS_DOUBLE(item);
} else if (PyLong_Check(item)) { } else if (PyLong_Check(item)) {
@ -1353,10 +1409,12 @@ font_setvaraxes(FontObject *self, PyObject *args) {
} else if (PyNumber_Check(item)) { } else if (PyNumber_Check(item)) {
coord = PyFloat_AsDouble(item); coord = PyFloat_AsDouble(item);
} else { } else {
Py_DECREF(item);
free(coords); free(coords);
PyErr_SetString(PyExc_TypeError, "list must contain numbers"); PyErr_SetString(PyExc_TypeError, "list must contain numbers");
return NULL; return NULL;
} }
Py_DECREF(item);
coords[i] = coord * 65536; coords[i] = coord * 65536;
} }
@ -1393,7 +1451,8 @@ static PyMethodDef font_methods[] = {
{"setvarname", (PyCFunction)font_setvarname, METH_VARARGS}, {"setvarname", (PyCFunction)font_setvarname, METH_VARARGS},
{"setvaraxes", (PyCFunction)font_setvaraxes, METH_VARARGS}, {"setvaraxes", (PyCFunction)font_setvaraxes, METH_VARARGS},
#endif #endif
{NULL, NULL}}; {NULL, NULL}
};
static PyObject * static PyObject *
font_getattr_family(FontObject *self, void *closure) { font_getattr_family(FontObject *self, void *closure) {
@ -1450,7 +1509,8 @@ static struct PyGetSetDef font_getsetters[] = {
{"x_ppem", (getter)font_getattr_x_ppem}, {"x_ppem", (getter)font_getattr_x_ppem},
{"y_ppem", (getter)font_getattr_y_ppem}, {"y_ppem", (getter)font_getattr_y_ppem},
{"glyphs", (getter)font_getattr_glyphs}, {"glyphs", (getter)font_getattr_glyphs},
{NULL}}; {NULL}
};
static PyTypeObject Font_Type = { static PyTypeObject Font_Type = {
PyVarObject_HEAD_INIT(NULL, 0) "Font", /*tp_name*/ PyVarObject_HEAD_INIT(NULL, 0) "Font", /*tp_name*/
@ -1486,7 +1546,8 @@ static PyTypeObject Font_Type = {
}; };
static PyMethodDef _functions[] = { static PyMethodDef _functions[] = {
{"getfont", (PyCFunction)getfont, METH_VARARGS | METH_KEYWORDS}, {NULL, NULL}}; {"getfont", (PyCFunction)getfont, METH_VARARGS | METH_KEYWORDS}, {NULL, NULL}
};
static int static int
setup_module(PyObject *m) { setup_module(PyObject *m) {
@ -1576,5 +1637,9 @@ PyInit__imagingft(void) {
return NULL; return NULL;
} }
#ifdef Py_GIL_DISABLED
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
#endif
return m; return m;
} }

View File

@ -209,7 +209,8 @@ _binop(PyObject *self, PyObject *args) {
} }
static PyMethodDef _functions[] = { static PyMethodDef _functions[] = {
{"unop", _unop, 1}, {"binop", _binop, 1}, {NULL, NULL}}; {"unop", _unop, 1}, {"binop", _binop, 1}, {NULL, NULL}
};
static void static void
install(PyObject *d, char *name, void *value) { install(PyObject *d, char *name, void *value) {
@ -290,5 +291,9 @@ PyInit__imagingmath(void) {
return NULL; return NULL;
} }
#ifdef Py_GIL_DISABLED
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
#endif
return m; return m;
} }

View File

@ -253,7 +253,8 @@ static PyMethodDef functions[] = {
{"apply", (PyCFunction)apply, METH_VARARGS, NULL}, {"apply", (PyCFunction)apply, METH_VARARGS, NULL},
{"get_on_pixels", (PyCFunction)get_on_pixels, METH_VARARGS, NULL}, {"get_on_pixels", (PyCFunction)get_on_pixels, METH_VARARGS, NULL},
{"match", (PyCFunction)match, METH_VARARGS, NULL}, {"match", (PyCFunction)match, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}}; {NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC PyMODINIT_FUNC
PyInit__imagingmorph(void) { PyInit__imagingmorph(void) {
@ -269,5 +270,9 @@ PyInit__imagingmorph(void) {
m = PyModule_Create(&module_def); m = PyModule_Create(&module_def);
#ifdef Py_GIL_DISABLED
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
#endif
return m; return m;
} }

View File

@ -62,5 +62,10 @@ PyInit__imagingtk(void) {
Py_DECREF(m); Py_DECREF(m);
return NULL; return NULL;
} }
#ifdef Py_GIL_DISABLED
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
#endif
return m; return m;
} }

View File

@ -42,7 +42,8 @@ static const char *const kErrorMessages[-WEBP_MUX_NOT_ENOUGH_DATA + 1] = {
"WEBP_MUX_INVALID_ARGUMENT", "WEBP_MUX_INVALID_ARGUMENT",
"WEBP_MUX_BAD_DATA", "WEBP_MUX_BAD_DATA",
"WEBP_MUX_MEMORY_ERROR", "WEBP_MUX_MEMORY_ERROR",
"WEBP_MUX_NOT_ENOUGH_DATA"}; "WEBP_MUX_NOT_ENOUGH_DATA"
};
PyObject * PyObject *
HandleMuxError(WebPMuxError err, char *chunk) { HandleMuxError(WebPMuxError err, char *chunk) {
@ -61,7 +62,8 @@ HandleMuxError(WebPMuxError err, char *chunk) {
sprintf(message, "could not assemble chunks: %s", kErrorMessages[-err]); sprintf(message, "could not assemble chunks: %s", kErrorMessages[-err]);
} else { } else {
message_len = sprintf( message_len = sprintf(
message, "could not set %.4s chunk: %s", chunk, kErrorMessages[-err]); message, "could not set %.4s chunk: %s", chunk, kErrorMessages[-err]
);
} }
if (message_len < 0) { if (message_len < 0) {
PyErr_SetString(PyExc_RuntimeError, "failed to construct error message"); PyErr_SetString(PyExc_RuntimeError, "failed to construct error message");
@ -138,7 +140,8 @@ _anim_encoder_new(PyObject *self, PyObject *args) {
&kmin, &kmin,
&kmax, &kmax,
&allow_mixed, &allow_mixed,
&verbose)) { &verbose
)) {
return NULL; return NULL;
} }
@ -214,7 +217,8 @@ _anim_encoder_add(PyObject *self, PyObject *args) {
&lossless, &lossless,
&quality_factor, &quality_factor,
&alpha_quality_factor, &alpha_quality_factor,
&method)) { &method
)) {
return NULL; return NULL;
} }
@ -283,7 +287,8 @@ _anim_encoder_assemble(PyObject *self, PyObject *args) {
&exif_bytes, &exif_bytes,
&exif_size, &exif_size,
&xmp_bytes, &xmp_bytes,
&xmp_size)) { &xmp_size
)) {
return NULL; return NULL;
} }
@ -421,7 +426,8 @@ _anim_decoder_get_info(PyObject *self) {
info->loop_count, info->loop_count,
info->bgcolor, info->bgcolor,
info->frame_count, info->frame_count,
decp->mode); decp->mode
);
} }
PyObject * PyObject *
@ -466,7 +472,8 @@ _anim_decoder_get_next(PyObject *self) {
} }
bytes = PyBytes_FromStringAndSize( bytes = PyBytes_FromStringAndSize(
(char *)buf, decp->info.canvas_width * 4 * decp->info.canvas_height); (char *)buf, decp->info.canvas_width * 4 * decp->info.canvas_height
);
ret = Py_BuildValue("Si", bytes, timestamp); ret = Py_BuildValue("Si", bytes, timestamp);
@ -621,7 +628,8 @@ WebPEncode_wrapper(PyObject *self, PyObject *args) {
&exif_bytes, &exif_bytes,
&exif_size, &exif_size,
&xmp_bytes, &xmp_bytes,
&xmp_size)) { &xmp_size
)) {
return NULL; return NULL;
} }
@ -828,12 +836,14 @@ WebPDecode_wrapper(PyObject *self, PyObject *args) {
if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "ICCP", &icc_profile_data)) { if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "ICCP", &icc_profile_data)) {
icc_profile = PyBytes_FromStringAndSize( icc_profile = PyBytes_FromStringAndSize(
(const char *)icc_profile_data.bytes, icc_profile_data.size); (const char *)icc_profile_data.bytes, icc_profile_data.size
);
} }
if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "EXIF", &exif_data)) { if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "EXIF", &exif_data)) {
exif = PyBytes_FromStringAndSize( exif = PyBytes_FromStringAndSize(
(const char *)exif_data.bytes, exif_data.size); (const char *)exif_data.bytes, exif_data.size
);
} }
WebPDataClear(&image.bitstream); WebPDataClear(&image.bitstream);
@ -848,12 +858,14 @@ WebPDecode_wrapper(PyObject *self, PyObject *args) {
if (config.output.colorspace < MODE_YUV) { if (config.output.colorspace < MODE_YUV) {
bytes = PyBytes_FromStringAndSize( bytes = PyBytes_FromStringAndSize(
(char *)config.output.u.RGBA.rgba, config.output.u.RGBA.size); (char *)config.output.u.RGBA.rgba, config.output.u.RGBA.size
);
} else { } else {
// Skipping YUV for now. Need Test Images. // Skipping YUV for now. Need Test Images.
// UNDONE -- unclear if we'll ever get here if we set mode_rgb* // UNDONE -- unclear if we'll ever get here if we set mode_rgb*
bytes = PyBytes_FromStringAndSize( bytes = PyBytes_FromStringAndSize(
(char *)config.output.u.YUVA.y, config.output.u.YUVA.y_size); (char *)config.output.u.YUVA.y, config.output.u.YUVA.y_size
);
} }
pymode = PyUnicode_FromString(mode); pymode = PyUnicode_FromString(mode);
@ -864,7 +876,8 @@ WebPDecode_wrapper(PyObject *self, PyObject *args) {
config.output.height, config.output.height,
pymode, pymode,
NULL == icc_profile ? Py_None : icc_profile, NULL == icc_profile ? Py_None : icc_profile,
NULL == exif ? Py_None : exif); NULL == exif ? Py_None : exif
);
end: end:
WebPFreeDecBuffer(&config.output); WebPFreeDecBuffer(&config.output);
@ -898,7 +911,8 @@ WebPDecoderVersion_str(void) {
"%d.%d.%d", "%d.%d.%d",
version_number >> 16, version_number >> 16,
(version_number >> 8) % 0x100, (version_number >> 8) % 0x100,
version_number % 0x100); version_number % 0x100
);
return version; return version;
} }
@ -932,7 +946,8 @@ static PyMethodDef webpMethods[] = {
WebPDecoderBuggyAlpha_wrapper, WebPDecoderBuggyAlpha_wrapper,
METH_NOARGS, METH_NOARGS,
"WebPDecoderBuggyAlpha"}, "WebPDecoderBuggyAlpha"},
{NULL, NULL}}; {NULL, NULL}
};
void void
addMuxFlagToModule(PyObject *m) { addMuxFlagToModule(PyObject *m) {
@ -1005,5 +1020,9 @@ PyInit__webp(void) {
return NULL; return NULL;
} }
#ifdef Py_GIL_DISABLED
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
#endif
return m; return m;
} }

View File

@ -46,7 +46,8 @@
typedef struct { typedef struct {
PyObject_HEAD int (*decode)( PyObject_HEAD int (*decode)(
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes); Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
);
int (*cleanup)(ImagingCodecState state); int (*cleanup)(ImagingCodecState state);
struct ImagingCodecStateInstance state; struct ImagingCodecStateInstance state;
Imaging im; Imaging im;
@ -938,7 +939,8 @@ PyImaging_Jpeg2KDecoderNew(PyObject *self, PyObject *args) {
PY_LONG_LONG length = -1; PY_LONG_LONG length = -1;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "ss|iiiL", &mode, &format, &reduce, &layers, &fd, &length)) { args, "ss|iiiL", &mode, &format, &reduce, &layers, &fd, &length
)) {
return NULL; return NULL;
} }

View File

@ -105,7 +105,8 @@ _draw(ImagingDisplayObject *display, PyObject *args) {
src + 0, src + 0,
src + 1, src + 1,
src + 2, src + 2,
src + 3)) { src + 3
)) {
return NULL; return NULL;
} }
@ -221,7 +222,8 @@ _tobytes(ImagingDisplayObject *display, PyObject *args) {
} }
return PyBytes_FromStringAndSize( return PyBytes_FromStringAndSize(
display->dib->bits, display->dib->ysize * display->dib->linesize); display->dib->bits, display->dib->ysize * display->dib->linesize
);
} }
static struct PyMethodDef methods[] = { static struct PyMethodDef methods[] = {
@ -247,7 +249,8 @@ _getattr_size(ImagingDisplayObject *self, void *closure) {
} }
static struct PyGetSetDef getsetters[] = { static struct PyGetSetDef getsetters[] = {
{"mode", (getter)_getattr_mode}, {"size", (getter)_getattr_size}, {NULL}}; {"mode", (getter)_getattr_mode}, {"size", (getter)_getattr_size}, {NULL}
};
static PyTypeObject ImagingDisplayType = { static PyTypeObject ImagingDisplayType = {
PyVarObject_HEAD_INIT(NULL, 0) "ImagingDisplay", /*tp_name*/ PyVarObject_HEAD_INIT(NULL, 0) "ImagingDisplay", /*tp_name*/
@ -341,9 +344,8 @@ PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) {
// added in Windows 10 (1607) // added in Windows 10 (1607)
// loaded dynamically to avoid link errors // loaded dynamically to avoid link errors
user32 = LoadLibraryA("User32.dll"); user32 = LoadLibraryA("User32.dll");
SetThreadDpiAwarenessContext_function = SetThreadDpiAwarenessContext_function = (Func_SetThreadDpiAwarenessContext
(Func_SetThreadDpiAwarenessContext)GetProcAddress( )GetProcAddress(user32, "SetThreadDpiAwarenessContext");
user32, "SetThreadDpiAwarenessContext");
if (SetThreadDpiAwarenessContext_function != NULL) { if (SetThreadDpiAwarenessContext_function != NULL) {
// DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = ((DPI_CONTEXT_HANDLE)-3) // DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = ((DPI_CONTEXT_HANDLE)-3)
dpiAwareness = SetThreadDpiAwarenessContext_function((HANDLE)-3); dpiAwareness = SetThreadDpiAwarenessContext_function((HANDLE)-3);
@ -403,7 +405,8 @@ PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) {
height, height,
PyBytes_AS_STRING(buffer), PyBytes_AS_STRING(buffer),
(BITMAPINFO *)&core, (BITMAPINFO *)&core,
DIB_RGB_COLORS)) { DIB_RGB_COLORS
)) {
goto error; goto error;
} }
@ -547,7 +550,8 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) {
ps.rcPaint.left, ps.rcPaint.left,
ps.rcPaint.top, ps.rcPaint.top,
ps.rcPaint.right, ps.rcPaint.right,
ps.rcPaint.bottom); ps.rcPaint.bottom
);
if (result) { if (result) {
Py_DECREF(result); Py_DECREF(result);
} else { } else {
@ -562,7 +566,8 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) {
0, 0,
0, 0,
rect.right - rect.left, rect.right - rect.left,
rect.bottom - rect.top); rect.bottom - rect.top
);
if (result) { if (result) {
Py_DECREF(result); Py_DECREF(result);
} else { } else {
@ -577,7 +582,8 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) {
0, 0,
0, 0,
rect.right - rect.left, rect.right - rect.left,
rect.bottom - rect.top); rect.bottom - rect.top
);
if (result) { if (result) {
Py_DECREF(result); Py_DECREF(result);
} else { } else {
@ -591,7 +597,8 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) {
case WM_SIZE: case WM_SIZE:
/* resize window */ /* resize window */
result = PyObject_CallFunction( result = PyObject_CallFunction(
callback, "sii", "resize", LOWORD(lParam), HIWORD(lParam)); callback, "sii", "resize", LOWORD(lParam), HIWORD(lParam)
);
if (result) { if (result) {
InvalidateRect(wnd, NULL, 1); InvalidateRect(wnd, NULL, 1);
Py_DECREF(result); Py_DECREF(result);
@ -670,7 +677,8 @@ PyImaging_CreateWindowWin32(PyObject *self, PyObject *args) {
HWND_DESKTOP, HWND_DESKTOP,
NULL, NULL,
NULL, NULL,
NULL); NULL
);
if (!wnd) { if (!wnd) {
PyErr_SetString(PyExc_OSError, "failed to create window"); PyErr_SetString(PyExc_OSError, "failed to create window");
@ -732,7 +740,8 @@ PyImaging_DrawWmf(PyObject *self, PyObject *args) {
&x0, &x0,
&x1, &x1,
&y0, &y0,
&y1)) { &y1
)) {
return NULL; return NULL;
} }
@ -844,7 +853,8 @@ PyImaging_GrabScreenX11(PyObject *self, PyObject *args) {
PyErr_Format( PyErr_Format(
PyExc_OSError, PyExc_OSError,
"X connection failed: error %i", "X connection failed: error %i",
xcb_connection_has_error(connection)); xcb_connection_has_error(connection)
);
xcb_disconnect(connection); xcb_disconnect(connection);
return NULL; return NULL;
} }
@ -878,8 +888,10 @@ PyImaging_GrabScreenX11(PyObject *self, PyObject *args) {
0, 0,
width, width,
height, height,
0x00ffffff), 0x00ffffff
&error); ),
&error
);
if (reply == NULL) { if (reply == NULL) {
PyErr_Format( PyErr_Format(
PyExc_OSError, PyExc_OSError,
@ -887,7 +899,8 @@ PyImaging_GrabScreenX11(PyObject *self, PyObject *args) {
error->error_code, error->error_code,
error->major_code, error->major_code,
error->minor_code, error->minor_code,
error->resource_id); error->resource_id
);
free(error); free(error);
xcb_disconnect(connection); xcb_disconnect(connection);
return NULL; return NULL;
@ -897,7 +910,8 @@ PyImaging_GrabScreenX11(PyObject *self, PyObject *args) {
if (reply->depth == 24) { if (reply->depth == 24) {
buffer = PyBytes_FromStringAndSize( buffer = PyBytes_FromStringAndSize(
(char *)xcb_get_image_data(reply), xcb_get_image_data_length(reply)); (char *)xcb_get_image_data(reply), xcb_get_image_data_length(reply)
);
} else { } else {
PyErr_Format(PyExc_OSError, "unsupported bit depth: %i", reply->depth); PyErr_Format(PyExc_OSError, "unsupported bit depth: %i", reply->depth);
} }

View File

@ -25,6 +25,7 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include "Python.h" #include "Python.h"
#include "thirdparty/pythoncapi_compat.h"
#include "libImaging/Imaging.h" #include "libImaging/Imaging.h"
#include "libImaging/Gif.h" #include "libImaging/Gif.h"
@ -38,7 +39,8 @@
typedef struct { typedef struct {
PyObject_HEAD int (*encode)( PyObject_HEAD int (*encode)(
Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes); Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes
);
int (*cleanup)(ImagingCodecState state); int (*cleanup)(ImagingCodecState state);
struct ImagingCodecStateInstance state; struct ImagingCodecStateInstance state;
Imaging im; Imaging im;
@ -134,7 +136,8 @@ _encode(ImagingEncoderObject *encoder, PyObject *args) {
} }
status = encoder->encode( status = encoder->encode(
encoder->im, &encoder->state, (UINT8 *)PyBytes_AsString(buf), bufsize); encoder->im, &encoder->state, (UINT8 *)PyBytes_AsString(buf), bufsize
);
/* adjust string length to avoid slicing in encoder */ /* adjust string length to avoid slicing in encoder */
if (_PyBytes_Resize(&buf, (status > 0) ? status : 0) < 0) { if (_PyBytes_Resize(&buf, (status > 0) ? status : 0) < 0) {
@ -571,7 +574,8 @@ PyImaging_ZipEncoderNew(PyObject *self, PyObject *args) {
&compress_level, &compress_level,
&compress_type, &compress_type,
&dictionary, &dictionary,
&dictionary_size)) { &dictionary_size
)) {
return NULL; return NULL;
} }
@ -652,15 +656,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
PyObject *item; PyObject *item;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, args, "sssnsOO", &mode, &rawmode, &compname, &fp, &filename, &tags, &types
"sssnsOO", )) {
&mode,
&rawmode,
&compname,
&fp,
&filename,
&tags,
&types)) {
return NULL; return NULL;
} }
@ -671,11 +668,17 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
tags_size = PyList_Size(tags); tags_size = PyList_Size(tags);
TRACE(("tags size: %d\n", (int)tags_size)); TRACE(("tags size: %d\n", (int)tags_size));
for (pos = 0; pos < tags_size; pos++) { for (pos = 0; pos < tags_size; pos++) {
item = PyList_GetItem(tags, pos); item = PyList_GetItemRef(tags, pos);
if (item == NULL) {
return NULL;
}
if (!PyTuple_Check(item) || PyTuple_Size(item) != 2) { if (!PyTuple_Check(item) || PyTuple_Size(item) != 2) {
Py_DECREF(item);
PyErr_SetString(PyExc_ValueError, "Invalid tags list"); PyErr_SetString(PyExc_ValueError, "Invalid tags list");
return NULL; return NULL;
} }
Py_DECREF(item);
} }
pos = 0; pos = 0;
} }
@ -703,11 +706,17 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
num_core_tags = sizeof(core_tags) / sizeof(int); num_core_tags = sizeof(core_tags) / sizeof(int);
for (pos = 0; pos < tags_size; pos++) { for (pos = 0; pos < tags_size; pos++) {
item = PyList_GetItem(tags, pos); item = PyList_GetItemRef(tags, pos);
if (item == NULL) {
return NULL;
}
// We already checked that tags is a 2-tuple list. // We already checked that tags is a 2-tuple list.
key = PyTuple_GetItem(item, 0); key = PyTuple_GET_ITEM(item, 0);
key_int = (int)PyLong_AsLong(key); key_int = (int)PyLong_AsLong(key);
value = PyTuple_GetItem(item, 1); value = PyTuple_GET_ITEM(item, 1);
Py_DECREF(item);
status = 0; status = 0;
is_core_tag = 0; is_core_tag = 0;
is_var_length = 0; is_var_length = 0;
@ -721,7 +730,10 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
} }
if (!is_core_tag) { if (!is_core_tag) {
PyObject *tag_type = PyDict_GetItem(types, key); PyObject *tag_type;
if (PyDict_GetItemRef(types, key, &tag_type) < 0) {
return NULL; // Exception has been already set
}
if (tag_type) { if (tag_type) {
int type_int = PyLong_AsLong(tag_type); int type_int = PyLong_AsLong(tag_type);
if (type_int >= TIFF_BYTE && type_int <= TIFF_DOUBLE) { if (type_int >= TIFF_BYTE && type_int <= TIFF_DOUBLE) {
@ -769,7 +781,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
is_var_length = 1; is_var_length = 1;
} }
if (ImagingLibTiffMergeFieldInfo( if (ImagingLibTiffMergeFieldInfo(
&encoder->state, type, key_int, is_var_length)) { &encoder->state, type, key_int, is_var_length
)) {
continue; continue;
} }
} }
@ -779,7 +792,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
&encoder->state, &encoder->state,
(ttag_t)key_int, (ttag_t)key_int,
PyBytes_Size(value), PyBytes_Size(value),
PyBytes_AsString(value)); PyBytes_AsString(value)
);
} else if (is_var_length) { } else if (is_var_length) {
Py_ssize_t len, i; Py_ssize_t len, i;
TRACE(("Setting from Tuple: %d \n", key_int)); TRACE(("Setting from Tuple: %d \n", key_int));
@ -789,7 +803,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
int stride = 256; int stride = 256;
if (len != 768) { if (len != 768) {
PyErr_SetString( PyErr_SetString(
PyExc_ValueError, "Requiring 768 items for Colormap"); PyExc_ValueError, "Requiring 768 items for Colormap"
);
return NULL; return NULL;
} }
UINT16 *av; UINT16 *av;
@ -804,7 +819,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
(ttag_t)key_int, (ttag_t)key_int,
av, av,
av + stride, av + stride,
av + stride * 2); av + stride * 2
);
free(av); free(av);
} }
} else if (key_int == TIFFTAG_YCBCRSUBSAMPLING) { } else if (key_int == TIFFTAG_YCBCRSUBSAMPLING) {
@ -812,7 +828,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
&encoder->state, &encoder->state,
(ttag_t)key_int, (ttag_t)key_int,
(UINT16)PyLong_AsLong(PyTuple_GetItem(value, 0)), (UINT16)PyLong_AsLong(PyTuple_GetItem(value, 0)),
(UINT16)PyLong_AsLong(PyTuple_GetItem(value, 1))); (UINT16)PyLong_AsLong(PyTuple_GetItem(value, 1))
);
} else if (type == TIFF_SHORT) { } else if (type == TIFF_SHORT) {
UINT16 *av; UINT16 *av;
/* malloc check ok, calloc checks for overflow */ /* malloc check ok, calloc checks for overflow */
@ -822,7 +839,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
av[i] = (UINT16)PyLong_AsLong(PyTuple_GetItem(value, i)); av[i] = (UINT16)PyLong_AsLong(PyTuple_GetItem(value, i));
} }
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, len, av); &encoder->state, (ttag_t)key_int, len, av
);
free(av); free(av);
} }
} else if (type == TIFF_LONG) { } else if (type == TIFF_LONG) {
@ -834,7 +852,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
av[i] = (UINT32)PyLong_AsLong(PyTuple_GetItem(value, i)); av[i] = (UINT32)PyLong_AsLong(PyTuple_GetItem(value, i));
} }
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, len, av); &encoder->state, (ttag_t)key_int, len, av
);
free(av); free(av);
} }
} else if (type == TIFF_SBYTE) { } else if (type == TIFF_SBYTE) {
@ -846,7 +865,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
av[i] = (INT8)PyLong_AsLong(PyTuple_GetItem(value, i)); av[i] = (INT8)PyLong_AsLong(PyTuple_GetItem(value, i));
} }
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, len, av); &encoder->state, (ttag_t)key_int, len, av
);
free(av); free(av);
} }
} else if (type == TIFF_SSHORT) { } else if (type == TIFF_SSHORT) {
@ -858,7 +878,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
av[i] = (INT16)PyLong_AsLong(PyTuple_GetItem(value, i)); av[i] = (INT16)PyLong_AsLong(PyTuple_GetItem(value, i));
} }
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, len, av); &encoder->state, (ttag_t)key_int, len, av
);
free(av); free(av);
} }
} else if (type == TIFF_SLONG) { } else if (type == TIFF_SLONG) {
@ -870,7 +891,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
av[i] = (INT32)PyLong_AsLong(PyTuple_GetItem(value, i)); av[i] = (INT32)PyLong_AsLong(PyTuple_GetItem(value, i));
} }
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, len, av); &encoder->state, (ttag_t)key_int, len, av
);
free(av); free(av);
} }
} else if (type == TIFF_FLOAT) { } else if (type == TIFF_FLOAT) {
@ -882,7 +904,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
av[i] = (FLOAT32)PyFloat_AsDouble(PyTuple_GetItem(value, i)); av[i] = (FLOAT32)PyFloat_AsDouble(PyTuple_GetItem(value, i));
} }
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, len, av); &encoder->state, (ttag_t)key_int, len, av
);
free(av); free(av);
} }
} else if (type == TIFF_DOUBLE) { } else if (type == TIFF_DOUBLE) {
@ -894,43 +917,54 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
av[i] = PyFloat_AsDouble(PyTuple_GetItem(value, i)); av[i] = PyFloat_AsDouble(PyTuple_GetItem(value, i));
} }
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, len, av); &encoder->state, (ttag_t)key_int, len, av
);
free(av); free(av);
} }
} }
} else { } else {
if (type == TIFF_SHORT) { if (type == TIFF_SHORT) {
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, (UINT16)PyLong_AsLong(value)); &encoder->state, (ttag_t)key_int, (UINT16)PyLong_AsLong(value)
);
} else if (type == TIFF_LONG) { } else if (type == TIFF_LONG) {
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, PyLong_AsLongLong(value)); &encoder->state, (ttag_t)key_int, PyLong_AsLongLong(value)
);
} else if (type == TIFF_SSHORT) { } else if (type == TIFF_SSHORT) {
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, (INT16)PyLong_AsLong(value)); &encoder->state, (ttag_t)key_int, (INT16)PyLong_AsLong(value)
);
} else if (type == TIFF_SLONG) { } else if (type == TIFF_SLONG) {
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, (INT32)PyLong_AsLong(value)); &encoder->state, (ttag_t)key_int, (INT32)PyLong_AsLong(value)
);
} else if (type == TIFF_FLOAT) { } else if (type == TIFF_FLOAT) {
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, (FLOAT32)PyFloat_AsDouble(value)); &encoder->state, (ttag_t)key_int, (FLOAT32)PyFloat_AsDouble(value)
);
} else if (type == TIFF_DOUBLE) { } else if (type == TIFF_DOUBLE) {
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, (FLOAT64)PyFloat_AsDouble(value)); &encoder->state, (ttag_t)key_int, (FLOAT64)PyFloat_AsDouble(value)
);
} else if (type == TIFF_SBYTE) { } else if (type == TIFF_SBYTE) {
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, (INT8)PyLong_AsLong(value)); &encoder->state, (ttag_t)key_int, (INT8)PyLong_AsLong(value)
);
} else if (type == TIFF_ASCII) { } else if (type == TIFF_ASCII) {
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, PyBytes_AsString(value)); &encoder->state, (ttag_t)key_int, PyBytes_AsString(value)
);
} else if (type == TIFF_RATIONAL) { } else if (type == TIFF_RATIONAL) {
status = ImagingLibTiffSetField( status = ImagingLibTiffSetField(
&encoder->state, (ttag_t)key_int, (FLOAT64)PyFloat_AsDouble(value)); &encoder->state, (ttag_t)key_int, (FLOAT64)PyFloat_AsDouble(value)
);
} else { } else {
TRACE( TRACE(
("Unhandled type for key %d : %s \n", ("Unhandled type for key %d : %s \n",
key_int, key_int,
PyBytes_AsString(PyObject_Str(value)))); PyBytes_AsString(PyObject_Str(value)))
);
} }
} }
if (!status) { if (!status) {
@ -991,7 +1025,8 @@ get_qtables_arrays(PyObject *qtables, int *qtablesLen) {
if (num_tables < 1 || num_tables > NUM_QUANT_TBLS) { if (num_tables < 1 || num_tables > NUM_QUANT_TBLS) {
PyErr_SetString( PyErr_SetString(
PyExc_ValueError, PyExc_ValueError,
"Not a valid number of quantization tables. Should be between 1 and 4."); "Not a valid number of quantization tables. Should be between 1 and 4."
);
Py_DECREF(tables); Py_DECREF(tables);
return NULL; return NULL;
} }
@ -1080,7 +1115,8 @@ PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) {
&extra, &extra,
&extra_size, &extra_size,
&rawExif, &rawExif,
&rawExifLen)) { &rawExifLen
)) {
return NULL; return NULL;
} }
@ -1250,7 +1286,8 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) {
&fd, &fd,
&comment, &comment,
&comment_size, &comment_size,
&plt)) { &plt
)) {
return NULL; return NULL;
} }
@ -1307,7 +1344,8 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) {
j2k_decode_coord_tuple(offset, &context->offset_x, &context->offset_y); j2k_decode_coord_tuple(offset, &context->offset_x, &context->offset_y);
j2k_decode_coord_tuple( j2k_decode_coord_tuple(
tile_offset, &context->tile_offset_x, &context->tile_offset_y); tile_offset, &context->tile_offset_x, &context->tile_offset_y
);
j2k_decode_coord_tuple(tile_size, &context->tile_size_x, &context->tile_size_y); j2k_decode_coord_tuple(tile_size, &context->tile_size_x, &context->tile_size_y);
/* Error on illegal tile offsets */ /* Error on illegal tile offsets */
@ -1317,7 +1355,8 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) {
PyErr_SetString( PyErr_SetString(
PyExc_ValueError, PyExc_ValueError,
"JPEG 2000 tile offset too small; top left tile must " "JPEG 2000 tile offset too small; top left tile must "
"intersect image area"); "intersect image area"
);
Py_DECREF(encoder); Py_DECREF(encoder);
return NULL; return NULL;
} }
@ -1325,8 +1364,8 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) {
if (context->tile_offset_x > context->offset_x || if (context->tile_offset_x > context->offset_x ||
context->tile_offset_y > context->offset_y) { context->tile_offset_y > context->offset_y) {
PyErr_SetString( PyErr_SetString(
PyExc_ValueError, PyExc_ValueError, "JPEG 2000 tile offset too large to cover image area"
"JPEG 2000 tile offset too large to cover image area"); );
Py_DECREF(encoder); Py_DECREF(encoder);
return NULL; return NULL;
} }
@ -1360,7 +1399,8 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args) {
j2k_decode_coord_tuple(cblk_size, &context->cblk_width, &context->cblk_height); j2k_decode_coord_tuple(cblk_size, &context->cblk_width, &context->cblk_height);
j2k_decode_coord_tuple( j2k_decode_coord_tuple(
precinct_size, &context->precinct_width, &context->precinct_height); precinct_size, &context->precinct_width, &context->precinct_height
);
context->irreversible = PyObject_IsTrue(irreversible); context->irreversible = PyObject_IsTrue(irreversible);
context->progression = prog_order; context->progression = prog_order;

View File

@ -36,7 +36,8 @@ add_item(const char *mode) {
"AccessInit: hash collision: %d for both %s and %s\n", "AccessInit: hash collision: %d for both %s and %s\n",
i, i,
mode, mode,
access_table[i].mode); access_table[i].mode
);
exit(1); exit(1);
} }
access_table[i].mode = mode; access_table[i].mode = mode;

View File

@ -243,7 +243,8 @@ static const bc7_mode_info bc7_modes[] = {
{1, 0, 2, 1, 5, 6, 0, 0, 2, 3}, {1, 0, 2, 1, 5, 6, 0, 0, 2, 3},
{1, 0, 2, 0, 7, 8, 0, 0, 2, 2}, {1, 0, 2, 0, 7, 8, 0, 0, 2, 2},
{1, 0, 0, 0, 7, 7, 1, 0, 4, 0}, {1, 0, 0, 0, 7, 7, 1, 0, 4, 0},
{2, 6, 0, 0, 5, 5, 1, 0, 2, 0}}; {2, 6, 0, 0, 5, 5, 1, 0, 2, 0}
};
/* Subset indices: /* Subset indices:
Table.P2, 1 bit per index */ Table.P2, 1 bit per index */
@ -254,7 +255,8 @@ static const UINT16 bc7_si2[] = {
0x718e, 0x399c, 0xaaaa, 0xf0f0, 0x5a5a, 0x33cc, 0x3c3c, 0x55aa, 0x9696, 0xa55a, 0x718e, 0x399c, 0xaaaa, 0xf0f0, 0x5a5a, 0x33cc, 0x3c3c, 0x55aa, 0x9696, 0xa55a,
0x73ce, 0x13c8, 0x324c, 0x3bdc, 0x6996, 0xc33c, 0x9966, 0x0660, 0x0272, 0x04e4, 0x73ce, 0x13c8, 0x324c, 0x3bdc, 0x6996, 0xc33c, 0x9966, 0x0660, 0x0272, 0x04e4,
0x4e40, 0x2720, 0xc936, 0x936c, 0x39c6, 0x639c, 0x9336, 0x9cc6, 0x817e, 0xe718, 0x4e40, 0x2720, 0xc936, 0x936c, 0x39c6, 0x639c, 0x9336, 0x9cc6, 0x817e, 0xe718,
0xccf0, 0x0fcc, 0x7744, 0xee22}; 0xccf0, 0x0fcc, 0x7744, 0xee22
};
/* Table.P3, 2 bits per index */ /* Table.P3, 2 bits per index */
static const UINT32 bc7_si3[] = { static const UINT32 bc7_si3[] = {
@ -267,20 +269,23 @@ static const UINT32 bc7_si3[] = {
0x66660000, 0xa5a0a5a0, 0x50a050a0, 0x69286928, 0x44aaaa44, 0x66666600, 0xaa444444, 0x66660000, 0xa5a0a5a0, 0x50a050a0, 0x69286928, 0x44aaaa44, 0x66666600, 0xaa444444,
0x54a854a8, 0x95809580, 0x96969600, 0xa85454a8, 0x80959580, 0xaa141414, 0x96960000, 0x54a854a8, 0x95809580, 0x96969600, 0xa85454a8, 0x80959580, 0xaa141414, 0x96960000,
0xaaaa1414, 0xa05050a0, 0xa0a5a5a0, 0x96000000, 0x40804080, 0xa9a8a9a8, 0xaaaaaa44, 0xaaaa1414, 0xa05050a0, 0xa0a5a5a0, 0x96000000, 0x40804080, 0xa9a8a9a8, 0xaaaaaa44,
0x2a4a5254}; 0x2a4a5254
};
/* Anchor indices: /* Anchor indices:
Table.A2 */ Table.A2 */
static const char bc7_ai0[] = { static const char bc7_ai0[] = {15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 8, 2, 2, 8, 15, 15, 15, 15, 2, 8, 2, 2, 8, 8, 15, 2, 8,
8, 15, 2, 8, 2, 2, 8, 8, 2, 2, 15, 15, 6, 8, 2, 8, 15, 15, 2, 8, 2, 2, 2, 2, 8, 8, 2, 2, 15, 15, 6, 8, 2, 8, 15,
2, 15, 15, 6, 6, 2, 6, 8, 15, 15, 2, 2, 15, 15, 15, 15, 15, 2, 2, 15}; 15, 2, 8, 2, 2, 2, 15, 15, 6, 6, 2, 6, 8,
15, 15, 2, 2, 15, 15, 15, 15, 15, 2, 2, 15};
/* Table.A3a */ /* Table.A3a */
static const char bc7_ai1[] = { static const char bc7_ai1[] = {3, 3, 15, 15, 8, 3, 15, 15, 8, 8, 6, 6, 6,
3, 3, 15, 15, 8, 3, 15, 15, 8, 8, 6, 6, 6, 5, 3, 3, 3, 3, 8, 15, 3, 3, 5, 3, 3, 3, 3, 8, 15, 3, 3, 6, 10, 5, 8,
6, 10, 5, 8, 8, 6, 8, 5, 15, 15, 8, 15, 3, 5, 6, 10, 8, 15, 15, 3, 15, 5, 8, 6, 8, 5, 15, 15, 8, 15, 3, 5, 6, 10, 8,
15, 15, 15, 15, 3, 15, 5, 5, 5, 8, 5, 10, 5, 10, 8, 13, 15, 12, 3, 3}; 15, 15, 3, 15, 5, 15, 15, 15, 15, 3, 15, 5, 5,
5, 8, 5, 10, 5, 10, 8, 13, 15, 12, 3, 3};
/* Table.A3b */ /* Table.A3b */
static const char bc7_ai2[] = {15, 8, 8, 3, 15, 15, 3, 8, 15, 15, 15, 15, 15, static const char bc7_ai2[] = {15, 8, 8, 3, 15, 15, 3, 8, 15, 15, 15, 15, 15,
@ -293,7 +298,8 @@ static const char bc7_ai2[] = {15, 8, 8, 3, 15, 15, 3, 8, 15, 15, 15, 15, 1
static const char bc7_weights2[] = {0, 21, 43, 64}; static const char bc7_weights2[] = {0, 21, 43, 64};
static const char bc7_weights3[] = {0, 9, 18, 27, 37, 46, 55, 64}; static const char bc7_weights3[] = {0, 9, 18, 27, 37, 46, 55, 64};
static const char bc7_weights4[] = { static const char bc7_weights4[] = {
0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64}; 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64
};
static const char * static const char *
bc7_get_weights(int n) { bc7_get_weights(int n) {
@ -526,7 +532,8 @@ static const bc6_mode_info bc6_modes[] = {
{1, 0, 0, 10, 10, 10, 10}, {1, 0, 0, 10, 10, 10, 10},
{1, 1, 0, 11, 9, 9, 9}, {1, 1, 0, 11, 9, 9, 9},
{1, 1, 0, 12, 8, 8, 8}, {1, 1, 0, 12, 8, 8, 8},
{1, 1, 0, 16, 4, 4, 4}}; {1, 1, 0, 16, 4, 4, 4}
};
/* Table.F, encoded as a sequence of bit indices */ /* Table.F, encoded as a sequence of bit indices */
static const UINT8 bc6_bit_packings[][75] = { static const UINT8 bc6_bit_packings[][75] = {
@ -591,7 +598,8 @@ static const UINT8 bc6_bit_packings[][75] = {
64, 65, 66, 67, 68, 69, 70, 71, 27, 26, 80, 81, 82, 83, 84, 85, 86, 87, 43, 42}, 64, 65, 66, 67, 68, 69, 70, 71, 27, 26, 80, 81, 82, 83, 84, 85, 86, 87, 43, 42},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 15, 14, 13, 12, 11, 10, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 15, 14, 13, 12, 11, 10,
64, 65, 66, 67, 31, 30, 29, 28, 27, 26, 80, 81, 82, 83, 47, 46, 45, 44, 43, 42}}; 64, 65, 66, 67, 31, 30, 29, 28, 27, 26, 80, 81, 82, 83, 47, 46, 45, 44, 43, 42}
};
static void static void
bc6_sign_extend(UINT16 *v, int prec) { bc6_sign_extend(UINT16 *v, int prec) {
@ -830,7 +838,8 @@ decode_bcn(
int bytes, int bytes,
int N, int N,
int C, int C,
char *pixel_format) { char *pixel_format
) {
int ymax = state->ysize + state->yoff; int ymax = state->ysize + state->yoff;
const UINT8 *ptr = src; const UINT8 *ptr = src;
switch (N) { switch (N) {

View File

@ -13,7 +13,8 @@ void static inline ImagingLineBoxBlur32(
int edgeA, int edgeA,
int edgeB, int edgeB,
UINT32 ww, UINT32 ww,
UINT32 fw) { UINT32 fw
) {
int x; int x;
UINT32 acc[4]; UINT32 acc[4];
UINT32 bulk[4]; UINT32 bulk[4];
@ -109,7 +110,8 @@ void static inline ImagingLineBoxBlur8(
int edgeA, int edgeA,
int edgeB, int edgeB,
UINT32 ww, UINT32 ww,
UINT32 fw) { UINT32 fw
) {
int x; int x;
UINT32 acc; UINT32 acc;
UINT32 bulk; UINT32 bulk;
@ -198,7 +200,8 @@ ImagingHorizontalBoxBlur(Imaging imOut, Imaging imIn, float floatRadius) {
edgeA, edgeA,
edgeB, edgeB,
ww, ww,
fw); fw
);
if (imIn == imOut) { if (imIn == imOut) {
// Commit. // Commit.
memcpy(imOut->image8[y], lineOut, imIn->xsize); memcpy(imOut->image8[y], lineOut, imIn->xsize);
@ -214,7 +217,8 @@ ImagingHorizontalBoxBlur(Imaging imOut, Imaging imIn, float floatRadius) {
edgeA, edgeA,
edgeB, edgeB,
ww, ww,
fw); fw
);
if (imIn == imOut) { if (imIn == imOut) {
// Commit. // Commit.
memcpy(imOut->image32[y], lineOut, imIn->xsize * 4); memcpy(imOut->image32[y], lineOut, imIn->xsize * 4);
@ -315,11 +319,13 @@ _gaussian_blur_radius(float radius, int passes) {
Imaging Imaging
ImagingGaussianBlur( ImagingGaussianBlur(
Imaging imOut, Imaging imIn, float xradius, float yradius, int passes) { Imaging imOut, Imaging imIn, float xradius, float yradius, int passes
) {
return ImagingBoxBlur( return ImagingBoxBlur(
imOut, imOut,
imIn, imIn,
_gaussian_blur_radius(xradius, passes), _gaussian_blur_radius(xradius, passes),
_gaussian_blur_radius(yradius, passes), _gaussian_blur_radius(yradius, passes),
passes); passes
);
} }

View File

@ -142,7 +142,8 @@ ImagingChopSoftLight(Imaging imIn1, Imaging imIn2) {
CHOP2( CHOP2(
(((255 - in1[x]) * (in1[x] * in2[x])) / 65536) + (((255 - in1[x]) * (in1[x] * in2[x])) / 65536) +
(in1[x] * (255 - ((255 - in1[x]) * (255 - in2[x]) / 255))) / 255, (in1[x] * (255 - ((255 - in1[x]) * (255 - in2[x]) / 255))) / 255,
NULL); NULL
);
} }
Imaging Imaging
@ -150,7 +151,8 @@ ImagingChopHardLight(Imaging imIn1, Imaging imIn2) {
CHOP2( CHOP2(
(in2[x] < 128) ? ((in1[x] * in2[x]) / 127) (in2[x] < 128) ? ((in1[x] * in2[x]) / 127)
: 255 - (((255 - in2[x]) * (255 - in1[x])) / 127), : 255 - (((255 - in2[x]) * (255 - in1[x])) / 127),
NULL); NULL
);
} }
Imaging Imaging
@ -158,5 +160,6 @@ ImagingOverlay(Imaging imIn1, Imaging imIn2) {
CHOP2( CHOP2(
(in1[x] < 128) ? ((in1[x] * in2[x]) / 127) (in1[x] < 128) ? ((in1[x] * in2[x]) / 127)
: 255 - (((255 - in1[x]) * (255 - in2[x])) / 127), : 255 - (((255 - in1[x]) * (255 - in2[x])) / 127),
NULL); NULL
);
} }

View File

@ -63,7 +63,8 @@ ImagingColorLUT3D_linear(
int size1D, int size1D,
int size2D, int size2D,
int size3D, int size3D,
INT16 *table) { INT16 *table
) {
/* This float to int conversion doesn't have rounding /* This float to int conversion doesn't have rounding
error compensation (+0.5) for two reasons: error compensation (+0.5) for two reasons:
1. As we don't hit the highest value, 1. As we don't hit the highest value,
@ -112,7 +113,8 @@ ImagingColorLUT3D_linear(
index2D >> SCALE_BITS, index2D >> SCALE_BITS,
index3D >> SCALE_BITS, index3D >> SCALE_BITS,
size1D, size1D,
size1D_2D); size1D_2D
);
INT16 result[4], left[4], right[4]; INT16 result[4], left[4], right[4];
INT16 leftleft[4], leftright[4], rightleft[4], rightright[4]; INT16 leftleft[4], leftright[4], rightleft[4], rightright[4];
@ -123,19 +125,22 @@ ImagingColorLUT3D_linear(
leftright, leftright,
&table[idx + size1D * 3], &table[idx + size1D * 3],
&table[idx + size1D * 3 + 3], &table[idx + size1D * 3 + 3],
shift1D); shift1D
);
interpolate3(left, leftleft, leftright, shift2D); interpolate3(left, leftleft, leftright, shift2D);
interpolate3( interpolate3(
rightleft, rightleft,
&table[idx + size1D_2D * 3], &table[idx + size1D_2D * 3],
&table[idx + size1D_2D * 3 + 3], &table[idx + size1D_2D * 3 + 3],
shift1D); shift1D
);
interpolate3( interpolate3(
rightright, rightright,
&table[idx + size1D_2D * 3 + size1D * 3], &table[idx + size1D_2D * 3 + size1D * 3],
&table[idx + size1D_2D * 3 + size1D * 3 + 3], &table[idx + size1D_2D * 3 + size1D * 3 + 3],
shift1D); shift1D
);
interpolate3(right, rightleft, rightright, shift2D); interpolate3(right, rightleft, rightright, shift2D);
interpolate3(result, left, right, shift3D); interpolate3(result, left, right, shift3D);
@ -144,7 +149,8 @@ ImagingColorLUT3D_linear(
clip8(result[0]), clip8(result[0]),
clip8(result[1]), clip8(result[1]),
clip8(result[2]), clip8(result[2]),
rowIn[x * 4 + 3]); rowIn[x * 4 + 3]
);
memcpy(rowOut + x * sizeof(v), &v, sizeof(v)); memcpy(rowOut + x * sizeof(v), &v, sizeof(v));
} }
@ -155,19 +161,22 @@ ImagingColorLUT3D_linear(
leftright, leftright,
&table[idx + size1D * 4], &table[idx + size1D * 4],
&table[idx + size1D * 4 + 4], &table[idx + size1D * 4 + 4],
shift1D); shift1D
);
interpolate4(left, leftleft, leftright, shift2D); interpolate4(left, leftleft, leftright, shift2D);
interpolate4( interpolate4(
rightleft, rightleft,
&table[idx + size1D_2D * 4], &table[idx + size1D_2D * 4],
&table[idx + size1D_2D * 4 + 4], &table[idx + size1D_2D * 4 + 4],
shift1D); shift1D
);
interpolate4( interpolate4(
rightright, rightright,
&table[idx + size1D_2D * 4 + size1D * 4], &table[idx + size1D_2D * 4 + size1D * 4],
&table[idx + size1D_2D * 4 + size1D * 4 + 4], &table[idx + size1D_2D * 4 + size1D * 4 + 4],
shift1D); shift1D
);
interpolate4(right, rightleft, rightright, shift2D); interpolate4(right, rightleft, rightright, shift2D);
interpolate4(result, left, right, shift3D); interpolate4(result, left, right, shift3D);
@ -176,7 +185,8 @@ ImagingColorLUT3D_linear(
clip8(result[0]), clip8(result[0]),
clip8(result[1]), clip8(result[1]),
clip8(result[2]), clip8(result[2]),
clip8(result[3])); clip8(result[3])
);
memcpy(rowOut + x * sizeof(v), &v, sizeof(v)); memcpy(rowOut + x * sizeof(v), &v, sizeof(v));
} }
} }

View File

@ -1044,7 +1044,8 @@ static struct {
{"I;16L", "F", I16L_F}, {"I;16L", "F", I16L_F},
{"I;16B", "F", I16B_F}, {"I;16B", "F", I16B_F},
{NULL}}; {NULL}
};
/* FIXME: translate indexed versions to pointer versions below this line */ /* FIXME: translate indexed versions to pointer versions below this line */
@ -1316,7 +1317,8 @@ frompalette(Imaging imOut, Imaging imIn, const char *mode) {
(UINT8 *)imOut->image[y], (UINT8 *)imOut->image[y],
(UINT8 *)imIn->image[y], (UINT8 *)imIn->image[y],
imIn->xsize, imIn->xsize,
imIn->palette); imIn->palette
);
} }
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
@ -1328,11 +1330,8 @@ frompalette(Imaging imOut, Imaging imIn, const char *mode) {
#endif #endif
static Imaging static Imaging
topalette( topalette(
Imaging imOut, Imaging imOut, Imaging imIn, const char *mode, ImagingPalette inpalette, int dither
Imaging imIn, ) {
const char *mode,
ImagingPalette inpalette,
int dither) {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
int alpha; int alpha;
int x, y; int x, y;
@ -1623,7 +1622,8 @@ tobilevel(Imaging imOut, Imaging imIn) {
static Imaging static Imaging
convert( convert(
Imaging imOut, Imaging imIn, const char *mode, ImagingPalette palette, int dither) { Imaging imOut, Imaging imIn, const char *mode, ImagingPalette palette, int dither
) {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
ImagingShuffler convert; ImagingShuffler convert;
int y; int y;
@ -1677,7 +1677,8 @@ convert(
#else #else
static char buf[100]; static char buf[100];
snprintf( snprintf(
buf, 100, "conversion from %.10s to %.10s not supported", imIn->mode, mode); buf, 100, "conversion from %.10s to %.10s not supported", imIn->mode, mode
);
return (Imaging)ImagingError_ValueError(buf); return (Imaging)ImagingError_ValueError(buf);
#endif #endif
} }
@ -1727,18 +1728,16 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) {
if (strcmp(mode, "RGBa") == 0) { if (strcmp(mode, "RGBa") == 0) {
premultiplied = 1; premultiplied = 1;
} }
} else if ( } else if (strcmp(imIn->mode, "RGB") == 0 &&
strcmp(imIn->mode, "RGB") == 0 && (strcmp(mode, "LA") == 0 || strcmp(mode, "La") == 0)) {
(strcmp(mode, "LA") == 0 || strcmp(mode, "La") == 0)) {
convert = rgb2la; convert = rgb2la;
source_transparency = 1; source_transparency = 1;
if (strcmp(mode, "La") == 0) { if (strcmp(mode, "La") == 0) {
premultiplied = 1; premultiplied = 1;
} }
} else if ( } else if ((strcmp(imIn->mode, "1") == 0 || strcmp(imIn->mode, "I") == 0 ||
(strcmp(imIn->mode, "1") == 0 || strcmp(imIn->mode, "I") == 0 || strcmp(imIn->mode, "I;16") == 0 || strcmp(imIn->mode, "L") == 0) &&
strcmp(imIn->mode, "I;16") == 0 || strcmp(imIn->mode, "L") == 0) && (strcmp(mode, "RGBA") == 0 || strcmp(mode, "LA") == 0)) {
(strcmp(mode, "RGBA") == 0 || strcmp(mode, "LA") == 0)) {
if (strcmp(imIn->mode, "1") == 0) { if (strcmp(imIn->mode, "1") == 0) {
convert = bit2rgb; convert = bit2rgb;
} else if (strcmp(imIn->mode, "I") == 0) { } else if (strcmp(imIn->mode, "I") == 0) {
@ -1756,7 +1755,8 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) {
100, 100,
"conversion from %.10s to %.10s not supported in convert_transparent", "conversion from %.10s to %.10s not supported in convert_transparent",
imIn->mode, imIn->mode,
mode); mode
);
return (Imaging)ImagingError_ValueError(buf); return (Imaging)ImagingError_ValueError(buf);
} }

View File

@ -47,7 +47,8 @@ static INT16 Y_R[] = {
4019, 4038, 4057, 4076, 4095, 4114, 4133, 4153, 4172, 4191, 4210, 4229, 4248, 4267, 4019, 4038, 4057, 4076, 4095, 4114, 4133, 4153, 4172, 4191, 4210, 4229, 4248, 4267,
4286, 4306, 4325, 4344, 4363, 4382, 4401, 4420, 4440, 4459, 4478, 4497, 4516, 4535, 4286, 4306, 4325, 4344, 4363, 4382, 4401, 4420, 4440, 4459, 4478, 4497, 4516, 4535,
4554, 4574, 4593, 4612, 4631, 4650, 4669, 4688, 4707, 4727, 4746, 4765, 4784, 4803, 4554, 4574, 4593, 4612, 4631, 4650, 4669, 4688, 4707, 4727, 4746, 4765, 4784, 4803,
4822, 4841, 4861, 4880}; 4822, 4841, 4861, 4880
};
static INT16 Y_G[] = { static INT16 Y_G[] = {
0, 38, 75, 113, 150, 188, 225, 263, 301, 338, 376, 413, 451, 488, 0, 38, 75, 113, 150, 188, 225, 263, 301, 338, 376, 413, 451, 488,
@ -68,7 +69,8 @@ static INT16 Y_G[] = {
7889, 7927, 7964, 8002, 8040, 8077, 8115, 8152, 8190, 8227, 8265, 8303, 8340, 8378, 7889, 7927, 7964, 8002, 8040, 8077, 8115, 8152, 8190, 8227, 8265, 8303, 8340, 8378,
8415, 8453, 8490, 8528, 8566, 8603, 8641, 8678, 8716, 8753, 8791, 8828, 8866, 8904, 8415, 8453, 8490, 8528, 8566, 8603, 8641, 8678, 8716, 8753, 8791, 8828, 8866, 8904,
8941, 8979, 9016, 9054, 9091, 9129, 9167, 9204, 9242, 9279, 9317, 9354, 9392, 9430, 8941, 8979, 9016, 9054, 9091, 9129, 9167, 9204, 9242, 9279, 9317, 9354, 9392, 9430,
9467, 9505, 9542, 9580}; 9467, 9505, 9542, 9580
};
static INT16 Y_B[] = { static INT16 Y_B[] = {
0, 7, 15, 22, 29, 36, 44, 51, 58, 66, 73, 80, 88, 95, 0, 7, 15, 22, 29, 36, 44, 51, 58, 66, 73, 80, 88, 95,
@ -89,7 +91,8 @@ static INT16 Y_B[] = {
1532, 1539, 1547, 1554, 1561, 1569, 1576, 1583, 1591, 1598, 1605, 1612, 1620, 1627, 1532, 1539, 1547, 1554, 1561, 1569, 1576, 1583, 1591, 1598, 1605, 1612, 1620, 1627,
1634, 1642, 1649, 1656, 1663, 1671, 1678, 1685, 1693, 1700, 1707, 1715, 1722, 1729, 1634, 1642, 1649, 1656, 1663, 1671, 1678, 1685, 1693, 1700, 1707, 1715, 1722, 1729,
1736, 1744, 1751, 1758, 1766, 1773, 1780, 1788, 1795, 1802, 1809, 1817, 1824, 1831, 1736, 1744, 1751, 1758, 1766, 1773, 1780, 1788, 1795, 1802, 1809, 1817, 1824, 1831,
1839, 1846, 1853, 1860}; 1839, 1846, 1853, 1860
};
static INT16 Cb_R[] = { static INT16 Cb_R[] = {
0, -10, -21, -31, -42, -53, -64, -75, -85, -96, -107, -118, 0, -10, -21, -31, -42, -53, -64, -75, -85, -96, -107, -118,
@ -113,7 +116,8 @@ static INT16 Cb_R[] = {
-2332, -2342, -2353, -2364, -2375, -2386, -2396, -2407, -2418, -2429, -2440, -2450, -2332, -2342, -2353, -2364, -2375, -2386, -2396, -2407, -2418, -2429, -2440, -2450,
-2461, -2472, -2483, -2494, -2504, -2515, -2526, -2537, -2548, -2558, -2569, -2580, -2461, -2472, -2483, -2494, -2504, -2515, -2526, -2537, -2548, -2558, -2569, -2580,
-2591, -2602, -2612, -2623, -2634, -2645, -2656, -2666, -2677, -2688, -2699, -2710, -2591, -2602, -2612, -2623, -2634, -2645, -2656, -2666, -2677, -2688, -2699, -2710,
-2720, -2731, -2742, -2753}; -2720, -2731, -2742, -2753
};
static INT16 Cb_G[] = { static INT16 Cb_G[] = {
0, -20, -41, -63, -84, -105, -126, -147, -169, -190, -211, -232, 0, -20, -41, -63, -84, -105, -126, -147, -169, -190, -211, -232,
@ -137,7 +141,8 @@ static INT16 Cb_G[] = {
-4578, -4600, -4621, -4642, -4663, -4684, -4706, -4727, -4748, -4769, -4790, -4812, -4578, -4600, -4621, -4642, -4663, -4684, -4706, -4727, -4748, -4769, -4790, -4812,
-4833, -4854, -4875, -4896, -4918, -4939, -4960, -4981, -5002, -5024, -5045, -5066, -4833, -4854, -4875, -4896, -4918, -4939, -4960, -4981, -5002, -5024, -5045, -5066,
-5087, -5108, -5130, -5151, -5172, -5193, -5214, -5236, -5257, -5278, -5299, -5320, -5087, -5108, -5130, -5151, -5172, -5193, -5214, -5236, -5257, -5278, -5299, -5320,
-5342, -5363, -5384, -5405}; -5342, -5363, -5384, -5405
};
static INT16 Cb_B[] = { static INT16 Cb_B[] = {
0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416,
@ -158,7 +163,8 @@ static INT16 Cb_B[] = {
6720, 6752, 6784, 6816, 6848, 6880, 6912, 6944, 6976, 7008, 7040, 7072, 7104, 7136, 6720, 6752, 6784, 6816, 6848, 6880, 6912, 6944, 6976, 7008, 7040, 7072, 7104, 7136,
7168, 7200, 7232, 7264, 7296, 7328, 7360, 7392, 7424, 7456, 7488, 7520, 7552, 7584, 7168, 7200, 7232, 7264, 7296, 7328, 7360, 7392, 7424, 7456, 7488, 7520, 7552, 7584,
7616, 7648, 7680, 7712, 7744, 7776, 7808, 7840, 7872, 7904, 7936, 7968, 8000, 8032, 7616, 7648, 7680, 7712, 7744, 7776, 7808, 7840, 7872, 7904, 7936, 7968, 8000, 8032,
8064, 8096, 8128, 8160}; 8064, 8096, 8128, 8160
};
#define Cr_R Cb_B #define Cr_R Cb_B
@ -184,7 +190,8 @@ static INT16 Cr_G[] = {
-5787, -5814, -5841, -5867, -5894, -5921, -5948, -5975, -6001, -6028, -6055, -6082, -5787, -5814, -5841, -5867, -5894, -5921, -5948, -5975, -6001, -6028, -6055, -6082,
-6109, -6135, -6162, -6189, -6216, -6243, -6269, -6296, -6323, -6350, -6376, -6403, -6109, -6135, -6162, -6189, -6216, -6243, -6269, -6296, -6323, -6350, -6376, -6403,
-6430, -6457, -6484, -6510, -6537, -6564, -6591, -6618, -6644, -6671, -6698, -6725, -6430, -6457, -6484, -6510, -6537, -6564, -6591, -6618, -6644, -6671, -6698, -6725,
-6752, -6778, -6805, -6832}; -6752, -6778, -6805, -6832
};
static INT16 Cr_B[] = { static INT16 Cr_B[] = {
0, -4, -9, -15, -20, -25, -30, -35, -41, -46, -51, -56, 0, -4, -9, -15, -20, -25, -30, -35, -41, -46, -51, -56,
@ -208,7 +215,8 @@ static INT16 Cr_B[] = {
-1123, -1128, -1133, -1139, -1144, -1149, -1154, -1159, -1165, -1170, -1175, -1180, -1123, -1128, -1133, -1139, -1144, -1149, -1154, -1159, -1165, -1170, -1175, -1180,
-1185, -1191, -1196, -1201, -1206, -1211, -1217, -1222, -1227, -1232, -1238, -1243, -1185, -1191, -1196, -1201, -1206, -1211, -1217, -1222, -1227, -1232, -1238, -1243,
-1248, -1253, -1258, -1264, -1269, -1274, -1279, -1284, -1290, -1295, -1300, -1305, -1248, -1253, -1258, -1264, -1269, -1274, -1279, -1284, -1290, -1295, -1300, -1305,
-1310, -1316, -1321, -1326}; -1310, -1316, -1321, -1326
};
static INT16 R_Cr[] = { static INT16 R_Cr[] = {
-11484, -11394, -11305, -11215, -11125, -11036, -10946, -10856, -10766, -10677, -11484, -11394, -11305, -11215, -11125, -11036, -10946, -10856, -10766, -10677,
@ -236,7 +244,8 @@ static INT16 R_Cr[] = {
8255, 8345, 8434, 8524, 8614, 8704, 8793, 8883, 8973, 9063, 8255, 8345, 8434, 8524, 8614, 8704, 8793, 8883, 8973, 9063,
9152, 9242, 9332, 9421, 9511, 9601, 9691, 9780, 9870, 9960, 9152, 9242, 9332, 9421, 9511, 9601, 9691, 9780, 9870, 9960,
10050, 10139, 10229, 10319, 10408, 10498, 10588, 10678, 10767, 10857, 10050, 10139, 10229, 10319, 10408, 10498, 10588, 10678, 10767, 10857,
10947, 11037, 11126, 11216, 11306, 11395}; 10947, 11037, 11126, 11216, 11306, 11395
};
static INT16 G_Cb[] = { static INT16 G_Cb[] = {
2819, 2797, 2775, 2753, 2731, 2709, 2687, 2665, 2643, 2621, 2599, 2577, 2819, 2797, 2775, 2753, 2731, 2709, 2687, 2665, 2643, 2621, 2599, 2577,
@ -260,7 +269,8 @@ static INT16 G_Cb[] = {
-1937, -1959, -1981, -2003, -2025, -2047, -2069, -2091, -2113, -2135, -2157, -2179, -1937, -1959, -1981, -2003, -2025, -2047, -2069, -2091, -2113, -2135, -2157, -2179,
-2201, -2224, -2246, -2268, -2290, -2312, -2334, -2356, -2378, -2400, -2422, -2444, -2201, -2224, -2246, -2268, -2290, -2312, -2334, -2356, -2378, -2400, -2422, -2444,
-2466, -2488, -2510, -2532, -2554, -2576, -2598, -2620, -2642, -2664, -2686, -2708, -2466, -2488, -2510, -2532, -2554, -2576, -2598, -2620, -2642, -2664, -2686, -2708,
-2730, -2752, -2774, -2796}; -2730, -2752, -2774, -2796
};
static INT16 G_Cr[] = { static INT16 G_Cr[] = {
5850, 5805, 5759, 5713, 5667, 5622, 5576, 5530, 5485, 5439, 5393, 5347, 5850, 5805, 5759, 5713, 5667, 5622, 5576, 5530, 5485, 5439, 5393, 5347,
@ -284,7 +294,8 @@ static INT16 G_Cr[] = {
-4021, -4067, -4112, -4158, -4204, -4250, -4295, -4341, -4387, -4432, -4478, -4524, -4021, -4067, -4112, -4158, -4204, -4250, -4295, -4341, -4387, -4432, -4478, -4524,
-4569, -4615, -4661, -4707, -4752, -4798, -4844, -4889, -4935, -4981, -5027, -5072, -4569, -4615, -4661, -4707, -4752, -4798, -4844, -4889, -4935, -4981, -5027, -5072,
-5118, -5164, -5209, -5255, -5301, -5346, -5392, -5438, -5484, -5529, -5575, -5621, -5118, -5164, -5209, -5255, -5301, -5346, -5392, -5438, -5484, -5529, -5575, -5621,
-5666, -5712, -5758, -5804}; -5666, -5712, -5758, -5804
};
static INT16 B_Cb[] = { static INT16 B_Cb[] = {
-14515, -14402, -14288, -14175, -14062, -13948, -13835, -13721, -13608, -13495, -14515, -14402, -14288, -14175, -14062, -13948, -13835, -13721, -13608, -13495,
@ -312,7 +323,8 @@ static INT16 B_Cb[] = {
10434, 10547, 10660, 10774, 10887, 11001, 11114, 11227, 11341, 11454, 10434, 10547, 10660, 10774, 10887, 11001, 11114, 11227, 11341, 11454,
11568, 11681, 11794, 11908, 12021, 12135, 12248, 12361, 12475, 12588, 11568, 11681, 11794, 11908, 12021, 12135, 12248, 12361, 12475, 12588,
12702, 12815, 12929, 13042, 13155, 13269, 13382, 13496, 13609, 13722, 12702, 12815, 12929, 13042, 13155, 13269, 13382, 13496, 13609, 13722,
13836, 13949, 14063, 14176, 14289, 14403}; 13836, 13949, 14063, 14176, 14289, 14403
};
void void
ImagingConvertRGB2YCbCr(UINT8 *out, const UINT8 *in, int pixels) { ImagingConvertRGB2YCbCr(UINT8 *out, const UINT8 *in, int pixels) {

View File

@ -95,7 +95,8 @@ ImagingNewDIB(const char *mode, int xsize, int ysize) {
} }
dib->bitmap = CreateDIBSection( dib->bitmap = CreateDIBSection(
dib->dc, dib->info, DIB_RGB_COLORS, (void **)&dib->bits, NULL, 0); dib->dc, dib->info, DIB_RGB_COLORS, (void **)&dib->bits, NULL, 0
);
if (!dib->bitmap) { if (!dib->bitmap) {
free(dib->info); free(dib->info);
free(dib); free(dib);
@ -218,7 +219,8 @@ ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4]) {
dib->bits + dib->linesize * (dib->ysize - (xy[1] + y) - 1) + dib->bits + dib->linesize * (dib->ysize - (xy[1] + y) - 1) +
xy[0] * dib->pixelsize, xy[0] * dib->pixelsize,
im->image[y], im->image[y],
im->xsize); im->xsize
);
} }
} }
@ -251,7 +253,8 @@ ImagingDrawDIB(ImagingDIB dib, void *dc, int dst[4], int src[4]) {
dib->bits, dib->bits,
dib->info, dib->info,
DIB_RGB_COLORS, DIB_RGB_COLORS,
SRCCOPY); SRCCOPY
);
} else { } else {
/* stretchblt (displays) */ /* stretchblt (displays) */
if (dib->palette != 0) { if (dib->palette != 0) {
@ -268,7 +271,8 @@ ImagingDrawDIB(ImagingDIB dib, void *dc, int dst[4], int src[4]) {
src[1], src[1],
src[2] - src[0], src[2] - src[0],
src[3] - src[1], src[3] - src[1],
SRCCOPY); SRCCOPY
);
} }
} }

View File

@ -120,9 +120,8 @@ hline8(Imaging im, int x0, int y0, int x1, int ink) {
if (x0 <= x1) { if (x0 <= x1) {
pixelwidth = strncmp(im->mode, "I;16", 4) == 0 ? 2 : 1; pixelwidth = strncmp(im->mode, "I;16", 4) == 0 ? 2 : 1;
memset( memset(
im->image8[y0] + x0 * pixelwidth, im->image8[y0] + x0 * pixelwidth, (UINT8)ink, (x1 - x0 + 1) * pixelwidth
(UINT8)ink, );
(x1 - x0 + 1) * pixelwidth);
} }
} }
} }
@ -408,7 +407,8 @@ x_cmp(const void *x0, const void *x1) {
static void static void
draw_horizontal_lines( draw_horizontal_lines(
Imaging im, int n, Edge *e, int ink, int *x_pos, int y, hline_handler hline) { Imaging im, int n, Edge *e, int ink, int *x_pos, int y, hline_handler hline
) {
int i; int i;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (e[i].ymin == y && e[i].ymin == e[i].ymax) { if (e[i].ymin == y && e[i].ymin == e[i].ymax) {
@ -440,13 +440,8 @@ draw_horizontal_lines(
*/ */
static inline int static inline int
polygon_generic( polygon_generic(
Imaging im, Imaging im, int n, Edge *e, int ink, int eofill, hline_handler hline, int hasAlpha
int n, ) {
Edge *e,
int ink,
int eofill,
hline_handler hline,
int hasAlpha) {
Edge **edge_table; Edge **edge_table;
float *xx; float *xx;
int edge_count = 0; int edge_count = 0;
@ -530,25 +525,29 @@ polygon_generic(
other_edge->x0; other_edge->x0;
if (ymin == current->ymax) { if (ymin == current->ymax) {
if (current->dx > 0) { if (current->dx > 0) {
xx[k] = fmax( xx[k] =
adjacent_line_x, fmax(
adjacent_line_x_other_edge) + adjacent_line_x, adjacent_line_x_other_edge
1; ) +
1;
} else { } else {
xx[k] = fmin( xx[k] =
adjacent_line_x, fmin(
adjacent_line_x_other_edge) - adjacent_line_x, adjacent_line_x_other_edge
1; ) -
1;
} }
} else { } else {
if (current->dx > 0) { if (current->dx > 0) {
xx[k] = fmin( xx[k] = fmin(
adjacent_line_x, adjacent_line_x_other_edge); adjacent_line_x, adjacent_line_x_other_edge
);
} else { } else {
xx[k] = fmax( xx[k] =
adjacent_line_x, fmax(
adjacent_line_x_other_edge) + adjacent_line_x, adjacent_line_x_other_edge
1; ) +
1;
} }
} }
break; break;
@ -699,7 +698,8 @@ ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void *ink_, in
int int
ImagingDrawWideLine( ImagingDrawWideLine(
Imaging im, int x0, int y0, int x1, int y1, const void *ink_, int width, int op) { Imaging im, int x0, int y0, int x1, int y1, const void *ink_, int width, int op
) {
DRAW *draw; DRAW *draw;
INT32 ink; INT32 ink;
int dx, dy; int dx, dy;
@ -730,7 +730,8 @@ ImagingDrawWideLine(
{x0 - dxmin, y0 + dymax}, {x0 - dxmin, y0 + dymax},
{x1 - dxmin, y1 + dymax}, {x1 - dxmin, y1 + dymax},
{x1 + dxmax, y1 - dymin}, {x1 + dxmax, y1 - dymin},
{x0 + dxmax, y0 - dymin}}; {x0 + dxmax, y0 - dymin}
};
add_edge(e + 0, vertices[0][0], vertices[0][1], vertices[1][0], vertices[1][1]); add_edge(e + 0, vertices[0][0], vertices[0][1], vertices[1][0], vertices[1][1]);
add_edge(e + 1, vertices[1][0], vertices[1][1], vertices[2][0], vertices[2][1]); add_edge(e + 1, vertices[1][0], vertices[1][1], vertices[2][0], vertices[2][1]);
@ -752,7 +753,8 @@ ImagingDrawRectangle(
const void *ink_, const void *ink_,
int fill, int fill,
int width, int width,
int op) { int op
) {
int i; int i;
int y; int y;
int tmp; int tmp;
@ -800,7 +802,8 @@ ImagingDrawRectangle(
int int
ImagingDrawPolygon( ImagingDrawPolygon(
Imaging im, int count, int *xy, const void *ink_, int fill, int width, int op) { Imaging im, int count, int *xy, const void *ink_, int fill, int width, int op
) {
int i, n, x0, y0, x1, y1; int i, n, x0, y0, x1, y1;
DRAW *draw; DRAW *draw;
INT32 ink; INT32 ink;
@ -851,7 +854,8 @@ ImagingDrawPolygon(
if (width == 1) { if (width == 1) {
for (i = 0; i < count - 1; i++) { for (i = 0; i < count - 1; i++) {
draw->line( draw->line(
im, xy[i * 2], xy[i * 2 + 1], xy[i * 2 + 2], xy[i * 2 + 3], ink); im, xy[i * 2], xy[i * 2 + 1], xy[i * 2 + 2], xy[i * 2 + 3], ink
);
} }
draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink); draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink);
} else { } else {
@ -864,10 +868,12 @@ ImagingDrawPolygon(
xy[i * 2 + 3], xy[i * 2 + 3],
ink_, ink_,
width, width,
op); op
);
} }
ImagingDrawWideLine( ImagingDrawWideLine(
im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink_, width, op); im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink_, width, op
);
} }
} }
@ -877,7 +883,8 @@ ImagingDrawPolygon(
int int
ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void *ink, int op) { ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void *ink, int op) {
return ImagingFill2( return ImagingFill2(
im, ink, bitmap, x0, y0, x0 + bitmap->xsize, y0 + bitmap->ysize); im, ink, bitmap, x0, y0, x0 + bitmap->xsize, y0 + bitmap->ysize
);
} }
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
@ -1086,7 +1093,8 @@ clip_tree_transpose(clip_node *root) {
// segments, i.e. something like correct bracket sequences. // segments, i.e. something like correct bracket sequences.
int int
clip_tree_do_clip( clip_tree_do_clip(
clip_node *root, int32_t x0, int32_t y, int32_t x1, event_list **ret) { clip_node *root, int32_t x0, int32_t y, int32_t x1, event_list **ret
) {
if (root == NULL) { if (root == NULL) {
event_list *start = malloc(sizeof(event_list)); event_list *start = malloc(sizeof(event_list));
if (!start) { if (!start) {
@ -1223,7 +1231,8 @@ typedef struct {
} clip_ellipse_state; } clip_ellipse_state;
typedef void (*clip_ellipse_init)( typedef void (*clip_ellipse_init)(
clip_ellipse_state *, int32_t, int32_t, int32_t, float, float); clip_ellipse_state *, int32_t, int32_t, int32_t, float, float
);
void void
debug_clip_tree(clip_node *root, int space) { debug_clip_tree(clip_node *root, int space) {
@ -1335,7 +1344,8 @@ arc_init(clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float
// A chord line. // A chord line.
void void
chord_line_init( chord_line_init(
clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float ar) { clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float ar
) {
ellipse_init(&s->st, a, b, a + b + 1); ellipse_init(&s->st, a, b, a + b + 1);
s->head = NULL; s->head = NULL;
@ -1362,7 +1372,8 @@ chord_line_init(
// Pie side. // Pie side.
void void
pie_side_init( pie_side_init(
clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float _) { clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float _
) {
ellipse_init(&s->st, a, b, a + b + 1); ellipse_init(&s->st, a, b, a + b + 1);
s->head = NULL; s->head = NULL;
@ -1478,7 +1489,8 @@ clip_ellipse_free(clip_ellipse_state *s) {
int8_t int8_t
clip_ellipse_next( clip_ellipse_next(
clip_ellipse_state *s, int32_t *ret_x0, int32_t *ret_y, int32_t *ret_x1) { clip_ellipse_state *s, int32_t *ret_x0, int32_t *ret_y, int32_t *ret_x1
) {
int32_t x0, y, x1; int32_t x0, y, x1;
while (s->head == NULL && ellipse_next(&s->st, &x0, &y, &x1) >= 0) { while (s->head == NULL && ellipse_next(&s->st, &x0, &y, &x1) >= 0) {
if (clip_tree_do_clip(s->root, x0, y, x1, &s->head) < 0) { if (clip_tree_do_clip(s->root, x0, y, x1, &s->head) < 0) {
@ -1512,7 +1524,8 @@ ellipseNew(
const void *ink_, const void *ink_,
int fill, int fill,
int width, int width,
int op) { int op
) {
DRAW *draw; DRAW *draw;
INT32 ink; INT32 ink;
DRAWINIT(); DRAWINIT();
@ -1547,7 +1560,8 @@ clipEllipseNew(
const void *ink_, const void *ink_,
int width, int width,
int op, int op,
clip_ellipse_init init) { clip_ellipse_init init
) {
DRAW *draw; DRAW *draw;
INT32 ink; INT32 ink;
DRAWINIT(); DRAWINIT();
@ -1580,7 +1594,8 @@ arcNew(
float end, float end,
const void *ink_, const void *ink_,
int width, int width,
int op) { int op
) {
return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, arc_init); return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, arc_init);
} }
@ -1595,7 +1610,8 @@ chordNew(
float end, float end,
const void *ink_, const void *ink_,
int width, int width,
int op) { int op
) {
return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, chord_init); return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, chord_init);
} }
@ -1610,9 +1626,11 @@ chordLineNew(
float end, float end,
const void *ink_, const void *ink_,
int width, int width,
int op) { int op
) {
return clipEllipseNew( return clipEllipseNew(
im, x0, y0, x1, y1, start, end, ink_, width, op, chord_line_init); im, x0, y0, x1, y1, start, end, ink_, width, op, chord_line_init
);
} }
static int static int
@ -1626,7 +1644,8 @@ pieNew(
float end, float end,
const void *ink_, const void *ink_,
int width, int width,
int op) { int op
) {
return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, pie_init); return clipEllipseNew(im, x0, y0, x1, y1, start, end, ink_, width, op, pie_init);
} }
@ -1640,7 +1659,8 @@ pieSideNew(
float start, float start,
const void *ink_, const void *ink_,
int width, int width,
int op) { int op
) {
return clipEllipseNew(im, x0, y0, x1, y1, start, 0, ink_, width, op, pie_side_init); return clipEllipseNew(im, x0, y0, x1, y1, start, 0, ink_, width, op, pie_side_init);
} }
@ -1654,7 +1674,8 @@ ImagingDrawEllipse(
const void *ink, const void *ink,
int fill, int fill,
int width, int width,
int op) { int op
) {
return ellipseNew(im, x0, y0, x1, y1, ink, fill, width, op); return ellipseNew(im, x0, y0, x1, y1, ink, fill, width, op);
} }
@ -1669,7 +1690,8 @@ ImagingDrawArc(
float end, float end,
const void *ink, const void *ink,
int width, int width,
int op) { int op
) {
normalize_angles(&start, &end); normalize_angles(&start, &end);
if (start + 360 == end) { if (start + 360 == end) {
return ImagingDrawEllipse(im, x0, y0, x1, y1, ink, 0, width, op); return ImagingDrawEllipse(im, x0, y0, x1, y1, ink, 0, width, op);
@ -1692,7 +1714,8 @@ ImagingDrawChord(
const void *ink, const void *ink,
int fill, int fill,
int width, int width,
int op) { int op
) {
normalize_angles(&start, &end); normalize_angles(&start, &end);
if (start + 360 == end) { if (start + 360 == end) {
return ImagingDrawEllipse(im, x0, y0, x1, y1, ink, fill, width, op); return ImagingDrawEllipse(im, x0, y0, x1, y1, ink, fill, width, op);
@ -1722,7 +1745,8 @@ ImagingDrawPieslice(
const void *ink, const void *ink,
int fill, int fill,
int width, int width,
int op) { int op
) {
normalize_angles(&start, &end); normalize_angles(&start, &end);
if (start + 360 == end) { if (start + 360 == end) {
return ellipseNew(im, x0, y0, x1, y1, ink, fill, width, op); return ellipseNew(im, x0, y0, x1, y1, ink, fill, width, op);
@ -1850,13 +1874,8 @@ ImagingOutlineLine(ImagingOutline outline, float x1, float y1) {
int int
ImagingOutlineCurve( ImagingOutlineCurve(
ImagingOutline outline, ImagingOutline outline, float x1, float y1, float x2, float y2, float x3, float y3
float x1, ) {
float y1,
float x2,
float y2,
float x3,
float y3) {
Edge *e; Edge *e;
int i; int i;
float xo, yo; float xo, yo;
@ -1970,7 +1989,8 @@ ImagingOutlineTransform(ImagingOutline outline, double a[6]) {
int int
ImagingDrawOutline( ImagingDrawOutline(
Imaging im, ImagingOutline outline, const void *ink_, int fill, int op) { Imaging im, ImagingOutline outline, const void *ink_, int fill, int op
) {
DRAW *draw; DRAW *draw;
INT32 ink; INT32 ink;

View File

@ -118,8 +118,8 @@ ImagingFillRadialGradient(const char *mode) {
for (y = 0; y < 256; y++) { for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) { for (x = 0; x < 256; x++) {
d = (int)sqrt( d = (int
(double)((x - 128) * (x - 128) + (y - 128) * (y - 128)) * 2.0); )sqrt((double)((x - 128) * (x - 128) + (y - 128) * (y - 128)) * 2.0);
if (d >= 255) { if (d >= 255) {
d = 255; d = 255;
} }

View File

@ -60,7 +60,8 @@ ImagingExpand(Imaging imIn, int xmargin, int ymargin) {
imOut = ImagingNewDirty( imOut = ImagingNewDirty(
imIn->mode, imIn->mode,
(ImagingNewParams){imIn->xsize + 2 * xmargin, imIn->ysize + 2 * ymargin}); (ImagingNewParams){imIn->xsize + 2 * xmargin, imIn->ysize + 2 * ymargin}
);
if (!imOut) { if (!imOut) {
return NULL; return NULL;
} }
@ -370,7 +371,8 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float *kernel, float offset) {
} }
} }
memcpy( memcpy(
out + x * sizeof(UINT32), in0 + x * sizeof(UINT32), sizeof(UINT32) * 2); out + x * sizeof(UINT32), in0 + x * sizeof(UINT32), sizeof(UINT32) * 2
);
} }
} }
memcpy(imOut->image[y], im->image[y], im->linesize); memcpy(imOut->image[y], im->image[y], im->linesize);

View File

@ -720,7 +720,8 @@ ImagingGenericTransform(
ImagingTransformMap transform, ImagingTransformMap transform,
void *transform_data, void *transform_data,
int filterid, int filterid,
int fill) { int fill
) {
/* slow generic transformation. use ImagingTransformAffine or /* slow generic transformation. use ImagingTransformAffine or
ImagingScaleAffine where possible. */ ImagingScaleAffine where possible. */
@ -775,14 +776,8 @@ ImagingGenericTransform(
static Imaging static Imaging
ImagingScaleAffine( ImagingScaleAffine(
Imaging imOut, Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, double a[6], int fill
Imaging imIn, ) {
int x0,
int y0,
int x1,
int y1,
double a[6],
int fill) {
/* scale, nearest neighbour resampling */ /* scale, nearest neighbour resampling */
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
@ -875,7 +870,8 @@ static inline int
check_fixed(double a[6], int x, int y) { check_fixed(double a[6], int x, int y) {
return ( return (
fabs(x * a[0] + y * a[1] + a[2]) < 32768.0 && fabs(x * a[0] + y * a[1] + a[2]) < 32768.0 &&
fabs(x * a[3] + y * a[4] + a[5]) < 32768.0); fabs(x * a[3] + y * a[4] + a[5]) < 32768.0
);
} }
static inline Imaging static inline Imaging
@ -888,7 +884,8 @@ affine_fixed(
int y1, int y1,
double a[6], double a[6],
int filterid, int filterid,
int fill) { int fill
) {
/* affine transform, nearest neighbour resampling, fixed point /* affine transform, nearest neighbour resampling, fixed point
arithmetics */ arithmetics */
@ -965,7 +962,8 @@ ImagingTransformAffine(
int y1, int y1,
double a[6], double a[6],
int filterid, int filterid,
int fill) { int fill
) {
/* affine transform, nearest neighbour resampling, floating point /* affine transform, nearest neighbour resampling, floating point
arithmetics*/ arithmetics*/
@ -978,7 +976,8 @@ ImagingTransformAffine(
if (filterid || imIn->type == IMAGING_TYPE_SPECIAL) { if (filterid || imIn->type == IMAGING_TYPE_SPECIAL) {
return ImagingGenericTransform( return ImagingGenericTransform(
imOut, imIn, x0, y0, x1, y1, affine_transform, a, filterid, fill); imOut, imIn, x0, y0, x1, y1, affine_transform, a, filterid, fill
);
} }
if (a[1] == 0 && a[3] == 0) { if (a[1] == 0 && a[3] == 0) {
@ -1073,13 +1072,15 @@ ImagingTransform(
int y1, int y1,
double a[8], double a[8],
int filterid, int filterid,
int fill) { int fill
) {
ImagingTransformMap transform; ImagingTransformMap transform;
switch (method) { switch (method) {
case IMAGING_TRANSFORM_AFFINE: case IMAGING_TRANSFORM_AFFINE:
return ImagingTransformAffine( return ImagingTransformAffine(
imOut, imIn, x0, y0, x1, y1, a, filterid, fill); imOut, imIn, x0, y0, x1, y1, a, filterid, fill
);
break; break;
case IMAGING_TRANSFORM_PERSPECTIVE: case IMAGING_TRANSFORM_PERSPECTIVE:
transform = perspective_transform; transform = perspective_transform;
@ -1092,5 +1093,6 @@ ImagingTransform(
} }
return ImagingGenericTransform( return ImagingGenericTransform(
imOut, imIn, x0, y0, x1, y1, transform, a, filterid, fill); imOut, imIn, x0, y0, x1, y1, transform, a, filterid, fill
);
} }

View File

@ -58,11 +58,10 @@ ImagingGetBBox(Imaging im, int bbox[4], int alpha_only) {
INT32 mask = 0xffffffff; INT32 mask = 0xffffffff;
if (im->bands == 3) { if (im->bands == 3) {
((UINT8 *)&mask)[3] = 0; ((UINT8 *)&mask)[3] = 0;
} else if ( } else if (alpha_only &&
alpha_only && (strcmp(im->mode, "RGBa") == 0 || strcmp(im->mode, "RGBA") == 0 ||
(strcmp(im->mode, "RGBa") == 0 || strcmp(im->mode, "RGBA") == 0 || strcmp(im->mode, "La") == 0 || strcmp(im->mode, "LA") == 0 ||
strcmp(im->mode, "La") == 0 || strcmp(im->mode, "LA") == 0 || strcmp(im->mode, "PA") == 0)) {
strcmp(im->mode, "PA") == 0)) {
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
mask = 0x000000ff; mask = 0x000000ff;
#else #else
@ -246,13 +245,14 @@ getcolors32(Imaging im, int maxcolors, int *size) {
code in Python 2.1.3; the exact implementation is borrowed from code in Python 2.1.3; the exact implementation is borrowed from
Python's Unicode property database (written by yours truly) /F */ Python's Unicode property database (written by yours truly) /F */
static int SIZES[] = { static int SIZES[] = {4, 3, 8, 3, 16, 3, 32, 5,
4, 3, 8, 3, 16, 3, 32, 5, 64, 3, 64, 3, 128, 3, 256, 29, 512, 17,
128, 3, 256, 29, 512, 17, 1024, 9, 2048, 5, 1024, 9, 2048, 5, 4096, 83, 8192, 27,
4096, 83, 8192, 27, 16384, 43, 32768, 3, 65536, 45, 16384, 43, 32768, 3, 65536, 45, 131072, 9,
131072, 9, 262144, 39, 524288, 39, 1048576, 9, 2097152, 5, 262144, 39, 524288, 39, 1048576, 9, 2097152, 5,
4194304, 3, 8388608, 33, 16777216, 27, 33554432, 9, 67108864, 71, 4194304, 3, 8388608, 33, 16777216, 27, 33554432, 9,
134217728, 39, 268435456, 9, 536870912, 5, 1073741824, 83, 0}; 67108864, 71, 134217728, 39, 268435456, 9, 536870912, 5,
1073741824, 83, 0};
code_size = code_poly = code_mask = 0; code_size = code_poly = code_mask = 0;

View File

@ -79,7 +79,8 @@ glzwe(
UINT8 *out_ptr, UINT8 *out_ptr,
UINT32 *in_avail, UINT32 *in_avail,
UINT32 *out_avail, UINT32 *out_avail,
UINT32 end_of_data) { UINT32 end_of_data
) {
switch (st->entry_state) { switch (st->entry_state) {
case LZW_TRY_IN1: case LZW_TRY_IN1:
get_first_byte: get_first_byte:
@ -312,7 +313,8 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
state->buffer, state->buffer,
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->xsize); state->xsize
);
state->x = 0; state->x = 0;
/* step forward, according to the interlace settings */ /* step forward, according to the interlace settings */
@ -348,7 +350,8 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
ptr, ptr,
&in_avail, &in_avail,
&out_avail, &out_avail,
state->state == FINISH); state->state == FINISH
);
out_used = sub_block_limit - ptr - out_avail; out_used = sub_block_limit - ptr - out_avail;
*sub_block_ptr += out_used; *sub_block_ptr += out_used;
ptr += out_used; ptr += out_used;

View File

@ -49,7 +49,8 @@ ImagingHexDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t byt
if (++state->x >= state->bytes) { if (++state->x >= state->bytes) {
/* Got a full line, unpack it */ /* Got a full line, unpack it */
state->shuffle( state->shuffle(
(UINT8 *)im->image[state->y], state->buffer, state->xsize); (UINT8 *)im->image[state->y], state->buffer, state->xsize
);
state->x = 0; state->x = 0;

View File

@ -316,7 +316,8 @@ extern Imaging
ImagingFill(Imaging im, const void *ink); ImagingFill(Imaging im, const void *ink);
extern int extern int
ImagingFill2( ImagingFill2(
Imaging into, const void *ink, Imaging mask, int x0, int y0, int x1, int y1); Imaging into, const void *ink, Imaging mask, int x0, int y0, int x1, int y1
);
extern Imaging extern Imaging
ImagingFillBand(Imaging im, int band, int color); ImagingFillBand(Imaging im, int band, int color);
extern Imaging extern Imaging
@ -331,7 +332,8 @@ extern Imaging
ImagingFlipTopBottom(Imaging imOut, Imaging imIn); ImagingFlipTopBottom(Imaging imOut, Imaging imIn);
extern Imaging extern Imaging
ImagingGaussianBlur( ImagingGaussianBlur(
Imaging imOut, Imaging imIn, float xradius, float yradius, int passes); Imaging imOut, Imaging imIn, float xradius, float yradius, int passes
);
extern Imaging extern Imaging
ImagingGetBand(Imaging im, int band); ImagingGetBand(Imaging im, int band);
extern Imaging extern Imaging
@ -394,7 +396,8 @@ ImagingTransform(
int y1, int y1,
double a[8], double a[8],
int filter, int filter,
int fill); int fill
);
extern Imaging extern Imaging
ImagingUnsharpMask(Imaging imOut, Imaging im, float radius, int percent, int threshold); ImagingUnsharpMask(Imaging imOut, Imaging im, float radius, int percent, int threshold);
extern Imaging extern Imaging
@ -407,7 +410,8 @@ ImagingColorLUT3D_linear(
int size1D, int size1D,
int size2D, int size2D,
int size3D, int size3D,
INT16 *table); INT16 *table
);
extern Imaging extern Imaging
ImagingCopy2(Imaging imOut, Imaging imIn); ImagingCopy2(Imaging imOut, Imaging imIn);
@ -461,7 +465,8 @@ ImagingDrawArc(
float end, float end,
const void *ink, const void *ink,
int width, int width,
int op); int op
);
extern int extern int
ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void *ink, int op); ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void *ink, int op);
extern int extern int
@ -476,7 +481,8 @@ ImagingDrawChord(
const void *ink, const void *ink,
int fill, int fill,
int width, int width,
int op); int op
);
extern int extern int
ImagingDrawEllipse( ImagingDrawEllipse(
Imaging im, Imaging im,
@ -487,12 +493,14 @@ ImagingDrawEllipse(
const void *ink, const void *ink,
int fill, int fill,
int width, int width,
int op); int op
);
extern int extern int
ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void *ink, int op); ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void *ink, int op);
extern int extern int
ImagingDrawWideLine( ImagingDrawWideLine(
Imaging im, int x0, int y0, int x1, int y1, const void *ink, int width, int op); Imaging im, int x0, int y0, int x1, int y1, const void *ink, int width, int op
);
extern int extern int
ImagingDrawPieslice( ImagingDrawPieslice(
Imaging im, Imaging im,
@ -505,12 +513,14 @@ ImagingDrawPieslice(
const void *ink, const void *ink,
int fill, int fill,
int width, int width,
int op); int op
);
extern int extern int
ImagingDrawPoint(Imaging im, int x, int y, const void *ink, int op); ImagingDrawPoint(Imaging im, int x, int y, const void *ink, int op);
extern int extern int
ImagingDrawPolygon( ImagingDrawPolygon(
Imaging im, int points, int *xy, const void *ink, int fill, int width, int op); Imaging im, int points, int *xy, const void *ink, int fill, int width, int op
);
extern int extern int
ImagingDrawRectangle( ImagingDrawRectangle(
Imaging im, Imaging im,
@ -521,7 +531,8 @@ ImagingDrawRectangle(
const void *ink, const void *ink,
int fill, int fill,
int width, int width,
int op); int op
);
/* Level 2 graphics (WORK IN PROGRESS) */ /* Level 2 graphics (WORK IN PROGRESS) */
extern ImagingOutline extern ImagingOutline
@ -531,7 +542,8 @@ ImagingOutlineDelete(ImagingOutline outline);
extern int extern int
ImagingDrawOutline( ImagingDrawOutline(
Imaging im, ImagingOutline outline, const void *ink, int fill, int op); Imaging im, ImagingOutline outline, const void *ink, int fill, int op
);
extern int extern int
ImagingOutlineMove(ImagingOutline outline, float x, float y); ImagingOutlineMove(ImagingOutline outline, float x, float y);
@ -539,7 +551,8 @@ extern int
ImagingOutlineLine(ImagingOutline outline, float x, float y); ImagingOutlineLine(ImagingOutline outline, float x, float y);
extern int extern int
ImagingOutlineCurve( ImagingOutlineCurve(
ImagingOutline outline, float x1, float y1, float x2, float y2, float x3, float y3); ImagingOutline outline, float x1, float y1, float x2, float y2, float x3, float y3
);
extern int extern int
ImagingOutlineTransform(ImagingOutline outline, double a[6]); ImagingOutlineTransform(ImagingOutline outline, double a[6]);
@ -566,7 +579,8 @@ ImagingSavePPM(Imaging im, const char *filename);
/* Codecs */ /* Codecs */
typedef struct ImagingCodecStateInstance *ImagingCodecState; typedef struct ImagingCodecStateInstance *ImagingCodecState;
typedef int (*ImagingCodec)( typedef int (*ImagingCodec)(
Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes); Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes
);
extern int extern int
ImagingBcnDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes); ImagingBcnDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
@ -596,7 +610,8 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes)
#ifdef HAVE_OPENJPEG #ifdef HAVE_OPENJPEG
extern int extern int
ImagingJpeg2KDecode( ImagingJpeg2KDecode(
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes); Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
);
extern int extern int
ImagingJpeg2KDecodeCleanup(ImagingCodecState state); ImagingJpeg2KDecodeCleanup(ImagingCodecState state);
extern int extern int
@ -607,7 +622,8 @@ ImagingJpeg2KEncodeCleanup(ImagingCodecState state);
#ifdef HAVE_LIBTIFF #ifdef HAVE_LIBTIFF
extern int extern int
ImagingLibTiffDecode( ImagingLibTiffDecode(
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes); Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
);
extern int extern int
ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes); ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
#endif #endif
@ -619,7 +635,8 @@ extern int
ImagingMspDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes); ImagingMspDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
extern int extern int
ImagingPackbitsDecode( ImagingPackbitsDecode(
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes); Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
);
extern int extern int
ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes); ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
extern int extern int
@ -632,13 +649,16 @@ extern int
ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes); ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
extern int extern int
ImagingSgiRleDecode( ImagingSgiRleDecode(
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes); Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
);
extern int extern int
ImagingSunRleDecode( ImagingSunRleDecode(
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes); Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
);
extern int extern int
ImagingTgaRleDecode( ImagingTgaRleDecode(
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes); Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
);
extern int extern int
ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes); ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
extern int extern int

View File

@ -67,7 +67,8 @@ j2k_skip(OPJ_OFF_T p_nb_bytes, void *p_user_data) {
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
typedef void (*j2k_unpacker_t)( typedef void (*j2k_unpacker_t)(
opj_image_t *in, const JPEG2KTILEINFO *tileInfo, const UINT8 *data, Imaging im); opj_image_t *in, const JPEG2KTILEINFO *tileInfo, const UINT8 *data, Imaging im
);
struct j2k_decode_unpacker { struct j2k_decode_unpacker {
const char *mode; const char *mode;
@ -89,10 +90,8 @@ j2ku_shift(unsigned x, int n) {
static void static void
j2ku_gray_l( j2ku_gray_l(
opj_image_t *in, opj_image_t *in, const JPEG2KTILEINFO *tileinfo, const UINT8 *tiledata, Imaging im
const JPEG2KTILEINFO *tileinfo, ) {
const UINT8 *tiledata,
Imaging im) {
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0; unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0; unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0; unsigned h = tileinfo->y1 - tileinfo->y0;
@ -145,10 +144,8 @@ j2ku_gray_l(
static void static void
j2ku_gray_i( j2ku_gray_i(
opj_image_t *in, opj_image_t *in, const JPEG2KTILEINFO *tileinfo, const UINT8 *tiledata, Imaging im
const JPEG2KTILEINFO *tileinfo, ) {
const UINT8 *tiledata,
Imaging im) {
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0; unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0; unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0; unsigned h = tileinfo->y1 - tileinfo->y0;
@ -204,10 +201,8 @@ j2ku_gray_i(
static void static void
j2ku_gray_rgb( j2ku_gray_rgb(
opj_image_t *in, opj_image_t *in, const JPEG2KTILEINFO *tileinfo, const UINT8 *tiledata, Imaging im
const JPEG2KTILEINFO *tileinfo, ) {
const UINT8 *tiledata,
Imaging im) {
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0; unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0; unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0; unsigned h = tileinfo->y1 - tileinfo->y0;
@ -268,10 +263,8 @@ j2ku_gray_rgb(
static void static void
j2ku_graya_la( j2ku_graya_la(
opj_image_t *in, opj_image_t *in, const JPEG2KTILEINFO *tileinfo, const UINT8 *tiledata, Imaging im
const JPEG2KTILEINFO *tileinfo, ) {
const UINT8 *tiledata,
Imaging im) {
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0; unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0; unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0; unsigned h = tileinfo->y1 - tileinfo->y0;
@ -347,10 +340,8 @@ j2ku_graya_la(
static void static void
j2ku_srgb_rgb( j2ku_srgb_rgb(
opj_image_t *in, opj_image_t *in, const JPEG2KTILEINFO *tileinfo, const UINT8 *tiledata, Imaging im
const JPEG2KTILEINFO *tileinfo, ) {
const UINT8 *tiledata,
Imaging im) {
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0; unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0; unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0; unsigned h = tileinfo->y1 - tileinfo->y0;
@ -413,10 +404,8 @@ j2ku_srgb_rgb(
static void static void
j2ku_sycc_rgb( j2ku_sycc_rgb(
opj_image_t *in, opj_image_t *in, const JPEG2KTILEINFO *tileinfo, const UINT8 *tiledata, Imaging im
const JPEG2KTILEINFO *tileinfo, ) {
const UINT8 *tiledata,
Imaging im) {
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0; unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0; unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0; unsigned h = tileinfo->y1 - tileinfo->y0;
@ -482,10 +471,8 @@ j2ku_sycc_rgb(
static void static void
j2ku_srgba_rgba( j2ku_srgba_rgba(
opj_image_t *in, opj_image_t *in, const JPEG2KTILEINFO *tileinfo, const UINT8 *tiledata, Imaging im
const JPEG2KTILEINFO *tileinfo, ) {
const UINT8 *tiledata,
Imaging im) {
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0; unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0; unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0; unsigned h = tileinfo->y1 - tileinfo->y0;
@ -547,10 +534,8 @@ j2ku_srgba_rgba(
static void static void
j2ku_sycca_rgba( j2ku_sycca_rgba(
opj_image_t *in, opj_image_t *in, const JPEG2KTILEINFO *tileinfo, const UINT8 *tiledata, Imaging im
const JPEG2KTILEINFO *tileinfo, ) {
const UINT8 *tiledata,
Imaging im) {
unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0; unsigned x0 = tileinfo->x0 - in->x0, y0 = tileinfo->y0 - in->y0;
unsigned w = tileinfo->x1 - tileinfo->x0; unsigned w = tileinfo->x1 - tileinfo->x0;
unsigned h = tileinfo->y1 - tileinfo->y0; unsigned h = tileinfo->y1 - tileinfo->y0;
@ -815,7 +800,8 @@ j2k_decode_entry(Imaging im, ImagingCodecState state) {
&tile_info.x1, &tile_info.x1,
&tile_info.y1, &tile_info.y1,
&tile_info.nb_comps, &tile_info.nb_comps,
&should_continue)) { &should_continue
)) {
state->errcode = IMAGING_CODEC_BROKEN; state->errcode = IMAGING_CODEC_BROKEN;
state->state = J2K_STATE_FAILED; state->state = J2K_STATE_FAILED;
goto quick_exit; goto quick_exit;
@ -906,7 +892,8 @@ j2k_decode_entry(Imaging im, ImagingCodecState state) {
tile_info.tile_index, tile_info.tile_index,
(OPJ_BYTE *)state->buffer, (OPJ_BYTE *)state->buffer,
tile_info.data_size, tile_info.data_size,
stream)) { stream
)) {
state->errcode = IMAGING_CODEC_BROKEN; state->errcode = IMAGING_CODEC_BROKEN;
state->state = J2K_STATE_FAILED; state->state = J2K_STATE_FAILED;
goto quick_exit; goto quick_exit;

View File

@ -89,7 +89,8 @@ j2k_seek(OPJ_OFF_T p_nb_bytes, void *p_user_data) {
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
typedef void (*j2k_pack_tile_t)( typedef void (*j2k_pack_tile_t)(
Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h); Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h
);
static void static void
j2k_pack_l(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) { j2k_pack_l(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) {
@ -157,7 +158,8 @@ j2k_pack_rgb(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsig
static void static void
j2k_pack_rgba( j2k_pack_rgba(
Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) { Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h
) {
UINT8 *pr = buf; UINT8 *pr = buf;
UINT8 *pg = pr + w * h; UINT8 *pg = pr + w * h;
UINT8 *pb = pg + w * h; UINT8 *pb = pg + w * h;
@ -205,8 +207,8 @@ j2k_set_cinema_params(Imaging im, int components, opj_cparameters_t *params) {
if (params->cp_cinema == OPJ_CINEMA4K_24) { if (params->cp_cinema == OPJ_CINEMA4K_24) {
float max_rate = float max_rate =
((float)(components * im->xsize * im->ysize * 8) / ((float)(components * im->xsize * im->ysize * 8) / (CINEMA_24_CS_LENGTH * 8)
(CINEMA_24_CS_LENGTH * 8)); );
params->POC[0].tile = 1; params->POC[0].tile = 1;
params->POC[0].resno0 = 0; params->POC[0].resno0 = 0;
@ -241,8 +243,8 @@ j2k_set_cinema_params(Imaging im, int components, opj_cparameters_t *params) {
params->max_comp_size = COMP_24_CS_MAX_LENGTH; params->max_comp_size = COMP_24_CS_MAX_LENGTH;
} else { } else {
float max_rate = float max_rate =
((float)(components * im->xsize * im->ysize * 8) / ((float)(components * im->xsize * im->ysize * 8) / (CINEMA_48_CS_LENGTH * 8)
(CINEMA_48_CS_LENGTH * 8)); );
for (n = 0; n < params->tcp_numlayers; ++n) { for (n = 0; n < params->tcp_numlayers; ++n) {
rate = 0; rate = 0;

View File

@ -206,9 +206,8 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t by
context->cinfo.out_color_space = JCS_EXT_RGBX; context->cinfo.out_color_space = JCS_EXT_RGBX;
} }
#endif #endif
else if ( else if (strcmp(context->rawmode, "CMYK") == 0 ||
strcmp(context->rawmode, "CMYK") == 0 || strcmp(context->rawmode, "CMYK;I") == 0) {
strcmp(context->rawmode, "CMYK;I") == 0) {
context->cinfo.out_color_space = JCS_CMYK; context->cinfo.out_color_space = JCS_CMYK;
} else if (strcmp(context->rawmode, "YCbCr") == 0) { } else if (strcmp(context->rawmode, "YCbCr") == 0) {
context->cinfo.out_color_space = JCS_YCbCr; context->cinfo.out_color_space = JCS_YCbCr;
@ -256,7 +255,8 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t by
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->buffer, state->buffer,
state->xsize); state->xsize
);
state->y++; state->y++;
} }
if (ok != 1) { if (ok != 1) {

View File

@ -175,7 +175,8 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
i, i,
&context->qtables[i * DCTSIZE2], &context->qtables[i * DCTSIZE2],
quality, quality,
FALSE); FALSE
);
context->cinfo.comp_info[i].quant_tbl_no = i; context->cinfo.comp_info[i].quant_tbl_no = i;
last_q = i; last_q = i;
} }
@ -183,7 +184,8 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
// jpeg_set_defaults created two qtables internally, but we only // jpeg_set_defaults created two qtables internally, but we only
// wanted one. // wanted one.
jpeg_add_quant_table( jpeg_add_quant_table(
&context->cinfo, 1, &context->qtables[0], quality, FALSE); &context->cinfo, 1, &context->qtables[0], quality, FALSE
);
} }
for (i = last_q; i < context->cinfo.num_components; i++) { for (i = last_q; i < context->cinfo.num_components; i++) {
context->cinfo.comp_info[i].quant_tbl_no = last_q; context->cinfo.comp_info[i].quant_tbl_no = last_q;
@ -273,7 +275,8 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
&context->cinfo, &context->cinfo,
JPEG_APP0 + 1, JPEG_APP0 + 1,
(unsigned char *)context->rawExif, (unsigned char *)context->rawExif,
context->rawExifLen); context->rawExifLen
);
} }
state->state++; state->state++;
@ -289,7 +292,8 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
memcpy( memcpy(
context->destination.pub.next_output_byte, context->destination.pub.next_output_byte,
context->extra + context->extra_offset, context->extra + context->extra_offset,
n); n
);
context->destination.pub.next_output_byte += n; context->destination.pub.next_output_byte += n;
context->destination.pub.free_in_buffer -= n; context->destination.pub.free_in_buffer -= n;
context->extra_offset += n; context->extra_offset += n;
@ -309,7 +313,8 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
&context->cinfo, &context->cinfo,
JPEG_COM, JPEG_COM,
(unsigned char *)context->comment, (unsigned char *)context->comment,
context->comment_size); context->comment_size
);
} }
state->state++; state->state++;
@ -324,7 +329,8 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
state->buffer, state->buffer,
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->xsize); state->xsize
);
ok = jpeg_write_scanlines(&context->cinfo, &state->buffer, 1); ok = jpeg_write_scanlines(&context->cinfo, &state->buffer, 1);
if (ok != 1) { if (ok != 1) {
break; break;

View File

@ -17,7 +17,8 @@
int int
ImagingPackbitsDecode( ImagingPackbitsDecode(
Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) { Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes
) {
UINT8 n; UINT8 n;
UINT8 *ptr; UINT8 *ptr;
int i; int i;
@ -79,7 +80,8 @@ ImagingPackbitsDecode(
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->buffer, state->buffer,
state->xsize); state->xsize
);
state->x = 0; state->x = 0;

View File

@ -33,7 +33,8 @@ paste(
int sy, int sy,
int xsize, int xsize,
int ysize, int ysize,
int pixelsize) { int pixelsize
) {
/* paste opaque region */ /* paste opaque region */
int y; int y;
@ -59,7 +60,8 @@ paste_mask_1(
int sy, int sy,
int xsize, int xsize,
int ysize, int ysize,
int pixelsize) { int pixelsize
) {
/* paste with mode "1" mask */ /* paste with mode "1" mask */
int x, y; int x, y;
@ -120,7 +122,8 @@ paste_mask_L(
int sy, int sy,
int xsize, int xsize,
int ysize, int ysize,
int pixelsize) { int pixelsize
) {
/* paste with mode "L" matte */ /* paste with mode "L" matte */
int x, y; int x, y;
@ -167,7 +170,8 @@ paste_mask_RGBA(
int sy, int sy,
int xsize, int xsize,
int ysize, int ysize,
int pixelsize) { int pixelsize
) {
/* paste with mode "RGBA" matte */ /* paste with mode "RGBA" matte */
int x, y; int x, y;
@ -214,7 +218,8 @@ paste_mask_RGBa(
int sy, int sy,
int xsize, int xsize,
int ysize, int ysize,
int pixelsize) { int pixelsize
) {
/* paste with mode "RGBa" matte */ /* paste with mode "RGBa" matte */
int x, y; int x, y;
@ -252,7 +257,8 @@ paste_mask_RGBa(
int int
ImagingPaste( ImagingPaste(
Imaging imOut, Imaging imIn, Imaging imMask, int dx0, int dy0, int dx1, int dy1) { Imaging imOut, Imaging imIn, Imaging imMask, int dx0, int dy0, int dx1, int dy1
) {
int xsize, ysize; int xsize, ysize;
int pixelsize; int pixelsize;
int sx0, sy0; int sx0, sy0;
@ -315,13 +321,15 @@ ImagingPaste(
} else if (strcmp(imMask->mode, "LA") == 0 || strcmp(imMask->mode, "RGBA") == 0) { } else if (strcmp(imMask->mode, "LA") == 0 || strcmp(imMask->mode, "RGBA") == 0) {
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
paste_mask_RGBA( paste_mask_RGBA(
imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize
);
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
} else if (strcmp(imMask->mode, "RGBa") == 0) { } else if (strcmp(imMask->mode, "RGBa") == 0) {
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
paste_mask_RGBa( paste_mask_RGBa(
imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize
);
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
} else { } else {
@ -334,13 +342,8 @@ ImagingPaste(
static inline void static inline void
fill( fill(
Imaging imOut, Imaging imOut, const void *ink_, int dx, int dy, int xsize, int ysize, int pixelsize
const void *ink_, ) {
int dx,
int dy,
int xsize,
int ysize,
int pixelsize) {
/* fill opaque region */ /* fill opaque region */
int x, y; int x, y;
@ -378,7 +381,8 @@ fill_mask_1(
int sy, int sy,
int xsize, int xsize,
int ysize, int ysize,
int pixelsize) { int pixelsize
) {
/* fill with mode "1" mask */ /* fill with mode "1" mask */
int x, y; int x, y;
@ -425,7 +429,8 @@ fill_mask_L(
int sy, int sy,
int xsize, int xsize,
int ysize, int ysize,
int pixelsize) { int pixelsize
) {
/* fill with mode "L" matte */ /* fill with mode "L" matte */
int x, y, i; int x, y, i;
@ -484,7 +489,8 @@ fill_mask_RGBA(
int sy, int sy,
int xsize, int xsize,
int ysize, int ysize,
int pixelsize) { int pixelsize
) {
/* fill with mode "RGBA" matte */ /* fill with mode "RGBA" matte */
int x, y, i; int x, y, i;
@ -529,7 +535,8 @@ fill_mask_RGBa(
int sy, int sy,
int xsize, int xsize,
int ysize, int ysize,
int pixelsize) { int pixelsize
) {
/* fill with mode "RGBa" matte */ /* fill with mode "RGBa" matte */
int x, y, i; int x, y, i;
@ -565,13 +572,8 @@ fill_mask_RGBa(
int int
ImagingFill2( ImagingFill2(
Imaging imOut, Imaging imOut, const void *ink, Imaging imMask, int dx0, int dy0, int dx1, int dy1
const void *ink, ) {
Imaging imMask,
int dx0,
int dy0,
int dx1,
int dy1) {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
int xsize, ysize; int xsize, ysize;
int pixelsize; int pixelsize;

View File

@ -68,7 +68,8 @@ ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t byt
memmove( memmove(
&state->buffer[i * state->xsize], &state->buffer[i * state->xsize],
&state->buffer[i * stride], &state->buffer[i * stride],
state->xsize); state->xsize
);
} }
} }
/* Got a full line, unpack it */ /* Got a full line, unpack it */
@ -76,7 +77,8 @@ ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t byt
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->buffer, state->buffer,
state->xsize); state->xsize
);
state->x = 0; state->x = 0;

View File

@ -71,7 +71,8 @@ ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
state->buffer, state->buffer,
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->xsize); state->xsize
);
state->y += 1; state->y += 1;

View File

@ -197,8 +197,8 @@ ImagingPoint(Imaging imIn, const char *mode, const void *table) {
return imOut; return imOut;
mode_mismatch: mode_mismatch:
return (Imaging)ImagingError_ValueError( return (Imaging
"point operation not supported for this mode"); )ImagingError_ValueError("point operation not supported for this mode");
} }
Imaging Imaging

View File

@ -103,7 +103,8 @@ static uint32_t
pixel_hash(const HashTable *h, const Pixel pixel) { pixel_hash(const HashTable *h, const Pixel pixel) {
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h); PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h);
return PIXEL_HASH( return PIXEL_HASH(
pixel.c.r >> d->scale, pixel.c.g >> d->scale, pixel.c.b >> d->scale); pixel.c.r >> d->scale, pixel.c.g >> d->scale, pixel.c.b >> d->scale
);
} }
static int static int
@ -111,9 +112,11 @@ pixel_cmp(const HashTable *h, const Pixel pixel1, const Pixel pixel2) {
PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h); PixelHashData *d = (PixelHashData *)hashtable_get_user_data(h);
uint32_t A, B; uint32_t A, B;
A = PIXEL_HASH( A = PIXEL_HASH(
pixel1.c.r >> d->scale, pixel1.c.g >> d->scale, pixel1.c.b >> d->scale); pixel1.c.r >> d->scale, pixel1.c.g >> d->scale, pixel1.c.b >> d->scale
);
B = PIXEL_HASH( B = PIXEL_HASH(
pixel2.c.r >> d->scale, pixel2.c.g >> d->scale, pixel2.c.b >> d->scale); pixel2.c.r >> d->scale, pixel2.c.g >> d->scale, pixel2.c.b >> d->scale
);
return (A == B) ? 0 : ((A < B) ? -1 : 1); return (A == B) ? 0 : ((A < B) ? -1 : 1);
} }
@ -129,7 +132,8 @@ new_count_func(const HashTable *h, const Pixel key, uint32_t *val) {
static void static void
rehash_collide( rehash_collide(
const HashTable *h, Pixel *keyp, uint32_t *valp, Pixel newkey, uint32_t newval) { const HashTable *h, Pixel *keyp, uint32_t *valp, Pixel newkey, uint32_t newval
) {
*valp += newval; *valp += newval;
} }
@ -157,7 +161,8 @@ create_pixel_hash(Pixel *pixelData, uint32_t nPixels) {
#endif #endif
for (i = 0; i < nPixels; i++) { for (i = 0; i < nPixels; i++) {
if (!hashtable_insert_or_update_computed( if (!hashtable_insert_or_update_computed(
hash, pixelData[i], new_count_func, exists_count_func)) { hash, pixelData[i], new_count_func, exists_count_func
)) {
; ;
} }
while (hashtable_get_count(hash) > MAX_HASH_ENTRIES) { while (hashtable_get_count(hash) > MAX_HASH_ENTRIES) {
@ -335,7 +340,8 @@ splitlists(
PixelList *nt[2][3], PixelList *nt[2][3],
uint32_t nCount[2], uint32_t nCount[2],
int axis, int axis,
uint32_t pixelCount) { uint32_t pixelCount
) {
uint32_t left; uint32_t left;
PixelList *l, *r, *c, *n; PixelList *l, *r, *c, *n;
@ -387,7 +393,8 @@ splitlists(
_prevCount[2], _prevCount[2],
_nextCount[0], _nextCount[0],
_nextCount[1], _nextCount[1],
_nextCount[2]); _nextCount[2]
);
exit(1); exit(1);
} }
} }
@ -531,12 +538,14 @@ split(BoxNode *node) {
if (node->tail[_i]->next[_i]) { if (node->tail[_i]->next[_i]) {
printf("tail is not tail\n"); printf("tail is not tail\n");
printf( printf(
"node->tail[%d]->next[%d]=%p\n", _i, _i, node->tail[_i]->next[_i]); "node->tail[%d]->next[%d]=%p\n", _i, _i, node->tail[_i]->next[_i]
);
} }
if (node->head[_i]->prev[_i]) { if (node->head[_i]->prev[_i]) {
printf("head is not head\n"); printf("head is not head\n");
printf( printf(
"node->head[%d]->prev[%d]=%p\n", _i, _i, node->head[_i]->prev[_i]); "node->head[%d]->prev[%d]=%p\n", _i, _i, node->head[_i]->prev[_i]
);
} }
} }
@ -573,14 +582,16 @@ split(BoxNode *node) {
_prevCount[2], _prevCount[2],
_nextCount[0], _nextCount[0],
_nextCount[1], _nextCount[1],
_nextCount[2]); _nextCount[2]
);
} }
} }
} }
#endif #endif
node->axis = axis; node->axis = axis;
if (!splitlists( if (!splitlists(
node->head, node->tail, heads, tails, newCounts, axis, node->pixelCount)) { node->head, node->tail, heads, tails, newCounts, axis, node->pixelCount
)) {
#ifndef NO_OUTPUT #ifndef NO_OUTPUT
printf("list split failed.\n"); printf("list split failed.\n");
#endif #endif
@ -772,7 +783,8 @@ _distance_index_cmp(const void *a, const void *b) {
static int static int
resort_distance_tables( resort_distance_tables(
uint32_t *avgDist, uint32_t **avgDistSortKey, Pixel *p, uint32_t nEntries) { uint32_t *avgDist, uint32_t **avgDistSortKey, Pixel *p, uint32_t nEntries
) {
uint32_t i, j, k; uint32_t i, j, k;
uint32_t **skRow; uint32_t **skRow;
uint32_t *skElt; uint32_t *skElt;
@ -801,7 +813,8 @@ resort_distance_tables(
static int static int
build_distance_tables( build_distance_tables(
uint32_t *avgDist, uint32_t **avgDistSortKey, Pixel *p, uint32_t nEntries) { uint32_t *avgDist, uint32_t **avgDistSortKey, Pixel *p, uint32_t nEntries
) {
uint32_t i, j; uint32_t i, j;
DistanceWithIndex *dwi; DistanceWithIndex *dwi;
@ -841,7 +854,8 @@ map_image_pixels(
uint32_t nPaletteEntries, uint32_t nPaletteEntries,
uint32_t *avgDist, uint32_t *avgDist,
uint32_t **avgDistSortKey, uint32_t **avgDistSortKey,
uint32_t *pixelArray) { uint32_t *pixelArray
) {
uint32_t *aD, **aDSK; uint32_t *aD, **aDSK;
uint32_t idx; uint32_t idx;
uint32_t i, j; uint32_t i, j;
@ -888,7 +902,8 @@ map_image_pixels_from_quantized_pixels(
uint32_t **avgDistSortKey, uint32_t **avgDistSortKey,
uint32_t *pixelArray, uint32_t *pixelArray,
uint32_t *avg[3], uint32_t *avg[3],
uint32_t *count) { uint32_t *count
) {
uint32_t *aD, **aDSK; uint32_t *aD, **aDSK;
uint32_t idx; uint32_t idx;
uint32_t i, j; uint32_t i, j;
@ -946,7 +961,8 @@ map_image_pixels_from_median_box(
HashTable *medianBoxHash, HashTable *medianBoxHash,
uint32_t *avgDist, uint32_t *avgDist,
uint32_t **avgDistSortKey, uint32_t **avgDistSortKey,
uint32_t *pixelArray) { uint32_t *pixelArray
) {
uint32_t *aD, **aDSK; uint32_t *aD, **aDSK;
uint32_t idx; uint32_t idx;
uint32_t i, j; uint32_t i, j;
@ -998,7 +1014,8 @@ compute_palette_from_median_cut(
uint32_t nPixels, uint32_t nPixels,
HashTable *medianBoxHash, HashTable *medianBoxHash,
Pixel **palette, Pixel **palette,
uint32_t nPaletteEntries) { uint32_t nPaletteEntries
) {
uint32_t i; uint32_t i;
uint32_t paletteEntry; uint32_t paletteEntry;
Pixel *p; Pixel *p;
@ -1055,7 +1072,8 @@ compute_palette_from_median_cut(
printf( printf(
"panic - paletteEntry>=nPaletteEntries (%d>=%d)\n", "panic - paletteEntry>=nPaletteEntries (%d>=%d)\n",
(int)paletteEntry, (int)paletteEntry,
(int)nPaletteEntries); (int)nPaletteEntries
);
#endif #endif
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
free(avg[i]); free(avg[i]);
@ -1092,7 +1110,8 @@ compute_palette_from_median_cut(
static int static int
recompute_palette_from_averages( recompute_palette_from_averages(
Pixel *palette, uint32_t nPaletteEntries, uint32_t *avg[3], uint32_t *count) { Pixel *palette, uint32_t nPaletteEntries, uint32_t *avg[3], uint32_t *count
) {
uint32_t i; uint32_t i;
for (i = 0; i < nPaletteEntries; i++) { for (i = 0; i < nPaletteEntries; i++) {
@ -1111,7 +1130,8 @@ compute_palette_from_quantized_pixels(
uint32_t nPaletteEntries, uint32_t nPaletteEntries,
uint32_t *avg[3], uint32_t *avg[3],
uint32_t *count, uint32_t *count,
uint32_t *qp) { uint32_t *qp
) {
uint32_t i; uint32_t i;
memset(count, 0, sizeof(uint32_t) * nPaletteEntries); memset(count, 0, sizeof(uint32_t) * nPaletteEntries);
@ -1145,7 +1165,8 @@ k_means(
Pixel *paletteData, Pixel *paletteData,
uint32_t nPaletteEntries, uint32_t nPaletteEntries,
uint32_t *qp, uint32_t *qp,
int threshold) { int threshold
) {
uint32_t *avg[3]; uint32_t *avg[3];
uint32_t *count; uint32_t *count;
uint32_t i; uint32_t i;
@ -1194,16 +1215,19 @@ k_means(
while (1) { while (1) {
if (!built) { if (!built) {
compute_palette_from_quantized_pixels( compute_palette_from_quantized_pixels(
pixelData, nPixels, paletteData, nPaletteEntries, avg, count, qp); pixelData, nPixels, paletteData, nPaletteEntries, avg, count, qp
);
if (!build_distance_tables( if (!build_distance_tables(
avgDist, avgDistSortKey, paletteData, nPaletteEntries)) { avgDist, avgDistSortKey, paletteData, nPaletteEntries
)) {
goto error_3; goto error_3;
} }
built = 1; built = 1;
} else { } else {
recompute_palette_from_averages(paletteData, nPaletteEntries, avg, count); recompute_palette_from_averages(paletteData, nPaletteEntries, avg, count);
resort_distance_tables( resort_distance_tables(
avgDist, avgDistSortKey, paletteData, nPaletteEntries); avgDist, avgDistSortKey, paletteData, nPaletteEntries
);
} }
changes = map_image_pixels_from_quantized_pixels( changes = map_image_pixels_from_quantized_pixels(
pixelData, pixelData,
@ -1214,7 +1238,8 @@ k_means(
avgDistSortKey, avgDistSortKey,
qp, qp,
avg, avg,
count); count
);
if (changes < 0) { if (changes < 0) {
goto error_3; goto error_3;
} }
@ -1273,7 +1298,8 @@ quantize(
Pixel **palette, Pixel **palette,
uint32_t *paletteLength, uint32_t *paletteLength,
uint32_t **quantizedPixels, uint32_t **quantizedPixels,
int kmeans) { int kmeans
) {
PixelList *hl[3]; PixelList *hl[3];
HashTable *h; HashTable *h;
BoxNode *root; BoxNode *root;
@ -1399,7 +1425,8 @@ quantize(
} }
if (!map_image_pixels_from_median_box( if (!map_image_pixels_from_median_box(
pixelData, nPixels, p, nPaletteEntries, h, avgDist, avgDistSortKey, qp)) { pixelData, nPixels, p, nPaletteEntries, h, avgDist, avgDistSortKey, qp
)) {
goto error_7; goto error_7;
} }
@ -1445,7 +1472,8 @@ quantize(
_SQR(pixelData[i].c.b - p[qp[i]].c.b))), _SQR(pixelData[i].c.b - p[qp[i]].c.b))),
sqrt((double)(_SQR(pixelData[i].c.r - p[bestmatch].c.r) + sqrt((double)(_SQR(pixelData[i].c.r - p[bestmatch].c.r) +
_SQR(pixelData[i].c.g - p[bestmatch].c.g) + _SQR(pixelData[i].c.g - p[bestmatch].c.g) +
_SQR(pixelData[i].c.b - p[bestmatch].c.b)))); _SQR(pixelData[i].c.b - p[bestmatch].c.b)))
);
} }
} }
hashtable_free(h2); hashtable_free(h2);
@ -1545,7 +1573,8 @@ quantize2(
Pixel **palette, Pixel **palette,
uint32_t *paletteLength, uint32_t *paletteLength,
uint32_t **quantizedPixels, uint32_t **quantizedPixels,
int kmeans) { int kmeans
) {
HashTable *h; HashTable *h;
uint32_t i; uint32_t i;
uint32_t mean[3]; uint32_t mean[3];
@ -1609,7 +1638,8 @@ quantize2(
} }
if (!map_image_pixels( if (!map_image_pixels(
pixelData, nPixels, p, nQuantPixels, avgDist, avgDistSortKey, qp)) { pixelData, nPixels, p, nQuantPixels, avgDist, avgDistSortKey, qp
)) {
goto error_4; goto error_4;
} }
if (kmeans > 0) { if (kmeans > 0) {
@ -1752,7 +1782,8 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) {
&palette, &palette,
&paletteLength, &paletteLength,
&newData, &newData,
kmeans); kmeans
);
break; break;
case 1: case 1:
/* maximum coverage */ /* maximum coverage */
@ -1763,7 +1794,8 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) {
&palette, &palette,
&paletteLength, &paletteLength,
&newData, &newData,
kmeans); kmeans
);
break; break;
case 2: case 2:
result = quantize_octree( result = quantize_octree(
@ -1773,7 +1805,8 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) {
&palette, &palette,
&paletteLength, &paletteLength,
&newData, &newData,
withAlpha); withAlpha
);
break; break;
case 3: case 3:
#ifdef HAVE_LIBIMAGEQUANT #ifdef HAVE_LIBIMAGEQUANT
@ -1785,7 +1818,8 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) {
&palette, &palette,
&paletteLength, &paletteLength,
&newData, &newData,
withAlpha); withAlpha
);
#else #else
result = -1; result = -1;
#endif #endif
@ -1836,7 +1870,8 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans) {
if (result == -1) { if (result == -1) {
return (Imaging)ImagingError_ValueError( return (Imaging)ImagingError_ValueError(
"dependency required by this method was not " "dependency required by this method was not "
"enabled at compile time"); "enabled at compile time"
);
} }
return (Imaging)ImagingError_ValueError("quantization error"); return (Imaging)ImagingError_ValueError("quantization error");

View File

@ -132,7 +132,8 @@ _hashtable_resize(HashTable *h) {
static int static int
_hashtable_insert_node( _hashtable_insert_node(
HashTable *h, HashNode *node, int resize, int update, CollisionFunc cf) { HashTable *h, HashNode *node, int resize, int update, CollisionFunc cf
) {
uint32_t hash = h->hashFunc(h, node->key) % h->length; uint32_t hash = h->hashFunc(h, node->key) % h->length;
HashNode **n, *nv; HashNode **n, *nv;
int i; int i;
@ -207,7 +208,8 @@ _hashtable_insert(HashTable *h, HashKey_t key, HashVal_t val, int resize, int up
int int
hashtable_insert_or_update_computed( hashtable_insert_or_update_computed(
HashTable *h, HashKey_t key, ComputeFunc newFunc, ComputeFunc existsFunc) { HashTable *h, HashKey_t key, ComputeFunc newFunc, ComputeFunc existsFunc
) {
HashNode **n, *nv; HashNode **n, *nv;
HashNode *t; HashNode *t;
int i; int i;

View File

@ -20,13 +20,12 @@ typedef uint32_t HashVal_t;
typedef uint32_t (*HashFunc)(const HashTable *, const HashKey_t); typedef uint32_t (*HashFunc)(const HashTable *, const HashKey_t);
typedef int (*HashCmpFunc)(const HashTable *, const HashKey_t, const HashKey_t); typedef int (*HashCmpFunc)(const HashTable *, const HashKey_t, const HashKey_t);
typedef void (*IteratorFunc)( typedef void (*IteratorFunc)(const HashTable *, const HashKey_t, const HashVal_t, void *);
const HashTable *, const HashKey_t, const HashVal_t, void *); typedef void (*IteratorUpdateFunc)(const HashTable *, const HashKey_t, HashVal_t *, void *);
typedef void (*IteratorUpdateFunc)(
const HashTable *, const HashKey_t, HashVal_t *, void *);
typedef void (*ComputeFunc)(const HashTable *, const HashKey_t, HashVal_t *); typedef void (*ComputeFunc)(const HashTable *, const HashKey_t, HashVal_t *);
typedef void (*CollisionFunc)( typedef void (*CollisionFunc)(
const HashTable *, HashKey_t *, HashVal_t *, HashKey_t, HashVal_t); const HashTable *, HashKey_t *, HashVal_t *, HashKey_t, HashVal_t
);
HashTable * HashTable *
hashtable_new(HashFunc hf, HashCmpFunc cf); hashtable_new(HashFunc hf, HashCmpFunc cf);
@ -42,7 +41,8 @@ int
hashtable_lookup(const HashTable *h, const HashKey_t key, HashVal_t *valp); hashtable_lookup(const HashTable *h, const HashKey_t key, HashVal_t *valp);
int int
hashtable_insert_or_update_computed( hashtable_insert_or_update_computed(
HashTable *h, HashKey_t key, ComputeFunc newFunc, ComputeFunc existsFunc); HashTable *h, HashKey_t key, ComputeFunc newFunc, ComputeFunc existsFunc
);
void * void *
hashtable_set_user_data(HashTable *h, void *data); hashtable_set_user_data(HashTable *h, void *data);
void * void *

View File

@ -107,11 +107,8 @@ free_color_cube(ColorCube cube) {
static long static long
color_bucket_offset_pos( color_bucket_offset_pos(
const ColorCube cube, const ColorCube cube, unsigned int r, unsigned int g, unsigned int b, unsigned int a
unsigned int r, ) {
unsigned int g,
unsigned int b,
unsigned int a) {
return r << cube->rOffset | g << cube->gOffset | b << cube->bOffset | return r << cube->rOffset | g << cube->gOffset | b << cube->bOffset |
a << cube->aOffset; a << cube->aOffset;
} }
@ -191,7 +188,8 @@ create_sorted_color_palette(const ColorCube cube) {
buckets, buckets,
cube->size, cube->size,
sizeof(struct _ColorBucket), sizeof(struct _ColorBucket),
(int (*)(void const *, void const *)) & compare_bucket_count); (int (*)(void const *, void const *)) & compare_bucket_count
);
return buckets; return buckets;
} }
@ -212,7 +210,8 @@ copy_color_cube(
unsigned int rBits, unsigned int rBits,
unsigned int gBits, unsigned int gBits,
unsigned int bBits, unsigned int bBits,
unsigned int aBits) { unsigned int aBits
) {
unsigned int r, g, b, a; unsigned int r, g, b, a;
long src_pos, dst_pos; long src_pos, dst_pos;
unsigned int src_reduce[4] = {0}, dst_reduce[4] = {0}; unsigned int src_reduce[4] = {0}, dst_reduce[4] = {0};
@ -262,15 +261,18 @@ copy_color_cube(
r >> src_reduce[0], r >> src_reduce[0],
g >> src_reduce[1], g >> src_reduce[1],
b >> src_reduce[2], b >> src_reduce[2],
a >> src_reduce[3]); a >> src_reduce[3]
);
dst_pos = color_bucket_offset_pos( dst_pos = color_bucket_offset_pos(
result, result,
r >> dst_reduce[0], r >> dst_reduce[0],
g >> dst_reduce[1], g >> dst_reduce[1],
b >> dst_reduce[2], b >> dst_reduce[2],
a >> dst_reduce[3]); a >> dst_reduce[3]
);
add_bucket_values( add_bucket_values(
&cube->buckets[src_pos], &result->buckets[dst_pos]); &cube->buckets[src_pos], &result->buckets[dst_pos]
);
} }
} }
} }
@ -328,7 +330,8 @@ combined_palette(
ColorBucket bucketsA, ColorBucket bucketsA,
unsigned long nBucketsA, unsigned long nBucketsA,
ColorBucket bucketsB, ColorBucket bucketsB,
unsigned long nBucketsB) { unsigned long nBucketsB
) {
ColorBucket result; ColorBucket result;
if (nBucketsA > LONG_MAX - nBucketsB || if (nBucketsA > LONG_MAX - nBucketsB ||
(nBucketsA + nBucketsB) > LONG_MAX / sizeof(struct _ColorBucket)) { (nBucketsA + nBucketsB) > LONG_MAX / sizeof(struct _ColorBucket)) {
@ -366,7 +369,8 @@ map_image_pixels(
const Pixel *pixelData, const Pixel *pixelData,
uint32_t nPixels, uint32_t nPixels,
const ColorCube lookupCube, const ColorCube lookupCube,
uint32_t *pixelArray) { uint32_t *pixelArray
) {
long i; long i;
for (i = 0; i < nPixels; i++) { for (i = 0; i < nPixels; i++) {
pixelArray[i] = lookup_color(lookupCube, &pixelData[i]); pixelArray[i] = lookup_color(lookupCube, &pixelData[i]);
@ -384,7 +388,8 @@ quantize_octree(
Pixel **palette, Pixel **palette,
uint32_t *paletteLength, uint32_t *paletteLength,
uint32_t **quantizedPixels, uint32_t **quantizedPixels,
int withAlpha) { int withAlpha
) {
ColorCube fineCube = NULL; ColorCube fineCube = NULL;
ColorCube coarseCube = NULL; ColorCube coarseCube = NULL;
ColorCube lookupCube = NULL; ColorCube lookupCube = NULL;
@ -461,7 +466,8 @@ quantize_octree(
subtract_color_buckets( subtract_color_buckets(
coarseCube, coarseCube,
&paletteBucketsFine[nAlreadySubtracted], &paletteBucketsFine[nAlreadySubtracted],
nFineColors - nAlreadySubtracted); nFineColors - nAlreadySubtracted
);
} }
/* create our palette buckets with fine and coarse combined */ /* create our palette buckets with fine and coarse combined */
@ -470,7 +476,8 @@ quantize_octree(
goto error; goto error;
} }
paletteBuckets = combined_palette( paletteBuckets = combined_palette(
paletteBucketsCoarse, nCoarseColors, paletteBucketsFine, nFineColors); paletteBucketsCoarse, nCoarseColors, paletteBucketsFine, nFineColors
);
free(paletteBucketsFine); free(paletteBucketsFine);
paletteBucketsFine = NULL; paletteBucketsFine = NULL;
@ -491,7 +498,8 @@ quantize_octree(
/* expand coarse cube (64) to larger fine cube (4k). the value of each /* expand coarse cube (64) to larger fine cube (4k). the value of each
coarse bucket is then present in the according 64 fine buckets. */ coarse bucket is then present in the according 64 fine buckets. */
lookupCube = copy_color_cube( lookupCube = copy_color_cube(
coarseLookupCube, cubeBits[0], cubeBits[1], cubeBits[2], cubeBits[3]); coarseLookupCube, cubeBits[0], cubeBits[1], cubeBits[2], cubeBits[3]
);
if (!lookupCube) { if (!lookupCube) {
goto error; goto error;
} }

View File

@ -26,7 +26,8 @@ quantize_pngquant(
Pixel **palette, Pixel **palette,
uint32_t *paletteLength, uint32_t *paletteLength,
uint32_t **quantizedPixels, uint32_t **quantizedPixels,
int withAlpha) { int withAlpha
) {
int result = 0; int result = 0;
liq_image *image = NULL; liq_image *image = NULL;
liq_attr *attr = NULL; liq_attr *attr = NULL;

View File

@ -12,6 +12,7 @@ quantize_pngquant(
Pixel **, Pixel **,
uint32_t *, uint32_t *,
uint32_t **, uint32_t **,
int); int
);
#endif #endif

View File

@ -103,7 +103,8 @@ MakeRankFunction(UINT8) MakeRankFunction(INT32) MakeRankFunction(FLOAT32)
memcpy( \ memcpy( \
buf + i * size, \ buf + i * size, \
&IMAGING_PIXEL_##type(im, x, y + i), \ &IMAGING_PIXEL_##type(im, x, y + i), \
size * sizeof(type)); \ size * sizeof(type) \
); \
} \ } \
IMAGING_PIXEL_##type(imOut, x, y) = Rank##type(buf, size2, rank); \ IMAGING_PIXEL_##type(imOut, x, y) = Rank##type(buf, size2, rank); \
} \ } \

View File

@ -75,7 +75,8 @@ ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t byt
(UINT8 *)im->image[state->y + state->yoff] + state->xoff * im->pixelsize, (UINT8 *)im->image[state->y + state->yoff] + state->xoff * im->pixelsize,
ptr, ptr,
im, im,
state); state
);
ptr += state->bytes; ptr += state->bytes;
bytes -= state->bytes; bytes -= state->bytes;

View File

@ -65,7 +65,8 @@ ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
state->shuffle( state->shuffle(
ptr, ptr,
(UINT8 *)im->image[state->y + state->yoff] + state->xoff * im->pixelsize, (UINT8 *)im->image[state->y + state->yoff] + state->xoff * im->pixelsize,
state->xsize); state->xsize
);
if (state->bytes > state->count) { if (state->bytes > state->count) {
/* zero-pad the buffer, if necessary */ /* zero-pad the buffer, if necessary */

View File

@ -82,7 +82,8 @@ ImagingReduceNxN(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale
} }
} }
v = MAKE_UINT32( v = MAKE_UINT32(
(ss0 * multiplier) >> 24, 0, 0, (ss3 * multiplier) >> 24); (ss0 * multiplier) >> 24, 0, 0, (ss3 * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else if (imIn->bands == 3) { } else if (imIn->bands == 3) {
@ -124,7 +125,8 @@ ImagingReduceNxN(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale
(ss0 * multiplier) >> 24, (ss0 * multiplier) >> 24,
(ss1 * multiplier) >> 24, (ss1 * multiplier) >> 24,
(ss2 * multiplier) >> 24, (ss2 * multiplier) >> 24,
0); 0
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else { // bands == 4 } else { // bands == 4
@ -171,7 +173,8 @@ ImagingReduceNxN(Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale
(ss0 * multiplier) >> 24, (ss0 * multiplier) >> 24,
(ss1 * multiplier) >> 24, (ss1 * multiplier) >> 24,
(ss2 * multiplier) >> 24, (ss2 * multiplier) >> 24,
(ss3 * multiplier) >> 24); (ss3 * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -226,7 +229,8 @@ ImagingReduce1xN(Imaging imOut, Imaging imIn, int box[4], int yscale) {
ss3 += line[xx * 4 + 3]; ss3 += line[xx * 4 + 3];
} }
v = MAKE_UINT32( v = MAKE_UINT32(
(ss0 * multiplier) >> 24, 0, 0, (ss3 * multiplier) >> 24); (ss0 * multiplier) >> 24, 0, 0, (ss3 * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else if (imIn->bands == 3) { } else if (imIn->bands == 3) {
@ -251,7 +255,8 @@ ImagingReduce1xN(Imaging imOut, Imaging imIn, int box[4], int yscale) {
(ss0 * multiplier) >> 24, (ss0 * multiplier) >> 24,
(ss1 * multiplier) >> 24, (ss1 * multiplier) >> 24,
(ss2 * multiplier) >> 24, (ss2 * multiplier) >> 24,
0); 0
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else { // bands == 4 } else { // bands == 4
@ -278,7 +283,8 @@ ImagingReduce1xN(Imaging imOut, Imaging imIn, int box[4], int yscale) {
(ss0 * multiplier) >> 24, (ss0 * multiplier) >> 24,
(ss1 * multiplier) >> 24, (ss1 * multiplier) >> 24,
(ss2 * multiplier) >> 24, (ss2 * multiplier) >> 24,
(ss3 * multiplier) >> 24); (ss3 * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -329,7 +335,8 @@ ImagingReduceNx1(Imaging imOut, Imaging imIn, int box[4], int xscale) {
ss3 += line[xx * 4 + 3]; ss3 += line[xx * 4 + 3];
} }
v = MAKE_UINT32( v = MAKE_UINT32(
(ss0 * multiplier) >> 24, 0, 0, (ss3 * multiplier) >> 24); (ss0 * multiplier) >> 24, 0, 0, (ss3 * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else if (imIn->bands == 3) { } else if (imIn->bands == 3) {
@ -351,7 +358,8 @@ ImagingReduceNx1(Imaging imOut, Imaging imIn, int box[4], int xscale) {
(ss0 * multiplier) >> 24, (ss0 * multiplier) >> 24,
(ss1 * multiplier) >> 24, (ss1 * multiplier) >> 24,
(ss2 * multiplier) >> 24, (ss2 * multiplier) >> 24,
0); 0
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else { // bands == 4 } else { // bands == 4
@ -375,7 +383,8 @@ ImagingReduceNx1(Imaging imOut, Imaging imIn, int box[4], int xscale) {
(ss0 * multiplier) >> 24, (ss0 * multiplier) >> 24,
(ss1 * multiplier) >> 24, (ss1 * multiplier) >> 24,
(ss2 * multiplier) >> 24, (ss2 * multiplier) >> 24,
(ss3 * multiplier) >> 24); (ss3 * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -425,7 +434,8 @@ ImagingReduce1x2(Imaging imOut, Imaging imIn, int box[4]) {
ss1 = line0[xx * 4 + 1] + line1[xx * 4 + 1]; ss1 = line0[xx * 4 + 1] + line1[xx * 4 + 1];
ss2 = line0[xx * 4 + 2] + line1[xx * 4 + 2]; ss2 = line0[xx * 4 + 2] + line1[xx * 4 + 2];
v = MAKE_UINT32( v = MAKE_UINT32(
(ss0 + amend) >> 1, (ss1 + amend) >> 1, (ss2 + amend) >> 1, 0); (ss0 + amend) >> 1, (ss1 + amend) >> 1, (ss2 + amend) >> 1, 0
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else { // bands == 4 } else { // bands == 4
@ -440,7 +450,8 @@ ImagingReduce1x2(Imaging imOut, Imaging imIn, int box[4]) {
(ss0 + amend) >> 1, (ss0 + amend) >> 1,
(ss1 + amend) >> 1, (ss1 + amend) >> 1,
(ss2 + amend) >> 1, (ss2 + amend) >> 1,
(ss3 + amend) >> 1); (ss3 + amend) >> 1
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -488,7 +499,8 @@ ImagingReduce2x1(Imaging imOut, Imaging imIn, int box[4]) {
ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5]; ss1 = line0[xx * 4 + 1] + line0[xx * 4 + 5];
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6]; ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6];
v = MAKE_UINT32( v = MAKE_UINT32(
(ss0 + amend) >> 1, (ss1 + amend) >> 1, (ss2 + amend) >> 1, 0); (ss0 + amend) >> 1, (ss1 + amend) >> 1, (ss2 + amend) >> 1, 0
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else { // bands == 4 } else { // bands == 4
@ -503,7 +515,8 @@ ImagingReduce2x1(Imaging imOut, Imaging imIn, int box[4]) {
(ss0 + amend) >> 1, (ss0 + amend) >> 1,
(ss1 + amend) >> 1, (ss1 + amend) >> 1,
(ss2 + amend) >> 1, (ss2 + amend) >> 1,
(ss3 + amend) >> 1); (ss3 + amend) >> 1
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -558,7 +571,8 @@ ImagingReduce2x2(Imaging imOut, Imaging imIn, int box[4]) {
ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line1[xx * 4 + 2] + ss2 = line0[xx * 4 + 2] + line0[xx * 4 + 6] + line1[xx * 4 + 2] +
line1[xx * 4 + 6]; line1[xx * 4 + 6];
v = MAKE_UINT32( v = MAKE_UINT32(
(ss0 + amend) >> 2, (ss1 + amend) >> 2, (ss2 + amend) >> 2, 0); (ss0 + amend) >> 2, (ss1 + amend) >> 2, (ss2 + amend) >> 2, 0
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else { // bands == 4 } else { // bands == 4
@ -577,7 +591,8 @@ ImagingReduce2x2(Imaging imOut, Imaging imIn, int box[4]) {
(ss0 + amend) >> 2, (ss0 + amend) >> 2,
(ss1 + amend) >> 2, (ss1 + amend) >> 2,
(ss2 + amend) >> 2, (ss2 + amend) >> 2,
(ss3 + amend) >> 2); (ss3 + amend) >> 2
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -623,7 +638,8 @@ ImagingReduce1x3(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
0, 0,
0, 0,
((ss3 + amend) * multiplier) >> 24); ((ss3 + amend) * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else if (imIn->bands == 3) { } else if (imIn->bands == 3) {
@ -637,7 +653,8 @@ ImagingReduce1x3(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
((ss1 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
((ss2 + amend) * multiplier) >> 24, ((ss2 + amend) * multiplier) >> 24,
0); 0
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else { // bands == 4 } else { // bands == 4
@ -652,7 +669,8 @@ ImagingReduce1x3(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
((ss1 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
((ss2 + amend) * multiplier) >> 24, ((ss2 + amend) * multiplier) >> 24,
((ss3 + amend) * multiplier) >> 24); ((ss3 + amend) * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -694,7 +712,8 @@ ImagingReduce3x1(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
0, 0,
0, 0,
((ss3 + amend) * multiplier) >> 24); ((ss3 + amend) * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else if (imIn->bands == 3) { } else if (imIn->bands == 3) {
@ -708,7 +727,8 @@ ImagingReduce3x1(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
((ss1 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
((ss2 + amend) * multiplier) >> 24, ((ss2 + amend) * multiplier) >> 24,
0); 0
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else { // bands == 4 } else { // bands == 4
@ -723,7 +743,8 @@ ImagingReduce3x1(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
((ss1 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
((ss2 + amend) * multiplier) >> 24, ((ss2 + amend) * multiplier) >> 24,
((ss3 + amend) * multiplier) >> 24); ((ss3 + amend) * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -775,7 +796,8 @@ ImagingReduce3x3(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
0, 0,
0, 0,
((ss3 + amend) * multiplier) >> 24); ((ss3 + amend) * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else if (imIn->bands == 3) { } else if (imIn->bands == 3) {
@ -795,7 +817,8 @@ ImagingReduce3x3(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
((ss1 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
((ss2 + amend) * multiplier) >> 24, ((ss2 + amend) * multiplier) >> 24,
0); 0
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else { // bands == 4 } else { // bands == 4
@ -818,7 +841,8 @@ ImagingReduce3x3(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
((ss1 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
((ss2 + amend) * multiplier) >> 24, ((ss2 + amend) * multiplier) >> 24,
((ss3 + amend) * multiplier) >> 24); ((ss3 + amend) * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -900,7 +924,8 @@ ImagingReduce4x4(Imaging imOut, Imaging imIn, int box[4]) {
line3[xx * 4 + 2] + line3[xx * 4 + 6] + line3[xx * 4 + 10] + line3[xx * 4 + 2] + line3[xx * 4 + 6] + line3[xx * 4 + 10] +
line3[xx * 4 + 14]; line3[xx * 4 + 14];
v = MAKE_UINT32( v = MAKE_UINT32(
(ss0 + amend) >> 4, (ss1 + amend) >> 4, (ss2 + amend) >> 4, 0); (ss0 + amend) >> 4, (ss1 + amend) >> 4, (ss2 + amend) >> 4, 0
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else { // bands == 4 } else { // bands == 4
@ -935,7 +960,8 @@ ImagingReduce4x4(Imaging imOut, Imaging imIn, int box[4]) {
(ss0 + amend) >> 4, (ss0 + amend) >> 4,
(ss1 + amend) >> 4, (ss1 + amend) >> 4,
(ss2 + amend) >> 4, (ss2 + amend) >> 4,
(ss3 + amend) >> 4); (ss3 + amend) >> 4
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -1007,7 +1033,8 @@ ImagingReduce5x5(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
0, 0,
0, 0,
((ss3 + amend) * multiplier) >> 24); ((ss3 + amend) * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else if (imIn->bands == 3) { } else if (imIn->bands == 3) {
@ -1045,7 +1072,8 @@ ImagingReduce5x5(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
((ss1 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
((ss2 + amend) * multiplier) >> 24, ((ss2 + amend) * multiplier) >> 24,
0); 0
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} else { // bands == 4 } else { // bands == 4
@ -1092,7 +1120,8 @@ ImagingReduce5x5(Imaging imOut, Imaging imIn, int box[4]) {
((ss0 + amend) * multiplier) >> 24, ((ss0 + amend) * multiplier) >> 24,
((ss1 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24,
((ss2 + amend) * multiplier) >> 24, ((ss2 + amend) * multiplier) >> 24,
((ss3 + amend) * multiplier) >> 24); ((ss3 + amend) * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -1181,7 +1210,8 @@ ImagingReduceCorners(Imaging imOut, Imaging imIn, int box[4], int xscale, int ys
(ss0 * multiplier) >> 24, (ss0 * multiplier) >> 24,
(ss1 * multiplier) >> 24, (ss1 * multiplier) >> 24,
(ss2 * multiplier) >> 24, (ss2 * multiplier) >> 24,
(ss3 * multiplier) >> 24); (ss3 * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -1207,7 +1237,8 @@ ImagingReduceCorners(Imaging imOut, Imaging imIn, int box[4], int xscale, int ys
(ss0 * multiplier) >> 24, (ss0 * multiplier) >> 24,
(ss1 * multiplier) >> 24, (ss1 * multiplier) >> 24,
(ss2 * multiplier) >> 24, (ss2 * multiplier) >> 24,
(ss3 * multiplier) >> 24); (ss3 * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -1232,7 +1263,8 @@ ImagingReduceCorners(Imaging imOut, Imaging imIn, int box[4], int xscale, int ys
(ss0 * multiplier) >> 24, (ss0 * multiplier) >> 24,
(ss1 * multiplier) >> 24, (ss1 * multiplier) >> 24,
(ss2 * multiplier) >> 24, (ss2 * multiplier) >> 24,
(ss3 * multiplier) >> 24); (ss3 * multiplier) >> 24
);
memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v)); memcpy(imOut->image[y] + x * sizeof(v), &v, sizeof(v));
} }
} }
@ -1240,7 +1272,8 @@ ImagingReduceCorners(Imaging imOut, Imaging imIn, int box[4], int xscale, int ys
void void
ImagingReduceNxN_32bpc( ImagingReduceNxN_32bpc(
Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale) { Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale
) {
/* The most general implementation for any xscale and yscale /* The most general implementation for any xscale and yscale
*/ */
int x, y, xx, yy; int x, y, xx, yy;
@ -1313,7 +1346,8 @@ ImagingReduceNxN_32bpc(
void void
ImagingReduceCorners_32bpc( ImagingReduceCorners_32bpc(
Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale) { Imaging imOut, Imaging imIn, int box[4], int xscale, int yscale
) {
/* Fill the last row and the last column for any xscale and yscale. /* Fill the last row and the last column for any xscale and yscale.
*/ */
int x, y, xx, yy; int x, y, xx, yy;
@ -1429,7 +1463,8 @@ ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4]) {
imOut = ImagingNewDirty( imOut = ImagingNewDirty(
imIn->mode, imIn->mode,
(ImagingNewParams){ (ImagingNewParams){
(box[2] + xscale - 1) / xscale, (box[3] + yscale - 1) / yscale}); (box[2] + xscale - 1) / xscale, (box[3] + yscale - 1) / yscale}
);
if (!imOut) { if (!imOut) {
return NULL; return NULL;
} }

View File

@ -186,7 +186,8 @@ precompute_coeffs(
int outSize, int outSize,
struct filter *filterp, struct filter *filterp,
int **boundsp, int **boundsp,
double **kkp) { double **kkp
) {
double support, scale, filterscale; double support, scale, filterscale;
double center, ww, ss; double center, ww, ss;
int xx, x, ksize, xmin, xmax; int xx, x, ksize, xmin, xmax;
@ -284,7 +285,8 @@ normalize_coeffs_8bpc(int outSize, int ksize, double *prekk) {
void void
ImagingResampleHorizontal_8bpc( ImagingResampleHorizontal_8bpc(
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *prekk) { Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *prekk
) {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
int ss0, ss1, ss2, ss3; int ss0, ss1, ss2, ss3;
int xx, yy, x, xmin, xmax; int xx, yy, x, xmin, xmax;
@ -376,7 +378,8 @@ ImagingResampleHorizontal_8bpc(
void void
ImagingResampleVertical_8bpc( ImagingResampleVertical_8bpc(
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *prekk) { Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *prekk
) {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
int ss0, ss1, ss2, ss3; int ss0, ss1, ss2, ss3;
int xx, yy, y, ymin, ymax; int xx, yy, y, ymin, ymax;
@ -459,7 +462,8 @@ ImagingResampleVertical_8bpc(
void void
ImagingResampleHorizontal_32bpc( ImagingResampleHorizontal_32bpc(
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk) { Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk
) {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
double ss; double ss;
int xx, yy, x, xmin, xmax; int xx, yy, x, xmin, xmax;
@ -502,7 +506,8 @@ ImagingResampleHorizontal_32bpc(
void void
ImagingResampleVertical_32bpc( ImagingResampleVertical_32bpc(
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk) { Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk
) {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
double ss; double ss;
int xx, yy, y, ymin, ymax; int xx, yy, y, ymin, ymax;
@ -544,7 +549,8 @@ ImagingResampleVertical_32bpc(
} }
typedef void (*ResampleFunction)( typedef void (*ResampleFunction)(
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk); Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk
);
Imaging Imaging
ImagingResampleInner( ImagingResampleInner(
@ -554,7 +560,8 @@ ImagingResampleInner(
struct filter *filterp, struct filter *filterp,
float box[4], float box[4],
ResampleFunction ResampleHorizontal, ResampleFunction ResampleHorizontal,
ResampleFunction ResampleVertical); ResampleFunction ResampleVertical
);
Imaging Imaging
ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) { ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) {
@ -609,7 +616,8 @@ ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) {
} }
return ImagingResampleInner( return ImagingResampleInner(
imIn, xsize, ysize, filterp, box, ResampleHorizontal, ResampleVertical); imIn, xsize, ysize, filterp, box, ResampleHorizontal, ResampleVertical
);
} }
Imaging Imaging
@ -620,7 +628,8 @@ ImagingResampleInner(
struct filter *filterp, struct filter *filterp,
float box[4], float box[4],
ResampleFunction ResampleHorizontal, ResampleFunction ResampleHorizontal,
ResampleFunction ResampleVertical) { ResampleFunction ResampleVertical
) {
Imaging imTemp = NULL; Imaging imTemp = NULL;
Imaging imOut = NULL; Imaging imOut = NULL;
@ -634,13 +643,15 @@ ImagingResampleInner(
need_vertical = ysize != imIn->ysize || box[1] || box[3] != ysize; need_vertical = ysize != imIn->ysize || box[1] || box[3] != ysize;
ksize_horiz = precompute_coeffs( ksize_horiz = precompute_coeffs(
imIn->xsize, box[0], box[2], xsize, filterp, &bounds_horiz, &kk_horiz); imIn->xsize, box[0], box[2], xsize, filterp, &bounds_horiz, &kk_horiz
);
if (!ksize_horiz) { if (!ksize_horiz) {
return NULL; return NULL;
} }
ksize_vert = precompute_coeffs( ksize_vert = precompute_coeffs(
imIn->ysize, box[1], box[3], ysize, filterp, &bounds_vert, &kk_vert); imIn->ysize, box[1], box[3], ysize, filterp, &bounds_vert, &kk_vert
);
if (!ksize_vert) { if (!ksize_vert) {
free(bounds_horiz); free(bounds_horiz);
free(kk_horiz); free(kk_horiz);
@ -663,7 +674,8 @@ ImagingResampleInner(
imIn->mode, (ImagingNewParams){xsize, ybox_last - ybox_first}); imIn->mode, (ImagingNewParams){xsize, ybox_last - ybox_first});
if (imTemp) { if (imTemp) {
ResampleHorizontal( ResampleHorizontal(
imTemp, imIn, ybox_first, ksize_horiz, bounds_horiz, kk_horiz); imTemp, imIn, ybox_first, ksize_horiz, bounds_horiz, kk_horiz
);
} }
free(bounds_horiz); free(bounds_horiz);
free(kk_horiz); free(kk_horiz);

View File

@ -114,7 +114,8 @@ expandrow(UINT8 *dest, UINT8 *src, int n, int z, int xsize, UINT8 *end_of_buffer
static int static int
expandrow2( expandrow2(
UINT8 *dest, const UINT8 *src, int n, int z, int xsize, UINT8 *end_of_buffer) { UINT8 *dest, const UINT8 *src, int n, int z, int xsize, UINT8 *end_of_buffer
) {
UINT8 pixel, count; UINT8 pixel, count;
int x = 0; int x = 0;
@ -252,7 +253,8 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
c->rlelength, c->rlelength,
im->bands, im->bands,
im->xsize, im->xsize,
&ptr[c->bufsize - 1]); &ptr[c->bufsize - 1]
);
} else { } else {
status = expandrow2( status = expandrow2(
&state->buffer[c->channo * 2], &state->buffer[c->channo * 2],
@ -260,7 +262,8 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
c->rlelength, c->rlelength,
im->bands, im->bands,
im->xsize, im->xsize,
&ptr[c->bufsize - 1]); &ptr[c->bufsize - 1]
);
} }
if (status == -1) { if (status == -1) {
state->errcode = IMAGING_CODEC_OVERRUN; state->errcode = IMAGING_CODEC_OVERRUN;

View File

@ -110,9 +110,8 @@ ImagingNewPrologueSubtype(const char *mode, ImagingNewParams p, int size) {
im->linesize = p.xsize * 4; im->linesize = p.xsize * 4;
im->type = IMAGING_TYPE_INT32; im->type = IMAGING_TYPE_INT32;
} else if ( } else if (strcmp(mode, "I;16") == 0 || strcmp(mode, "I;16L") == 0 ||
strcmp(mode, "I;16") == 0 || strcmp(mode, "I;16L") == 0 || strcmp(mode, "I;16B") == 0 || strcmp(mode, "I;16N") == 0) {
strcmp(mode, "I;16B") == 0 || strcmp(mode, "I;16N") == 0) {
/* EXPERIMENTAL */ /* EXPERIMENTAL */
/* 16-bit raw integer images */ /* 16-bit raw integer images */
im->bands = 1; im->bands = 1;
@ -237,7 +236,9 @@ ImagingNewPrologueSubtype(const char *mode, ImagingNewParams p, int size) {
Imaging Imaging
ImagingNewPrologue(const char *mode, ImagingNewParams p) { ImagingNewPrologue(const char *mode, ImagingNewParams p) {
return ImagingNewPrologueSubtype(mode, p, sizeof(struct ImagingMemoryInstance)); return ImagingNewPrologueSubtype(
mode, p, sizeof(struct ImagingMemoryInstance)
);
} }
void void

View File

@ -107,7 +107,8 @@ ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->buffer, state->buffer,
state->xsize); state->xsize
);
state->x = 0; state->x = 0;

View File

@ -93,7 +93,8 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->buffer, state->buffer,
state->xsize); state->xsize
);
state->x = 0; state->x = 0;

View File

@ -63,7 +63,8 @@ ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes)
state->buffer, state->buffer,
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->xsize); state->xsize
);
} }
row = state->buffer; row = state->buffer;
@ -146,7 +147,8 @@ ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes)
} }
memcpy( memcpy(
dst, state->buffer + (state->x * bytesPerPixel - state->count), flushCount); dst, state->buffer + (state->x * bytesPerPixel - state->count), flushCount
);
dst += flushCount; dst += flushCount;
bytes -= flushCount; bytes -= flushCount;

View File

@ -44,7 +44,8 @@ dump_state(const TIFFSTATE *state) {
(int)state->size, (int)state->size,
(uint)state->eof, (uint)state->eof,
state->data, state->data,
state->ifd)); state->ifd)
);
} }
/* /*
@ -64,7 +65,8 @@ _tiffReadProc(thandle_t hdata, tdata_t buf, tsize_t size) {
"_tiffReadProc", "_tiffReadProc",
"Invalid Read at loc %" PRIu64 ", eof: %" PRIu64, "Invalid Read at loc %" PRIu64 ", eof: %" PRIu64,
state->loc, state->loc,
state->eof); state->eof
);
return 0; return 0;
} }
to_read = min(size, min(state->size, (tsize_t)state->eof) - (tsize_t)state->loc); to_read = min(size, min(state->size, (tsize_t)state->eof) - (tsize_t)state->loc);
@ -200,13 +202,15 @@ ImagingLibTiffInit(ImagingCodecState state, int fp, uint32_t offset) {
state->state, state->state,
state->x, state->x,
state->y, state->y,
state->ystep)); state->ystep)
);
TRACE( TRACE(
("State: xsize %d, ysize %d, xoff %d, yoff %d \n", ("State: xsize %d, ysize %d, xoff %d, yoff %d \n",
state->xsize, state->xsize,
state->ysize, state->ysize,
state->xoff, state->xoff,
state->yoff)); state->yoff)
);
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes)); TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
TRACE(("State: context %p \n", state->context)); TRACE(("State: context %p \n", state->context));
@ -226,7 +230,8 @@ _pickUnpackers(
ImagingCodecState state, ImagingCodecState state,
TIFF *tiff, TIFF *tiff,
uint16_t planarconfig, uint16_t planarconfig,
ImagingShuffler *unpackers) { ImagingShuffler *unpackers
) {
// if number of bands is 1, there is no difference with contig case // if number of bands is 1, there is no difference with contig case
if (planarconfig == PLANARCONFIG_SEPARATE && im->bands > 1) { if (planarconfig == PLANARCONFIG_SEPARATE && im->bands > 1) {
uint16_t bits_per_sample = 8; uint16_t bits_per_sample = 8;
@ -356,7 +361,8 @@ _decodeAsRGBA(Imaging im, ImagingCodecState state, TIFF *tiff) {
(UINT8 *)im->image[state->y + state->yoff + current_row] + (UINT8 *)im->image[state->y + state->yoff + current_row] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->buffer + current_row * row_byte_size, state->buffer + current_row * row_byte_size,
state->xsize); state->xsize
);
} }
} }
@ -374,7 +380,8 @@ _decodeTile(
ImagingCodecState state, ImagingCodecState state,
TIFF *tiff, TIFF *tiff,
int planes, int planes,
ImagingShuffler *unpackers) { ImagingShuffler *unpackers
) {
INT32 x, y, tile_y, current_tile_length, current_tile_width; INT32 x, y, tile_y, current_tile_length, current_tile_width;
UINT32 tile_width, tile_length; UINT32 tile_width, tile_length;
tsize_t tile_bytes_size, row_byte_size; tsize_t tile_bytes_size, row_byte_size;
@ -453,7 +460,8 @@ _decodeTile(
("Writing tile data at %dx%d using tile_width: %d; \n", ("Writing tile data at %dx%d using tile_width: %d; \n",
tile_y + y, tile_y + y,
x, x,
current_tile_width)); current_tile_width)
);
// UINT8 * bbb = state->buffer + tile_y * row_byte_size; // UINT8 * bbb = state->buffer + tile_y * row_byte_size;
// TRACE(("chars: %x%x%x%x\n", ((UINT8 *)bbb)[0], ((UINT8 *)bbb)[1], // TRACE(("chars: %x%x%x%x\n", ((UINT8 *)bbb)[0], ((UINT8 *)bbb)[1],
@ -462,7 +470,8 @@ _decodeTile(
shuffler( shuffler(
(UINT8 *)im->image[tile_y + y] + x * im->pixelsize, (UINT8 *)im->image[tile_y + y] + x * im->pixelsize,
state->buffer + tile_y * row_byte_size, state->buffer + tile_y * row_byte_size,
current_tile_width); current_tile_width
);
} }
} }
} }
@ -477,7 +486,8 @@ _decodeStrip(
ImagingCodecState state, ImagingCodecState state,
TIFF *tiff, TIFF *tiff,
int planes, int planes,
ImagingShuffler *unpackers) { ImagingShuffler *unpackers
) {
INT32 strip_row = 0; INT32 strip_row = 0;
UINT8 *new_data; UINT8 *new_data;
UINT32 rows_per_strip; UINT32 rows_per_strip;
@ -544,9 +554,10 @@ _decodeStrip(
tiff, tiff,
TIFFComputeStrip(tiff, state->y, plane), TIFFComputeStrip(tiff, state->y, plane),
(tdata_t)state->buffer, (tdata_t)state->buffer,
strip_size) == -1) { strip_size
TRACE( ) == -1) {
("Decode Error, strip %d\n", TIFFComputeStrip(tiff, state->y, 0))); TRACE(("Decode Error, strip %d\n", TIFFComputeStrip(tiff, state->y, 0))
);
state->errcode = IMAGING_CODEC_BROKEN; state->errcode = IMAGING_CODEC_BROKEN;
return -1; return -1;
} }
@ -567,7 +578,8 @@ _decodeStrip(
(UINT8 *)im->image[state->y + state->yoff + strip_row] + (UINT8 *)im->image[state->y + state->yoff + strip_row] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->buffer + strip_row * row_byte_size, state->buffer + strip_row * row_byte_size,
state->xsize); state->xsize
);
} }
} }
} }
@ -577,7 +589,8 @@ _decodeStrip(
int int
ImagingLibTiffDecode( ImagingLibTiffDecode(
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes) { Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
) {
TIFFSTATE *clientstate = (TIFFSTATE *)state->context; TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
char *filename = "tempfile.tif"; char *filename = "tempfile.tif";
char *mode = "rC"; char *mode = "rC";
@ -602,13 +615,15 @@ ImagingLibTiffDecode(
state->state, state->state,
state->x, state->x,
state->y, state->y,
state->ystep)); state->ystep)
);
TRACE( TRACE(
("State: xsize %d, ysize %d, xoff %d, yoff %d \n", ("State: xsize %d, ysize %d, xoff %d, yoff %d \n",
state->xsize, state->xsize,
state->ysize, state->ysize,
state->xoff, state->xoff,
state->yoff)); state->yoff)
);
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes)); TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
TRACE( TRACE(
("Buffer: %p: %c%c%c%c\n", ("Buffer: %p: %c%c%c%c\n",
@ -616,26 +631,30 @@ ImagingLibTiffDecode(
(char)buffer[0], (char)buffer[0],
(char)buffer[1], (char)buffer[1],
(char)buffer[2], (char)buffer[2],
(char)buffer[3])); (char)buffer[3])
);
TRACE( TRACE(
("State->Buffer: %c%c%c%c\n", ("State->Buffer: %c%c%c%c\n",
(char)state->buffer[0], (char)state->buffer[0],
(char)state->buffer[1], (char)state->buffer[1],
(char)state->buffer[2], (char)state->buffer[2],
(char)state->buffer[3])); (char)state->buffer[3])
);
TRACE( TRACE(
("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n", ("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n",
im->mode, im->mode,
im->type, im->type,
im->bands, im->bands,
im->xsize, im->xsize,
im->ysize)); im->ysize)
);
TRACE( TRACE(
("Image: image8 %p, image32 %p, image %p, block %p \n", ("Image: image8 %p, image32 %p, image %p, block %p \n",
im->image8, im->image8,
im->image32, im->image32,
im->image, im->image,
im->block)); im->block)
);
TRACE(("Image: pixelsize: %d, linesize %d \n", im->pixelsize, im->linesize)); TRACE(("Image: pixelsize: %d, linesize %d \n", im->pixelsize, im->linesize));
dump_state(clientstate); dump_state(clientstate);
@ -665,7 +684,8 @@ ImagingLibTiffDecode(
_tiffCloseProc, _tiffCloseProc,
_tiffSizeProc, _tiffSizeProc,
_tiffMapProc, _tiffMapProc,
_tiffUnmapProc); _tiffUnmapProc
);
} }
if (!tiff) { if (!tiff) {
@ -694,7 +714,8 @@ ImagingLibTiffDecode(
state->xsize, state->xsize,
img_width, img_width,
state->ysize, state->ysize,
img_height)); img_height)
);
state->errcode = IMAGING_CODEC_BROKEN; state->errcode = IMAGING_CODEC_BROKEN;
goto decode_err; goto decode_err;
} }
@ -739,7 +760,8 @@ ImagingLibTiffDecode(
INT32 y; INT32 y;
TIFFGetFieldDefaulted( TIFFGetFieldDefaulted(
tiff, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo); tiff, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo
);
if (extrasamples >= 1 && (sampleinfo[0] == EXTRASAMPLE_UNSPECIFIED || if (extrasamples >= 1 && (sampleinfo[0] == EXTRASAMPLE_UNSPECIFIED ||
sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA)) { sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA)) {
@ -793,13 +815,15 @@ ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
state->state, state->state,
state->x, state->x,
state->y, state->y,
state->ystep)); state->ystep)
);
TRACE( TRACE(
("State: xsize %d, ysize %d, xoff %d, yoff %d \n", ("State: xsize %d, ysize %d, xoff %d, yoff %d \n",
state->xsize, state->xsize,
state->ysize, state->ysize,
state->xoff, state->xoff,
state->yoff)); state->yoff)
);
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes)); TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
TRACE(("State: context %p \n", state->context)); TRACE(("State: context %p \n", state->context));
@ -839,7 +863,8 @@ ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
_tiffCloseProc, _tiffCloseProc,
_tiffSizeProc, _tiffSizeProc,
_tiffNullMapProc, _tiffNullMapProc,
_tiffUnmapProc); /*force no mmap*/ _tiffUnmapProc
); /*force no mmap*/
} }
if (!clientstate->tiff) { if (!clientstate->tiff) {
@ -852,7 +877,8 @@ ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
int int
ImagingLibTiffMergeFieldInfo( ImagingLibTiffMergeFieldInfo(
ImagingCodecState state, TIFFDataType field_type, int key, int is_var_length) { ImagingCodecState state, TIFFDataType field_type, int key, int is_var_length
) {
// Refer to libtiff docs (http://www.simplesystems.org/libtiff/addingtags.html) // Refer to libtiff docs (http://www.simplesystems.org/libtiff/addingtags.html)
TIFFSTATE *clientstate = (TIFFSTATE *)state->context; TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
uint32_t n; uint32_t n;
@ -874,7 +900,8 @@ ImagingLibTiffMergeFieldInfo(
FIELD_CUSTOM, FIELD_CUSTOM,
1, 1,
passcount, passcount,
"CustomField"}}; "CustomField"}
};
n = sizeof(info) / sizeof(info[0]); n = sizeof(info) / sizeof(info[0]);
@ -922,13 +949,15 @@ ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int byt
state->state, state->state,
state->x, state->x,
state->y, state->y,
state->ystep)); state->ystep)
);
TRACE( TRACE(
("State: xsize %d, ysize %d, xoff %d, yoff %d \n", ("State: xsize %d, ysize %d, xoff %d, yoff %d \n",
state->xsize, state->xsize,
state->ysize, state->ysize,
state->xoff, state->xoff,
state->yoff)); state->yoff)
);
TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes)); TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
TRACE( TRACE(
("Buffer: %p: %c%c%c%c\n", ("Buffer: %p: %c%c%c%c\n",
@ -936,26 +965,30 @@ ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int byt
(char)buffer[0], (char)buffer[0],
(char)buffer[1], (char)buffer[1],
(char)buffer[2], (char)buffer[2],
(char)buffer[3])); (char)buffer[3])
);
TRACE( TRACE(
("State->Buffer: %c%c%c%c\n", ("State->Buffer: %c%c%c%c\n",
(char)state->buffer[0], (char)state->buffer[0],
(char)state->buffer[1], (char)state->buffer[1],
(char)state->buffer[2], (char)state->buffer[2],
(char)state->buffer[3])); (char)state->buffer[3])
);
TRACE( TRACE(
("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n", ("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n",
im->mode, im->mode,
im->type, im->type,
im->bands, im->bands,
im->xsize, im->xsize,
im->ysize)); im->ysize)
);
TRACE( TRACE(
("Image: image8 %p, image32 %p, image %p, block %p \n", ("Image: image8 %p, image32 %p, image %p, block %p \n",
im->image8, im->image8,
im->image32, im->image32,
im->image, im->image,
im->block)); im->block)
);
TRACE(("Image: pixelsize: %d, linesize %d \n", im->pixelsize, im->linesize)); TRACE(("Image: pixelsize: %d, linesize %d \n", im->pixelsize, im->linesize));
dump_state(clientstate); dump_state(clientstate);
@ -967,10 +1000,12 @@ ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int byt
state->buffer, state->buffer,
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->xsize); state->xsize
);
if (TIFFWriteScanline( if (TIFFWriteScanline(
tiff, (tdata_t)(state->buffer), (uint32_t)state->y, 0) == -1) { tiff, (tdata_t)(state->buffer), (uint32_t)state->y, 0
) == -1) {
TRACE(("Encode Error, row %d\n", state->y)); TRACE(("Encode Error, row %d\n", state->y));
state->errcode = IMAGING_CODEC_BROKEN; state->errcode = IMAGING_CODEC_BROKEN;
TIFFClose(tiff); TIFFClose(tiff);
@ -1013,7 +1048,8 @@ ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int byt
(char)buffer[0], (char)buffer[0],
(char)buffer[1], (char)buffer[1],
(char)buffer[2], (char)buffer[2],
(char)buffer[3])); (char)buffer[3])
);
if (clientstate->loc == clientstate->eof) { if (clientstate->loc == clientstate->eof) {
TRACE(("Hit EOF, calling an end, freeing data")); TRACE(("Hit EOF, calling an end, freeing data"));
state->errcode = IMAGING_CODEC_END; state->errcode = IMAGING_CODEC_END;

View File

@ -41,7 +41,8 @@ extern int
ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp); ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp);
extern int extern int
ImagingLibTiffMergeFieldInfo( ImagingLibTiffMergeFieldInfo(
ImagingCodecState state, TIFFDataType field_type, int key, int is_var_length); ImagingCodecState state, TIFFDataType field_type, int key, int is_var_length
);
extern int extern int
ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...); ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...);

View File

@ -104,7 +104,8 @@ static UINT8 BITFLIP[] = {
3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243, 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251, 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255}; 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
};
/* Unpack to "1" image */ /* Unpack to "1" image */
@ -882,7 +883,8 @@ unpackRGBa16L(UINT8 *_out, const UINT8 *in, int pixels) {
CLIP8(in[1] * 255 / a), CLIP8(in[1] * 255 / a),
CLIP8(in[3] * 255 / a), CLIP8(in[3] * 255 / a),
CLIP8(in[5] * 255 / a), CLIP8(in[5] * 255 / a),
a); a
);
} }
memcpy(_out, &iv, sizeof(iv)); memcpy(_out, &iv, sizeof(iv));
in += 8; in += 8;
@ -906,7 +908,8 @@ unpackRGBa16B(UINT8 *_out, const UINT8 *in, int pixels) {
CLIP8(in[0] * 255 / a), CLIP8(in[0] * 255 / a),
CLIP8(in[2] * 255 / a), CLIP8(in[2] * 255 / a),
CLIP8(in[4] * 255 / a), CLIP8(in[4] * 255 / a),
a); a
);
} }
memcpy(_out, &iv, sizeof(iv)); memcpy(_out, &iv, sizeof(iv));
in += 8; in += 8;
@ -930,7 +933,8 @@ unpackRGBa(UINT8 *_out, const UINT8 *in, int pixels) {
CLIP8(in[0] * 255 / a), CLIP8(in[0] * 255 / a),
CLIP8(in[1] * 255 / a), CLIP8(in[1] * 255 / a),
CLIP8(in[2] * 255 / a), CLIP8(in[2] * 255 / a),
a); a
);
} }
memcpy(_out, &iv, sizeof(iv)); memcpy(_out, &iv, sizeof(iv));
in += 4; in += 4;
@ -954,7 +958,8 @@ unpackRGBaskip1(UINT8 *_out, const UINT8 *in, int pixels) {
CLIP8(in[0] * 255 / a), CLIP8(in[0] * 255 / a),
CLIP8(in[1] * 255 / a), CLIP8(in[1] * 255 / a),
CLIP8(in[2] * 255 / a), CLIP8(in[2] * 255 / a),
a); a
);
} }
in += 5; in += 5;
} }
@ -976,7 +981,8 @@ unpackRGBaskip2(UINT8 *_out, const UINT8 *in, int pixels) {
CLIP8(in[0] * 255 / a), CLIP8(in[0] * 255 / a),
CLIP8(in[1] * 255 / a), CLIP8(in[1] * 255 / a),
CLIP8(in[2] * 255 / a), CLIP8(in[2] * 255 / a),
a); a
);
} }
in += 6; in += 6;
} }
@ -998,7 +1004,8 @@ unpackBGRa(UINT8 *_out, const UINT8 *in, int pixels) {
CLIP8(in[2] * 255 / a), CLIP8(in[2] * 255 / a),
CLIP8(in[1] * 255 / a), CLIP8(in[1] * 255 / a),
CLIP8(in[0] * 255 / a), CLIP8(in[0] * 255 / a),
a); a
);
} }
memcpy(_out, &iv, sizeof(iv)); memcpy(_out, &iv, sizeof(iv));
in += 4; in += 4;
@ -1029,7 +1036,8 @@ unpackRGBAL(UINT8 *_out, const UINT8 *in, int pixels) {
in[i], in[i],
in[i + pixels], in[i + pixels],
in[i + pixels + pixels], in[i + pixels + pixels],
in[i + pixels + pixels + pixels]); in[i + pixels + pixels + pixels]
);
memcpy(_out, &iv, sizeof(iv)); memcpy(_out, &iv, sizeof(iv));
} }
} }

View File

@ -34,7 +34,8 @@ static INT16 L[] = {
261, 262, 264, 265, 266, 268, 269, 270, 272, 273, 274, 276, 277, 278, 280, 281, 261, 262, 264, 265, 266, 268, 269, 270, 272, 273, 274, 276, 277, 278, 280, 281,
283, 284, 285, 287, 288, 289, 291, 292, 293, 295, 296, 297, 299, 300, 302, 303, 283, 284, 285, 287, 288, 289, 291, 292, 293, 295, 296, 297, 299, 300, 302, 303,
304, 306, 307, 308, 310, 311, 312, 314, 315, 317, 318, 319, 321, 322, 323, 325, 304, 306, 307, 308, 310, 311, 312, 314, 315, 317, 318, 319, 321, 322, 323, 325,
326, 327, 329, 330, 331, 333, 334, 336, 337, 338, 340, 341, 342, 344, 345, 346}; 326, 327, 329, 330, 331, 333, 334, 336, 337, 338, 340, 341, 342, 344, 345, 346
};
static INT16 CB[] = { static INT16 CB[] = {
-345, -343, -341, -338, -336, -334, -332, -329, -327, -325, -323, -321, -318, -316, -345, -343, -341, -338, -336, -334, -332, -329, -327, -325, -323, -321, -318, -316,
@ -55,7 +56,8 @@ static INT16 CB[] = {
120, 122, 124, 126, 129, 131, 133, 135, 138, 140, 142, 144, 146, 149, 120, 122, 124, 126, 129, 131, 133, 135, 138, 140, 142, 144, 146, 149,
151, 153, 155, 157, 160, 162, 164, 166, 169, 171, 173, 175, 177, 180, 151, 153, 155, 157, 160, 162, 164, 166, 169, 171, 173, 175, 177, 180,
182, 184, 186, 189, 191, 193, 195, 197, 200, 202, 204, 206, 208, 211, 182, 184, 186, 189, 191, 193, 195, 197, 200, 202, 204, 206, 208, 211,
213, 215, 217, 220}; 213, 215, 217, 220
};
static INT16 GB[] = { static INT16 GB[] = {
67, 67, 66, 66, 65, 65, 65, 64, 64, 63, 63, 62, 62, 62, 61, 61, 67, 67, 66, 66, 65, 65, 65, 64, 64, 63, 63, 62, 62, 62, 61, 61,
@ -73,7 +75,8 @@ static INT16 GB[] = {
-14, -15, -15, -16, -16, -17, -17, -18, -18, -18, -19, -19, -20, -20, -21, -21, -14, -15, -15, -16, -16, -17, -17, -18, -18, -18, -19, -19, -20, -20, -21, -21,
-21, -22, -22, -23, -23, -24, -24, -24, -25, -25, -26, -26, -27, -27, -27, -28, -21, -22, -22, -23, -23, -24, -24, -24, -25, -25, -26, -26, -27, -27, -27, -28,
-28, -29, -29, -30, -30, -30, -31, -31, -32, -32, -33, -33, -33, -34, -34, -35, -28, -29, -29, -30, -30, -30, -31, -31, -32, -32, -33, -33, -33, -34, -34, -35,
-35, -36, -36, -36, -37, -37, -38, -38, -39, -39, -39, -40, -40, -41, -41, -42}; -35, -36, -36, -36, -37, -37, -38, -38, -39, -39, -39, -40, -40, -41, -41, -42
};
static INT16 CR[] = { static INT16 CR[] = {
-249, -247, -245, -243, -241, -239, -238, -236, -234, -232, -230, -229, -227, -225, -249, -247, -245, -243, -241, -239, -238, -236, -234, -232, -230, -229, -227, -225,
@ -94,7 +97,8 @@ static INT16 CR[] = {
133, 135, 137, 138, 140, 142, 144, 146, 148, 149, 151, 153, 155, 157, 133, 135, 137, 138, 140, 142, 144, 146, 148, 149, 151, 153, 155, 157,
158, 160, 162, 164, 166, 168, 169, 171, 173, 175, 177, 179, 180, 182, 158, 160, 162, 164, 166, 168, 169, 171, 173, 175, 177, 179, 180, 182,
184, 186, 188, 189, 191, 193, 195, 197, 199, 200, 202, 204, 206, 208, 184, 186, 188, 189, 191, 193, 195, 197, 199, 200, 202, 204, 206, 208,
209, 211, 213, 215}; 209, 211, 213, 215
};
static INT16 GR[] = { static INT16 GR[] = {
127, 126, 125, 124, 123, 122, 121, 121, 120, 119, 118, 117, 116, 115, 114, 127, 126, 125, 124, 123, 122, 121, 121, 120, 119, 118, 117, 116, 115, 114,
@ -114,7 +118,8 @@ static INT16 GR[] = {
-67, -68, -69, -69, -70, -71, -72, -73, -74, -75, -76, -77, -78, -79, -80, -67, -68, -69, -69, -70, -71, -72, -73, -74, -75, -76, -77, -78, -79, -80,
-81, -82, -82, -83, -84, -85, -86, -87, -88, -89, -90, -91, -92, -93, -94, -81, -82, -82, -83, -84, -85, -86, -87, -88, -89, -90, -91, -92, -93, -94,
-94, -95, -96, -97, -98, -99, -100, -101, -102, -103, -104, -105, -106, -107, -107, -94, -95, -96, -97, -98, -99, -100, -101, -102, -103, -104, -105, -106, -107, -107,
-108}; -108
};
#define R 0 #define R 0
#define G 1 #define G 1

View File

@ -23,7 +23,8 @@ clip8(int in) {
Imaging Imaging
ImagingUnsharpMask( ImagingUnsharpMask(
Imaging imOut, Imaging imIn, float radius, int percent, int threshold) { Imaging imOut, Imaging imIn, float radius, int percent, int threshold
) {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
Imaging result; Imaging result;

View File

@ -40,7 +40,8 @@ ImagingXbmEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
state->shuffle( state->shuffle(
state->buffer, state->buffer,
(UINT8 *)im->image[state->y + state->yoff] + state->xoff * im->pixelsize, (UINT8 *)im->image[state->y + state->yoff] + state->xoff * im->pixelsize,
state->xsize); state->xsize
);
if (state->y < state->ysize - 1) { if (state->y < state->ysize - 1) {
/* any line but the last */ /* any line but the last */

View File

@ -217,7 +217,8 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t byt
state->shuffle( state->shuffle(
(UINT8 *)im->image[state->y] + col * im->pixelsize, (UINT8 *)im->image[state->y] + col * im->pixelsize,
state->buffer + context->prefix + i, state->buffer + context->prefix + i,
1); 1
);
col += COL_INCREMENT[context->pass]; col += COL_INCREMENT[context->pass];
} }
} else { } else {
@ -229,7 +230,8 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t byt
UINT8 byte = *(state->buffer + context->prefix + (i / 8)); UINT8 byte = *(state->buffer + context->prefix + (i / 8));
byte <<= (i % 8); byte <<= (i % 8);
state->shuffle( state->shuffle(
(UINT8 *)im->image[state->y] + col * im->pixelsize, &byte, 1); (UINT8 *)im->image[state->y] + col * im->pixelsize, &byte, 1
);
col += COL_INCREMENT[context->pass]; col += COL_INCREMENT[context->pass];
} }
} }
@ -253,7 +255,8 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t byt
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->buffer + context->prefix, state->buffer + context->prefix,
state->xsize); state->xsize
);
state->y++; state->y++;
} }

View File

@ -98,7 +98,8 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
15, 15,
9, 9,
/* compression strategy (image data are filtered)*/ /* compression strategy (image data are filtered)*/
compress_type); compress_type
);
if (err < 0) { if (err < 0) {
state->errcode = IMAGING_CODEC_CONFIG; state->errcode = IMAGING_CODEC_CONFIG;
return -1; return -1;
@ -108,7 +109,8 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
err = deflateSetDictionary( err = deflateSetDictionary(
&context->z_stream, &context->z_stream,
(unsigned char *)context->dictionary, (unsigned char *)context->dictionary,
context->dictionary_size); context->dictionary_size
);
if (err < 0) { if (err < 0) {
state->errcode = IMAGING_CODEC_CONFIG; state->errcode = IMAGING_CODEC_CONFIG;
return -1; return -1;
@ -163,7 +165,8 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
state->buffer + 1, state->buffer + 1,
(UINT8 *)im->image[state->y + state->yoff] + (UINT8 *)im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xoff * im->pixelsize,
state->xsize); state->xsize
);
state->y++; state->y++;

View File

@ -75,7 +75,8 @@ PyImaging_MapBuffer(PyObject *self, PyObject *args) {
&stride, &stride,
&ystep, &ystep,
&depth, &depth,
&bands)) { &bands
)) {
return NULL; return NULL;
} }

View File

@ -26,6 +26,7 @@
*/ */
#include "Python.h" #include "Python.h"
#include "thirdparty/pythoncapi_compat.h"
#include "libImaging/Imaging.h" #include "libImaging/Imaging.h"
#include <math.h> #include <math.h>
@ -179,14 +180,21 @@ PyPath_Flatten(PyObject *data, double **pxy) {
} \ } \
free(xy); \ free(xy); \
return -1; \ return -1; \
} \
if (decref) { \
Py_DECREF(op); \
} }
/* Copy table to path array */ /* Copy table to path array */
if (PyList_Check(data)) { if (PyList_Check(data)) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
double x, y; double x, y;
PyObject *op = PyList_GET_ITEM(data, i); PyObject *op = PyList_GetItemRef(data, i);
assign_item_to_array(op, 0); if (op == NULL) {
free(xy);
return -1;
}
assign_item_to_array(op, 1);
} }
} else if (PyTuple_Check(data)) { } else if (PyTuple_Check(data)) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
@ -209,7 +217,6 @@ PyPath_Flatten(PyObject *data, double **pxy) {
} }
} }
assign_item_to_array(op, 1); assign_item_to_array(op, 1);
Py_DECREF(op);
} }
} }
@ -482,7 +489,8 @@ path_transform(PyPathObject *self, PyObject *args) {
double wrap = 0.0; double wrap = 0.0;
if (!PyArg_ParseTuple( if (!PyArg_ParseTuple(
args, "(dddddd)|d:transform", &a, &b, &c, &d, &e, &f, &wrap)) { args, "(dddddd)|d:transform", &a, &b, &c, &d, &e, &f, &wrap
)) {
return NULL; return NULL;
} }
@ -563,7 +571,8 @@ path_subscript(PyPathObject *self, PyObject *item) {
PyErr_Format( PyErr_Format(
PyExc_TypeError, PyExc_TypeError,
"Path indices must be integers, not %.200s", "Path indices must be integers, not %.200s",
Py_TYPE(item)->tp_name); Py_TYPE(item)->tp_name
);
return NULL; return NULL;
} }
} }
@ -579,7 +588,8 @@ static PySequenceMethods path_as_sequence = {
}; };
static PyMappingMethods path_as_mapping = { static PyMappingMethods path_as_mapping = {
(lenfunc)path_len, (binaryfunc)path_subscript, NULL}; (lenfunc)path_len, (binaryfunc)path_subscript, NULL
};
static PyTypeObject PyPathType = { static PyTypeObject PyPathType = {
PyVarObject_HEAD_INIT(NULL, 0) "Path", /*tp_name*/ PyVarObject_HEAD_INIT(NULL, 0) "Path", /*tp_name*/

1360
src/thirdparty/pythoncapi_compat.h vendored Normal file

File diff suppressed because it is too large Load Diff