Merge branch 'master' of github.com:python-pillow/Pillow into winbuild-rewrite

# Conflicts:
#	.github/workflows/test-windows.yml
#	winbuild/config.py
#       winbuild/build_prepare.py
This commit is contained in:
nulano 2020-05-25 14:32:21 +02:00
commit 9640b48040
96 changed files with 2718 additions and 1459 deletions

View File

@ -30,3 +30,9 @@ repos:
hooks: hooks:
- id: check-merge-conflict - id: check-merge-conflict
- id: check-yaml - id: check-yaml
- repo: https://github.com/Lucas-C/pre-commit-hooks
rev: v1.1.7
hooks:
- id: remove-tabs
exclude: (Makefile$|\.bat$|\.cmake$|\.eps$|\.fits$|\.opt$)

View File

@ -5,6 +5,15 @@ Changelog (Pillow)
7.2.0 (unreleased) 7.2.0 (unreleased)
------------------ ------------------
- Fix repeatedly loading .gbr #4620
[ElinksFr, radarhere]
- JPEG: Truncate icclist instead of setting to None #4613
[homm]
- Fixes default offset for Exif #4594
[rodrigob, radarhere]
- Fixed bug when unpickling TIFF images #4565 - Fixed bug when unpickling TIFF images #4565
[radarhere] [radarhere]
@ -5310,23 +5319,23 @@ Pre-fork
+ Added keyword options to the "save" method. The following options + Added keyword options to the "save" method. The following options
are currently supported: are currently supported:
format option description Format Option Description
-------------------------------------------------------- --------------------------------------------------------
JPEG optimize minimize output file at the JPEG optimize Minimize output file at the
expense of compression speed. expense of compression speed.
JPEG progressive enable progressive output. the JPEG progressive Enable progressive output.
option value is ignored. The option value is ignored.
JPEG quality set compression quality (1-100). JPEG quality Set compression quality (1-100).
the default value is 75. The default value is 75.
JPEG smooth smooth dithered images. value JPEG smooth Smooth dithered images.
is strength (1-100). default is Value is strength (1-100).
off (0). Default is off (0).
PNG optimize minimize output file at the PNG optimize Minimize output file at the
expense of compression speed. expense of compression speed.
Expect more options in future releases. Also note that Expect more options in future releases. Also note that
file writers silently ignore unknown options. file writers silently ignore unknown options.
@ -5347,31 +5356,31 @@ Pre-fork
+ Various improvements to the sample scripts: + Various improvements to the sample scripts:
"pilconvert" Carries out some extra tricks in order to make "pilconvert" Carries out some extra tricks in order to make
the resulting file as small as possible. the resulting file as small as possible.
"explode" (NEW) Split an image sequence into individual frames. "explode" (NEW) Split an image sequence into individual frames.
"gifmaker" (NEW) Convert a sequence file into a GIF animation. "gifmaker" (NEW) Convert a sequence file into a GIF animation.
Note that the GIF encoder create "uncompressed" GIF Note that the GIF encoder create "uncompressed" GIF
files, so animations created by this script are files, so animations created by this script are
rather large (typically 2-5 times the compressed rather large (typically 2-5 times the compressed
sizes). sizes).
"image2py" (NEW) Convert a single image to a python module. See "image2py" (NEW) Convert a single image to a python module. See
comments in this script for details. comments in this script for details.
"player" If multiple images are given on the command line, "player" If multiple images are given on the command line,
they are interpreted as frames in a sequence. The they are interpreted as frames in a sequence. The
script assumes that they all have the same size. script assumes that they all have the same size.
Also note that this script now can play FLI/FLC Also note that this script now can play FLI/FLC
and GIF animations. and GIF animations.
This player can also execute embedded Python This player can also execute embedded Python
animation applets (ARG format only). animation applets (ARG format only).
"viewer" Transparent images ("P" with transparency property, "viewer" Transparent images ("P" with transparency property,
and "RGBA") are superimposed on the standard Tk back- and "RGBA") are superimposed on the standard Tk back-
ground. ground.
+ Fixed colour argument to "new". For multilayer images, pass a + Fixed colour argument to "new". For multilayer images, pass a
tuple: (Red, Green, Blue), (Red, Green, Blue, Alpha), or (Cyan, tuple: (Red, Green, Blue), (Red, Green, Blue, Alpha), or (Cyan,

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

View File

@ -15,3 +15,11 @@ def test_gbr_file():
with Image.open("Tests/images/gbr.gbr") as im: with Image.open("Tests/images/gbr.gbr") as im:
with Image.open("Tests/images/gbr.png") as target: with Image.open("Tests/images/gbr.png") as target:
assert_image_equal(target, im) assert_image_equal(target, im)
def test_multiple_load_operations():
with Image.open("Tests/images/gbr.gbr") as im:
im.load()
im.load()
with Image.open("Tests/images/gbr.png") as target:
assert_image_equal(target, im)

View File

@ -500,7 +500,7 @@ class TestFileJpeg:
def test_load_djpeg(self): def test_load_djpeg(self):
with Image.open(TEST_FILE) as img: with Image.open(TEST_FILE) as img:
img.load_djpeg() img.load_djpeg()
assert_image_similar(img, Image.open(TEST_FILE), 0) assert_image_similar(img, Image.open(TEST_FILE), 5)
@pytest.mark.skipif(not cjpeg_available(), reason="cjpeg not available") @pytest.mark.skipif(not cjpeg_available(), reason="cjpeg not available")
def test_save_cjpeg(self, tmp_path): def test_save_cjpeg(self, tmp_path):
@ -689,6 +689,10 @@ class TestFileJpeg:
apps_13_lengths = [len(v) for k, v in im.applist if k == "APP13"] apps_13_lengths = [len(v) for k, v in im.applist if k == "APP13"]
assert [65504, 24] == apps_13_lengths assert [65504, 24] == apps_13_lengths
def test_icc_after_SOF(self):
with Image.open("Tests/images/icc-after-SOF.jpg") as im:
assert im.info["icc_profile"] == b"profile"
@pytest.mark.skipif(not is_win32(), reason="Windows only") @pytest.mark.skipif(not is_win32(), reason="Windows only")
@skip_unless_feature("jpg") @skip_unless_feature("jpg")

View File

@ -174,8 +174,10 @@ def assert_compare_images(a, b, max_average_diff, max_diff=255):
average_diff = sum(i * num for i, num in enumerate(ch_hist)) / ( average_diff = sum(i * num for i, num in enumerate(ch_hist)) / (
a.size[0] * a.size[1] a.size[0] * a.size[1]
) )
msg = "average pixel value difference {:.4f} > expected {:.4f} " msg = (
"for '{}' band".format(average_diff, max_average_diff, band) "average pixel value difference {:.4f} > expected {:.4f} "
"for '{}' band".format(average_diff, max_average_diff, band)
)
assert max_average_diff >= average_diff, msg assert max_average_diff >= average_diff, msg
last_diff = [i for i, num in enumerate(ch_hist) if num > 0][-1] last_diff = [i for i, num in enumerate(ch_hist) if num > 0][-1]

View File

@ -261,9 +261,9 @@ class TestPyDecoder:
with Image.open(out) as reloaded: with Image.open(out) as reloaded:
reloaded_exif = reloaded.getexif() reloaded_exif = reloaded.getexif()
assert reloaded_exif[258] == 8 assert reloaded_exif[258] == 8
assert 40960 not in exif assert 40960 not in reloaded_exif
assert reloaded_exif[40963] == 455 assert reloaded_exif[40963] == 455
assert exif[11] == "Pillow test" assert reloaded_exif[11] == "Pillow test"
with Image.open("Tests/images/no-dpi-in-exif.jpg") as im: # Big endian with Image.open("Tests/images/no-dpi-in-exif.jpg") as im: # Big endian
exif = im.getexif() exif = im.getexif()
@ -281,9 +281,9 @@ class TestPyDecoder:
with Image.open(out) as reloaded: with Image.open(out) as reloaded:
reloaded_exif = reloaded.getexif() reloaded_exif = reloaded.getexif()
assert reloaded_exif[258] == 8 assert reloaded_exif[258] == 8
assert 40960 not in exif assert 34665 not in reloaded_exif
assert reloaded_exif[40963] == 455 assert reloaded_exif[40963] == 455
assert exif[305] == "Pillow test" assert reloaded_exif[305] == "Pillow test"
@skip_unless_feature("webp") @skip_unless_feature("webp")
@skip_unless_feature("webp_anim") @skip_unless_feature("webp_anim")
@ -302,7 +302,7 @@ class TestPyDecoder:
reloaded_exif = reloaded.getexif() reloaded_exif = reloaded.getexif()
assert reloaded_exif[258] == 8 assert reloaded_exif[258] == 8
assert reloaded_exif[40963] == 455 assert reloaded_exif[40963] == 455
assert exif[305] == "Pillow test" assert reloaded_exif[305] == "Pillow test"
im.save(out, exif=exif) im.save(out, exif=exif)
check_exif() check_exif()

View File

@ -4,12 +4,12 @@
# Use SVN to just fetch a single Git subdirectory # Use SVN to just fetch a single Git subdirectory
svn_export() svn_export()
{ {
if [ ! -z $1 ]; then if [ ! -z $1 ]; then
echo "" echo ""
echo "Retrying svn export..." echo "Retrying svn export..."
echo "" echo ""
fi fi
svn export --force https://github.com/python-pillow/pillow-depends/trunk/test_images ../Tests/images svn export --force https://github.com/python-pillow/pillow-depends/trunk/test_images ../Tests/images
} }
svn_export || svn_export retry || svn_export retry || svn_export retry svn_export || svn_export retry || svn_export retry || svn_export retry

View File

@ -17,8 +17,8 @@ itself. Such plug-ins usually have names like
Pillow decodes files in 2 stages: Pillow decodes files in 2 stages:
1. It loops over the available image plugins in the loaded order, and 1. It loops over the available image plugins in the loaded order, and
calls the plugin's ``accept`` function with the first 16 bytes of calls the plugin's ``_accept`` function with the first 16 bytes of
the file. If the ``accept`` function returns true, the plugin's the file. If the ``_accept`` function returns true, the plugin's
``_open`` method is called to set up the image metadata and image ``_open`` method is called to set up the image metadata and image
tiles. The ``_open`` method is not for decoding the actual image tiles. The ``_open`` method is not for decoding the actual image
data. data.
@ -53,6 +53,11 @@ true color.
from PIL import Image, ImageFile from PIL import Image, ImageFile
def _accept(prefix):
return prefix[:4] == b"SPAM"
class SpamImageFile(ImageFile.ImageFile): class SpamImageFile(ImageFile.ImageFile):
format = "SPAM" format = "SPAM"
@ -60,12 +65,7 @@ true color.
def _open(self): def _open(self):
# check header header = self.fp.read(128).split()
header = self.fp.read(128)
if header[:4] != b"SPAM":
raise SyntaxError("not a SPAM file")
header = header.split()
# size in pixels (width, height) # size in pixels (width, height)
self._size = int(header[1]), int(header[2]) self._size = int(header[1]), int(header[2])
@ -86,7 +86,7 @@ true color.
("raw", (0, 0) + self.size, 128, (self.mode, 0, 1)) ("raw", (0, 0) + self.size, 128, (self.mode, 0, 1))
] ]
Image.register_open(SpamImageFile.format, SpamImageFile) Image.register_open(SpamImageFile.format, SpamImageFile, _accept)
Image.register_extension(SpamImageFile.format, ".spam") Image.register_extension(SpamImageFile.format, ".spam")
Image.register_extension(SpamImageFile.format, ".spa") # dos version Image.register_extension(SpamImageFile.format, ".spa") # dos version
@ -179,7 +179,7 @@ complete list, see the table in the :py:mod:`Unpack.c` module. The following
table describes some commonly used **raw modes**: table describes some commonly used **raw modes**:
+-----------+-----------------------------------------------------------------+ +-----------+-----------------------------------------------------------------+
| mode | description | | mode | description |
+===========+=================================================================+ +===========+=================================================================+
| ``1`` | 1-bit bilevel, stored with the leftmost pixel in the most | | ``1`` | 1-bit bilevel, stored with the leftmost pixel in the most |
| | significant bit. 0 means black, 1 means white. | | | significant bit. 0 means black, 1 means white. |
@ -223,7 +223,7 @@ You can use the ``raw`` decoder to read images where data is packed in any
standard machine data type, using one of the following raw modes: standard machine data type, using one of the following raw modes:
============ ======================================= ============ =======================================
mode description mode description
============ ======================================= ============ =======================================
``F`` 32-bit native floating point. ``F`` 32-bit native floating point.
``F;8`` 8-bit unsigned integer. ``F;8`` 8-bit unsigned integer.

View File

@ -329,7 +329,7 @@ In Fedora, the command is::
.. Note:: ``redhat-rpm-config`` is required on Fedora 23, but not earlier versions. .. Note:: ``redhat-rpm-config`` is required on Fedora 23, but not earlier versions.
Prerequisites are installed on **Ubuntu 16.04 LTS** with:: Prerequisites for **Ubuntu 16.04 LTS - 20.04 LTS** are installed with::
sudo apt-get install libtiff5-dev libjpeg8-dev libopenjp2-7-dev zlib1g-dev \ sudo apt-get install libtiff5-dev libjpeg8-dev libopenjp2-7-dev zlib1g-dev \
libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python3-tk \ libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python3-tk \
@ -434,7 +434,7 @@ These platforms have been reported to work at the versions mentioned.
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+
|**Operating system** |**Tested Python versions** |**Latest tested Pillow version**|**Tested processors** | |**Operating system** |**Tested Python versions** |**Latest tested Pillow version**|**Tested processors** |
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+
| macOS 10.15 Catalina | 3.5, 3.6, 3.7, 3.8 | 7.0.0 |x86-64 | | macOS 10.15 Catalina | 3.5, 3.6, 3.7, 3.8 | 7.1.2 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+
| macOS 10.14 Mojave | 2.7, 3.5, 3.6, 3.7 | 6.0.0 |x86-64 | | macOS 10.14 Mojave | 2.7, 3.5, 3.6, 3.7 | 6.0.0 |x86-64 |
| +------------------------------+--------------------------------+ + | +------------------------------+--------------------------------+ +

View File

@ -58,8 +58,8 @@ Functions
``warnings.simplefilter('ignore', Image.DecompressionBombWarning)``. See also `the logging ``warnings.simplefilter('ignore', Image.DecompressionBombWarning)``. See also `the logging
documentation`_ to have warnings output to the logging facility instead of stderr. documentation`_ to have warnings output to the logging facility instead of stderr.
.. _decompression bombs: https://en.wikipedia.org/wiki/Zip_bomb .. _decompression bombs: https://en.wikipedia.org/wiki/Zip_bomb
.. _the logging documentation: https://docs.python.org/3/library/logging.html#integration-with-the-warnings-module .. _the logging documentation: https://docs.python.org/3/library/logging.html#integration-with-the-warnings-module
Image processing Image processing
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^

View File

@ -413,10 +413,10 @@ can be easily displayed in a chromaticity diagram, for example).
with :py:attr:`.intent_supported`. with :py:attr:`.intent_supported`.
:param intent: One of ``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC``, :param intent: One of ``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC``,
``ImageCms.INTENT_PERCEPTUAL``, ``ImageCms.INTENT_PERCEPTUAL``,
``ImageCms.INTENT_RELATIVE_COLORIMETRIC`` ``ImageCms.INTENT_RELATIVE_COLORIMETRIC``
and ``ImageCms.INTENT_SATURATION``. and ``ImageCms.INTENT_SATURATION``.
:param direction: One of ``ImageCms.DIRECTION_INPUT``, :param direction: One of ``ImageCms.DIRECTION_INPUT``,
``ImageCms.DIRECTION_OUTPUT`` ``ImageCms.DIRECTION_OUTPUT``
and ``ImageCms.DIRECTION_PROOF`` and ``ImageCms.DIRECTION_PROOF``
:return: Boolean if the intent and direction is supported. :return: Boolean if the intent and direction is supported.

View File

@ -9,13 +9,14 @@ this class store bitmap fonts, and are used with the
:py:meth:`PIL.ImageDraw.Draw.text` method. :py:meth:`PIL.ImageDraw.Draw.text` method.
PIL uses its own font file format to store bitmap fonts. You can use the PIL uses its own font file format to store bitmap fonts. You can use the
:command:`pilfont` utility to convert BDF and PCF font descriptors (X window :command:`pilfont` utility from
font formats) to this format. `pillow-scripts <https://pypi.org/project/pillow-scripts/>`_
to convert BDF and PCF font descriptors (X window font formats) to this format.
Starting with version 1.1.4, PIL can be configured to support TrueType and Starting with version 1.1.4, PIL can be configured to support TrueType and
OpenType fonts (as well as other font formats supported by the FreeType OpenType fonts (as well as other font formats supported by the FreeType
library). For earlier versions, TrueType support is only available as part of library). For earlier versions, TrueType support is only available as part of
the imToolkit package the imToolkit package.
Example Example
------- -------

View File

@ -10,3 +10,4 @@ multi_line_output = 3
[tool:pytest] [tool:pytest]
addopts = -rs addopts = -rs
testpaths = Tests

View File

@ -730,7 +730,11 @@ class pil_build_ext(build_ext):
if struct.unpack("h", b"\0\1")[0] == 1: if struct.unpack("h", b"\0\1")[0] == 1:
defs.append(("WORDS_BIGENDIAN", None)) defs.append(("WORDS_BIGENDIAN", None))
if sys.platform == "win32" and not (PLATFORM_PYPY or PLATFORM_MINGW): if (
sys.platform == "win32"
and sys.version_info < (3, 9)
and not (PLATFORM_PYPY or PLATFORM_MINGW)
):
defs.append(("PILLOW_VERSION", '"\\"%s\\""' % PILLOW_VERSION)) defs.append(("PILLOW_VERSION", '"\\"%s\\""' % PILLOW_VERSION))
else: else:
defs.append(("PILLOW_VERSION", '"%s"' % PILLOW_VERSION)) defs.append(("PILLOW_VERSION", '"%s"' % PILLOW_VERSION))

View File

@ -84,6 +84,10 @@ class GbrImageFile(ImageFile.ImageFile):
self._data_size = width * height * color_depth self._data_size = width * height * color_depth
def load(self): def load(self):
if self.im:
# Already loaded
return
self.im = Image.core.new(self.mode, self.size) self.im = Image.core.new(self.mode, self.size)
self.frombytes(self.fp.read(self._data_size)) self.frombytes(self.fp.read(self._data_size))

View File

@ -3281,7 +3281,7 @@ class Exif(MutableMapping):
self._data.update(ifd) self._data.update(ifd)
self._ifds[0x8769] = ifd self._ifds[0x8769] = ifd
def tobytes(self, offset=0): def tobytes(self, offset=8):
from . import TiffImagePlugin from . import TiffImagePlugin
if self.endian == "<": if self.endian == "<":

View File

@ -54,7 +54,7 @@ def invert(image):
def lighter(image1, image2): def lighter(image1, image2):
""" """
Compares the two images, pixel by pixel, and returns a new image containing Compares the two images, pixel by pixel, and returns a new image containing
the lighter values. At least one of the images must have mode "1". the lighter values.
.. code-block:: python .. code-block:: python
@ -71,7 +71,7 @@ def lighter(image1, image2):
def darker(image1, image2): def darker(image1, image2):
""" """
Compares the two images, pixel by pixel, and returns a new image containing Compares the two images, pixel by pixel, and returns a new image containing
the darker values. At least one of the images must have mode "1". the darker values.
.. code-block:: python .. code-block:: python
@ -88,7 +88,7 @@ def darker(image1, image2):
def difference(image1, image2): def difference(image1, image2):
""" """
Returns the absolute value of the pixel-by-pixel difference between the two Returns the absolute value of the pixel-by-pixel difference between the two
images. At least one of the images must have mode "1". images.
.. code-block:: python .. code-block:: python
@ -107,8 +107,7 @@ def multiply(image1, image2):
Superimposes two images on top of each other. Superimposes two images on top of each other.
If you multiply an image with a solid black image, the result is black. If If you multiply an image with a solid black image, the result is black. If
you multiply with a solid white image, the image is unaffected. At least you multiply with a solid white image, the image is unaffected.
one of the images must have mode "1".
.. code-block:: python .. code-block:: python
@ -124,8 +123,7 @@ def multiply(image1, image2):
def screen(image1, image2): def screen(image1, image2):
""" """
Superimposes two inverted images on top of each other. At least one of the Superimposes two inverted images on top of each other.
images must have mode "1".
.. code-block:: python .. code-block:: python
@ -179,7 +177,6 @@ def add(image1, image2, scale=1.0, offset=0):
""" """
Adds two images, dividing the result by scale and adding the Adds two images, dividing the result by scale and adding the
offset. If omitted, scale defaults to 1.0, and offset to 0.0. offset. If omitted, scale defaults to 1.0, and offset to 0.0.
At least one of the images must have mode "1".
.. code-block:: python .. code-block:: python
@ -196,8 +193,7 @@ def add(image1, image2, scale=1.0, offset=0):
def subtract(image1, image2, scale=1.0, offset=0): def subtract(image1, image2, scale=1.0, offset=0):
""" """
Subtracts two images, dividing the result by scale and adding the offset. Subtracts two images, dividing the result by scale and adding the offset.
If omitted, scale defaults to 1.0, and offset to 0.0. At least one of the If omitted, scale defaults to 1.0, and offset to 0.0.
images must have mode "1".
.. code-block:: python .. code-block:: python
@ -212,8 +208,7 @@ def subtract(image1, image2, scale=1.0, offset=0):
def add_modulo(image1, image2): def add_modulo(image1, image2):
"""Add two images, without clipping the result. At least one of the images """Add two images, without clipping the result.
must have mode "1".
.. code-block:: python .. code-block:: python
@ -228,8 +223,7 @@ def add_modulo(image1, image2):
def subtract_modulo(image1, image2): def subtract_modulo(image1, image2):
"""Subtract two images, without clipping the result. At least one of the """Subtract two images, without clipping the result.
images must have mode "1".
.. code-block:: python .. code-block:: python
@ -244,8 +238,12 @@ def subtract_modulo(image1, image2):
def logical_and(image1, image2): def logical_and(image1, image2):
"""Logical AND between two images. At least one of the images must have """Logical AND between two images.
mode "1".
Both of the images must have mode "1". If you would like to perform a
logical AND on an image with a mode other than "1", try
:py:meth:`~PIL.ImageChops.multiply` instead, using a black-and-white mask
as the second image.
.. code-block:: python .. code-block:: python
@ -260,8 +258,9 @@ def logical_and(image1, image2):
def logical_or(image1, image2): def logical_or(image1, image2):
"""Logical OR between two images. At least one of the images must have """Logical OR between two images.
mode "1".
Both of the images must have mode "1".
.. code-block:: python .. code-block:: python
@ -276,8 +275,9 @@ def logical_or(image1, image2):
def logical_xor(image1, image2): def logical_xor(image1, image2):
"""Logical XOR between two images. At least one of the images must have """Logical XOR between two images.
mode "1".
Both of the images must have mode "1".
.. code-block:: python .. code-block:: python

View File

@ -221,7 +221,7 @@ def SOF(self, marker):
else: else:
icc_profile = None # wrong number of fragments icc_profile = None # wrong number of fragments
self.info["icc_profile"] = icc_profile self.info["icc_profile"] = icc_profile
self.icclist = None self.icclist = []
for i in range(6, len(s), 3): for i in range(6, len(s), 3):
t = s[i : i + 3] t = s[i : i + 3]
@ -593,9 +593,9 @@ def convert_dict_qtables(qtables):
def get_sampling(im): def get_sampling(im):
# There's no subsampling when image have only 1 layer # There's no subsampling when images have only 1 layer
# (grayscale images) or when they are CMYK (4 layers), # (grayscale images) or when they are CMYK (4 layers),
# so set subsampling to default value. # so set subsampling to the default value.
# #
# NOTE: currently Pillow can't encode JPEG to YCCK format. # NOTE: currently Pillow can't encode JPEG to YCCK format.
# If YCCK support is added in the future, subsampling code will have # If YCCK support is added in the future, subsampling code will have

View File

@ -68,8 +68,9 @@ ImagingFind(const char* name)
#else #else
id = atol(name); id = atol(name);
#endif #endif
if (!id) if (!id) {
return NULL; return NULL;
}
return (Imaging) id; return (Imaging) id;
} }
@ -119,10 +120,11 @@ PyImagingPhotoPut(ClientData clientdata, Tcl_Interp* interp,
block.offset[0] = 0; block.offset[0] = 0;
block.offset[1] = 1; block.offset[1] = 1;
block.offset[2] = 2; block.offset[2] = 2;
if (strcmp(im->mode, "RGBA") == 0) if (strcmp(im->mode, "RGBA") == 0) {
block.offset[3] = 3; /* alpha (or reserved, under 8.2) */ block.offset[3] = 3; /* alpha (or reserved, under 8.2) */
else } else {
block.offset[3] = 0; /* no alpha */ block.offset[3] = 0; /* no alpha */
}
} else { } else {
TCL_APPEND_RESULT(interp, "Bad mode", (char*) NULL); TCL_APPEND_RESULT(interp, "Bad mode", (char*) NULL);
return TCL_ERROR; return TCL_ERROR;
@ -136,10 +138,11 @@ PyImagingPhotoPut(ClientData clientdata, Tcl_Interp* interp,
if (TK_LT_85) { /* Tk 8.4 */ if (TK_LT_85) { /* Tk 8.4 */
TK_PHOTO_PUT_BLOCK_84(photo, &block, 0, 0, block.width, block.height, TK_PHOTO_PUT_BLOCK_84(photo, &block, 0, 0, block.width, block.height,
TK_PHOTO_COMPOSITE_SET); TK_PHOTO_COMPOSITE_SET);
if (strcmp(im->mode, "RGBA") == 0) if (strcmp(im->mode, "RGBA") == 0) {
/* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */ /* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */
/* (fixed in Tk 8.5a3) */ /* (fixed in Tk 8.5a3) */
TK_PHOTO_SET_SIZE_84(photo, block.width, block.height); TK_PHOTO_SET_SIZE_84(photo, block.width, block.height);
}
} else { } else {
/* Tk >=8.5 */ /* Tk >=8.5 */
TK_PHOTO_PUT_BLOCK_85(interp, photo, &block, 0, 0, block.width, TK_PHOTO_PUT_BLOCK_85(interp, photo, &block, 0, 0, block.width,

File diff suppressed because it is too large Load Diff

View File

@ -88,8 +88,9 @@ cms_profile_new(cmsHPROFILE profile)
CmsProfileObject* self; CmsProfileObject* self;
self = PyObject_New(CmsProfileObject, &CmsProfile_Type); self = PyObject_New(CmsProfileObject, &CmsProfile_Type);
if (!self) if (!self) {
return NULL; return NULL;
}
self->profile = profile; self->profile = profile;
@ -102,8 +103,9 @@ cms_profile_open(PyObject* self, PyObject* args)
cmsHPROFILE hProfile; cmsHPROFILE hProfile;
char* sProfile; char* sProfile;
if (!PyArg_ParseTuple(args, "s:profile_open", &sProfile)) if (!PyArg_ParseTuple(args, "s:profile_open", &sProfile)) {
return NULL; return NULL;
}
hProfile = cmsOpenProfileFromFile(sProfile, "r"); hProfile = cmsOpenProfileFromFile(sProfile, "r");
if (!hProfile) { if (!hProfile) {
@ -121,8 +123,9 @@ cms_profile_fromstring(PyObject* self, PyObject* args)
char* pProfile; char* pProfile;
Py_ssize_t nProfile; Py_ssize_t nProfile;
if (!PyArg_ParseTuple(args, "y#:profile_frombytes", &pProfile, &nProfile)) if (!PyArg_ParseTuple(args, "y#:profile_frombytes", &pProfile, &nProfile)) {
return NULL; return NULL;
}
hProfile = cmsOpenProfileFromMem(pProfile, nProfile); hProfile = cmsOpenProfileFromMem(pProfile, nProfile);
if (!hProfile) { if (!hProfile) {
@ -198,8 +201,9 @@ cms_transform_new(cmsHTRANSFORM transform, char* mode_in, char* mode_out)
CmsTransformObject* self; CmsTransformObject* self;
self = PyObject_New(CmsTransformObject, &CmsTransform_Type); self = PyObject_New(CmsTransformObject, &CmsTransform_Type);
if (!self) if (!self) {
return NULL; return NULL;
}
self->transform = transform; self->transform = transform;
@ -292,17 +296,19 @@ pyCMSgetAuxChannelChannel (cmsUInt32Number format, int auxChannelNdx)
if (T_SWAPFIRST(format) && T_DOSWAP(format)) { if (T_SWAPFIRST(format) && T_DOSWAP(format)) {
// reverse order, before anything but last extra is shifted last // reverse order, before anything but last extra is shifted last
if (auxChannelNdx == numExtras - 1) if (auxChannelNdx == numExtras - 1) {
return numColors + numExtras - 1; return numColors + numExtras - 1;
else } else {
return numExtras - 2 - auxChannelNdx; return numExtras - 2 - auxChannelNdx;
}
} }
else if (T_SWAPFIRST(format)) { else if (T_SWAPFIRST(format)) {
// in order, after color channels, but last extra is shifted to first // in order, after color channels, but last extra is shifted to first
if (auxChannelNdx == numExtras - 1) if (auxChannelNdx == numExtras - 1) {
return 0; return 0;
else } else {
return numColors + 1 + auxChannelNdx; return numColors + 1 + auxChannelNdx;
}
} }
else if (T_DOSWAP(format)) { else if (T_DOSWAP(format)) {
// reverse order, before anything // reverse order, before anything
@ -330,23 +336,26 @@ pyCMScopyAux (cmsHTRANSFORM hTransform, Imaging imDst, const Imaging imSrc)
int e; int e;
// trivially copied // trivially copied
if (imDst == imSrc) if (imDst == imSrc) {
return; return;
}
dstLCMSFormat = cmsGetTransformOutputFormat(hTransform); dstLCMSFormat = cmsGetTransformOutputFormat(hTransform);
srcLCMSFormat = cmsGetTransformInputFormat(hTransform); srcLCMSFormat = cmsGetTransformInputFormat(hTransform);
// currently, all Pillow formats are chunky formats, but check it anyway // currently, all Pillow formats are chunky formats, but check it anyway
if (T_PLANAR(dstLCMSFormat) || T_PLANAR(srcLCMSFormat)) if (T_PLANAR(dstLCMSFormat) || T_PLANAR(srcLCMSFormat)) {
return; return;
}
// copy only if channel format is identical, except OPTIMIZED is ignored as it // copy only if channel format is identical, except OPTIMIZED is ignored as it
// does not affect the aux channel // does not affect the aux channel
if (T_FLOAT(dstLCMSFormat) != T_FLOAT(srcLCMSFormat) if (T_FLOAT(dstLCMSFormat) != T_FLOAT(srcLCMSFormat)
|| T_FLAVOR(dstLCMSFormat) != T_FLAVOR(srcLCMSFormat) || T_FLAVOR(dstLCMSFormat) != T_FLAVOR(srcLCMSFormat)
|| T_ENDIAN16(dstLCMSFormat) != T_ENDIAN16(srcLCMSFormat) || T_ENDIAN16(dstLCMSFormat) != T_ENDIAN16(srcLCMSFormat)
|| T_BYTES(dstLCMSFormat) != T_BYTES(srcLCMSFormat)) || T_BYTES(dstLCMSFormat) != T_BYTES(srcLCMSFormat)) {
return; return;
}
numSrcExtras = T_EXTRA(srcLCMSFormat); numSrcExtras = T_EXTRA(srcLCMSFormat);
numDstExtras = T_EXTRA(dstLCMSFormat); numDstExtras = T_EXTRA(dstLCMSFormat);
@ -367,8 +376,9 @@ pyCMScopyAux (cmsHTRANSFORM hTransform, Imaging imDst, const Imaging imSrc)
char* pDstExtras = imDst->image[y] + dstChannel * channelSize; char* pDstExtras = imDst->image[y] + dstChannel * channelSize;
const char* pSrcExtras = imSrc->image[y] + srcChannel * channelSize; const char* pSrcExtras = imSrc->image[y] + srcChannel * channelSize;
for (x = 0; x < xSize; x++) for (x = 0; x < xSize; x++) {
memcpy(pDstExtras + x * dstChunkSize, pSrcExtras + x * srcChunkSize, channelSize); memcpy(pDstExtras + x * dstChunkSize, pSrcExtras + x * srcChunkSize, channelSize);
}
} }
} }
} }
@ -378,14 +388,16 @@ pyCMSdoTransform(Imaging im, Imaging imOut, cmsHTRANSFORM hTransform)
{ {
int i; int i;
if (im->xsize > imOut->xsize || im->ysize > imOut->ysize) if (im->xsize > imOut->xsize || im->ysize > imOut->ysize) {
return -1; return -1;
}
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
// transform color channels only // transform color channels only
for (i = 0; i < im->ysize; i++) for (i = 0; i < im->ysize; i++) {
cmsDoTransform(hTransform, im->image[i], imOut->image[i], im->xsize); cmsDoTransform(hTransform, im->image[i], imOut->image[i], im->xsize);
}
// lcms by default does nothing to the auxiliary channels leaving those // lcms by default does nothing to the auxiliary channels leaving those
// unchanged. To do "the right thing" here, i.e. maintain identical results // unchanged. To do "the right thing" here, i.e. maintain identical results
@ -417,8 +429,9 @@ _buildTransform(cmsHPROFILE hInputProfile, cmsHPROFILE hOutputProfile, char *sIn
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (!hTransform) if (!hTransform) {
PyErr_SetString(PyExc_ValueError, "cannot build transform"); PyErr_SetString(PyExc_ValueError, "cannot build transform");
}
return hTransform; /* if NULL, an exception is set */ return hTransform; /* if NULL, an exception is set */
} }
@ -442,8 +455,9 @@ _buildProofTransform(cmsHPROFILE hInputProfile, cmsHPROFILE hOutputProfile, cmsH
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (!hTransform) if (!hTransform) {
PyErr_SetString(PyExc_ValueError, "cannot build proof transform"); PyErr_SetString(PyExc_ValueError, "cannot build proof transform");
}
return hTransform; /* if NULL, an exception is set */ return hTransform; /* if NULL, an exception is set */
} }
@ -462,13 +476,15 @@ buildTransform(PyObject *self, PyObject *args) {
cmsHTRANSFORM transform = NULL; cmsHTRANSFORM transform = NULL;
if (!PyArg_ParseTuple(args, "O!O!ss|ii:buildTransform", &CmsProfile_Type, &pInputProfile, &CmsProfile_Type, &pOutputProfile, &sInMode, &sOutMode, &iRenderingIntent, &cmsFLAGS)) if (!PyArg_ParseTuple(args, "O!O!ss|ii:buildTransform", &CmsProfile_Type, &pInputProfile, &CmsProfile_Type, &pOutputProfile, &sInMode, &sOutMode, &iRenderingIntent, &cmsFLAGS)) {
return NULL; return NULL;
}
transform = _buildTransform(pInputProfile->profile, pOutputProfile->profile, sInMode, sOutMode, iRenderingIntent, cmsFLAGS); transform = _buildTransform(pInputProfile->profile, pOutputProfile->profile, sInMode, sOutMode, iRenderingIntent, cmsFLAGS);
if (!transform) if (!transform) {
return NULL; return NULL;
}
return cms_transform_new(transform, sInMode, sOutMode); return cms_transform_new(transform, sInMode, sOutMode);
} }
@ -487,13 +503,15 @@ buildProofTransform(PyObject *self, PyObject *args)
cmsHTRANSFORM transform = NULL; cmsHTRANSFORM transform = NULL;
if (!PyArg_ParseTuple(args, "O!O!O!ss|iii:buildProofTransform", &CmsProfile_Type, &pInputProfile, &CmsProfile_Type, &pOutputProfile, &CmsProfile_Type, &pProofProfile, &sInMode, &sOutMode, &iRenderingIntent, &iProofIntent, &cmsFLAGS)) if (!PyArg_ParseTuple(args, "O!O!O!ss|iii:buildProofTransform", &CmsProfile_Type, &pInputProfile, &CmsProfile_Type, &pOutputProfile, &CmsProfile_Type, &pProofProfile, &sInMode, &sOutMode, &iRenderingIntent, &iProofIntent, &cmsFLAGS)) {
return NULL; return NULL;
}
transform = _buildProofTransform(pInputProfile->profile, pOutputProfile->profile, pProofProfile->profile, sInMode, sOutMode, iRenderingIntent, iProofIntent, cmsFLAGS); transform = _buildProofTransform(pInputProfile->profile, pOutputProfile->profile, pProofProfile->profile, sInMode, sOutMode, iRenderingIntent, iProofIntent, cmsFLAGS);
if (!transform) if (!transform) {
return NULL; return NULL;
}
return cms_transform_new(transform, sInMode, sOutMode); return cms_transform_new(transform, sInMode, sOutMode);
@ -509,8 +527,9 @@ cms_transform_apply(CmsTransformObject *self, PyObject *args)
int result; int result;
if (!PyArg_ParseTuple(args, "nn:apply", &idIn, &idOut)) if (!PyArg_ParseTuple(args, "nn:apply", &idIn, &idOut)) {
return NULL; return NULL;
}
im = (Imaging) idIn; im = (Imaging) idIn;
imOut = (Imaging) idOut; imOut = (Imaging) idOut;
@ -532,8 +551,9 @@ createProfile(PyObject *self, PyObject *args)
cmsCIExyY whitePoint; cmsCIExyY whitePoint;
cmsBool result; cmsBool result;
if (!PyArg_ParseTuple(args, "s|d:createProfile", &sColorSpace, &dColorTemp)) if (!PyArg_ParseTuple(args, "s|d:createProfile", &sColorSpace, &dColorTemp)) {
return NULL; return NULL;
}
if (strcmp(sColorSpace, "LAB") == 0) { if (strcmp(sColorSpace, "LAB") == 0) {
if (dColorTemp > 0.0) { if (dColorTemp > 0.0) {
@ -575,8 +595,9 @@ cms_profile_is_intent_supported(CmsProfileObject *self, PyObject *args)
int intent; int intent;
int direction; int direction;
if (!PyArg_ParseTuple(args, "ii:is_intent_supported", &intent, &direction)) if (!PyArg_ParseTuple(args, "ii:is_intent_supported", &intent, &direction)) {
return NULL; return NULL;
}
result = cmsIsIntentSupported(self->profile, intent, direction); result = cmsIsIntentSupported(self->profile, intent, direction);
@ -602,8 +623,9 @@ 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(args, "|" F_HANDLE "i:get_display_profile", &handle, &is_dc)) if (!PyArg_ParseTuple(args, "|" F_HANDLE "i:get_display_profile", &handle, &is_dc)) {
return NULL; return NULL;
}
filename_size = sizeof(filename); filename_size = sizeof(filename);
@ -615,8 +637,9 @@ cms_get_display_profile_win32(PyObject* self, PyObject* args)
ReleaseDC((HWND) handle, dc); ReleaseDC((HWND) handle, dc);
} }
if (ok) if (ok) {
return PyUnicode_FromStringAndSize(filename, filename_size-1); return PyUnicode_FromStringAndSize(filename, filename_size-1);
}
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
@ -745,10 +768,11 @@ _profile_read_ciexyz(CmsProfileObject* self, cmsTagSignature info, int multi)
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
if (multi) if (multi) {
return _xyz3_py(XYZ); return _xyz3_py(XYZ);
else } else {
return _xyz_py(XYZ); return _xyz_py(XYZ);
}
} }
static PyObject* static PyObject*
@ -826,8 +850,9 @@ static cmsBool _calculate_rgb_primaries(CmsProfileObject* self, cmsCIEXYZTRIPLE*
// double array of RGB values with max on each identity // double array of RGB values with max on each identity
hXYZ = cmsCreateXYZProfile(); hXYZ = cmsCreateXYZProfile();
if (hXYZ == NULL) if (hXYZ == NULL) {
return 0; return 0;
}
// transform from our profile to XYZ using doubles for highest precision // transform from our profile to XYZ using doubles for highest precision
hTransform = cmsCreateTransform(self->profile, TYPE_RGB_DBL, hTransform = cmsCreateTransform(self->profile, TYPE_RGB_DBL,
@ -835,8 +860,9 @@ static cmsBool _calculate_rgb_primaries(CmsProfileObject* self, cmsCIEXYZTRIPLE*
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;
}
cmsDoTransform(hTransform, (void*) input, result, 3); cmsDoTransform(hTransform, (void*) input, result, 3);
cmsDeleteTransform(hTransform); cmsDeleteTransform(hTransform);
@ -881,8 +907,9 @@ _is_intent_supported(CmsProfileObject* self, int clut)
/* Only valid for ICC Intents (otherwise we read invalid memory in lcms cmsio1.c). */ /* Only valid for ICC Intents (otherwise we read invalid memory in lcms cmsio1.c). */
if (!(intent == INTENT_PERCEPTUAL || intent == INTENT_RELATIVE_COLORIMETRIC if (!(intent == INTENT_PERCEPTUAL || intent == INTENT_RELATIVE_COLORIMETRIC
|| intent == INTENT_SATURATION || intent == INTENT_ABSOLUTE_COLORIMETRIC)) || intent == INTENT_SATURATION || intent == INTENT_ABSOLUTE_COLORIMETRIC)) {
continue; continue;
}
id = PyLong_FromLong((long) intent); id = PyLong_FromLong((long) intent);
entry = Py_BuildValue("(OOO)", entry = Py_BuildValue("(OOO)",
@ -1276,8 +1303,9 @@ cms_profile_getattr_red_primary(CmsProfileObject* self, void* closure)
cmsBool result = 0; cmsBool result = 0;
cmsCIEXYZTRIPLE primaries; cmsCIEXYZTRIPLE primaries;
if (cmsIsMatrixShaper(self->profile)) if (cmsIsMatrixShaper(self->profile)) {
result = _calculate_rgb_primaries(self, &primaries); result = _calculate_rgb_primaries(self, &primaries);
}
if (! result) { if (! result) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
@ -1292,8 +1320,9 @@ cms_profile_getattr_green_primary(CmsProfileObject* self, void* closure)
cmsBool result = 0; cmsBool result = 0;
cmsCIEXYZTRIPLE primaries; cmsCIEXYZTRIPLE primaries;
if (cmsIsMatrixShaper(self->profile)) if (cmsIsMatrixShaper(self->profile)) {
result = _calculate_rgb_primaries(self, &primaries); result = _calculate_rgb_primaries(self, &primaries);
}
if (! result) { if (! result) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
@ -1308,8 +1337,9 @@ cms_profile_getattr_blue_primary(CmsProfileObject* self, void* closure)
cmsBool result = 0; cmsBool result = 0;
cmsCIEXYZTRIPLE primaries; cmsCIEXYZTRIPLE primaries;
if (cmsIsMatrixShaper(self->profile)) if (cmsIsMatrixShaper(self->profile)) {
result = _calculate_rgb_primaries(self, &primaries); result = _calculate_rgb_primaries(self, &primaries);
}
if (! result) { if (! result) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
@ -1387,12 +1417,13 @@ cms_profile_getattr_icc_measurement_condition (CmsProfileObject* self, void* clo
return Py_None; return Py_None;
} }
if (mc->Geometry == 1) if (mc->Geometry == 1) {
geo = "45/0, 0/45"; geo = "45/0, 0/45";
else if (mc->Geometry == 2) } else if (mc->Geometry == 2) {
geo = "0d, d/0"; geo = "0d, d/0";
else } else {
geo = "unknown"; geo = "unknown";
}
return Py_BuildValue("{s:i,s:(ddd),s:s,s:d,s:s}", return Py_BuildValue("{s:i,s:(ddd),s:s,s:d,s:s}",
"observer", mc->Observer, "observer", mc->Observer,
@ -1611,8 +1642,9 @@ PyInit__imagingcms(void) {
m = PyModule_Create(&module_def); m = PyModule_Create(&module_def);
if (setup_module(m) < 0) if (setup_module(m) < 0) {
return NULL; return NULL;
}
PyDateTime_IMPORT; PyDateTime_IMPORT;

View File

@ -137,11 +137,12 @@ geterror(int code)
{ {
int i; int i;
for (i = 0; ft_errors[i].message; i++) for (i = 0; ft_errors[i].message; i++) {
if (ft_errors[i].code == code) { if (ft_errors[i].code == code) {
PyErr_SetString(PyExc_OSError, ft_errors[i].message); PyErr_SetString(PyExc_OSError, ft_errors[i].message);
return NULL; return NULL;
} }
}
PyErr_SetString(PyExc_OSError, "unknown freetype error"); PyErr_SetString(PyExc_OSError, "unknown freetype error");
return NULL; return NULL;
@ -274,8 +275,9 @@ getfont(PyObject* self_, PyObject* args, PyObject* kw)
self = PyObject_New(FontObject, &Font_Type); self = PyObject_New(FontObject, &Font_Type);
if (!self) { if (!self) {
if (filename) if (filename) {
PyMem_Free(filename); PyMem_Free(filename);
}
return NULL; return NULL;
} }
@ -299,8 +301,9 @@ getfont(PyObject* self_, PyObject* args, PyObject* kw)
} }
} }
if (!error) if (!error) {
error = FT_Set_Pixel_Sizes(self->face, 0, size); error = FT_Set_Pixel_Sizes(self->face, 0, size);
}
if (!error && encoding && strlen((char*) encoding) == 4) { if (!error && encoding && strlen((char*) encoding) == 4) {
FT_Encoding encoding_tag = FT_MAKE_TAG( FT_Encoding encoding_tag = FT_MAKE_TAG(
@ -308,8 +311,9 @@ getfont(PyObject* self_, PyObject* args, PyObject* kw)
); );
error = FT_Select_Charmap(self->face, encoding_tag); error = FT_Select_Charmap(self->face, encoding_tag);
} }
if (filename) if (filename) {
PyMem_Free(filename); PyMem_Free(filename);
}
if (error) { if (error) {
if (self->font_bytes) { if (self->font_bytes) {
@ -327,8 +331,9 @@ static int
font_getchar(PyObject* string, int index, FT_ULong* char_out) font_getchar(PyObject* string, int index, FT_ULong* char_out)
{ {
if (PyUnicode_Check(string)) { if (PyUnicode_Check(string)) {
if (index >= PyUnicode_GET_LENGTH(string)) if (index >= PyUnicode_GET_LENGTH(string)) {
return 0; return 0;
}
*char_out = PyUnicode_READ_CHAR(string, index); *char_out = PyUnicode_READ_CHAR(string, index);
return 1; return 1;
} }
@ -401,11 +406,11 @@ text_layout_raqm(PyObject* string, FontObject* self, const char* dir, PyObject *
direction = RAQM_DIRECTION_DEFAULT; direction = RAQM_DIRECTION_DEFAULT;
if (dir) { if (dir) {
if (strcmp(dir, "rtl") == 0) if (strcmp(dir, "rtl") == 0) {
direction = RAQM_DIRECTION_RTL; direction = RAQM_DIRECTION_RTL;
else if (strcmp(dir, "ltr") == 0) } else if (strcmp(dir, "ltr") == 0) {
direction = RAQM_DIRECTION_LTR; direction = RAQM_DIRECTION_LTR;
else if (strcmp(dir, "ttb") == 0) { } else if (strcmp(dir, "ttb") == 0) {
direction = RAQM_DIRECTION_TTB; direction = RAQM_DIRECTION_TTB;
if (p_raqm.version_atleast == NULL || !(*p_raqm.version_atleast)(0, 7, 0)) { if (p_raqm.version_atleast == NULL || !(*p_raqm.version_atleast)(0, 7, 0)) {
PyErr_SetString(PyExc_ValueError, "libraqm 0.7 or greater required for 'ttb' direction"); PyErr_SetString(PyExc_ValueError, "libraqm 0.7 or greater required for 'ttb' direction");
@ -443,8 +448,9 @@ text_layout_raqm(PyObject* string, FontObject* self, const char* dir, PyObject *
if (PyUnicode_Check(item)) { if (PyUnicode_Check(item)) {
bytes = PyUnicode_AsUTF8String(item); bytes = PyUnicode_AsUTF8String(item);
if (bytes == NULL) if (bytes == NULL) {
goto failed; goto failed;
}
feature = PyBytes_AS_STRING(bytes); feature = PyBytes_AS_STRING(bytes);
size = PyBytes_GET_SIZE(bytes); size = PyBytes_GET_SIZE(bytes);
} }
@ -608,8 +614,9 @@ font_getsize(FontObject* self, PyObject* args)
/* calculate size and bearing for a given string */ /* calculate size and bearing for a given string */
PyObject* string; PyObject* string;
if (!PyArg_ParseTuple(args, "O|zOz:getsize", &string, &dir, &features, &lang)) if (!PyArg_ParseTuple(args, "O|zOz:getsize", &string, &dir, &features, &lang)) {
return NULL; return NULL;
}
count = text_layout(string, self, dir, features, lang, &glyph_info, 0); count = text_layout(string, self, dir, features, lang, &glyph_info, 0);
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
@ -631,8 +638,9 @@ font_getsize(FontObject* self, PyObject* args)
* Yifu Yu<root@jackyyf.com>, 2014-10-15 * Yifu Yu<root@jackyyf.com>, 2014-10-15
*/ */
error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP); error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP);
if (error) if (error) {
return geterror(error); return geterror(error);
}
if (i == 0) { if (i == 0) {
if (horizontal_dir) { if (horizontal_dir) {
@ -657,21 +665,26 @@ font_getsize(FontObject* self, PyObject* args)
offset = glyph_info[i].x_advance - offset = glyph_info[i].x_advance -
face->glyph->metrics.width - face->glyph->metrics.width -
face->glyph->metrics.horiBearingX; face->glyph->metrics.horiBearingX;
if (offset < 0) if (offset < 0) {
x_advanced -= offset; x_advanced -= offset;
if (x_advanced > x_max) }
if (x_advanced > x_max) {
x_max = x_advanced; x_max = x_advanced;
}
bbox.yMax += glyph_info[i].y_offset; bbox.yMax += glyph_info[i].y_offset;
bbox.yMin += glyph_info[i].y_offset; bbox.yMin += glyph_info[i].y_offset;
if (bbox.yMax > y_max) if (bbox.yMax > y_max) {
y_max = bbox.yMax; y_max = bbox.yMax;
if (bbox.yMin < y_min) }
if (bbox.yMin < y_min) {
y_min = bbox.yMin; y_min = bbox.yMin;
}
// find max distance of baseline from top // find max distance of baseline from top
if (face->glyph->metrics.horiBearingY > yoffset) if (face->glyph->metrics.horiBearingY > yoffset) {
yoffset = face->glyph->metrics.horiBearingY; yoffset = face->glyph->metrics.horiBearingY;
}
} else { } else {
y_max -= glyph_info[i].y_advance; y_max -= glyph_info[i].y_advance;
@ -681,14 +694,17 @@ font_getsize(FontObject* self, PyObject* args)
offset = -glyph_info[i].y_advance - offset = -glyph_info[i].y_advance -
face->glyph->metrics.height - face->glyph->metrics.height -
face->glyph->metrics.vertBearingY; face->glyph->metrics.vertBearingY;
if (offset < 0) if (offset < 0) {
y_max -= offset; y_max -= offset;
}
} }
if (bbox.xMax > x_max) if (bbox.xMax > x_max) {
x_max = bbox.xMax; x_max = bbox.xMax;
if (i == 0 || bbox.xMin < x_min) }
if (i == 0 || bbox.xMin < x_min) {
x_min = bbox.xMin; x_min = bbox.xMin;
}
} }
FT_Done_Glyph(glyph); FT_Done_Glyph(glyph);
@ -702,20 +718,22 @@ font_getsize(FontObject* self, PyObject* args)
if (face) { if (face) {
if (horizontal_dir) { if (horizontal_dir) {
// left bearing // left bearing
if (xoffset < 0) if (xoffset < 0) {
x_max -= xoffset; x_max -= xoffset;
else } else {
xoffset = 0; xoffset = 0;
}
/* difference between the font ascender and the distance of /* difference between the font ascender and the distance of
* the baseline from the top */ * the baseline from the top */
yoffset = PIXEL(self->face->size->metrics.ascender - yoffset); yoffset = PIXEL(self->face->size->metrics.ascender - yoffset);
} else { } else {
// top bearing // top bearing
if (yoffset < 0) if (yoffset < 0) {
y_max -= yoffset; y_max -= yoffset;
else } else {
yoffset = 0; yoffset = 0;
}
} }
} }
@ -800,8 +818,9 @@ font_render(FontObject* self, PyObject* args)
temp = bitmap.rows - glyph_slot->bitmap_top; temp = bitmap.rows - glyph_slot->bitmap_top;
temp -= PIXEL(glyph_info[i].y_offset); temp -= PIXEL(glyph_info[i].y_offset);
if (temp > ascender) if (temp > ascender) {
ascender = temp; ascender = temp;
}
} }
if (stroker == NULL) { if (stroker == NULL) {
@ -855,10 +874,12 @@ font_render(FontObject* self, PyObject* args)
x0 = 0; x0 = 0;
x1 = bitmap.width; x1 = bitmap.width;
if (xx < 0) if (xx < 0) {
x0 = -xx; x0 = -xx;
if (xx + x1 > im->xsize) }
if (xx + x1 > im->xsize) {
x1 = im->xsize - xx; x1 = im->xsize - xx;
}
source = (unsigned char*) bitmap.buffer; source = (unsigned char*) bitmap.buffer;
for (bitmap_y = 0; bitmap_y < bitmap.rows; bitmap_y++) { for (bitmap_y = 0; bitmap_y < bitmap.rows; bitmap_y++) {
@ -876,8 +897,9 @@ font_render(FontObject* self, PyObject* args)
// use monochrome mask (on palette images, etc) // use monochrome mask (on palette images, etc)
int j, k, m = 128; int j, k, m = 128;
for (j = k = 0; j < x1; j++) { for (j = k = 0; j < x1; j++) {
if (j >= x0 && (source[k] & m)) if (j >= x0 && (source[k] & m)) {
target[j] = 255; target[j] = 255;
}
if (!(m >>= 1)) { if (!(m >>= 1)) {
m = 128; m = 128;
k++; k++;
@ -887,8 +909,9 @@ font_render(FontObject* self, PyObject* args)
// use antialiased rendering // use antialiased rendering
int k; int k;
for (k = x0; k < x1; k++) { for (k = x0; k < x1; k++) {
if (target[k] < source[k]) if (target[k] < source[k]) {
target[k] = source[k]; target[k] = source[k];
}
} }
} }
} }
@ -919,8 +942,9 @@ font_render(FontObject* self, PyObject* args)
PyObject *list_names, *list_name; PyObject *list_names, *list_name;
error = FT_Get_MM_Var(self->face, &master); error = FT_Get_MM_Var(self->face, &master);
if (error) if (error) {
return geterror(error); return geterror(error);
}
num_namedstyles = master->num_namedstyles; num_namedstyles = master->num_namedstyles;
list_names = PyList_New(num_namedstyles); list_names = PyList_New(num_namedstyles);
@ -928,12 +952,14 @@ font_render(FontObject* self, PyObject* args)
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) {
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 (PyList_GetItem(list_names, j) != NULL) {
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);
@ -958,8 +984,9 @@ font_render(FontObject* self, PyObject* args)
FT_SfntName name; FT_SfntName name;
PyObject *list_axes, *list_axis, *axis_name; PyObject *list_axes, *list_axis, *axis_name;
error = FT_Get_MM_Var(self->face, &master); error = FT_Get_MM_Var(self->face, &master);
if (error) if (error) {
return geterror(error); return geterror(error);
}
num_axis = master->num_axis; num_axis = master->num_axis;
name_count = FT_Get_Sfnt_Name_Count(self->face); name_count = FT_Get_Sfnt_Name_Count(self->face);
@ -978,8 +1005,9 @@ font_render(FontObject* self, PyObject* args)
for (j = 0; j < name_count; j++) { for (j = 0; j < name_count; j++) {
error = FT_Get_Sfnt_Name(self->face, j, &name); error = FT_Get_Sfnt_Name(self->face, j, &name);
if (error) if (error) {
return geterror(error); return geterror(error);
}
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);
@ -1002,12 +1030,14 @@ font_render(FontObject* self, PyObject* args)
int error; int error;
int instance_index; int instance_index;
if (!PyArg_ParseTuple(args, "i", &instance_index)) if (!PyArg_ParseTuple(args, "i", &instance_index)) {
return NULL; return NULL;
}
error = FT_Set_Named_Instance(self->face, instance_index); error = FT_Set_Named_Instance(self->face, instance_index);
if (error) if (error) {
return geterror(error); return geterror(error);
}
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
@ -1022,8 +1052,9 @@ font_render(FontObject* self, PyObject* args)
Py_ssize_t i, num_coords; Py_ssize_t i, num_coords;
FT_Fixed *coords; FT_Fixed *coords;
FT_Fixed coord; FT_Fixed coord;
if (!PyArg_ParseTuple(args, "O", &axes)) if (!PyArg_ParseTuple(args, "O", &axes)) {
return NULL; return NULL;
}
if (!PyList_Check(axes)) { if (!PyList_Check(axes)) {
PyErr_SetString(PyExc_TypeError, "argument must be a list"); PyErr_SetString(PyExc_TypeError, "argument must be a list");
@ -1037,13 +1068,13 @@ font_render(FontObject* self, PyObject* args)
} }
for (i = 0; i < num_coords; i++) { for (i = 0; i < num_coords; i++) {
item = PyList_GET_ITEM(axes, i); item = PyList_GET_ITEM(axes, i);
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)) {
coord = (float) PyLong_AS_LONG(item); coord = (float) PyLong_AS_LONG(item);
else if (PyNumber_Check(item)) } else if (PyNumber_Check(item)) {
coord = PyFloat_AsDouble(item); coord = PyFloat_AsDouble(item);
else { } else {
free(coords); free(coords);
PyErr_SetString(PyExc_TypeError, "list must contain numbers"); PyErr_SetString(PyExc_TypeError, "list must contain numbers");
return NULL; return NULL;
@ -1053,8 +1084,9 @@ font_render(FontObject* self, PyObject* args)
error = FT_Set_Var_Design_Coordinates(self->face, num_coords, coords); error = FT_Set_Var_Design_Coordinates(self->face, num_coords, coords);
free(coords); free(coords);
if (error) if (error) {
return geterror(error); return geterror(error);
}
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
@ -1090,16 +1122,18 @@ static PyMethodDef font_methods[] = {
static PyObject* static PyObject*
font_getattr_family(FontObject* self, void* closure) font_getattr_family(FontObject* self, void* closure)
{ {
if (self->face->family_name) if (self->face->family_name) {
return PyUnicode_FromString(self->face->family_name); return PyUnicode_FromString(self->face->family_name);
}
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static PyObject* static PyObject*
font_getattr_style(FontObject* self, void* closure) font_getattr_style(FontObject* self, void* closure)
{ {
if (self->face->style_name) if (self->face->style_name) {
return PyUnicode_FromString(self->face->style_name); return PyUnicode_FromString(self->face->style_name);
}
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@ -1200,8 +1234,9 @@ setup_module(PyObject* m) {
/* Ready object type */ /* Ready object type */
PyType_Ready(&Font_Type); PyType_Ready(&Font_Type);
if (FT_Init_FreeType(&library)) if (FT_Init_FreeType(&library)) {
return 0; /* leave it uninitialized */ return 0; /* leave it uninitialized */
}
FT_Library_Version(library, &major, &minor, &patch); FT_Library_Version(library, &major, &minor, &patch);
@ -1230,8 +1265,9 @@ PyInit__imagingft(void) {
m = PyModule_Create(&module_def); m = PyModule_Create(&module_def);
if (setup_module(m) < 0) if (setup_module(m) < 0) {
return NULL; return NULL;
}
return m; return m;
} }

View File

@ -88,12 +88,14 @@ void name(Imaging out, Imaging im1, Imaging im2)\
static int powi(int x, int y) static int powi(int x, int y)
{ {
double v = pow(x, y) + 0.5; double v = pow(x, y) + 0.5;
if (errno == EDOM) if (errno == EDOM) {
return 0; return 0;
if (v < MIN_INT32) }
if (v < MIN_INT32) {
v = MIN_INT32; v = MIN_INT32;
else if (v > MAX_INT32) } else if (v > MAX_INT32) {
v = MAX_INT32; v = MAX_INT32;
}
return (int) v; return (int) v;
} }
@ -167,8 +169,9 @@ _unop(PyObject* self, PyObject* args)
void (*unop)(Imaging, Imaging); void (*unop)(Imaging, Imaging);
Py_ssize_t op, i0, i1; Py_ssize_t op, i0, i1;
if (!PyArg_ParseTuple(args, "nnn", &op, &i0, &i1)) if (!PyArg_ParseTuple(args, "nnn", &op, &i0, &i1)) {
return NULL; return NULL;
}
out = (Imaging) i0; out = (Imaging) i0;
im1 = (Imaging) i1; im1 = (Imaging) i1;
@ -190,8 +193,9 @@ _binop(PyObject* self, PyObject* args)
void (*binop)(Imaging, Imaging, Imaging); void (*binop)(Imaging, Imaging, Imaging);
Py_ssize_t op, i0, i1, i2; Py_ssize_t op, i0, i1, i2;
if (!PyArg_ParseTuple(args, "nnnn", &op, &i0, &i1, &i2)) if (!PyArg_ParseTuple(args, "nnnn", &op, &i0, &i1, &i2)) {
return NULL; return NULL;
}
out = (Imaging) i0; out = (Imaging) i0;
im1 = (Imaging) i1; im1 = (Imaging) i1;
@ -215,8 +219,9 @@ static void
install(PyObject *d, char* name, void* value) install(PyObject *d, char* name, void* value)
{ {
PyObject *v = PyLong_FromSsize_t((Py_ssize_t) value); PyObject *v = PyLong_FromSsize_t((Py_ssize_t) value);
if (!v || PyDict_SetItemString(d, name, v)) if (!v || PyDict_SetItemString(d, name, v)) {
PyErr_Clear(); PyErr_Clear();
}
Py_XDECREF(v); Py_XDECREF(v);
} }
@ -286,8 +291,9 @@ PyInit__imagingmath(void) {
m = PyModule_Create(&module_def); m = PyModule_Create(&module_def);
if (setup_module(m) < 0) if (setup_module(m) < 0) {
return NULL; return NULL;
}
return m; return m;
} }

View File

@ -85,8 +85,9 @@ apply(PyObject *self, PyObject* args)
/* zero boundary conditions. TBD support other modes */ /* zero boundary conditions. TBD support other modes */
outrow[0] = outrow[width-1] = 0; outrow[0] = outrow[width-1] = 0;
if (row_idx==0 || row_idx == height-1) { if (row_idx==0 || row_idx == height-1) {
for(col_idx=0; col_idx<width; col_idx++) for(col_idx=0; col_idx<width; col_idx++) {
outrow[col_idx] = 0; outrow[col_idx] = 0;
}
continue; continue;
} }
@ -286,8 +287,9 @@ PyInit__imagingmorph(void) {
m = PyModule_Create(&module_def); m = PyModule_Create(&module_def);
if (setup_module(m) < 0) if (setup_module(m) < 0) {
return NULL; return NULL;
}
return m; return m;
} }

View File

@ -38,12 +38,13 @@ _tkinit(PyObject* self, PyObject* args)
PyObject* arg; PyObject* arg;
int is_interp; int is_interp;
if (!PyArg_ParseTuple(args, "Oi", &arg, &is_interp)) if (!PyArg_ParseTuple(args, "Oi", &arg, &is_interp)) {
return NULL; return NULL;
}
if (is_interp) if (is_interp) {
interp = (Tcl_Interp*)PyLong_AsVoidPtr(arg); interp = (Tcl_Interp*)PyLong_AsVoidPtr(arg);
else { } else {
TkappObject* app; TkappObject* app;
/* Do it the hard way. This will break if the TkappObject /* Do it the hard way. This will break if the TkappObject
layout changes */ layout changes */

View File

@ -724,8 +724,9 @@ PyObject* WebPDecode_wrapper(PyObject* self, PyObject* args)
WebPData exif_data = {0}; WebPData exif_data = {0};
WebPMux* mux = WebPMuxCreate(&data, copy_data); WebPMux* mux = WebPMuxCreate(&data, copy_data);
if (NULL == mux) if (NULL == mux) {
goto end; goto end;
}
if (WEBP_MUX_OK != WebPMuxGetFrame(mux, 1, &image)) if (WEBP_MUX_OK != WebPMuxGetFrame(mux, 1, &image))
{ {
@ -738,11 +739,13 @@ PyObject* WebPDecode_wrapper(PyObject* self, PyObject* args)
vp8_status_code = WebPDecode(webp, size, &config); vp8_status_code = WebPDecode(webp, size, &config);
if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "ICCP", &icc_profile_data)) if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "ICCP", &icc_profile_data)) {
icc_profile = PyBytes_FromStringAndSize((const char*)icc_profile_data.bytes, icc_profile_data.size); icc_profile = PyBytes_FromStringAndSize((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((const char*)exif_data.bytes, exif_data.size); exif = PyBytes_FromStringAndSize((const char*)exif_data.bytes, exif_data.size);
}
WebPDataClear(&image.bitstream); WebPDataClear(&image.bitstream);
WebPMuxDelete(mux); WebPMuxDelete(mux);
@ -750,8 +753,9 @@ PyObject* WebPDecode_wrapper(PyObject* self, PyObject* args)
#endif #endif
} }
if (vp8_status_code != VP8_STATUS_OK) if (vp8_status_code != VP8_STATUS_OK) {
goto end; goto end;
}
if (config.output.colorspace < MODE_YUV) { if (config.output.colorspace < MODE_YUV) {
bytes = PyBytes_FromStringAndSize((char*)config.output.u.RGBA.rgba, bytes = PyBytes_FromStringAndSize((char*)config.output.u.RGBA.rgba,
@ -777,8 +781,9 @@ end:
Py_XDECREF(icc_profile); Py_XDECREF(icc_profile);
Py_XDECREF(exif); Py_XDECREF(exif);
if (Py_None == ret) if (Py_None == ret) {
Py_RETURN_NONE; Py_RETURN_NONE;
}
return ret; return ret;
} }
@ -847,8 +852,9 @@ static int setup_module(PyObject* m) {
#ifdef HAVE_WEBPANIM #ifdef HAVE_WEBPANIM
/* Ready object types */ /* Ready object types */
if (PyType_Ready(&WebPAnimDecoder_Type) < 0 || if (PyType_Ready(&WebPAnimDecoder_Type) < 0 ||
PyType_Ready(&WebPAnimEncoder_Type) < 0) PyType_Ready(&WebPAnimEncoder_Type) < 0) {
return -1; return -1;
}
#endif #endif
return 0; return 0;
} }
@ -866,8 +872,9 @@ PyInit__webp(void) {
}; };
m = PyModule_Create(&module_def); m = PyModule_Create(&module_def);
if (setup_module(m) < 0) if (setup_module(m) < 0) {
return NULL; return NULL;
}
return m; return m;
} }

View File

@ -63,12 +63,14 @@ PyImaging_DecoderNew(int contextsize)
ImagingDecoderObject *decoder; ImagingDecoderObject *decoder;
void *context; void *context;
if(PyType_Ready(&ImagingDecoderType) < 0) if(PyType_Ready(&ImagingDecoderType) < 0) {
return NULL; return NULL;
}
decoder = PyObject_New(ImagingDecoderObject, &ImagingDecoderType); decoder = PyObject_New(ImagingDecoderObject, &ImagingDecoderType);
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
/* Clear the decoder state */ /* Clear the decoder state */
memset(&decoder->state, 0, sizeof(decoder->state)); memset(&decoder->state, 0, sizeof(decoder->state));
@ -81,8 +83,9 @@ PyImaging_DecoderNew(int contextsize)
(void) PyErr_NoMemory(); (void) PyErr_NoMemory();
return NULL; return NULL;
} }
} else } else {
context = 0; context = 0;
}
/* Initialize decoder context */ /* Initialize decoder context */
decoder->state.context = context; decoder->state.context = context;
@ -104,8 +107,9 @@ PyImaging_DecoderNew(int contextsize)
static void static void
_dealloc(ImagingDecoderObject* decoder) _dealloc(ImagingDecoderObject* decoder)
{ {
if (decoder->cleanup) if (decoder->cleanup) {
decoder->cleanup(&decoder->state); decoder->cleanup(&decoder->state);
}
free(decoder->state.buffer); free(decoder->state.buffer);
free(decoder->state.context); free(decoder->state.context);
Py_XDECREF(decoder->lock); Py_XDECREF(decoder->lock);
@ -121,8 +125,9 @@ _decode(ImagingDecoderObject* decoder, PyObject* args)
int status; int status;
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
if (!PyArg_ParseTuple(args, "y#", &buffer, &bufsize)) if (!PyArg_ParseTuple(args, "y#", &buffer, &bufsize)) {
return NULL; return NULL;
}
if (!decoder->pulls_fd) { if (!decoder->pulls_fd) {
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
@ -164,11 +169,13 @@ _setimage(ImagingDecoderObject* decoder, PyObject* args)
x0 = y0 = x1 = y1 = 0; x0 = y0 = x1 = y1 = 0;
/* FIXME: should publish the ImagingType descriptor */ /* FIXME: should publish the ImagingType descriptor */
if (!PyArg_ParseTuple(args, "O|(iiii)", &op, &x0, &y0, &x1, &y1)) if (!PyArg_ParseTuple(args, "O|(iiii)", &op, &x0, &y0, &x1, &y1)) {
return NULL; return NULL;
}
im = PyImaging_AsImaging(op); im = PyImaging_AsImaging(op);
if (!im) if (!im) {
return NULL; return NULL;
}
decoder->im = im; decoder->im = im;
@ -203,8 +210,9 @@ _setimage(ImagingDecoderObject* decoder, PyObject* args)
} }
/* malloc check ok, overflow checked above */ /* malloc check ok, overflow checked above */
state->buffer = (UINT8*) malloc(state->bytes); state->buffer = (UINT8*) malloc(state->bytes);
if (!state->buffer) if (!state->buffer) {
return PyErr_NoMemory(); return PyErr_NoMemory();
}
} }
/* Keep a reference to the image object, to make sure it doesn't /* Keep a reference to the image object, to make sure it doesn't
@ -223,8 +231,9 @@ _setfd(ImagingDecoderObject* decoder, PyObject* args)
PyObject* fd; PyObject* fd;
ImagingCodecState state; ImagingCodecState state;
if (!PyArg_ParseTuple(args, "O", &fd)) if (!PyArg_ParseTuple(args, "O", &fd)) {
return NULL; return NULL;
}
state = &decoder->state; state = &decoder->state;
@ -330,8 +339,9 @@ PyImaging_BitDecoderNew(PyObject* self, PyObject* args)
int sign = 0; int sign = 0;
int ystep = 1; int ystep = 1;
if (!PyArg_ParseTuple(args, "s|iiiii", &mode, &bits, &pad, &fill, if (!PyArg_ParseTuple(args, "s|iiiii", &mode, &bits, &pad, &fill,
&sign, &ystep)) &sign, &ystep)) {
return NULL; return NULL;
}
if (strcmp(mode, "F") != 0) { if (strcmp(mode, "F") != 0) {
PyErr_SetString(PyExc_ValueError, "bad image mode"); PyErr_SetString(PyExc_ValueError, "bad image mode");
@ -339,8 +349,9 @@ PyImaging_BitDecoderNew(PyObject* self, PyObject* args)
} }
decoder = PyImaging_DecoderNew(sizeof(BITSTATE)); decoder = PyImaging_DecoderNew(sizeof(BITSTATE));
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
decoder->decode = ImagingBitDecode; decoder->decode = ImagingBitDecode;
@ -368,8 +379,9 @@ PyImaging_BcnDecoderNew(PyObject* self, PyObject* args)
char* actual; char* actual;
int n = 0; int n = 0;
int ystep = 1; int ystep = 1;
if (!PyArg_ParseTuple(args, "s|ii", &mode, &n, &ystep)) if (!PyArg_ParseTuple(args, "s|ii", &mode, &n, &ystep)) {
return NULL; return NULL;
}
switch (n) { switch (n) {
case 1: /* BC1: 565 color, 1-bit alpha */ case 1: /* BC1: 565 color, 1-bit alpha */
@ -394,8 +406,9 @@ PyImaging_BcnDecoderNew(PyObject* self, PyObject* args)
} }
decoder = PyImaging_DecoderNew(0); decoder = PyImaging_DecoderNew(0);
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
decoder->decode = ImagingBcnDecode; decoder->decode = ImagingBcnDecode;
decoder->state.state = n; decoder->state.state = n;
@ -415,8 +428,9 @@ PyImaging_FliDecoderNew(PyObject* self, PyObject* args)
ImagingDecoderObject* decoder; ImagingDecoderObject* decoder;
decoder = PyImaging_DecoderNew(0); decoder = PyImaging_DecoderNew(0);
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
decoder->decode = ImagingFliDecode; decoder->decode = ImagingFliDecode;
@ -436,8 +450,9 @@ PyImaging_GifDecoderNew(PyObject* self, PyObject* args)
char* mode; char* mode;
int bits = 8; int bits = 8;
int interlace = 0; int interlace = 0;
if (!PyArg_ParseTuple(args, "s|ii", &mode, &bits, &interlace)) if (!PyArg_ParseTuple(args, "s|ii", &mode, &bits, &interlace)) {
return NULL; return NULL;
}
if (strcmp(mode, "L") != 0 && strcmp(mode, "P") != 0) { if (strcmp(mode, "L") != 0 && strcmp(mode, "P") != 0) {
PyErr_SetString(PyExc_ValueError, "bad image mode"); PyErr_SetString(PyExc_ValueError, "bad image mode");
@ -445,8 +460,9 @@ PyImaging_GifDecoderNew(PyObject* self, PyObject* args)
} }
decoder = PyImaging_DecoderNew(sizeof(GIFDECODERSTATE)); decoder = PyImaging_DecoderNew(sizeof(GIFDECODERSTATE));
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
decoder->decode = ImagingGifDecode; decoder->decode = ImagingGifDecode;
@ -468,15 +484,18 @@ PyImaging_HexDecoderNew(PyObject* self, PyObject* args)
char* mode; char* mode;
char* rawmode; char* rawmode;
if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) {
return NULL; return NULL;
}
decoder = PyImaging_DecoderNew(0); decoder = PyImaging_DecoderNew(0);
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
if (get_unpacker(decoder, mode, rawmode) < 0) if (get_unpacker(decoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
decoder->decode = ImagingHexDecode; decoder->decode = ImagingHexDecode;
@ -504,17 +523,20 @@ PyImaging_LibTiffDecoderNew(PyObject* self, PyObject* args)
int fp; int fp;
uint32 ifdoffset; uint32 ifdoffset;
if (! PyArg_ParseTuple(args, "sssiI", &mode, &rawmode, &compname, &fp, &ifdoffset)) if (! PyArg_ParseTuple(args, "sssiI", &mode, &rawmode, &compname, &fp, &ifdoffset)) {
return NULL; return NULL;
}
TRACE(("new tiff decoder %s\n", compname)); TRACE(("new tiff decoder %s\n", compname));
decoder = PyImaging_DecoderNew(sizeof(TIFFSTATE)); decoder = PyImaging_DecoderNew(sizeof(TIFFSTATE));
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
if (get_unpacker(decoder, mode, rawmode) < 0) if (get_unpacker(decoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
if (! ImagingLibTiffInit(&decoder->state, fp, ifdoffset)) { if (! ImagingLibTiffInit(&decoder->state, fp, ifdoffset)) {
Py_DECREF(decoder); Py_DECREF(decoder);
@ -541,15 +563,18 @@ PyImaging_PackbitsDecoderNew(PyObject* self, PyObject* args)
char* mode; char* mode;
char* rawmode; char* rawmode;
if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) {
return NULL; return NULL;
}
decoder = PyImaging_DecoderNew(0); decoder = PyImaging_DecoderNew(0);
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
if (get_unpacker(decoder, mode, rawmode) < 0) if (get_unpacker(decoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
decoder->decode = ImagingPackbitsDecode; decoder->decode = ImagingPackbitsDecode;
@ -567,12 +592,14 @@ PyImaging_PcdDecoderNew(PyObject* self, PyObject* args)
ImagingDecoderObject* decoder; ImagingDecoderObject* decoder;
decoder = PyImaging_DecoderNew(0); decoder = PyImaging_DecoderNew(0);
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
/* Unpack from PhotoYCC to RGB */ /* Unpack from PhotoYCC to RGB */
if (get_unpacker(decoder, "RGB", "YCC;P") < 0) if (get_unpacker(decoder, "RGB", "YCC;P") < 0) {
return NULL; return NULL;
}
decoder->decode = ImagingPcdDecode; decoder->decode = ImagingPcdDecode;
@ -592,15 +619,18 @@ PyImaging_PcxDecoderNew(PyObject* self, PyObject* args)
char* mode; char* mode;
char* rawmode; char* rawmode;
int stride; int stride;
if (!PyArg_ParseTuple(args, "ssi", &mode, &rawmode, &stride)) if (!PyArg_ParseTuple(args, "ssi", &mode, &rawmode, &stride)) {
return NULL; return NULL;
}
decoder = PyImaging_DecoderNew(0); decoder = PyImaging_DecoderNew(0);
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
if (get_unpacker(decoder, mode, rawmode) < 0) if (get_unpacker(decoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
decoder->state.bytes = stride; decoder->state.bytes = stride;
@ -623,15 +653,18 @@ PyImaging_RawDecoderNew(PyObject* self, PyObject* args)
char* rawmode; char* rawmode;
int stride = 0; int stride = 0;
int ystep = 1; int ystep = 1;
if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &stride, &ystep)) if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &stride, &ystep)) {
return NULL; return NULL;
}
decoder = PyImaging_DecoderNew(sizeof(RAWSTATE)); decoder = PyImaging_DecoderNew(sizeof(RAWSTATE));
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
if (get_unpacker(decoder, mode, rawmode) < 0) if (get_unpacker(decoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
decoder->decode = ImagingRawDecode; decoder->decode = ImagingRawDecode;
@ -656,15 +689,18 @@ PyImaging_SgiRleDecoderNew(PyObject* self, PyObject* args)
char* rawmode; char* rawmode;
int ystep = 1; int ystep = 1;
int bpc = 1; int bpc = 1;
if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &ystep, &bpc)) if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &ystep, &bpc)) {
return NULL; return NULL;
}
decoder = PyImaging_DecoderNew(sizeof(SGISTATE)); decoder = PyImaging_DecoderNew(sizeof(SGISTATE));
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
if (get_unpacker(decoder, mode, rawmode) < 0) if (get_unpacker(decoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
decoder->pulls_fd = 1; decoder->pulls_fd = 1;
decoder->decode = ImagingSgiRleDecode; decoder->decode = ImagingSgiRleDecode;
@ -687,15 +723,18 @@ PyImaging_SunRleDecoderNew(PyObject* self, PyObject* args)
char* mode; char* mode;
char* rawmode; char* rawmode;
if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) {
return NULL; return NULL;
}
decoder = PyImaging_DecoderNew(0); decoder = PyImaging_DecoderNew(0);
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
if (get_unpacker(decoder, mode, rawmode) < 0) if (get_unpacker(decoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
decoder->decode = ImagingSunRleDecode; decoder->decode = ImagingSunRleDecode;
@ -716,15 +755,18 @@ PyImaging_TgaRleDecoderNew(PyObject* self, PyObject* args)
char* rawmode; char* rawmode;
int ystep = 1; int ystep = 1;
int depth = 8; int depth = 8;
if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &ystep, &depth)) if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &ystep, &depth)) {
return NULL; return NULL;
}
decoder = PyImaging_DecoderNew(0); decoder = PyImaging_DecoderNew(0);
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
if (get_unpacker(decoder, mode, rawmode) < 0) if (get_unpacker(decoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
decoder->decode = ImagingTgaRleDecode; decoder->decode = ImagingTgaRleDecode;
@ -745,11 +787,13 @@ PyImaging_XbmDecoderNew(PyObject* self, PyObject* args)
ImagingDecoderObject* decoder; ImagingDecoderObject* decoder;
decoder = PyImaging_DecoderNew(0); decoder = PyImaging_DecoderNew(0);
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
if (get_unpacker(decoder, "1", "1;R") < 0) if (get_unpacker(decoder, "1", "1;R") < 0) {
return NULL; return NULL;
}
decoder->decode = ImagingXbmDecode; decoder->decode = ImagingXbmDecode;
@ -773,15 +817,18 @@ PyImaging_ZipDecoderNew(PyObject* self, PyObject* args)
char* mode; char* mode;
char* rawmode; char* rawmode;
int interlaced = 0; int interlaced = 0;
if (!PyArg_ParseTuple(args, "ss|i", &mode, &rawmode, &interlaced)) if (!PyArg_ParseTuple(args, "ss|i", &mode, &rawmode, &interlaced)) {
return NULL; return NULL;
}
decoder = PyImaging_DecoderNew(sizeof(ZIPSTATE)); decoder = PyImaging_DecoderNew(sizeof(ZIPSTATE));
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
if (get_unpacker(decoder, mode, rawmode) < 0) if (get_unpacker(decoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
decoder->decode = ImagingZipDecode; decoder->decode = ImagingZipDecode;
decoder->cleanup = ImagingZipDecodeCleanup; decoder->cleanup = ImagingZipDecodeCleanup;
@ -826,15 +873,18 @@ PyImaging_JpegDecoderNew(PyObject* self, PyObject* args)
int draft = 0; int draft = 0;
if (!PyArg_ParseTuple(args, "ssz|ii", &mode, &rawmode, &jpegmode, if (!PyArg_ParseTuple(args, "ssz|ii", &mode, &rawmode, &jpegmode,
&scale, &draft)) &scale, &draft)) {
return NULL; return NULL;
}
if (!jpegmode) if (!jpegmode) {
jpegmode = ""; jpegmode = "";
}
decoder = PyImaging_DecoderNew(sizeof(JPEGSTATE)); decoder = PyImaging_DecoderNew(sizeof(JPEGSTATE));
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
// libjpeg-turbo supports different output formats. // libjpeg-turbo supports different output formats.
// We are choosing Pillow's native format (3 color bytes + 1 padding) // We are choosing Pillow's native format (3 color bytes + 1 padding)
@ -843,8 +893,9 @@ PyImaging_JpegDecoderNew(PyObject* self, PyObject* args)
rawmode = "RGBX"; rawmode = "RGBX";
} }
if (get_unpacker(decoder, mode, rawmode) < 0) if (get_unpacker(decoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
decoder->decode = ImagingJpegDecode; decoder->decode = ImagingJpegDecode;
decoder->cleanup = ImagingJpegDecodeCleanup; decoder->cleanup = ImagingJpegDecodeCleanup;
@ -882,21 +933,24 @@ PyImaging_Jpeg2KDecoderNew(PyObject* self, PyObject* args)
PY_LONG_LONG length = -1; PY_LONG_LONG length = -1;
if (!PyArg_ParseTuple(args, "ss|iiiL", &mode, &format, if (!PyArg_ParseTuple(args, "ss|iiiL", &mode, &format,
&reduce, &layers, &fd, &length)) &reduce, &layers, &fd, &length)) {
return NULL; return NULL;
}
if (strcmp(format, "j2k") == 0) if (strcmp(format, "j2k") == 0) {
codec_format = OPJ_CODEC_J2K; codec_format = OPJ_CODEC_J2K;
else if (strcmp(format, "jpt") == 0) } else if (strcmp(format, "jpt") == 0) {
codec_format = OPJ_CODEC_JPT; codec_format = OPJ_CODEC_JPT;
else if (strcmp(format, "jp2") == 0) } else if (strcmp(format, "jp2") == 0) {
codec_format = OPJ_CODEC_JP2; codec_format = OPJ_CODEC_JP2;
else } else {
return NULL; return NULL;
}
decoder = PyImaging_DecoderNew(sizeof(JPEG2KDECODESTATE)); decoder = PyImaging_DecoderNew(sizeof(JPEG2KDECODESTATE));
if (decoder == NULL) if (decoder == NULL) {
return NULL; return NULL;
}
decoder->pulls_fd = 1; decoder->pulls_fd = 1;
decoder->decode = ImagingJpeg2KDecode; decoder->decode = ImagingJpeg2KDecode;

View File

@ -52,12 +52,14 @@ _new(const char* mode, int xsize, int ysize)
{ {
ImagingDisplayObject *display; ImagingDisplayObject *display;
if (PyType_Ready(&ImagingDisplayType) < 0) if (PyType_Ready(&ImagingDisplayType) < 0) {
return NULL; return NULL;
}
display = PyObject_New(ImagingDisplayObject, &ImagingDisplayType); display = PyObject_New(ImagingDisplayObject, &ImagingDisplayType);
if (display == NULL) if (display == NULL) {
return NULL; return NULL;
}
display->dib = ImagingNewDIB(mode, xsize, ysize); display->dib = ImagingNewDIB(mode, xsize, ysize);
if (!display->dib) { if (!display->dib) {
@ -71,8 +73,9 @@ _new(const char* mode, int xsize, int ysize)
static void static void
_delete(ImagingDisplayObject* display) _delete(ImagingDisplayObject* display)
{ {
if (display->dib) if (display->dib) {
ImagingDeleteDIB(display->dib); ImagingDeleteDIB(display->dib);
}
PyObject_Del(display); PyObject_Del(display);
} }
@ -80,8 +83,9 @@ static PyObject*
_expose(ImagingDisplayObject* display, PyObject* args) _expose(ImagingDisplayObject* display, PyObject* args)
{ {
HDC hdc; HDC hdc;
if (!PyArg_ParseTuple(args, F_HANDLE, &hdc)) if (!PyArg_ParseTuple(args, F_HANDLE, &hdc)) {
return NULL; return NULL;
}
ImagingExposeDIB(display->dib, hdc); ImagingExposeDIB(display->dib, hdc);
@ -97,8 +101,9 @@ _draw(ImagingDisplayObject* display, PyObject* args)
int src[4]; int src[4];
if (!PyArg_ParseTuple(args, F_HANDLE "(iiii)(iiii)", &hdc, if (!PyArg_ParseTuple(args, F_HANDLE "(iiii)(iiii)", &hdc,
dst+0, dst+1, dst+2, dst+3, dst+0, dst+1, dst+2, dst+3,
src+0, src+1, src+2, src+3)) src+0, src+1, src+2, src+3)) {
return NULL; return NULL;
}
ImagingDrawDIB(display->dib, hdc, dst, src); ImagingDrawDIB(display->dib, hdc, dst, src);
@ -116,16 +121,20 @@ _paste(ImagingDisplayObject* display, PyObject* args)
PyObject* op; PyObject* op;
int xy[4]; int xy[4];
xy[0] = xy[1] = xy[2] = xy[3] = 0; xy[0] = xy[1] = xy[2] = xy[3] = 0;
if (!PyArg_ParseTuple(args, "O|(iiii)", &op, xy+0, xy+1, xy+2, xy+3)) if (!PyArg_ParseTuple(args, "O|(iiii)", &op, xy+0, xy+1, xy+2, xy+3)) {
return NULL; return NULL;
}
im = PyImaging_AsImaging(op); im = PyImaging_AsImaging(op);
if (!im) if (!im) {
return NULL; return NULL;
}
if (xy[2] <= xy[0]) if (xy[2] <= xy[0]) {
xy[2] = xy[0] + im->xsize; xy[2] = xy[0] + im->xsize;
if (xy[3] <= xy[1]) }
if (xy[3] <= xy[1]) {
xy[3] = xy[1] + im->ysize; xy[3] = xy[1] + im->ysize;
}
ImagingPasteDIB(display->dib, im, xy); ImagingPasteDIB(display->dib, im, xy);
@ -139,8 +148,9 @@ _query_palette(ImagingDisplayObject* display, PyObject* args)
HDC hdc; HDC hdc;
int status; int status;
if (!PyArg_ParseTuple(args, F_HANDLE, &hdc)) if (!PyArg_ParseTuple(args, F_HANDLE, &hdc)) {
return NULL; return NULL;
}
status = ImagingQueryPaletteDIB(display->dib, hdc); status = ImagingQueryPaletteDIB(display->dib, hdc);
@ -153,8 +163,9 @@ _getdc(ImagingDisplayObject* display, PyObject* args)
HWND window; HWND window;
HDC dc; HDC dc;
if (!PyArg_ParseTuple(args, F_HANDLE, &window)) if (!PyArg_ParseTuple(args, F_HANDLE, &window)) {
return NULL; return NULL;
}
dc = GetDC(window); dc = GetDC(window);
if (!dc) { if (!dc) {
@ -171,8 +182,9 @@ _releasedc(ImagingDisplayObject* display, PyObject* args)
HWND window; HWND window;
HDC dc; HDC dc;
if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, &window, &dc)) if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, &window, &dc)) {
return NULL; return NULL;
}
ReleaseDC(window, dc); ReleaseDC(window, dc);
@ -186,8 +198,9 @@ _frombytes(ImagingDisplayObject* display, PyObject* args)
char* ptr; char* ptr;
int bytes; int bytes;
if (!PyArg_ParseTuple(args, "y#:frombytes", &ptr, &bytes)) if (!PyArg_ParseTuple(args, "y#:frombytes", &ptr, &bytes)) {
return NULL; return NULL;
}
if (display->dib->ysize * display->dib->linesize != bytes) { if (display->dib->ysize * display->dib->linesize != bytes) {
PyErr_SetString(PyExc_ValueError, "wrong size"); PyErr_SetString(PyExc_ValueError, "wrong size");
@ -203,8 +216,9 @@ _frombytes(ImagingDisplayObject* display, PyObject* args)
static PyObject* static PyObject*
_tobytes(ImagingDisplayObject* display, PyObject* args) _tobytes(ImagingDisplayObject* display, PyObject* args)
{ {
if (!PyArg_ParseTuple(args, ":tobytes")) if (!PyArg_ParseTuple(args, ":tobytes")) {
return NULL; return NULL;
}
return PyBytes_FromStringAndSize( return PyBytes_FromStringAndSize(
display->dib->bits, display->dib->ysize * display->dib->linesize display->dib->bits, display->dib->ysize * display->dib->linesize
@ -284,12 +298,14 @@ PyImaging_DisplayWin32(PyObject* self, PyObject* args)
char *mode; char *mode;
int xsize, ysize; int xsize, ysize;
if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) {
return NULL; return NULL;
}
display = _new(mode, xsize, ysize); display = _new(mode, xsize, ysize);
if (display == NULL) if (display == NULL) {
return NULL; return NULL;
}
return (PyObject*) display; return (PyObject*) display;
} }
@ -324,8 +340,9 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
HMODULE user32; HMODULE user32;
Func_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContext_function; Func_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContext_function;
if (!PyArg_ParseTuple(args, "|ii", &includeLayeredWindows, &all_screens)) if (!PyArg_ParseTuple(args, "|ii", &includeLayeredWindows, &all_screens)) {
return NULL; return NULL;
}
/* step 1: create a memory DC large enough to hold the /* step 1: create a memory DC large enough to hold the
entire screen */ entire screen */
@ -361,25 +378,30 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
FreeLibrary(user32); FreeLibrary(user32);
bitmap = CreateCompatibleBitmap(screen, width, height); bitmap = CreateCompatibleBitmap(screen, width, height);
if (!bitmap) if (!bitmap) {
goto error; goto error;
}
if (!SelectObject(screen_copy, bitmap)) if (!SelectObject(screen_copy, bitmap)) {
goto error; goto error;
}
/* step 2: copy bits into memory DC bitmap */ /* step 2: copy bits into memory DC bitmap */
rop = SRCCOPY; rop = SRCCOPY;
if (includeLayeredWindows) if (includeLayeredWindows) {
rop |= CAPTUREBLT; rop |= CAPTUREBLT;
if (!BitBlt(screen_copy, 0, 0, width, height, screen, x, y, rop)) }
if (!BitBlt(screen_copy, 0, 0, width, height, screen, x, y, rop)) {
goto error; goto error;
}
/* step 3: extract bits from bitmap */ /* step 3: extract bits from bitmap */
buffer = PyBytes_FromStringAndSize(NULL, height * ((width*3 + 3) & -4)); buffer = PyBytes_FromStringAndSize(NULL, height * ((width*3 + 3) & -4));
if (!buffer) if (!buffer) {
return NULL; return NULL;
}
core.bcSize = sizeof(core); core.bcSize = sizeof(core);
core.bcWidth = width; core.bcWidth = width;
@ -387,8 +409,9 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
core.bcPlanes = 1; core.bcPlanes = 1;
core.bcBitCount = 24; core.bcBitCount = 24;
if (!GetDIBits(screen_copy, bitmap, 0, height, PyBytes_AS_STRING(buffer), if (!GetDIBits(screen_copy, bitmap, 0, height, PyBytes_AS_STRING(buffer),
(BITMAPINFO*) &core, DIB_RGB_COLORS)) (BITMAPINFO*) &core, DIB_RGB_COLORS)) {
goto error; goto error;
}
DeleteObject(bitmap); DeleteObject(bitmap);
DeleteDC(screen_copy); DeleteDC(screen_copy);
@ -418,12 +441,15 @@ static BOOL CALLBACK list_windows_callback(HWND hwnd, LPARAM lParam)
title_size = GetWindowTextLength(hwnd); title_size = GetWindowTextLength(hwnd);
if (title_size > 0) { if (title_size > 0) {
title = PyUnicode_FromStringAndSize(NULL, title_size); title = PyUnicode_FromStringAndSize(NULL, title_size);
if (title) if (title) {
GetWindowTextW(hwnd, PyUnicode_AS_UNICODE(title), title_size+1); GetWindowTextW(hwnd, PyUnicode_AS_UNICODE(title), title_size+1);
} else }
} else {
title = PyUnicode_FromString(""); title = PyUnicode_FromString("");
if (!title) }
if (!title) {
return 0; return 0;
}
/* get bounding boxes */ /* get bounding boxes */
GetClientRect(hwnd, &inner); GetClientRect(hwnd, &inner);
@ -434,15 +460,17 @@ static BOOL CALLBACK list_windows_callback(HWND hwnd, LPARAM lParam)
inner.left, inner.top, inner.right, inner.bottom, inner.left, inner.top, inner.right, inner.bottom,
outer.left, outer.top, outer.right, outer.bottom outer.left, outer.top, outer.right, outer.bottom
); );
if (!item) if (!item) {
return 0; return 0;
}
status = PyList_Append(window_list, item); status = PyList_Append(window_list, item);
Py_DECREF(item); Py_DECREF(item);
if (status < 0) if (status < 0) {
return 0; return 0;
}
return 1; return 1;
} }
@ -453,8 +481,9 @@ PyImaging_ListWindowsWin32(PyObject* self, PyObject* args)
PyObject* window_list; PyObject* window_list;
window_list = PyList_New(0); window_list = PyList_New(0);
if (!window_list) if (!window_list) {
return NULL; return NULL;
}
EnumWindows(list_windows_callback, (LPARAM) window_list); EnumWindows(list_windows_callback, (LPARAM) window_list);
@ -556,8 +585,9 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
GetWindowLongPtr(wnd, sizeof(PyObject*)); GetWindowLongPtr(wnd, sizeof(PyObject*));
current_threadstate = PyThreadState_Swap(NULL); current_threadstate = PyThreadState_Swap(NULL);
PyEval_RestoreThread(threadstate); PyEval_RestoreThread(threadstate);
} else } else {
return DefWindowProc(wnd, message, wParam, lParam); return DefWindowProc(wnd, message, wParam, lParam);
}
} }
/* process message */ /* process message */
@ -575,28 +605,31 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right, ps.rcPaint.bottom ps.rcPaint.right, ps.rcPaint.bottom
); );
if (result) if (result) {
Py_DECREF(result); Py_DECREF(result);
else } else {
callback_error("window damage callback"); callback_error("window damage callback");
}
result = PyObject_CallFunction( result = PyObject_CallFunction(
callback, "s" F_HANDLE "iiii", "clear", dc, callback, "s" F_HANDLE "iiii", "clear", dc,
0, 0, rect.right-rect.left, rect.bottom-rect.top 0, 0, rect.right-rect.left, rect.bottom-rect.top
); );
if (result) if (result) {
Py_DECREF(result); Py_DECREF(result);
else } else {
callback_error("window clear callback"); callback_error("window clear callback");
}
result = PyObject_CallFunction( result = PyObject_CallFunction(
callback, "s" F_HANDLE "iiii", "repair", dc, callback, "s" F_HANDLE "iiii", "repair", dc,
0, 0, rect.right-rect.left, rect.bottom-rect.top 0, 0, rect.right-rect.left, rect.bottom-rect.top
); );
if (result) if (result) {
Py_DECREF(result); Py_DECREF(result);
else } else {
callback_error("window repair callback"); callback_error("window repair callback");
}
ReleaseDC(wnd, dc); ReleaseDC(wnd, dc);
EndPaint(wnd, &ps); EndPaint(wnd, &ps);
@ -610,17 +643,19 @@ windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
if (result) { if (result) {
InvalidateRect(wnd, NULL, 1); InvalidateRect(wnd, NULL, 1);
Py_DECREF(result); Py_DECREF(result);
} else } else {
callback_error("window resize callback"); callback_error("window resize callback");
}
break; break;
case WM_DESTROY: case WM_DESTROY:
/* destroy window */ /* destroy window */
result = PyObject_CallFunction(callback, "s", "destroy"); result = PyObject_CallFunction(callback, "s", "destroy");
if (result) if (result) {
Py_DECREF(result); Py_DECREF(result);
else } else {
callback_error("window destroy callback"); callback_error("window destroy callback");
}
Py_DECREF(callback); Py_DECREF(callback);
break; break;
@ -646,13 +681,16 @@ PyImaging_CreateWindowWin32(PyObject* self, PyObject* args)
char* title; char* title;
PyObject* callback; PyObject* callback;
int width = 0, height = 0; int width = 0, height = 0;
if (!PyArg_ParseTuple(args, "sO|ii", &title, &callback, &width, &height)) if (!PyArg_ParseTuple(args, "sO|ii", &title, &callback, &width, &height)) {
return NULL; return NULL;
}
if (width <= 0) if (width <= 0) {
width = CW_USEDEFAULT; width = CW_USEDEFAULT;
if (height <= 0) }
if (height <= 0) {
height = CW_USEDEFAULT; height = CW_USEDEFAULT;
}
/* register toplevel window class */ /* register toplevel window class */
windowClass.style = CS_CLASSDC; windowClass.style = CS_CLASSDC;
@ -731,8 +769,9 @@ PyImaging_DrawWmf(PyObject* self, PyObject* args)
int width, height; int width, height;
int x0, y0, x1, y1; int x0, y0, x1, y1;
if (!PyArg_ParseTuple(args, "y#(ii)(iiii):_load", &data, &datasize, if (!PyArg_ParseTuple(args, "y#(ii)(iiii):_load", &data, &datasize,
&width, &height, &x0, &x1, &y0, &y1)) &width, &height, &x0, &x1, &y0, &y1)) {
return NULL; return NULL;
}
/* step 1: copy metafile contents into METAFILE object */ /* step 1: copy metafile contents into METAFILE object */
@ -806,8 +845,9 @@ PyImaging_DrawWmf(PyObject* self, PyObject* args)
error: error:
DeleteEnhMetaFile(meta); DeleteEnhMetaFile(meta);
if (bitmap) if (bitmap) {
DeleteObject(bitmap); DeleteObject(bitmap);
}
DeleteDC(dc); DeleteDC(dc);
@ -838,8 +878,9 @@ PyImaging_GrabScreenX11(PyObject* self, PyObject* args)
xcb_generic_error_t* error; xcb_generic_error_t* error;
PyObject* buffer = NULL; PyObject* buffer = NULL;
if (!PyArg_ParseTuple(args, "|z", &display_name)) if (!PyArg_ParseTuple(args, "|z", &display_name)) {
return NULL; return NULL;
}
/* connect to X and get screen data */ /* connect to X and get screen data */
@ -893,8 +934,9 @@ PyImaging_GrabScreenX11(PyObject* self, PyObject* args)
free(reply); free(reply);
xcb_disconnect(connection); xcb_disconnect(connection);
if (!buffer) if (!buffer) {
return NULL; return NULL;
}
return Py_BuildValue("(ii)N", width, height, buffer); return Py_BuildValue("(ii)N", width, height, buffer);
} }

View File

@ -55,12 +55,14 @@ PyImaging_EncoderNew(int contextsize)
ImagingEncoderObject *encoder; ImagingEncoderObject *encoder;
void *context; void *context;
if(PyType_Ready(&ImagingEncoderType) < 0) if(PyType_Ready(&ImagingEncoderType) < 0) {
return NULL; return NULL;
}
encoder = PyObject_New(ImagingEncoderObject, &ImagingEncoderType); encoder = PyObject_New(ImagingEncoderObject, &ImagingEncoderType);
if (encoder == NULL) if (encoder == NULL) {
return NULL; return NULL;
}
/* Clear the encoder state */ /* Clear the encoder state */
memset(&encoder->state, 0, sizeof(encoder->state)); memset(&encoder->state, 0, sizeof(encoder->state));
@ -73,8 +75,9 @@ PyImaging_EncoderNew(int contextsize)
(void) PyErr_NoMemory(); (void) PyErr_NoMemory();
return NULL; return NULL;
} }
} else } else {
context = 0; context = 0;
}
/* Initialize encoder context */ /* Initialize encoder context */
encoder->state.context = context; encoder->state.context = context;
@ -93,8 +96,9 @@ PyImaging_EncoderNew(int contextsize)
static void static void
_dealloc(ImagingEncoderObject* encoder) _dealloc(ImagingEncoderObject* encoder)
{ {
if (encoder->cleanup) if (encoder->cleanup) {
encoder->cleanup(&encoder->state); encoder->cleanup(&encoder->state);
}
free(encoder->state.buffer); free(encoder->state.buffer);
free(encoder->state.context); free(encoder->state.context);
Py_XDECREF(encoder->lock); Py_XDECREF(encoder->lock);
@ -125,19 +129,22 @@ _encode(ImagingEncoderObject* encoder, PyObject* args)
Py_ssize_t bufsize = 16384; Py_ssize_t bufsize = 16384;
if (!PyArg_ParseTuple(args, "|n", &bufsize)) if (!PyArg_ParseTuple(args, "|n", &bufsize)) {
return NULL; return NULL;
}
buf = PyBytes_FromStringAndSize(NULL, bufsize); buf = PyBytes_FromStringAndSize(NULL, bufsize);
if (!buf) if (!buf) {
return NULL; return NULL;
}
status = encoder->encode(encoder->im, &encoder->state, status = encoder->encode(encoder->im, &encoder->state,
(UINT8*) PyBytes_AsString(buf), bufsize); (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) {
return NULL; return NULL;
}
result = Py_BuildValue("iiO", status, encoder->state.errcode, buf); result = Py_BuildValue("iiO", status, encoder->state.errcode, buf);
@ -179,14 +186,16 @@ _encode_to_file(ImagingEncoderObject* encoder, PyObject* args)
Py_ssize_t fh; Py_ssize_t fh;
Py_ssize_t bufsize = 16384; Py_ssize_t bufsize = 16384;
if (!PyArg_ParseTuple(args, "n|n", &fh, &bufsize)) if (!PyArg_ParseTuple(args, "n|n", &fh, &bufsize)) {
return NULL; return NULL;
}
/* Allocate an encoder buffer */ /* Allocate an encoder buffer */
/* malloc check ok, either constant int, or checked by PyArg_ParseTuple */ /* malloc check ok, either constant int, or checked by PyArg_ParseTuple */
buf = (UINT8*) malloc(bufsize); buf = (UINT8*) malloc(bufsize);
if (!buf) if (!buf) {
return PyErr_NoMemory(); return PyErr_NoMemory();
}
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
@ -197,12 +206,13 @@ _encode_to_file(ImagingEncoderObject* encoder, PyObject* args)
status = encoder->encode(encoder->im, &encoder->state, buf, bufsize); status = encoder->encode(encoder->im, &encoder->state, buf, bufsize);
if (status > 0) if (status > 0) {
if (write(fh, buf, status) < 0) { if (write(fh, buf, status) < 0) {
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
free(buf); free(buf);
return PyErr_SetFromErrno(PyExc_OSError); return PyErr_SetFromErrno(PyExc_OSError);
} }
}
} while (encoder->state.errcode == 0); } while (encoder->state.errcode == 0);
@ -228,11 +238,13 @@ _setimage(ImagingEncoderObject* encoder, PyObject* args)
x0 = y0 = x1 = y1 = 0; x0 = y0 = x1 = y1 = 0;
/* FIXME: should publish the ImagingType descriptor */ /* FIXME: should publish the ImagingType descriptor */
if (!PyArg_ParseTuple(args, "O|(nnnn)", &op, &x0, &y0, &x1, &y1)) if (!PyArg_ParseTuple(args, "O|(nnnn)", &op, &x0, &y0, &x1, &y1)) {
return NULL; return NULL;
}
im = PyImaging_AsImaging(op); im = PyImaging_AsImaging(op);
if (!im) if (!im) {
return NULL; return NULL;
}
encoder->im = im; encoder->im = im;
@ -264,8 +276,9 @@ _setimage(ImagingEncoderObject* encoder, PyObject* args)
state->bytes = (state->bits * state->xsize+7)/8; state->bytes = (state->bits * state->xsize+7)/8;
/* malloc check ok, overflow checked above */ /* malloc check ok, overflow checked above */
state->buffer = (UINT8*) malloc(state->bytes); state->buffer = (UINT8*) malloc(state->bytes);
if (!state->buffer) if (!state->buffer) {
return PyErr_NoMemory(); return PyErr_NoMemory();
}
} }
/* Keep a reference to the image object, to make sure it doesn't /* Keep a reference to the image object, to make sure it doesn't
@ -284,8 +297,9 @@ _setfd(ImagingEncoderObject* encoder, PyObject* args)
PyObject* fd; PyObject* fd;
ImagingCodecState state; ImagingCodecState state;
if (!PyArg_ParseTuple(args, "O", &fd)) if (!PyArg_ParseTuple(args, "O", &fd)) {
return NULL; return NULL;
}
state = &encoder->state; state = &encoder->state;
@ -386,8 +400,9 @@ PyImaging_EpsEncoderNew(PyObject* self, PyObject* args)
ImagingEncoderObject* encoder; ImagingEncoderObject* encoder;
encoder = PyImaging_EncoderNew(0); encoder = PyImaging_EncoderNew(0);
if (encoder == NULL) if (encoder == NULL) {
return NULL; return NULL;
}
encoder->encode = ImagingEpsEncode; encoder->encode = ImagingEpsEncode;
@ -408,15 +423,18 @@ PyImaging_GifEncoderNew(PyObject* self, PyObject* args)
char *rawmode; char *rawmode;
Py_ssize_t bits = 8; Py_ssize_t bits = 8;
Py_ssize_t interlace = 0; Py_ssize_t interlace = 0;
if (!PyArg_ParseTuple(args, "ss|nn", &mode, &rawmode, &bits, &interlace)) if (!PyArg_ParseTuple(args, "ss|nn", &mode, &rawmode, &bits, &interlace)) {
return NULL; return NULL;
}
encoder = PyImaging_EncoderNew(sizeof(GIFENCODERSTATE)); encoder = PyImaging_EncoderNew(sizeof(GIFENCODERSTATE));
if (encoder == NULL) if (encoder == NULL) {
return NULL; return NULL;
}
if (get_packer(encoder, mode, rawmode) < 0) if (get_packer(encoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
encoder->encode = ImagingGifEncode; encoder->encode = ImagingGifEncode;
@ -473,15 +491,18 @@ PyImaging_RawEncoderNew(PyObject* self, PyObject* args)
Py_ssize_t stride = 0; Py_ssize_t stride = 0;
Py_ssize_t ystep = 1; Py_ssize_t ystep = 1;
if (!PyArg_ParseTuple(args, "ss|nn", &mode, &rawmode, &stride, &ystep)) if (!PyArg_ParseTuple(args, "ss|nn", &mode, &rawmode, &stride, &ystep)) {
return NULL; return NULL;
}
encoder = PyImaging_EncoderNew(0); encoder = PyImaging_EncoderNew(0);
if (encoder == NULL) if (encoder == NULL) {
return NULL; return NULL;
}
if (get_packer(encoder, mode, rawmode) < 0) if (get_packer(encoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
encoder->encode = ImagingRawEncode; encoder->encode = ImagingRawEncode;
@ -505,15 +526,18 @@ PyImaging_TgaRleEncoderNew(PyObject* self, PyObject* args)
char *rawmode; char *rawmode;
Py_ssize_t ystep = 1; Py_ssize_t ystep = 1;
if (!PyArg_ParseTuple(args, "ss|n", &mode, &rawmode, &ystep)) if (!PyArg_ParseTuple(args, "ss|n", &mode, &rawmode, &ystep)) {
return NULL; return NULL;
}
encoder = PyImaging_EncoderNew(0); encoder = PyImaging_EncoderNew(0);
if (encoder == NULL) if (encoder == NULL) {
return NULL; return NULL;
}
if (get_packer(encoder, mode, rawmode) < 0) if (get_packer(encoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
encoder->encode = ImagingTgaRleEncode; encoder->encode = ImagingTgaRleEncode;
@ -534,11 +558,13 @@ PyImaging_XbmEncoderNew(PyObject* self, PyObject* args)
ImagingEncoderObject* encoder; ImagingEncoderObject* encoder;
encoder = PyImaging_EncoderNew(0); encoder = PyImaging_EncoderNew(0);
if (encoder == NULL) if (encoder == NULL) {
return NULL; return NULL;
}
if (get_packer(encoder, "1", "1;R") < 0) if (get_packer(encoder, "1", "1;R") < 0) {
return NULL; return NULL;
}
encoder->encode = ImagingXbmEncode; encoder->encode = ImagingXbmEncode;
@ -569,19 +595,22 @@ PyImaging_ZipEncoderNew(PyObject* self, PyObject* args)
if (!PyArg_ParseTuple(args, "ss|nnny#", &mode, &rawmode, if (!PyArg_ParseTuple(args, "ss|nnny#", &mode, &rawmode,
&optimize, &optimize,
&compress_level, &compress_type, &compress_level, &compress_type,
&dictionary, &dictionary_size)) &dictionary, &dictionary_size)) {
return NULL; return NULL;
}
/* Copy to avoid referencing Python's memory */ /* Copy to avoid referencing Python's memory */
if (dictionary && dictionary_size > 0) { if (dictionary && dictionary_size > 0) {
/* malloc check ok, size comes from PyArg_ParseTuple */ /* malloc check ok, size comes from PyArg_ParseTuple */
char* p = malloc(dictionary_size); char* p = malloc(dictionary_size);
if (!p) if (!p) {
return PyErr_NoMemory(); return PyErr_NoMemory();
}
memcpy(p, dictionary, dictionary_size); memcpy(p, dictionary, dictionary_size);
dictionary = p; dictionary = p;
} else } else {
dictionary = NULL; dictionary = NULL;
}
encoder = PyImaging_EncoderNew(sizeof(ZIPSTATE)); encoder = PyImaging_EncoderNew(sizeof(ZIPSTATE));
if (encoder == NULL) { if (encoder == NULL) {
@ -597,9 +626,10 @@ PyImaging_ZipEncoderNew(PyObject* self, PyObject* args)
encoder->encode = ImagingZipEncode; encoder->encode = ImagingZipEncode;
encoder->cleanup = ImagingZipEncodeCleanup; encoder->cleanup = ImagingZipEncodeCleanup;
if (rawmode[0] == 'P') if (rawmode[0] == 'P') {
/* disable filtering */ /* disable filtering */
((ZIPSTATE*)encoder->state.context)->mode = ZIP_PNG_PALETTE; ((ZIPSTATE*)encoder->state.context)->mode = ZIP_PNG_PALETTE;
}
((ZIPSTATE*)encoder->state.context)->optimize = optimize; ((ZIPSTATE*)encoder->state.context)->optimize = optimize;
((ZIPSTATE*)encoder->state.context)->compress_level = compress_level; ((ZIPSTATE*)encoder->state.context)->compress_level = compress_level;
@ -675,11 +705,13 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
TRACE(("new tiff encoder %s fp: %d, filename: %s \n", compname, fp, filename)); TRACE(("new tiff encoder %s fp: %d, filename: %s \n", compname, fp, filename));
encoder = PyImaging_EncoderNew(sizeof(TIFFSTATE)); encoder = PyImaging_EncoderNew(sizeof(TIFFSTATE));
if (encoder == NULL) if (encoder == NULL) {
return NULL; return NULL;
}
if (get_packer(encoder, mode, rawmode) < 0) if (get_packer(encoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
if (! ImagingLibTiffEncodeInit(&encoder->state, filename, fp)) { if (! ImagingLibTiffEncodeInit(&encoder->state, filename, fp)) {
Py_DECREF(encoder); Py_DECREF(encoder);
@ -1027,12 +1059,14 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
&mode, &rawmode, &quality, &mode, &rawmode, &quality,
&progressive, &smooth, &optimize, &streamtype, &progressive, &smooth, &optimize, &streamtype,
&xdpi, &ydpi, &subsampling, &qtables, &extra, &extra_size, &xdpi, &ydpi, &subsampling, &qtables, &extra, &extra_size,
&rawExif, &rawExifLen)) &rawExif, &rawExifLen)) {
return NULL; return NULL;
}
encoder = PyImaging_EncoderNew(sizeof(JPEGENCODERSTATE)); encoder = PyImaging_EncoderNew(sizeof(JPEGENCODERSTATE));
if (encoder == NULL) if (encoder == NULL) {
return NULL; return NULL;
}
// libjpeg-turbo supports different output formats. // libjpeg-turbo supports different output formats.
// We are choosing Pillow's native format (3 color bytes + 1 padding) // We are choosing Pillow's native format (3 color bytes + 1 padding)
@ -1041,8 +1075,9 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
rawmode = "RGBX"; rawmode = "RGBX";
} }
if (get_packer(encoder, mode, rawmode) < 0) if (get_packer(encoder, mode, rawmode) < 0) {
return NULL; return NULL;
}
// Freed in JpegEncode, Case 5 // Freed in JpegEncode, Case 5
qarrays = get_qtables_arrays(qtables, &qtablesLen); qarrays = get_qtables_arrays(qtables, &qtablesLen);
@ -1050,24 +1085,29 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
if (extra && extra_size > 0) { if (extra && extra_size > 0) {
/* malloc check ok, length is from python parsearg */ /* malloc check ok, length is from python parsearg */
char* p = malloc(extra_size); // Freed in JpegEncode, Case 5 char* p = malloc(extra_size); // Freed in JpegEncode, Case 5
if (!p) if (!p) {
return PyErr_NoMemory(); return PyErr_NoMemory();
}
memcpy(p, extra, extra_size); memcpy(p, extra, extra_size);
extra = p; extra = p;
} else } else {
extra = NULL; extra = NULL;
}
if (rawExif && rawExifLen > 0) { if (rawExif && rawExifLen > 0) {
/* malloc check ok, length is from python parsearg */ /* malloc check ok, length is from python parsearg */
char* pp = malloc(rawExifLen); // Freed in JpegEncode, Case 5 char* pp = malloc(rawExifLen); // Freed in JpegEncode, Case 5
if (!pp) { if (!pp) {
if (extra) free(extra); if (extra) {
free(extra);
}
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
memcpy(pp, rawExif, rawExifLen); memcpy(pp, rawExif, rawExifLen);
rawExif = pp; rawExif = pp;
} else } else {
rawExif = NULL; rawExif = NULL;
}
encoder->encode = ImagingJpegEncode; encoder->encode = ImagingJpegEncode;
@ -1111,10 +1151,12 @@ j2k_decode_coord_tuple(PyObject *tuple, int *x, int *y)
*x = (int)PyLong_AsLong(PyTuple_GET_ITEM(tuple, 0)); *x = (int)PyLong_AsLong(PyTuple_GET_ITEM(tuple, 0));
*y = (int)PyLong_AsLong(PyTuple_GET_ITEM(tuple, 1)); *y = (int)PyLong_AsLong(PyTuple_GET_ITEM(tuple, 1));
if (*x < 0) if (*x < 0) {
*x = 0; *x = 0;
if (*y < 0) }
if (*y < 0) {
*y = 0; *y = 0;
}
} }
} }
@ -1144,45 +1186,50 @@ PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args)
&quality_mode, &quality_layers, &num_resolutions, &quality_mode, &quality_layers, &num_resolutions,
&cblk_size, &precinct_size, &cblk_size, &precinct_size,
&irreversible, &progression, &cinema_mode, &irreversible, &progression, &cinema_mode,
&fd)) &fd)) {
return NULL; return NULL;
}
if (strcmp (format, "j2k") == 0) if (strcmp (format, "j2k") == 0) {
codec_format = OPJ_CODEC_J2K; codec_format = OPJ_CODEC_J2K;
else if (strcmp (format, "jpt") == 0) } else if (strcmp (format, "jpt") == 0) {
codec_format = OPJ_CODEC_JPT; codec_format = OPJ_CODEC_JPT;
else if (strcmp (format, "jp2") == 0) } else if (strcmp (format, "jp2") == 0) {
codec_format = OPJ_CODEC_JP2; codec_format = OPJ_CODEC_JP2;
else } else {
return NULL; return NULL;
}
if (strcmp(progression, "LRCP") == 0) if (strcmp(progression, "LRCP") == 0) {
prog_order = OPJ_LRCP; prog_order = OPJ_LRCP;
else if (strcmp(progression, "RLCP") == 0) } else if (strcmp(progression, "RLCP") == 0) {
prog_order = OPJ_RLCP; prog_order = OPJ_RLCP;
else if (strcmp(progression, "RPCL") == 0) } else if (strcmp(progression, "RPCL") == 0) {
prog_order = OPJ_RPCL; prog_order = OPJ_RPCL;
else if (strcmp(progression, "PCRL") == 0) } else if (strcmp(progression, "PCRL") == 0) {
prog_order = OPJ_PCRL; prog_order = OPJ_PCRL;
else if (strcmp(progression, "CPRL") == 0) } else if (strcmp(progression, "CPRL") == 0) {
prog_order = OPJ_CPRL; prog_order = OPJ_CPRL;
else } else {
return NULL; return NULL;
}
if (strcmp(cinema_mode, "no") == 0) if (strcmp(cinema_mode, "no") == 0) {
cine_mode = OPJ_OFF; cine_mode = OPJ_OFF;
else if (strcmp(cinema_mode, "cinema2k-24") == 0) } else if (strcmp(cinema_mode, "cinema2k-24") == 0) {
cine_mode = OPJ_CINEMA2K_24; cine_mode = OPJ_CINEMA2K_24;
else if (strcmp(cinema_mode, "cinema2k-48") == 0) } else if (strcmp(cinema_mode, "cinema2k-48") == 0) {
cine_mode = OPJ_CINEMA2K_48; cine_mode = OPJ_CINEMA2K_48;
else if (strcmp(cinema_mode, "cinema4k-24") == 0) } else if (strcmp(cinema_mode, "cinema4k-24") == 0) {
cine_mode = OPJ_CINEMA4K_24; cine_mode = OPJ_CINEMA4K_24;
else } else {
return NULL; return NULL;
}
encoder = PyImaging_EncoderNew(sizeof(JPEG2KENCODESTATE)); encoder = PyImaging_EncoderNew(sizeof(JPEG2KENCODESTATE));
if (!encoder) if (!encoder) {
return NULL; return NULL;
}
encoder->encode = ImagingJpeg2KEncode; encoder->encode = ImagingJpeg2KEncode;
encoder->cleanup = ImagingJpeg2KEncodeCleanup; encoder->cleanup = ImagingJpeg2KEncodeCleanup;

View File

@ -22,8 +22,9 @@ static inline UINT32
hash(const char* mode) hash(const char* mode)
{ {
UINT32 i = ACCESS_TABLE_HASH; UINT32 i = ACCESS_TABLE_HASH;
while (*mode) while (*mode) {
i = ((i<<5) + i) ^ (UINT8) *mode++; i = ((i<<5) + i) ^ (UINT8) *mode++;
}
return i % ACCESS_TABLE_SIZE; return i % ACCESS_TABLE_SIZE;
} }
@ -149,10 +150,11 @@ get_pixel_32B(Imaging im, int x, int y, void* color)
static void static void
put_pixel(Imaging im, int x, int y, const void* color) put_pixel(Imaging im, int x, int y, const void* color)
{ {
if (im->image8) if (im->image8) {
im->image8[y][x] = *((UINT8*) color); im->image8[y][x] = *((UINT8*) color);
else } else {
memcpy(&im->image32[y][x], color, sizeof(INT32)); memcpy(&im->image32[y][x], color, sizeof(INT32));
}
} }
static void static void
@ -237,8 +239,9 @@ ImagingAccess
ImagingAccessNew(Imaging im) ImagingAccessNew(Imaging im)
{ {
ImagingAccess access = &access_table[hash(im->mode)]; ImagingAccess access = &access_table[hash(im->mode)];
if (im->mode[0] != access->mode[0] || strcmp(im->mode, access->mode) != 0) if (im->mode[0] != access->mode[0] || strcmp(im->mode, access->mode) != 0) {
return NULL; return NULL;
}
return access; return access;
} }

View File

@ -33,19 +33,22 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc)
if (!imDst || !imSrc || if (!imDst || !imSrc ||
strcmp(imDst->mode, "RGBA") || strcmp(imDst->mode, "RGBA") ||
imDst->type != IMAGING_TYPE_UINT8 || imDst->type != IMAGING_TYPE_UINT8 ||
imDst->bands != 4) imDst->bands != 4) {
return ImagingError_ModeError(); return ImagingError_ModeError();
}
if (strcmp(imDst->mode, imSrc->mode) || if (strcmp(imDst->mode, imSrc->mode) ||
imDst->type != imSrc->type || imDst->type != imSrc->type ||
imDst->bands != imSrc->bands || imDst->bands != imSrc->bands ||
imDst->xsize != imSrc->xsize || imDst->xsize != imSrc->xsize ||
imDst->ysize != imSrc->ysize) imDst->ysize != imSrc->ysize) {
return ImagingError_Mismatch(); return ImagingError_Mismatch();
}
imOut = ImagingNewDirty(imDst->mode, imDst->xsize, imDst->ysize); imOut = ImagingNewDirty(imDst->mode, imDst->xsize, imDst->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
for (y = 0; y < imDst->ysize; y++) { for (y = 0; y < imDst->ysize; y++) {
rgba8* dst = (rgba8*) imDst->image[y]; rgba8* dst = (rgba8*) imDst->image[y];

View File

@ -26,23 +26,28 @@ ImagingGetBand(Imaging imIn, int band)
int x, y; int x, y;
/* Check arguments */ /* Check arguments */
if (!imIn || imIn->type != IMAGING_TYPE_UINT8) if (!imIn || imIn->type != IMAGING_TYPE_UINT8) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (band < 0 || band >= imIn->bands) if (band < 0 || band >= imIn->bands) {
return (Imaging) ImagingError_ValueError("band index out of range"); return (Imaging) ImagingError_ValueError("band index out of range");
}
/* Shortcuts */ /* Shortcuts */
if (imIn->bands == 1) if (imIn->bands == 1) {
return ImagingCopy(imIn); return ImagingCopy(imIn);
}
/* Special case for LXXA etc */ /* Special case for LXXA etc */
if (imIn->bands == 2 && band == 1) if (imIn->bands == 2 && band == 1) {
band = 3; band = 3;
}
imOut = ImagingNewDirty("L", imIn->xsize, imIn->ysize); imOut = ImagingNewDirty("L", imIn->xsize, imIn->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
/* Extract band from image */ /* Extract band from image */
for (y = 0; y < imIn->ysize; y++) { for (y = 0; y < imIn->ysize; y++) {
@ -173,24 +178,29 @@ ImagingPutBand(Imaging imOut, Imaging imIn, int band)
int x, y; int x, y;
/* Check arguments */ /* Check arguments */
if (!imIn || imIn->bands != 1 || !imOut) if (!imIn || imIn->bands != 1 || !imOut) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (band < 0 || band >= imOut->bands) if (band < 0 || band >= imOut->bands) {
return (Imaging) ImagingError_ValueError("band index out of range"); return (Imaging) ImagingError_ValueError("band index out of range");
}
if (imIn->type != imOut->type || if (imIn->type != imOut->type ||
imIn->xsize != imOut->xsize || imIn->xsize != imOut->xsize ||
imIn->ysize != imOut->ysize) imIn->ysize != imOut->ysize) {
return (Imaging) ImagingError_Mismatch(); return (Imaging) ImagingError_Mismatch();
}
/* Shortcuts */ /* Shortcuts */
if (imOut->bands == 1) if (imOut->bands == 1) {
return ImagingCopy2(imOut, imIn); return ImagingCopy2(imOut, imIn);
}
/* Special case for LXXA etc */ /* Special case for LXXA etc */
if (imOut->bands == 2 && band == 1) if (imOut->bands == 2 && band == 1) {
band = 3; band = 3;
}
/* Insert band into image */ /* Insert band into image */
for (y = 0; y < imIn->ysize; y++) { for (y = 0; y < imIn->ysize; y++) {
@ -211,15 +221,18 @@ ImagingFillBand(Imaging imOut, int band, int color)
int x, y; int x, y;
/* Check arguments */ /* Check arguments */
if (!imOut || imOut->type != IMAGING_TYPE_UINT8) if (!imOut || imOut->type != IMAGING_TYPE_UINT8) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (band < 0 || band >= imOut->bands) if (band < 0 || band >= imOut->bands) {
return (Imaging) ImagingError_ValueError("band index out of range"); return (Imaging) ImagingError_ValueError("band index out of range");
}
/* Special case for LXXA etc */ /* Special case for LXXA etc */
if (imOut->bands == 2 && band == 1) if (imOut->bands == 2 && band == 1) {
band = 3; band = 3;
}
color = CLIP8(color); color = CLIP8(color);
@ -263,16 +276,18 @@ ImagingMerge(const char* mode, Imaging bands[4])
bandsCount = i; bandsCount = i;
imOut = ImagingNewDirty(mode, firstBand->xsize, firstBand->ysize); imOut = ImagingNewDirty(mode, firstBand->xsize, firstBand->ysize);
if ( ! imOut) if ( ! imOut) {
return NULL; return NULL;
}
if (imOut->bands != bandsCount) { if (imOut->bands != bandsCount) {
ImagingDelete(imOut); ImagingDelete(imOut);
return (Imaging) ImagingError_ValueError("wrong number of bands"); return (Imaging) ImagingError_ValueError("wrong number of bands");
} }
if (imOut->bands == 1) if (imOut->bands == 1) {
return ImagingCopy2(imOut, firstBand); return ImagingCopy2(imOut, firstBand);
}
if (imOut->bands == 2) { if (imOut->bands == 2) {
for (y = 0; y < imOut->ysize; y++) { for (y = 0; y < imOut->ysize; y++) {

View File

@ -610,15 +610,21 @@ static int bc6_unquantize(UINT16 v, int prec, int sign) {
int x; int x;
if (!sign) { if (!sign) {
x = v; x = v;
if (prec >= 15) return x; if (prec >= 15) {
if (x == 0) return 0; return x;
}
if (x == 0) {
return 0;
}
if (x == ((1 << prec) - 1)) { if (x == ((1 << prec) - 1)) {
return 0xffff; return 0xffff;
} }
return ((x << 15) + 0x4000) >> (prec - 1); return ((x << 15) + 0x4000) >> (prec - 1);
} else { } else {
x = (INT16)v; x = (INT16)v;
if (prec >= 16) return x; if (prec >= 16) {
return x;
}
if (x < 0) { if (x < 0) {
s = 1; s = 1;
x = -x; x = -x;
@ -820,7 +826,9 @@ static int decode_bcn(Imaging im, ImagingCodecState state, const UINT8* src, int
put_block(im, state, (const char *)col, sizeof(col[0]), C); \ put_block(im, state, (const char *)col, sizeof(col[0]), C); \
ptr += SZ; \ ptr += SZ; \
bytes -= SZ; \ bytes -= SZ; \
if (state->y >= ymax) return -1; \ if (state->y >= ymax) {\
return -1; \
}\
} \ } \
break break
@ -836,7 +844,9 @@ static int decode_bcn(Imaging im, ImagingCodecState state, const UINT8* src, int
put_block(im, state, (const char *)col, sizeof(col[0]), C); put_block(im, state, (const char *)col, sizeof(col[0]), C);
ptr += 16; ptr += 16;
bytes -= 16; bytes -= 16;
if (state->y >= ymax) return -1; \ if (state->y >= ymax) {\
return -1; \
}\
} }
break; break;
DECODE_LOOP(7, 16, rgba); DECODE_LOOP(7, 16, rgba);

View File

@ -43,15 +43,17 @@ ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
bitstate->mask = (1<<bitstate->bits)-1; bitstate->mask = (1<<bitstate->bits)-1;
if (bitstate->sign) if (bitstate->sign) {
bitstate->signmask = (1<<(bitstate->bits-1)); bitstate->signmask = (1<<(bitstate->bits-1));
}
/* check image orientation */ /* check image orientation */
if (state->ystep < 0) { if (state->ystep < 0) {
state->y = state->ysize-1; state->y = state->ysize-1;
state->ystep = -1; state->ystep = -1;
} else } else {
state->ystep = 1; state->ystep = 1;
}
state->state = 1; state->state = 1;
@ -67,12 +69,13 @@ ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
bytes--; bytes--;
/* get a byte from the input stream and insert in the bit buffer */ /* get a byte from the input stream and insert in the bit buffer */
if (bitstate->fill&1) if (bitstate->fill&1) {
/* fill MSB first */ /* fill MSB first */
bitstate->bitbuffer |= (unsigned long) byte << bitstate->bitcount; bitstate->bitbuffer |= (unsigned long) byte << bitstate->bitcount;
else } else {
/* fill LSB first */ /* fill LSB first */
bitstate->bitbuffer = (bitstate->bitbuffer << 8) | byte; bitstate->bitbuffer = (bitstate->bitbuffer << 8) | byte;
}
bitstate->bitcount += 8; bitstate->bitcount += 8;
@ -85,35 +88,39 @@ ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
if (bitstate->fill&2) { if (bitstate->fill&2) {
/* store LSB first */ /* store LSB first */
data = bitstate->bitbuffer & bitstate->mask; data = bitstate->bitbuffer & bitstate->mask;
if (bitstate->bitcount > 32) if (bitstate->bitcount > 32) {
/* bitbuffer overflow; restore it from last input byte */ /* bitbuffer overflow; restore it from last input byte */
bitstate->bitbuffer = byte >> (8 - (bitstate->bitcount - bitstate->bitbuffer = byte >> (8 - (bitstate->bitcount -
bitstate->bits)); bitstate->bits));
else } else {
bitstate->bitbuffer >>= bitstate->bits; bitstate->bitbuffer >>= bitstate->bits;
} else }
} else {
/* store MSB first */ /* store MSB first */
data = (bitstate->bitbuffer >> (bitstate->bitcount - data = (bitstate->bitbuffer >> (bitstate->bitcount -
bitstate->bits)) bitstate->bits))
& bitstate->mask; & bitstate->mask;
}
bitstate->bitcount -= bitstate->bits; bitstate->bitcount -= bitstate->bits;
if (bitstate->lutsize > 0) { if (bitstate->lutsize > 0) {
/* map through lookup table */ /* map through lookup table */
if (data <= 0) if (data <= 0) {
pixel = bitstate->lut[0]; pixel = bitstate->lut[0];
else if (data >= bitstate->lutsize) } else if (data >= bitstate->lutsize) {
pixel = bitstate->lut[bitstate->lutsize-1]; pixel = bitstate->lut[bitstate->lutsize-1];
else } else {
pixel = bitstate->lut[data]; pixel = bitstate->lut[data];
}
} else { } else {
/* convert */ /* convert */
if (data & bitstate->signmask) if (data & bitstate->signmask) {
/* image memory contains signed data */ /* image memory contains signed data */
pixel = (FLOAT32) (INT32) (data | ~bitstate->mask); pixel = (FLOAT32) (INT32) (data | ~bitstate->mask);
else } else {
pixel = (FLOAT32) data; pixel = (FLOAT32) data;
}
} }
*(FLOAT32*)(&im->image32[state->y][state->x]) = pixel; *(FLOAT32*)(&im->image32[state->y][state->x]) = pixel;
@ -128,8 +135,9 @@ ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
} }
state->x = 0; state->x = 0;
/* reset bit buffer */ /* reset bit buffer */
if (bitstate->pad > 0) if (bitstate->pad > 0) {
bitstate->bitcount = 0; bitstate->bitcount = 0;
}
} }
} }
} }

View File

@ -28,24 +28,28 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha)
/* Check arguments */ /* Check arguments */
if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8 if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8
|| imIn1->palette || strcmp(imIn1->mode, "1") == 0 || imIn1->palette || strcmp(imIn1->mode, "1") == 0
|| imIn2->palette || strcmp(imIn2->mode, "1") == 0) || imIn2->palette || strcmp(imIn2->mode, "1") == 0) {
return ImagingError_ModeError(); return ImagingError_ModeError();
}
if (imIn1->type != imIn2->type || if (imIn1->type != imIn2->type ||
imIn1->bands != imIn2->bands || imIn1->bands != imIn2->bands ||
imIn1->xsize != imIn2->xsize || imIn1->xsize != imIn2->xsize ||
imIn1->ysize != imIn2->ysize) imIn1->ysize != imIn2->ysize) {
return ImagingError_Mismatch(); return ImagingError_Mismatch();
}
/* Shortcuts */ /* Shortcuts */
if (alpha == 0.0) if (alpha == 0.0) {
return ImagingCopy(imIn1); return ImagingCopy(imIn1);
else if (alpha == 1.0) } else if (alpha == 1.0) {
return ImagingCopy(imIn2); return ImagingCopy(imIn2);
}
imOut = ImagingNewDirty(imIn1->mode, imIn1->xsize, imIn1->ysize); imOut = ImagingNewDirty(imIn1->mode, imIn1->xsize, imIn1->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
if (alpha >= 0 && alpha <= 1.0) { if (alpha >= 0 && alpha <= 1.0) {
/* Interpolate between bands */ /* Interpolate between bands */
@ -53,9 +57,10 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha)
UINT8* in1 = (UINT8*) imIn1->image[y]; UINT8* in1 = (UINT8*) imIn1->image[y];
UINT8* in2 = (UINT8*) imIn2->image[y]; UINT8* in2 = (UINT8*) imIn2->image[y];
UINT8* out = (UINT8*) imOut->image[y]; UINT8* out = (UINT8*) imOut->image[y];
for (x = 0; x < imIn1->linesize; x++) for (x = 0; x < imIn1->linesize; x++) {
out[x] = (UINT8) out[x] = (UINT8)
((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x])); ((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x]));
}
} }
} else { } else {
/* Extrapolation; must make sure to clip resulting values */ /* Extrapolation; must make sure to clip resulting values */
@ -66,12 +71,13 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha)
for (x = 0; x < imIn1->linesize; x++) { for (x = 0; x < imIn1->linesize; x++) {
float temp = (float) float temp = (float)
((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x])); ((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x]));
if (temp <= 0.0) if (temp <= 0.0) {
out[x] = 0; out[x] = 0;
else if (temp >= 255.0) } else if (temp >= 255.0) {
out[x] = 255; out[x] = 255;
else } else {
out[x] = (UINT8) temp; out[x] = (UINT8) temp;
}
} }
} }
} }

View File

@ -184,8 +184,9 @@ ImagingHorizontalBoxBlur(Imaging imOut, Imaging imIn, float floatRadius)
int edgeB = MAX(imIn->xsize - radius - 1, 0); int edgeB = MAX(imIn->xsize - radius - 1, 0);
UINT32 *lineOut = calloc(imIn->xsize, sizeof(UINT32)); UINT32 *lineOut = calloc(imIn->xsize, sizeof(UINT32));
if (lineOut == NULL) if (lineOut == NULL) {
return ImagingError_MemoryError(); return ImagingError_MemoryError();
}
// printf(">>> %d %d %d\n", radius, ww, fw); // printf(">>> %d %d %d\n", radius, ww, fw);
@ -248,11 +249,13 @@ ImagingBoxBlur(Imaging imOut, Imaging imIn, float radius, int n)
imIn->type != imOut->type || imIn->type != imOut->type ||
imIn->bands != imOut->bands || imIn->bands != imOut->bands ||
imIn->xsize != imOut->xsize || imIn->xsize != imOut->xsize ||
imIn->ysize != imOut->ysize) imIn->ysize != imOut->ysize) {
return ImagingError_Mismatch(); return ImagingError_Mismatch();
}
if (imIn->type != IMAGING_TYPE_UINT8) if (imIn->type != IMAGING_TYPE_UINT8) {
return ImagingError_ModeError(); return ImagingError_ModeError();
}
if (!(strcmp(imIn->mode, "RGB") == 0 || if (!(strcmp(imIn->mode, "RGB") == 0 ||
strcmp(imIn->mode, "RGBA") == 0 || strcmp(imIn->mode, "RGBA") == 0 ||
@ -261,12 +264,14 @@ ImagingBoxBlur(Imaging imOut, Imaging imIn, float radius, int n)
strcmp(imIn->mode, "CMYK") == 0 || strcmp(imIn->mode, "CMYK") == 0 ||
strcmp(imIn->mode, "L") == 0 || strcmp(imIn->mode, "L") == 0 ||
strcmp(imIn->mode, "LA") == 0 || strcmp(imIn->mode, "LA") == 0 ||
strcmp(imIn->mode, "La") == 0)) strcmp(imIn->mode, "La") == 0)) {
return ImagingError_ModeError(); return ImagingError_ModeError();
}
imTransposed = ImagingNewDirty(imIn->mode, imIn->ysize, imIn->xsize); imTransposed = ImagingNewDirty(imIn->mode, imIn->ysize, imIn->xsize);
if (!imTransposed) if (!imTransposed) {
return NULL; return NULL;
}
/* Apply blur in one dimension. /* Apply blur in one dimension.
Use imOut as a destination at first pass, Use imOut as a destination at first pass,

View File

@ -23,20 +23,22 @@
int x, y;\ int x, y;\
Imaging imOut;\ Imaging imOut;\
imOut = create(imIn1, imIn2, mode);\ imOut = create(imIn1, imIn2, mode);\
if (!imOut)\ if (!imOut) {\
return NULL;\ return NULL;\
}\
for (y = 0; y < imOut->ysize; y++) {\ for (y = 0; y < imOut->ysize; y++) {\
UINT8* out = (UINT8*) imOut->image[y];\ UINT8* out = (UINT8*) imOut->image[y];\
UINT8* in1 = (UINT8*) imIn1->image[y];\ UINT8* in1 = (UINT8*) imIn1->image[y];\
UINT8* in2 = (UINT8*) imIn2->image[y];\ UINT8* in2 = (UINT8*) imIn2->image[y];\
for (x = 0; x < imOut->linesize; x++) {\ for (x = 0; x < imOut->linesize; x++) {\
int temp = operation;\ int temp = operation;\
if (temp <= 0)\ if (temp <= 0) {\
out[x] = 0;\ out[x] = 0;\
else if (temp >= 255)\ } else if (temp >= 255) {\
out[x] = 255;\ out[x] = 255;\
else\ } else {\
out[x] = temp;\ out[x] = temp;\
}\
}\ }\
}\ }\
return imOut; return imOut;
@ -45,8 +47,9 @@
int x, y;\ int x, y;\
Imaging imOut;\ Imaging imOut;\
imOut = create(imIn1, imIn2, mode);\ imOut = create(imIn1, imIn2, mode);\
if (!imOut)\ if (!imOut) {\
return NULL;\ return NULL;\
}\
for (y = 0; y < imOut->ysize; y++) {\ for (y = 0; y < imOut->ysize; y++) {\
UINT8* out = (UINT8*) imOut->image[y];\ UINT8* out = (UINT8*) imOut->image[y];\
UINT8* in1 = (UINT8*) imIn1->image[y];\ UINT8* in1 = (UINT8*) imIn1->image[y];\
@ -63,11 +66,13 @@ create(Imaging im1, Imaging im2, char* mode)
int xsize, ysize; int xsize, ysize;
if (!im1 || !im2 || im1->type != IMAGING_TYPE_UINT8 || if (!im1 || !im2 || im1->type != IMAGING_TYPE_UINT8 ||
(mode != NULL && (strcmp(im1->mode, "1") || strcmp(im2->mode, "1")))) (mode != NULL && (strcmp(im1->mode, "1") || strcmp(im2->mode, "1")))) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (im1->type != im2->type || if (im1->type != im2->type ||
im1->bands != im2->bands) im1->bands != im2->bands) {
return (Imaging) ImagingError_Mismatch(); return (Imaging) ImagingError_Mismatch();
}
xsize = (im1->xsize < im2->xsize) ? im1->xsize : im2->xsize; xsize = (im1->xsize < im2->xsize) ? im1->xsize : im2->xsize;
ysize = (im1->ysize < im2->ysize) ? im1->ysize : im2->ysize; ysize = (im1->ysize < im2->ysize) ? im1->ysize : im2->ysize;

View File

@ -123,8 +123,9 @@ static void
l2bit(UINT8* out, const UINT8* in, int xsize) l2bit(UINT8* out, const UINT8* in, int xsize)
{ {
int x; int x;
for (x = 0; x < xsize; x++) for (x = 0; x < xsize; x++) {
*out++ = (*in++ >= 128) ? 255 : 0; *out++ = (*in++ >= 128) ? 255 : 0;
}
} }
static void static void
@ -206,8 +207,9 @@ static void
la2l(UINT8* out, const UINT8* in, int xsize) la2l(UINT8* out, const UINT8* in, int xsize)
{ {
int x; int x;
for (x = 0; x < xsize; x++, in += 4) for (x = 0; x < xsize; x++, in += 4) {
*out++ = in[0]; *out++ = in[0];
}
} }
static void static void
@ -240,18 +242,20 @@ static void
rgb2bit(UINT8* out, const UINT8* in, int xsize) rgb2bit(UINT8* out, const UINT8* in, int xsize)
{ {
int x; int x;
for (x = 0; x < xsize; x++, in += 4) for (x = 0; x < xsize; x++, in += 4) {
/* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */
*out++ = (L(in) >= 128000) ? 255 : 0; *out++ = (L(in) >= 128000) ? 255 : 0;
}
} }
static void static void
rgb2l(UINT8* out, const UINT8* in, int xsize) rgb2l(UINT8* out, const UINT8* in, int xsize)
{ {
int x; int x;
for (x = 0; x < xsize; x++, in += 4) for (x = 0; x < xsize; x++, in += 4) {
/* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */
*out++ = L24(in) >> 16; *out++ = L24(in) >> 16;
}
} }
static void static void
@ -653,12 +657,13 @@ i2l(UINT8* out, const UINT8* in_, int xsize)
for (x = 0; x < xsize; x++, out++, in_ += 4) { for (x = 0; x < xsize; x++, out++, in_ += 4) {
INT32 v; INT32 v;
memcpy(&v, in_, sizeof(v)); memcpy(&v, in_, sizeof(v));
if (v <= 0) if (v <= 0) {
*out = 0; *out = 0;
else if (v >= 255) } else if (v >= 255) {
*out = 255; *out = 255;
else } else {
*out = (UINT8) v; *out = (UINT8) v;
}
} }
} }
@ -681,12 +686,13 @@ i2rgb(UINT8* out, const UINT8* in_, int xsize)
int x; int x;
INT32* in = (INT32*) in_; INT32* in = (INT32*) in_;
for (x = 0; x < xsize; x++, in++, out+=4) { for (x = 0; x < xsize; x++, in++, out+=4) {
if (*in <= 0) if (*in <= 0) {
out[0] = out[1] = out[2] = 0; out[0] = out[1] = out[2] = 0;
else if (*in >= 255) } else if (*in >= 255) {
out[0] = out[1] = out[2] = 255; out[0] = out[1] = out[2] = 255;
else } else {
out[0] = out[1] = out[2] = (UINT8) *in; out[0] = out[1] = out[2] = (UINT8) *in;
}
out[3] = 255; out[3] = 255;
} }
} }
@ -741,12 +747,13 @@ f2l(UINT8* out, const UINT8* in_, int xsize)
for (x = 0; x < xsize; x++, out++, in_ += 4) { for (x = 0; x < xsize; x++, out++, in_ += 4) {
FLOAT32 v; FLOAT32 v;
memcpy(&v, in_, sizeof(v)); memcpy(&v, in_, sizeof(v));
if (v <= 0.0) if (v <= 0.0) {
*out = 0; *out = 0;
else if (v >= 255.0) } else if (v >= 255.0) {
*out = 255; *out = 255;
else } else {
*out = (UINT8) v; *out = (UINT8) v;
}
} }
} }
@ -797,8 +804,9 @@ static void
ycbcr2l(UINT8* out, const UINT8* in, int xsize) ycbcr2l(UINT8* out, const UINT8* in, int xsize)
{ {
int x; int x;
for (x = 0; x < xsize; x++, in += 4) for (x = 0; x < xsize; x++, in += 4) {
*out++ = in[0]; *out++ = in[0];
}
} }
static void static void
@ -908,22 +916,26 @@ static void
I16L_L(UINT8* out, const UINT8* in, int xsize) I16L_L(UINT8* out, const UINT8* in, int xsize)
{ {
int x; int x;
for (x = 0; x < xsize; x++, in += 2) for (x = 0; x < xsize; x++, in += 2) {
if (in[1] != 0) if (in[1] != 0) {
*out++ = 255; *out++ = 255;
else } else {
*out++ = in[0]; *out++ = in[0];
}
}
} }
static void static void
I16B_L(UINT8* out, const UINT8* in, int xsize) I16B_L(UINT8* out, const UINT8* in, int xsize)
{ {
int x; int x;
for (x = 0; x < xsize; x++, in += 2) for (x = 0; x < xsize; x++, in += 2) {
if (in[0] != 0) if (in[0] != 0) {
*out++ = 255; *out++ = 255;
else } else {
*out++ = in[1]; *out++ = in[1];
}
}
} }
static struct { static struct {
@ -1056,8 +1068,9 @@ p2bit(UINT8* out, const UINT8* in, int xsize, const UINT8* palette)
{ {
int x; int x;
/* FIXME: precalculate greyscale palette? */ /* FIXME: precalculate greyscale palette? */
for (x = 0; x < xsize; x++) for (x = 0; x < xsize; x++) {
*out++ = (L(&palette[in[x]*4]) >= 128000) ? 255 : 0; *out++ = (L(&palette[in[x]*4]) >= 128000) ? 255 : 0;
}
} }
static void static void
@ -1065,8 +1078,9 @@ pa2bit(UINT8* out, const UINT8* in, int xsize, const UINT8* palette)
{ {
int x; int x;
/* FIXME: precalculate greyscale palette? */ /* FIXME: precalculate greyscale palette? */
for (x = 0; x < xsize; x++, in += 4) for (x = 0; x < xsize; x++, in += 4) {
*out++ = (L(&palette[in[0]*4]) >= 128000) ? 255 : 0; *out++ = (L(&palette[in[0]*4]) >= 128000) ? 255 : 0;
}
} }
static void static void
@ -1074,8 +1088,9 @@ p2l(UINT8* out, const UINT8* in, int xsize, const UINT8* palette)
{ {
int x; int x;
/* FIXME: precalculate greyscale palette? */ /* FIXME: precalculate greyscale palette? */
for (x = 0; x < xsize; x++) for (x = 0; x < xsize; x++) {
*out++ = L(&palette[in[x]*4]) / 1000; *out++ = L(&palette[in[x]*4]) / 1000;
}
} }
static void static void
@ -1083,8 +1098,9 @@ pa2l(UINT8* out, const UINT8* in, int xsize, const UINT8* palette)
{ {
int x; int x;
/* FIXME: precalculate greyscale palette? */ /* FIXME: precalculate greyscale palette? */
for (x = 0; x < xsize; x++, in += 4) for (x = 0; x < xsize; x++, in += 4) {
*out++ = L(&palette[in[0]*4]) / 1000; *out++ = L(&palette[in[0]*4]) / 1000;
}
} }
static void static void
@ -1138,8 +1154,9 @@ pa2i(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette)
{ {
int x; int x;
INT32* out = (INT32*) out_; INT32* out = (INT32*) out_;
for (x = 0; x < xsize; x++, in += 4) for (x = 0; x < xsize; x++, in += 4) {
*out++ = L(&palette[in[0]*4]) / 1000; *out++ = L(&palette[in[0]*4]) / 1000;
}
} }
static void static void
@ -1157,8 +1174,9 @@ pa2f(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette)
{ {
int x; int x;
FLOAT32* out = (FLOAT32*) out_; FLOAT32* out = (FLOAT32*) out_;
for (x = 0; x < xsize; x++, in += 4) for (x = 0; x < xsize; x++, in += 4) {
*out++ = (float) L(&palette[in[0]*4]) / 1000.0F; *out++ = (float) L(&palette[in[0]*4]) / 1000.0F;
}
} }
static void static void
@ -1273,46 +1291,50 @@ frompalette(Imaging imOut, Imaging imIn, const char *mode)
/* Map palette image to L, RGB, RGBA, or CMYK */ /* Map palette image to L, RGB, RGBA, or CMYK */
if (!imIn->palette) if (!imIn->palette) {
return (Imaging) ImagingError_ValueError("no palette"); return (Imaging) ImagingError_ValueError("no palette");
}
alpha = !strcmp(imIn->mode, "PA"); alpha = !strcmp(imIn->mode, "PA");
if (strcmp(mode, "1") == 0) if (strcmp(mode, "1") == 0) {
convert = alpha ? pa2bit : p2bit; convert = alpha ? pa2bit : p2bit;
else if (strcmp(mode, "L") == 0) } else if (strcmp(mode, "L") == 0) {
convert = alpha ? pa2l : p2l; convert = alpha ? pa2l : p2l;
else if (strcmp(mode, "LA") == 0) } else if (strcmp(mode, "LA") == 0) {
convert = alpha ? pa2la : p2la; convert = alpha ? pa2la : p2la;
else if (strcmp(mode, "PA") == 0) } else if (strcmp(mode, "PA") == 0) {
convert = p2pa; convert = p2pa;
else if (strcmp(mode, "I") == 0) } else if (strcmp(mode, "I") == 0) {
convert = alpha ? pa2i : p2i; convert = alpha ? pa2i : p2i;
else if (strcmp(mode, "F") == 0) } else if (strcmp(mode, "F") == 0) {
convert = alpha ? pa2f : p2f; convert = alpha ? pa2f : p2f;
else if (strcmp(mode, "RGB") == 0) } else if (strcmp(mode, "RGB") == 0) {
convert = alpha ? pa2rgb : p2rgb; convert = alpha ? pa2rgb : p2rgb;
else if (strcmp(mode, "RGBA") == 0) } else if (strcmp(mode, "RGBA") == 0) {
convert = alpha ? pa2rgba : p2rgba; convert = alpha ? pa2rgba : p2rgba;
else if (strcmp(mode, "RGBX") == 0) } else if (strcmp(mode, "RGBX") == 0) {
convert = alpha ? pa2rgba : p2rgba; convert = alpha ? pa2rgba : p2rgba;
else if (strcmp(mode, "CMYK") == 0) } else if (strcmp(mode, "CMYK") == 0) {
convert = alpha ? pa2cmyk : p2cmyk; convert = alpha ? pa2cmyk : p2cmyk;
else if (strcmp(mode, "YCbCr") == 0) } else if (strcmp(mode, "YCbCr") == 0) {
convert = alpha ? pa2ycbcr : p2ycbcr; convert = alpha ? pa2ycbcr : p2ycbcr;
else if (strcmp(mode, "HSV") == 0) } else if (strcmp(mode, "HSV") == 0) {
convert = alpha ? pa2hsv : p2hsv; convert = alpha ? pa2hsv : p2hsv;
else } else {
return (Imaging) ImagingError_ValueError("conversion not supported"); return (Imaging) ImagingError_ValueError("conversion not supported");
}
imOut = ImagingNew2Dirty(mode, imOut, imIn); imOut = ImagingNew2Dirty(mode, imOut, imIn);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
for (y = 0; y < imIn->ysize; y++) for (y = 0; y < imIn->ysize; y++) {
(*convert)((UINT8*) imOut->image[y], (UINT8*) imIn->image[y], (*convert)((UINT8*) imOut->image[y], (UINT8*) imIn->image[y],
imIn->xsize, imIn->palette->palette); imIn->xsize, imIn->palette->palette);
}
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
return imOut; return imOut;
@ -1330,26 +1352,30 @@ topalette(Imaging imOut, Imaging imIn, const char *mode, ImagingPalette inpalett
ImagingPalette palette = inpalette;; ImagingPalette palette = inpalette;;
/* Map L or RGB/RGBX/RGBA to palette image */ /* Map L or RGB/RGBX/RGBA to palette image */
if (strcmp(imIn->mode, "L") != 0 && strncmp(imIn->mode, "RGB", 3) != 0) if (strcmp(imIn->mode, "L") != 0 && strncmp(imIn->mode, "RGB", 3) != 0) {
return (Imaging) ImagingError_ValueError("conversion not supported"); return (Imaging) ImagingError_ValueError("conversion not supported");
}
alpha = !strcmp(mode, "PA"); alpha = !strcmp(mode, "PA");
if (palette == NULL) { if (palette == NULL) {
/* FIXME: make user configurable */ /* FIXME: make user configurable */
if (imIn->bands == 1) if (imIn->bands == 1) {
palette = ImagingPaletteNew("RGB"); /* Initialised to grey ramp */ palette = ImagingPaletteNew("RGB"); /* Initialised to grey ramp */
else } else {
palette = ImagingPaletteNewBrowser(); /* Standard colour cube */ palette = ImagingPaletteNewBrowser(); /* Standard colour cube */
}
} }
if (!palette) if (!palette) {
return (Imaging) ImagingError_ValueError("no palette"); return (Imaging) ImagingError_ValueError("no palette");
}
imOut = ImagingNew2Dirty(mode, imOut, imIn); imOut = ImagingNew2Dirty(mode, imOut, imIn);
if (!imOut) { if (!imOut) {
if (palette != inpalette) if (palette != inpalette) {
ImagingPaletteDelete(palette); ImagingPaletteDelete(palette);
}
return NULL; return NULL;
} }
@ -1376,8 +1402,9 @@ topalette(Imaging imOut, Imaging imIn, const char *mode, ImagingPalette inpalett
/* Create mapping cache */ /* Create mapping cache */
if (ImagingPaletteCachePrepare(palette) < 0) { if (ImagingPaletteCachePrepare(palette) < 0) {
ImagingDelete(imOut); ImagingDelete(imOut);
if (palette != inpalette) if (palette != inpalette) {
ImagingPaletteDelete(palette); ImagingPaletteDelete(palette);
}
return NULL; return NULL;
} }
@ -1415,8 +1442,9 @@ topalette(Imaging imOut, Imaging imIn, const char *mode, ImagingPalette inpalett
/* get closest colour */ /* get closest colour */
cache = &ImagingPaletteCache(palette, r, g, b); cache = &ImagingPaletteCache(palette, r, g, b);
if (cache[0] == 0x100) if (cache[0] == 0x100) {
ImagingPaletteCacheUpdate(palette, r, g, b); ImagingPaletteCacheUpdate(palette, r, g, b);
}
if (alpha) { if (alpha) {
out[x*4] = out[x*4+1] = out[x*4+2] = (UINT8) cache[0]; out[x*4] = out[x*4+1] = out[x*4+2] = (UINT8) cache[0];
out[x*4+3] = 255; out[x*4+3] = 255;
@ -1464,8 +1492,9 @@ topalette(Imaging imOut, Imaging imIn, const char *mode, ImagingPalette inpalett
/* get closest colour */ /* get closest colour */
cache = &ImagingPaletteCache(palette, r, g, b); cache = &ImagingPaletteCache(palette, r, g, b);
if (cache[0] == 0x100) if (cache[0] == 0x100) {
ImagingPaletteCacheUpdate(palette, r, g, b); ImagingPaletteCacheUpdate(palette, r, g, b);
}
if (alpha) { if (alpha) {
out[x*4] = out[x*4+1] = out[x*4+2] = (UINT8) cache[0]; out[x*4] = out[x*4+1] = out[x*4+2] = (UINT8) cache[0];
out[x*4+3] = 255; out[x*4+3] = 255;
@ -1477,12 +1506,14 @@ topalette(Imaging imOut, Imaging imIn, const char *mode, ImagingPalette inpalett
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
} }
if (inpalette != palette) if (inpalette != palette) {
ImagingPaletteCacheDelete(palette); ImagingPaletteCacheDelete(palette);
}
} }
if (inpalette != palette) if (inpalette != palette) {
ImagingPaletteDelete(palette); ImagingPaletteDelete(palette);
}
return imOut; return imOut;
} }
@ -1495,12 +1526,14 @@ tobilevel(Imaging imOut, Imaging imIn, int dither)
int* errors; int* errors;
/* Map L or RGB to dithered 1 image */ /* Map L or RGB to dithered 1 image */
if (strcmp(imIn->mode, "L") != 0 && strcmp(imIn->mode, "RGB") != 0) if (strcmp(imIn->mode, "L") != 0 && strcmp(imIn->mode, "RGB") != 0) {
return (Imaging) ImagingError_ValueError("conversion not supported"); return (Imaging) ImagingError_ValueError("conversion not supported");
}
imOut = ImagingNew2Dirty("1", imOut, imIn); imOut = ImagingNew2Dirty("1", imOut, imIn);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
errors = calloc(imIn->xsize + 1, sizeof(int)); errors = calloc(imIn->xsize + 1, sizeof(int));
if (!errors) { if (!errors) {
@ -1582,63 +1615,72 @@ convert(Imaging imOut, Imaging imIn, const char *mode,
ImagingShuffler convert; ImagingShuffler convert;
int y; int y;
if (!imIn) if (!imIn) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (!mode) { if (!mode) {
/* Map palette image to full depth */ /* Map palette image to full depth */
if (!imIn->palette) if (!imIn->palette) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
mode = imIn->palette->mode; mode = imIn->palette->mode;
} else } else {
/* Same mode? */ /* Same mode? */
if (!strcmp(imIn->mode, mode)) if (!strcmp(imIn->mode, mode)) {
return ImagingCopy2(imOut, imIn); return ImagingCopy2(imOut, imIn);
}
}
/* test for special conversions */ /* test for special conversions */
if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "PA") == 0) if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "PA") == 0) {
return frompalette(imOut, imIn, mode); return frompalette(imOut, imIn, mode);
}
if (strcmp(mode, "P") == 0 || strcmp(mode, "PA") == 0) if (strcmp(mode, "P") == 0 || strcmp(mode, "PA") == 0) {
return topalette(imOut, imIn, mode, palette, dither); return topalette(imOut, imIn, mode, palette, dither);
}
if (dither && strcmp(mode, "1") == 0) if (dither && strcmp(mode, "1") == 0) {
return tobilevel(imOut, imIn, dither); return tobilevel(imOut, imIn, dither);
}
/* standard conversion machinery */ /* standard conversion machinery */
convert = NULL; convert = NULL;
for (y = 0; converters[y].from; y++) for (y = 0; converters[y].from; y++) {
if (!strcmp(imIn->mode, converters[y].from) && if (!strcmp(imIn->mode, converters[y].from) &&
!strcmp(mode, converters[y].to)) { !strcmp(mode, converters[y].to)) {
convert = converters[y].convert; convert = converters[y].convert;
break; break;
} }
}
if (!convert) if (!convert) {
#ifdef notdef #ifdef notdef
return (Imaging) ImagingError_ValueError("conversion not supported"); return (Imaging) ImagingError_ValueError("conversion not supported");
#else #else
{ static char buf[256];
static char buf[256]; /* FIXME: may overflow if mode is too large */
/* FIXME: may overflow if mode is too large */ sprintf(buf, "conversion from %s to %s not supported", imIn->mode, mode);
sprintf(buf, "conversion from %s to %s not supported", imIn->mode, mode); return (Imaging) ImagingError_ValueError(buf);
return (Imaging) ImagingError_ValueError(buf);
}
#endif #endif
}
imOut = ImagingNew2Dirty(mode, imOut, imIn); imOut = ImagingNew2Dirty(mode, imOut, imIn);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
for (y = 0; y < imIn->ysize; y++) for (y = 0; y < imIn->ysize; y++) {
(*convert)((UINT8*) imOut->image[y], (UINT8*) imIn->image[y], (*convert)((UINT8*) imOut->image[y], (UINT8*) imIn->image[y],
imIn->xsize); imIn->xsize);
}
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
return imOut; return imOut;
@ -1727,17 +1769,19 @@ ImagingConvertInPlace(Imaging imIn, const char* mode)
int y; int y;
/* limited support for inplace conversion */ /* limited support for inplace conversion */
if (strcmp(imIn->mode, "L") == 0 && strcmp(mode, "1") == 0) if (strcmp(imIn->mode, "L") == 0 && strcmp(mode, "1") == 0) {
convert = l2bit; convert = l2bit;
else if (strcmp(imIn->mode, "1") == 0 && strcmp(mode, "L") == 0) } else if (strcmp(imIn->mode, "1") == 0 && strcmp(mode, "L") == 0) {
convert = bit2l; convert = bit2l;
else } else {
return ImagingError_ModeError(); return ImagingError_ModeError();
}
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
for (y = 0; y < imIn->ysize; y++) for (y = 0; y < imIn->ysize; y++) {
(*convert)((UINT8*) imIn->image[y], (UINT8*) imIn->image[y], (*convert)((UINT8*) imIn->image[y], (UINT8*) imIn->image[y],
imIn->xsize); imIn->xsize);
}
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
return imIn; return imIn;

View File

@ -25,21 +25,25 @@ _copy(Imaging imOut, Imaging imIn)
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
int y; int y;
if (!imIn) if (!imIn) {
return (Imaging) ImagingError_ValueError(NULL); return (Imaging) ImagingError_ValueError(NULL);
}
imOut = ImagingNew2Dirty(imIn->mode, imOut, imIn); imOut = ImagingNew2Dirty(imIn->mode, imOut, imIn);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
if (imIn->block != NULL && imOut->block != NULL) if (imIn->block != NULL && imOut->block != NULL) {
memcpy(imOut->block, imIn->block, imIn->ysize * imIn->linesize); memcpy(imOut->block, imIn->block, imIn->ysize * imIn->linesize);
else } else {
for (y = 0; y < imIn->ysize; y++) for (y = 0; y < imIn->ysize; y++) {
memcpy(imOut->image[y], imIn->image[y], imIn->linesize); memcpy(imOut->image[y], imIn->image[y], imIn->linesize);
}
}
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
return imOut; return imOut;

View File

@ -27,24 +27,29 @@ ImagingCrop(Imaging imIn, int sx0, int sy0, int sx1, int sy1)
int dx0, dy0, dx1, dy1; int dx0, dy0, dx1, dy1;
INT32 zero = 0; INT32 zero = 0;
if (!imIn) if (!imIn) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
xsize = sx1 - sx0; xsize = sx1 - sx0;
if (xsize < 0) if (xsize < 0) {
xsize = 0; xsize = 0;
}
ysize = sy1 - sy0; ysize = sy1 - sy0;
if (ysize < 0) if (ysize < 0) {
ysize = 0; ysize = 0;
}
imOut = ImagingNewDirty(imIn->mode, xsize, ysize); imOut = ImagingNewDirty(imIn->mode, xsize, ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
if (sx0 < 0 || sy0 < 0 || sx1 > imIn->xsize || sy1 > imIn->ysize) if (sx0 < 0 || sy0 < 0 || sx1 > imIn->xsize || sy1 > imIn->ysize) {
(void) ImagingFill(imOut, &zero); (void) ImagingFill(imOut, &zero);
}
dx0 = -sx0; dx0 = -sx0;
dy0 = -sy0; dy0 = -sy0;

View File

@ -40,8 +40,9 @@ ImagingGetModeDIB(int size_out[2])
mode = "P"; mode = "P";
if (!(GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE)) { if (!(GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE)) {
mode = "RGB"; mode = "RGB";
if (GetDeviceCaps(dc, BITSPIXEL) == 1) if (GetDeviceCaps(dc, BITSPIXEL) == 1) {
mode = "1"; mode = "1";
}
} }
if (size_out) { if (size_out) {
@ -66,14 +67,16 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
/* Check mode */ /* Check mode */
if (strcmp(mode, "1") != 0 && strcmp(mode, "L") != 0 && if (strcmp(mode, "1") != 0 && strcmp(mode, "L") != 0 &&
strcmp(mode, "RGB") != 0) strcmp(mode, "RGB") != 0) {
return (ImagingDIB) ImagingError_ModeError(); return (ImagingDIB) ImagingError_ModeError();
}
/* Create DIB context and info header */ /* Create DIB context and info header */
/* malloc check ok, small constant allocation */ /* malloc check ok, small constant allocation */
dib = (ImagingDIB) malloc(sizeof(*dib)); dib = (ImagingDIB) malloc(sizeof(*dib));
if (!dib) if (!dib) {
return (ImagingDIB) ImagingError_MemoryError(); return (ImagingDIB) ImagingError_MemoryError();
}
/* malloc check ok, small constant allocation */ /* malloc check ok, small constant allocation */
dib->info = (BITMAPINFO*) malloc(sizeof(BITMAPINFOHEADER) + dib->info = (BITMAPINFO*) malloc(sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD)); 256 * sizeof(RGBQUAD));
@ -113,9 +116,9 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
dib->pixelsize = strlen(mode); dib->pixelsize = strlen(mode);
dib->linesize = (xsize * dib->pixelsize + 3) & -4; dib->linesize = (xsize * dib->pixelsize + 3) & -4;
if (dib->pixelsize == 1) if (dib->pixelsize == 1) {
dib->pack = dib->unpack = (ImagingShuffler) memcpy; dib->pack = dib->unpack = (ImagingShuffler) memcpy;
else { } else {
dib->pack = ImagingPackBGR; dib->pack = ImagingPackBGR;
dib->unpack = ImagingPackBGR; dib->unpack = ImagingPackBGR;
} }
@ -174,14 +177,16 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
* images. */ * images. */
i = 10; i = 10;
for (r = 0; r < 256; r += 51) for (r = 0; r < 256; r += 51) {
for (g = 0; g < 256; g += 51) for (g = 0; g < 256; g += 51) {
for (b = 0; b < 256; b += 51) { for (b = 0; b < 256; b += 51) {
pal->palPalEntry[i].peRed = r; pal->palPalEntry[i].peRed = r;
pal->palPalEntry[i].peGreen = g; pal->palPalEntry[i].peGreen = g;
pal->palPalEntry[i].peBlue = b; pal->palPalEntry[i].peBlue = b;
i++; i++;
} }
}
}
for (r = 1; r < 22-1; r++) { for (r = 1; r < 22-1; r++) {
/* Black and white are already provided by the cube. */ /* Black and white are already provided by the cube. */
pal->palPalEntry[i].peRed = pal->palPalEntry[i].peRed =
@ -195,14 +200,16 @@ ImagingNewDIB(const char *mode, int xsize, int ysize)
/* Colour DIB. Alternate palette. */ /* Colour DIB. Alternate palette. */
i = 10; i = 10;
for (r = 0; r < 256; r += 37) for (r = 0; r < 256; r += 37) {
for (g = 0; g < 256; g += 32) for (g = 0; g < 256; g += 32) {
for (b = 0; b < 256; b += 64) { for (b = 0; b < 256; b += 64) {
pal->palPalEntry[i].peRed = r; pal->palPalEntry[i].peRed = r;
pal->palPalEntry[i].peGreen = g; pal->palPalEntry[i].peGreen = g;
pal->palPalEntry[i].peBlue = b; pal->palPalEntry[i].peBlue = b;
i++; i++;
} }
}
}
#endif #endif
@ -223,9 +230,10 @@ ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4])
/* FIXME: check size! */ /* FIXME: check size! */
int y; int y;
for (y = 0; y < im->ysize; y++) for (y = 0; y < im->ysize; y++) {
dib->pack(dib->bits + dib->linesize*(dib->ysize-(xy[1]+y)-1) + dib->pack(dib->bits + dib->linesize*(dib->ysize-(xy[1]+y)-1) +
xy[0]*dib->pixelsize, im->image[y], im->xsize); xy[0]*dib->pixelsize, im->image[y], im->xsize);
}
} }
@ -234,8 +242,9 @@ ImagingExposeDIB(ImagingDIB dib, void *dc)
{ {
/* Copy bitmap to display */ /* Copy bitmap to display */
if (dib->palette != 0) if (dib->palette != 0) {
SelectPalette((HDC) dc, dib->palette, FALSE); SelectPalette((HDC) dc, dib->palette, FALSE);
}
BitBlt((HDC) dc, 0, 0, dib->xsize, dib->ysize, dib->dc, 0, 0, SRCCOPY); BitBlt((HDC) dc, 0, 0, dib->xsize, dib->ysize, dib->dc, 0, 0, SRCCOPY);
} }
@ -251,8 +260,9 @@ ImagingDrawDIB(ImagingDIB dib, void *dc, int dst[4], int src[4])
dib->info, DIB_RGB_COLORS, SRCCOPY); dib->info, DIB_RGB_COLORS, SRCCOPY);
} else { } else {
/* stretchblt (displays) */ /* stretchblt (displays) */
if (dib->palette != 0) if (dib->palette != 0) {
SelectPalette((HDC) dc, dib->palette, FALSE); SelectPalette((HDC) dc, dib->palette, FALSE);
}
StretchBlt((HDC) dc, dst[0], dst[1], dst[2]-dst[0], dst[3]-dst[1], StretchBlt((HDC) dc, dst[0], dst[1], dst[2]-dst[0], dst[3]-dst[1],
dib->dc, src[0], src[1], src[2]-src[0], src[3]-src[1], dib->dc, src[0], src[1], src[2]-src[0], src[3]-src[1],
SRCCOPY); SRCCOPY);
@ -275,8 +285,9 @@ ImagingQueryPaletteDIB(ImagingDIB dib, void *dc)
/* Restore palette */ /* Restore palette */
SelectPalette((HDC) dc, now, FALSE); SelectPalette((HDC) dc, now, FALSE);
} else } else {
n = 0; n = 0;
}
return n; /* number of colours that was changed */ return n; /* number of colours that was changed */
} }
@ -286,14 +297,16 @@ ImagingDeleteDIB(ImagingDIB dib)
{ {
/* Clean up */ /* Clean up */
if (dib->palette) if (dib->palette) {
DeleteObject(dib->palette); DeleteObject(dib->palette);
}
if (dib->bitmap) { if (dib->bitmap) {
SelectObject(dib->dc, dib->old_bitmap); SelectObject(dib->dc, dib->old_bitmap);
DeleteObject(dib->bitmap); DeleteObject(dib->bitmap);
} }
if (dib->dc) if (dib->dc) {
DeleteDC(dib->dc); DeleteDC(dib->dc);
}
free(dib->info); free(dib->info);
} }

View File

@ -79,8 +79,9 @@ point8(Imaging im, int x, int y, int ink)
static inline void static inline void
point32(Imaging im, int x, int y, int ink) point32(Imaging im, int x, int y, int ink)
{ {
if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
im->image32[y][x] = ink; im->image32[y][x] = ink;
}
} }
static inline void static inline void
@ -103,16 +104,19 @@ hline8(Imaging im, int x0, int y0, int x1, int ink)
int tmp, pixelwidth; int tmp, pixelwidth;
if (y0 >= 0 && y0 < im->ysize) { if (y0 >= 0 && y0 < im->ysize) {
if (x0 > x1) if (x0 > x1) {
tmp = x0, x0 = x1, x1 = tmp; tmp = x0, x0 = x1, x1 = tmp;
if (x0 < 0) }
if (x0 < 0) {
x0 = 0; x0 = 0;
else if (x0 >= im->xsize) } else if (x0 >= im->xsize) {
return; return;
if (x1 < 0) }
if (x1 < 0) {
return; return;
else if (x1 >= im->xsize) } else if (x1 >= im->xsize) {
x1 = im->xsize-1; x1 = im->xsize-1;
}
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(im->image8[y0] + x0 * pixelwidth, (UINT8) ink, memset(im->image8[y0] + x0 * pixelwidth, (UINT8) ink,
@ -128,19 +132,23 @@ hline32(Imaging im, int x0, int y0, int x1, int ink)
INT32* p; INT32* p;
if (y0 >= 0 && y0 < im->ysize) { if (y0 >= 0 && y0 < im->ysize) {
if (x0 > x1) if (x0 > x1) {
tmp = x0, x0 = x1, x1 = tmp; tmp = x0, x0 = x1, x1 = tmp;
if (x0 < 0) }
if (x0 < 0) {
x0 = 0; x0 = 0;
else if (x0 >= im->xsize) } else if (x0 >= im->xsize) {
return; return;
if (x1 < 0) }
if (x1 < 0) {
return; return;
else if (x1 >= im->xsize) } else if (x1 >= im->xsize) {
x1 = im->xsize-1; x1 = im->xsize-1;
}
p = im->image32[y0]; p = im->image32[y0];
while (x0 <= x1) while (x0 <= x1) {
p[x0++] = ink; p[x0++] = ink;
}
} }
} }
@ -151,16 +159,19 @@ hline32rgba(Imaging im, int x0, int y0, int x1, int ink)
unsigned int tmp1; unsigned int tmp1;
if (y0 >= 0 && y0 < im->ysize) { if (y0 >= 0 && y0 < im->ysize) {
if (x0 > x1) if (x0 > x1) {
tmp = x0, x0 = x1, x1 = tmp; tmp = x0, x0 = x1, x1 = tmp;
if (x0 < 0) }
if (x0 < 0) {
x0 = 0; x0 = 0;
else if (x0 >= im->xsize) } else if (x0 >= im->xsize) {
return; return;
if (x1 < 0) }
if (x1 < 0) {
return; return;
else if (x1 >= im->xsize) } else if (x1 >= im->xsize) {
x1 = im->xsize-1; x1 = im->xsize-1;
}
if (x0 <= x1) { if (x0 <= x1) {
UINT8* out = (UINT8*) im->image[y0]+x0*4; UINT8* out = (UINT8*) im->image[y0]+x0*4;
UINT8* in = (UINT8*) &ink; UINT8* in = (UINT8*) &ink;
@ -183,19 +194,21 @@ line8(Imaging im, int x0, int y0, int x1, int y1, int ink)
/* normalize coordinates */ /* normalize coordinates */
dx = x1-x0; dx = x1-x0;
if (dx < 0) if (dx < 0) {
dx = -dx, xs = -1; dx = -dx, xs = -1;
else } else {
xs = 1; xs = 1;
}
dy = y1-y0; dy = y1-y0;
if (dy < 0) if (dy < 0) {
dy = -dy, ys = -1; dy = -dy, ys = -1;
else } else {
ys = 1; ys = 1;
}
n = (dx > dy) ? dx : dy; n = (dx > dy) ? dx : dy;
if (dx == 0) if (dx == 0) {
/* vertical */ /* vertical */
for (i = 0; i < dy; i++) { for (i = 0; i < dy; i++) {
@ -203,7 +216,7 @@ line8(Imaging im, int x0, int y0, int x1, int y1, int ink)
y0 += ys; y0 += ys;
} }
else if (dy == 0) } else if (dy == 0) {
/* horizontal */ /* horizontal */
for (i = 0; i < dx; i++) { for (i = 0; i < dx; i++) {
@ -211,7 +224,7 @@ line8(Imaging im, int x0, int y0, int x1, int y1, int ink)
x0 += xs; x0 += xs;
} }
else if (dx > dy) { } else if (dx > dy) {
/* bresenham, horizontal slope */ /* bresenham, horizontal slope */
n = dx; n = dx;
@ -259,19 +272,21 @@ line32(Imaging im, int x0, int y0, int x1, int y1, int ink)
/* normalize coordinates */ /* normalize coordinates */
dx = x1-x0; dx = x1-x0;
if (dx < 0) if (dx < 0) {
dx = -dx, xs = -1; dx = -dx, xs = -1;
else } else {
xs = 1; xs = 1;
}
dy = y1-y0; dy = y1-y0;
if (dy < 0) if (dy < 0) {
dy = -dy, ys = -1; dy = -dy, ys = -1;
else } else {
ys = 1; ys = 1;
}
n = (dx > dy) ? dx : dy; n = (dx > dy) ? dx : dy;
if (dx == 0) if (dx == 0) {
/* vertical */ /* vertical */
for (i = 0; i < dy; i++) { for (i = 0; i < dy; i++) {
@ -279,7 +294,7 @@ line32(Imaging im, int x0, int y0, int x1, int y1, int ink)
y0 += ys; y0 += ys;
} }
else if (dy == 0) } else if (dy == 0) {
/* horizontal */ /* horizontal */
for (i = 0; i < dx; i++) { for (i = 0; i < dx; i++) {
@ -287,7 +302,7 @@ line32(Imaging im, int x0, int y0, int x1, int y1, int ink)
x0 += xs; x0 += xs;
} }
else if (dx > dy) { } else if (dx > dy) {
/* bresenham, horizontal slope */ /* bresenham, horizontal slope */
n = dx; n = dx;
@ -335,19 +350,21 @@ line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink)
/* normalize coordinates */ /* normalize coordinates */
dx = x1-x0; dx = x1-x0;
if (dx < 0) if (dx < 0) {
dx = -dx, xs = -1; dx = -dx, xs = -1;
else } else {
xs = 1; xs = 1;
}
dy = y1-y0; dy = y1-y0;
if (dy < 0) if (dy < 0) {
dy = -dy, ys = -1; dy = -dy, ys = -1;
else } else {
ys = 1; ys = 1;
}
n = (dx > dy) ? dx : dy; n = (dx > dy) ? dx : dy;
if (dx == 0) if (dx == 0) {
/* vertical */ /* vertical */
for (i = 0; i < dy; i++) { for (i = 0; i < dy; i++) {
@ -355,7 +372,7 @@ line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink)
y0 += ys; y0 += ys;
} }
else if (dy == 0) } else if (dy == 0) {
/* horizontal */ /* horizontal */
for (i = 0; i < dx; i++) { for (i = 0; i < dx; i++) {
@ -363,7 +380,7 @@ line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink)
x0 += xs; x0 += xs;
} }
else if (dx > dy) { } else if (dx > dy) {
/* bresenham, horizontal slope */ /* bresenham, horizontal slope */
n = dx; n = dx;
@ -406,12 +423,13 @@ static int
x_cmp(const void *x0, const void *x1) x_cmp(const void *x0, const void *x1)
{ {
float diff = *((float*)x0) - *((float*)x1); float diff = *((float*)x0) - *((float*)x1);
if (diff < 0) if (diff < 0) {
return -1; return -1;
else if (diff > 0) } else if (diff > 0) {
return 1; return 1;
else } else {
return 0; return 0;
}
} }
@ -566,25 +584,28 @@ add_edge(Edge *e, int x0, int y0, int x1, int y1)
{ {
/* printf("edge %d %d %d %d\n", x0, y0, x1, y1); */ /* printf("edge %d %d %d %d\n", x0, y0, x1, y1); */
if (x0 <= x1) if (x0 <= x1) {
e->xmin = x0, e->xmax = x1; e->xmin = x0, e->xmax = x1;
else } else {
e->xmin = x1, e->xmax = x0; e->xmin = x1, e->xmax = x0;
}
if (y0 <= y1) if (y0 <= y1) {
e->ymin = y0, e->ymax = y1; e->ymin = y0, e->ymax = y1;
else } else {
e->ymin = y1, e->ymax = y0; e->ymin = y1, e->ymax = y0;
}
if (y0 == y1) { if (y0 == y1) {
e->d = 0; e->d = 0;
e->dx = 0.0; e->dx = 0.0;
} else { } else {
e->dx = ((float)(x1-x0)) / (y1-y0); e->dx = ((float)(x1-x0)) / (y1-y0);
if (y0 == e->ymin) if (y0 == e->ymin) {
e->d = 1; e->d = 1;
else } else {
e->d = -1; e->d = -1;
}
} }
e->x0 = x0; e->x0 = x0;
@ -701,23 +722,27 @@ ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1,
DRAWINIT(); DRAWINIT();
if (y0 > y1) if (y0 > y1) {
tmp = y0, y0 = y1, y1 = tmp; tmp = y0, y0 = y1, y1 = tmp;
}
if (fill) { if (fill) {
if (y0 < 0) if (y0 < 0) {
y0 = 0; y0 = 0;
else if (y0 >= im->ysize) } else if (y0 >= im->ysize) {
return 0; return 0;
}
if (y1 < 0) if (y1 < 0) {
return 0; return 0;
else if (y1 > im->ysize) } else if (y1 > im->ysize) {
y1 = im->ysize; y1 = im->ysize;
}
for (y = y0; y <= y1; y++) for (y = y0; y <= y1; y++) {
draw->hline(im, x0, y, x1, ink); draw->hline(im, x0, y, x1, ink);
}
} else { } else {
/* outline */ /* outline */
@ -743,8 +768,9 @@ ImagingDrawPolygon(Imaging im, int count, int* xy, const void* ink_,
DRAW* draw; DRAW* draw;
INT32 ink; INT32 ink;
if (count <= 0) if (count <= 0) {
return 0; return 0;
}
DRAWINIT(); DRAWINIT();
@ -757,18 +783,21 @@ ImagingDrawPolygon(Imaging im, int count, int* xy, const void* ink_,
(void) ImagingError_MemoryError(); (void) ImagingError_MemoryError();
return -1; return -1;
} }
for (i = n = 0; i < count-1; i++) for (i = n = 0; i < count-1; i++) {
add_edge(&e[n++], xy[i+i], xy[i+i+1], xy[i+i+2], xy[i+i+3]); add_edge(&e[n++], xy[i+i], xy[i+i+1], xy[i+i+2], xy[i+i+3]);
if (xy[i+i] != xy[0] || xy[i+i+1] != xy[1]) }
if (xy[i+i] != xy[0] || xy[i+i+1] != xy[1]) {
add_edge(&e[n++], xy[i+i], xy[i+i+1], xy[0], xy[1]); add_edge(&e[n++], xy[i+i], xy[i+i+1], xy[0], xy[1]);
}
draw->polygon(im, n, e, ink, 0); draw->polygon(im, n, e, ink, 0);
free(e); free(e);
} else { } else {
/* Outline */ /* Outline */
for (i = 0; i < count-1; i++) for (i = 0; i < count-1; i++) {
draw->line(im, xy[i+i], xy[i+i+1], xy[i+i+2], xy[i+i+3], ink); draw->line(im, xy[i+i], xy[i+i+1], xy[i+i+2], xy[i+i+3], ink);
}
draw->line(im, xy[i+i], xy[i+i+1], xy[0], xy[1], ink); draw->line(im, xy[i+i], xy[i+i+1], xy[0], xy[1], ink);
} }
@ -838,8 +867,9 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
DRAWINIT(); DRAWINIT();
while (end < start) while (end < start) {
end += 360; end += 360;
}
if (end - start > 360) { if (end - start > 360) {
// no need to go in loops // no need to go in loops
@ -848,8 +878,9 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
w = x1 - x0; w = x1 - x0;
h = y1 - y0; h = y1 - y0;
if (w <= 0 || h <= 0) if (w <= 0 || h <= 0) {
return 0; return 0;
}
cx = (x0 + x1) / 2; cx = (x0 + x1) / 2;
cy = (y0 + y1) / 2; cy = (y0 + y1) / 2;
@ -860,10 +891,11 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
i = end; i = end;
} }
ellipsePoint(cx, cy, w, h, i, &x, &y); ellipsePoint(cx, cy, w, h, i, &x, &y);
if (i != start) if (i != start) {
draw->line(im, lx, ly, x, y, ink); draw->line(im, lx, ly, x, y, ink);
else } else {
sx = x, sy = y; sx = x, sy = y;
}
lx = x, ly = y; lx = x, ly = y;
} }
@ -874,8 +906,9 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
draw->line(im, cx, cy, sx, sy, ink); draw->line(im, cx, cy, sx, sy, ink);
} }
} else if (mode == CHORD) { } else if (mode == CHORD) {
if (x != sx || y != sy) if (x != sx || y != sy) {
draw->line(im, x, y, sx, sy, ink); draw->line(im, x, y, sx, sy, ink);
}
} }
} }
} else { } else {
@ -908,8 +941,9 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
} }
lx = x, ly = y; lx = x, ly = y;
} }
if (n == 0) if (n == 0) {
return 0; return 0;
}
if (inner) { if (inner) {
// Inner circle // Inner circle
@ -930,10 +964,11 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
i = end; i = end;
} }
ellipsePoint(cx, cy, w, h, i, &x, &y); ellipsePoint(cx, cy, w, h, i, &x, &y);
if (i == start) if (i == start) {
sx_inner = x, sy_inner = y; sx_inner = x, sy_inner = y;
else } else {
add_edge(&e[n++], lx_inner, ly_inner, x, y); add_edge(&e[n++], lx_inner, ly_inner, x, y);
}
lx_inner = x, ly_inner = y; lx_inner = x, ly_inner = y;
} }
} }
@ -1026,8 +1061,9 @@ ImagingOutlineNew(void)
ImagingOutline outline; ImagingOutline outline;
outline = calloc(1, sizeof(struct ImagingOutlineInstance)); outline = calloc(1, sizeof(struct ImagingOutlineInstance));
if (!outline) if (!outline) {
return (ImagingOutline) ImagingError_MemoryError(); return (ImagingOutline) ImagingError_MemoryError();
}
outline->edges = NULL; outline->edges = NULL;
outline->count = outline->size = 0; outline->count = outline->size = 0;
@ -1040,11 +1076,13 @@ ImagingOutlineNew(void)
void void
ImagingOutlineDelete(ImagingOutline outline) ImagingOutlineDelete(ImagingOutline outline)
{ {
if (!outline) if (!outline) {
return; return;
}
if (outline->edges) if (outline->edges) {
free(outline->edges); free(outline->edges);
}
free(outline); free(outline);
} }
@ -1068,8 +1106,9 @@ allocate(ImagingOutline outline, int extra)
/* malloc check ok, overflow checked above */ /* malloc check ok, overflow checked above */
e = realloc(outline->edges, outline->size * sizeof(Edge)); e = realloc(outline->edges, outline->size * sizeof(Edge));
} }
if (!e) if (!e) {
return NULL; return NULL;
}
outline->edges = e; outline->edges = e;
} }
@ -1095,8 +1134,9 @@ ImagingOutlineLine(ImagingOutline outline, float x1, float y1)
Edge* e; Edge* e;
e = allocate(outline, 1); e = allocate(outline, 1);
if (!e) if (!e) {
return -1; /* out of memory */ return -1; /* out of memory */
}
add_edge(e, (int) outline->x, (int) outline->y, (int) x1, (int) y1); add_edge(e, (int) outline->x, (int) outline->y, (int) x1, (int) y1);
@ -1117,8 +1157,9 @@ ImagingOutlineCurve(ImagingOutline outline, float x1, float y1,
#define STEPS 32 #define STEPS 32
e = allocate(outline, STEPS); e = allocate(outline, STEPS);
if (!e) if (!e) {
return -1; /* out of memory */ return -1; /* out of memory */
}
xo = outline->x; xo = outline->x;
yo = outline->y; yo = outline->y;
@ -1153,8 +1194,9 @@ ImagingOutlineCurve(ImagingOutline outline, float x1, float y1,
int int
ImagingOutlineClose(ImagingOutline outline) ImagingOutlineClose(ImagingOutline outline)
{ {
if (outline->x == outline->x0 && outline->y == outline->y0) if (outline->x == outline->x0 && outline->y == outline->y0) {
return 0; return 0;
}
return ImagingOutlineLine(outline, outline->x0, outline->y0); return ImagingOutlineLine(outline, outline->x0, outline->y0);
} }
@ -1191,14 +1233,16 @@ ImagingOutlineTransform(ImagingOutline outline, double a[6])
y0 = eIn->y0; y0 = eIn->y0;
/* FIXME: ouch! */ /* FIXME: ouch! */
if (eIn->x0 == eIn->xmin) if (eIn->x0 == eIn->xmin) {
x1 = eIn->xmax; x1 = eIn->xmax;
else } else {
x1 = eIn->xmin; x1 = eIn->xmin;
if (eIn->y0 == eIn->ymin) }
if (eIn->y0 == eIn->ymin) {
y1 = eIn->ymax; y1 = eIn->ymax;
else } else {
y1 = eIn->ymin; y1 = eIn->ymin;
}
/* full moon tonight! if this doesn't work, you may need to /* full moon tonight! if this doesn't work, you may need to
upgrade your compiler (make sure you have the right service upgrade your compiler (make sure you have the right service

View File

@ -34,12 +34,14 @@ ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality)
/* Check arguments */ /* Check arguments */
width = extent[2] - extent[0]; width = extent[2] - extent[0];
height = extent[3] - extent[1]; height = extent[3] - extent[1];
if (width < 0.0 || height < 0.0 || quality < 2) if (width < 0.0 || height < 0.0 || quality < 2) {
return (Imaging) ImagingError_ValueError(NULL); return (Imaging) ImagingError_ValueError(NULL);
}
im = ImagingNewDirty("L", xsize, ysize); im = ImagingNewDirty("L", xsize, ysize);
if (!im) if (!im) {
return NULL; return NULL;
}
dr = width/(xsize-1); dr = width/(xsize-1);
di = height/(ysize-1); di = height/(ysize-1);
@ -82,8 +84,9 @@ ImagingEffectNoise(int xsize, int ysize, float sigma)
double this, next; double this, next;
imOut = ImagingNewDirty("L", xsize, ysize); imOut = ImagingNewDirty("L", xsize, ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
next = 0.0; next = 0.0;
nextok = 0; nextok = 0;
@ -123,20 +126,23 @@ ImagingEffectSpread(Imaging imIn, int distance)
imOut = ImagingNewDirty(imIn->mode, imIn->xsize, imIn->ysize); imOut = ImagingNewDirty(imIn->mode, imIn->xsize, imIn->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
#define SPREAD(type, image)\ #define SPREAD(type, image)\
for (y = 0; y < imOut->ysize; y++)\ for (y = 0; y < imOut->ysize; y++) {\
for (x = 0; x < imOut->xsize; x++) {\ for (x = 0; x < imOut->xsize; x++) {\
int xx = x + (rand() % distance) - distance/2;\ int xx = x + (rand() % distance) - distance/2;\
int yy = y + (rand() % distance) - distance/2;\ int yy = y + (rand() % distance) - distance/2;\
if (xx >= 0 && xx < imIn->xsize && yy >= 0 && yy < imIn->ysize) {\ if (xx >= 0 && xx < imIn->xsize && yy >= 0 && yy < imIn->ysize) {\
imOut->image[yy][xx] = imIn->image[y][x];\ imOut->image[yy][xx] = imIn->image[y][x];\
imOut->image[y][x] = imIn->image[yy][xx];\ imOut->image[y][x] = imIn->image[yy][xx];\
} else\ } else {\
imOut->image[y][x] = imIn->image[y][x];\ imOut->image[y][x] = imIn->image[y][x];\
} }\
}\
}
if (imIn->image8) { if (imIn->image8) {
SPREAD(UINT8, image8); SPREAD(UINT8, image8);

View File

@ -40,15 +40,17 @@ ImagingEpsEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
for (;;) { for (;;) {
if (state->state == NEWLINE) { if (state->state == NEWLINE) {
if (bytes < 1) if (bytes < 1) {
break; break;
}
*ptr++ = '\n'; *ptr++ = '\n';
bytes--; bytes--;
state->state = HEXBYTE; state->state = HEXBYTE;
} }
if (bytes < 2) if (bytes < 2) {
break; break;
}
i = in[state->x++]; i = in[state->x++];
*ptr++ = hex[(i>>4)&15]; *ptr++ = hex[(i>>4)&15];
@ -56,8 +58,9 @@ ImagingEpsEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
bytes -= 2; bytes -= 2;
/* Skip junk bytes */ /* Skip junk bytes */
if (im->bands == 3 && (state->x & 3) == 3) if (im->bands == 3 && (state->x & 3) == 3) {
state->x++; state->x++;
}
if (++state->count >= 79/2) { if (++state->count >= 79/2) {
state->state = NEWLINE; state->state = NEWLINE;

View File

@ -56,8 +56,9 @@ ImagingError_Mismatch(void)
void * void *
ImagingError_ValueError(const char *message) ImagingError_ValueError(const char *message)
{ {
if (!message) if (!message) {
message = "exception: bad argument to function"; message = "exception: bad argument to function";
}
fprintf(stderr, "*** %s\n", message); fprintf(stderr, "*** %s\n", message);
return NULL; return NULL;
} }

View File

@ -31,15 +31,18 @@ ImagingSaveRaw(Imaging im, FILE* fp)
/* @PIL227: FIXME: for mode "1", map != 0 to 255 */ /* @PIL227: FIXME: for mode "1", map != 0 to 255 */
/* PGM "L" */ /* PGM "L" */
for (y = 0; y < im->ysize; y++) for (y = 0; y < im->ysize; y++) {
fwrite(im->image[y], 1, im->xsize, fp); fwrite(im->image[y], 1, im->xsize, fp);
}
} else { } else {
/* PPM "RGB" or other internal format */ /* PPM "RGB" or other internal format */
for (y = 0; y < im->ysize; y++) for (y = 0; y < im->ysize; y++) {
for (x = i = 0; x < im->xsize; x++, i += im->pixelsize) for (x = i = 0; x < im->xsize; x++, i += im->pixelsize) {
fwrite(im->image[y]+i, 1, im->bands, fp); fwrite(im->image[y]+i, 1, im->bands, fp);
}
}
} }

View File

@ -30,27 +30,33 @@ ImagingFill(Imaging im, const void* colour)
/* use generic API */ /* use generic API */
ImagingAccess access = ImagingAccessNew(im); ImagingAccess access = ImagingAccessNew(im);
if (access) { if (access) {
for (y = 0; y < im->ysize; y++) for (y = 0; y < im->ysize; y++) {
for (x = 0; x < im->xsize; x++) for (x = 0; x < im->xsize; x++) {
access->put_pixel(im, x, y, colour); access->put_pixel(im, x, y, colour);
}
}
ImagingAccessDelete(im, access); ImagingAccessDelete(im, access);
} else { } else {
/* wipe the image */ /* wipe the image */
for (y = 0; y < im->ysize; y++) for (y = 0; y < im->ysize; y++) {
memset(im->image[y], 0, im->linesize); memset(im->image[y], 0, im->linesize);
}
} }
} else { } else {
INT32 c = 0L; INT32 c = 0L;
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
memcpy(&c, colour, im->pixelsize); memcpy(&c, colour, im->pixelsize);
if (im->image32 && c != 0L) { if (im->image32 && c != 0L) {
for (y = 0; y < im->ysize; y++) for (y = 0; y < im->ysize; y++) {
for (x = 0; x < im->xsize; x++) for (x = 0; x < im->xsize; x++) {
im->image32[y][x] = c; im->image32[y][x] = c;
}
}
} else { } else {
unsigned char cc = (unsigned char) *(UINT8*) colour; unsigned char cc = (unsigned char) *(UINT8*) colour;
for (y = 0; y < im->ysize; y++) for (y = 0; y < im->ysize; y++) {
memset(im->image[y], cc, im->linesize); memset(im->image[y], cc, im->linesize);
}
} }
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
} }

View File

@ -29,10 +29,12 @@
static inline UINT8 clip8(float in) static inline UINT8 clip8(float in)
{ {
if (in <= 0.0) if (in <= 0.0) {
return 0; return 0;
if (in >= 255.0) }
if (in >= 255.0) {
return 255; return 255;
}
return (UINT8) in; return (UINT8) in;
} }
@ -43,32 +45,40 @@ ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode)
int x, y; int x, y;
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
if (xmargin < 0 && ymargin < 0) if (xmargin < 0 && ymargin < 0) {
return (Imaging) ImagingError_ValueError("bad kernel size"); return (Imaging) ImagingError_ValueError("bad kernel size");
}
imOut = ImagingNewDirty( imOut = ImagingNewDirty(
imIn->mode, imIn->xsize+2*xmargin, imIn->ysize+2*ymargin); imIn->mode, imIn->xsize+2*xmargin, imIn->ysize+2*ymargin);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
#define EXPAND_LINE(type, image, yin, yout) {\ #define EXPAND_LINE(type, image, yin, yout) {\
for (x = 0; x < xmargin; x++)\ for (x = 0; x < xmargin; x++) {\
imOut->image[yout][x] = imIn->image[yin][0];\ imOut->image[yout][x] = imIn->image[yin][0];\
for (x = 0; x < imIn->xsize; x++)\ }\
for (x = 0; x < imIn->xsize; x++) {\
imOut->image[yout][x+xmargin] = imIn->image[yin][x];\ imOut->image[yout][x+xmargin] = imIn->image[yin][x];\
for (x = 0; x < xmargin; x++)\ }\
for (x = 0; x < xmargin; x++) {\
imOut->image[yout][xmargin+imIn->xsize+x] =\ imOut->image[yout][xmargin+imIn->xsize+x] =\
imIn->image[yin][imIn->xsize-1];\ imIn->image[yin][imIn->xsize-1];\
} }\
}
#define EXPAND(type, image) {\ #define EXPAND(type, image) {\
for (y = 0; y < ymargin; y++)\ for (y = 0; y < ymargin; y++) {\
EXPAND_LINE(type, image, 0, y);\ EXPAND_LINE(type, image, 0, y);\
for (y = 0; y < imIn->ysize; y++)\ }\
for (y = 0; y < imIn->ysize; y++) {\
EXPAND_LINE(type, image, y, y+ymargin);\ EXPAND_LINE(type, image, y, y+ymargin);\
for (y = 0; y < ymargin; y++)\ }\
for (y = 0; y < ymargin; y++) {\
EXPAND_LINE(type, image, imIn->ysize-1, ymargin+imIn->ysize+y);\ EXPAND_LINE(type, image, imIn->ysize-1, ymargin+imIn->ysize+y);\
} }\
}
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
if (imIn->image8) { if (imIn->image8) {
@ -330,18 +340,22 @@ ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32* kernel,
Imaging imOut; Imaging imOut;
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
if ( ! im || im->type != IMAGING_TYPE_UINT8) if ( ! im || im->type != IMAGING_TYPE_UINT8) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (im->xsize < xsize || im->ysize < ysize) if (im->xsize < xsize || im->ysize < ysize) {
return ImagingCopy(im); return ImagingCopy(im);
}
if ((xsize != 3 && xsize != 5) || xsize != ysize) if ((xsize != 3 && xsize != 5) || xsize != ysize) {
return (Imaging) ImagingError_ValueError("bad kernel size"); return (Imaging) ImagingError_ValueError("bad kernel size");
}
imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize); imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
if (xsize == 3) { if (xsize == 3) {

View File

@ -41,8 +41,9 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
/* If not even the chunk size is present, we'd better leave */ /* If not even the chunk size is present, we'd better leave */
if (bytes < 4) if (bytes < 4) {
return 0; return 0;
}
/* We don't decode anything unless we have a full chunk in the /* We don't decode anything unless we have a full chunk in the
input buffer */ input buffer */
@ -50,8 +51,9 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
ptr = buf; ptr = buf;
framesize = I32(ptr); framesize = I32(ptr);
if (framesize < I32(ptr)) if (framesize < I32(ptr)) {
return 0; return 0;
}
/* Make sure this is a frame chunk. The Python driver takes /* Make sure this is a frame chunk. The Python driver takes
case of other chunk types. */ case of other chunk types. */
@ -112,8 +114,9 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
if (data[1] >= 128) { if (data[1] >= 128) {
ERR_IF_DATA_OOB(4) ERR_IF_DATA_OOB(4)
i = 256-data[1]; /* run */ i = 256-data[1]; /* run */
if (x + i + i > state->xsize) if (x + i + i > state->xsize) {
break; break;
}
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
local_buf[x++] = data[2]; local_buf[x++] = data[2];
local_buf[x++] = data[3]; local_buf[x++] = data[3];
@ -121,16 +124,18 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
data += 2 + 2; data += 2 + 2;
} else { } else {
i = 2 * (int) data[1]; /* chunk */ i = 2 * (int) data[1]; /* chunk */
if (x + i > state->xsize) if (x + i > state->xsize) {
break; break;
}
ERR_IF_DATA_OOB(2+i) ERR_IF_DATA_OOB(2+i)
memcpy(local_buf + x, data + 2, i); memcpy(local_buf + x, data + 2, i);
data += 2 + i; data += 2 + i;
x += i; x += i;
} }
} }
if (p < packets) if (p < packets) {
break; /* didn't process all packets */ break; /* didn't process all packets */
}
} }
if (l < lines) { if (l < lines) {
/* didn't process all lines */ /* didn't process all lines */
@ -151,22 +156,25 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
x += data[0]; /* skip pixels */ x += data[0]; /* skip pixels */
if (data[1] & 0x80) { if (data[1] & 0x80) {
i = 256-data[1]; /* run */ i = 256-data[1]; /* run */
if (x + i > state->xsize) if (x + i > state->xsize) {
break; break;
}
ERR_IF_DATA_OOB(3) ERR_IF_DATA_OOB(3)
memset(out + x, data[2], i); memset(out + x, data[2], i);
data += 3; data += 3;
} else { } else {
i = data[1]; /* chunk */ i = data[1]; /* chunk */
if (x + i > state->xsize) if (x + i > state->xsize) {
break; break;
}
ERR_IF_DATA_OOB(2+i) ERR_IF_DATA_OOB(2+i)
memcpy(out + x, data + 2, i); memcpy(out + x, data + 2, i);
data += i + 2; data += i + 2;
} }
} }
if (p < packets) if (p < packets) {
break; /* didn't process all packets */ break; /* didn't process all packets */
}
} }
if (y < ymax) { if (y < ymax) {
/* didn't process all lines */ /* didn't process all lines */
@ -176,8 +184,9 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
break; break;
case 13: case 13:
/* FLI BLACK chunk */ /* FLI BLACK chunk */
for (y = 0; y < state->ysize; y++) for (y = 0; y < state->ysize; y++) {
memset(im->image[y], 0, state->xsize); memset(im->image[y], 0, state->xsize);
}
break; break;
case 15: case 15:
/* FLI BRUN chunk */ /* FLI BRUN chunk */
@ -197,8 +206,9 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
data += i + 1; data += i + 1;
} else { } else {
i = data[0]; i = data[0];
if (x + i > state->xsize) if (x + i > state->xsize) {
break; /* safety first */ break; /* safety first */
}
memset(out + x, data[1], i); memset(out + x, data[1], i);
data += 2; data += 2;
} }

View File

@ -20,10 +20,12 @@ ImagingFlipLeftRight(Imaging imOut, Imaging imIn)
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
int x, y, xr; int x, y, xr;
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) }
if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) {
return (Imaging) ImagingError_Mismatch(); return (Imaging) ImagingError_Mismatch();
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
@ -32,8 +34,9 @@ ImagingFlipLeftRight(Imaging imOut, Imaging imIn)
INT* in = (INT *)imIn->image[y]; \ INT* in = (INT *)imIn->image[y]; \
INT* out = (INT *)imOut->image[y]; \ INT* out = (INT *)imOut->image[y]; \
xr = imIn->xsize-1; \ xr = imIn->xsize-1; \
for (x = 0; x < imIn->xsize; x++, xr--) \ for (x = 0; x < imIn->xsize; x++, xr--) { \
out[xr] = in[x]; \ out[xr] = in[x]; \
} \
} }
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
@ -62,18 +65,21 @@ ImagingFlipTopBottom(Imaging imOut, Imaging imIn)
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
int y, yr; int y, yr;
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) }
if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) {
return (Imaging) ImagingError_Mismatch(); return (Imaging) ImagingError_Mismatch();
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
yr = imIn->ysize - 1; yr = imIn->ysize - 1;
for (y = 0; y < imIn->ysize; y++, yr--) for (y = 0; y < imIn->ysize; y++, yr--) {
memcpy(imOut->image[yr], imIn->image[y], imIn->linesize); memcpy(imOut->image[yr], imIn->image[y], imIn->linesize);
}
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
@ -88,10 +94,12 @@ ImagingRotate90(Imaging imOut, Imaging imIn)
int x, y, xx, yy, xr, xxsize, yysize; int x, y, xx, yy, xr, xxsize, yysize;
int xxx, yyy, xxxsize, yyysize; int xxx, yyy, xxxsize, yyysize;
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) }
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) {
return (Imaging) ImagingError_Mismatch(); return (Imaging) ImagingError_Mismatch();
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
@ -144,10 +152,12 @@ ImagingTranspose(Imaging imOut, Imaging imIn)
int x, y, xx, yy, xxsize, yysize; int x, y, xx, yy, xxsize, yysize;
int xxx, yyy, xxxsize, yyysize; int xxx, yyy, xxxsize, yyysize;
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) }
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) {
return (Imaging) ImagingError_Mismatch(); return (Imaging) ImagingError_Mismatch();
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
@ -199,10 +209,12 @@ ImagingTransverse(Imaging imOut, Imaging imIn)
int x, y, xr, yr, xx, yy, xxsize, yysize; int x, y, xr, yr, xx, yy, xxsize, yysize;
int xxx, yyy, xxxsize, yyysize; int xxx, yyy, xxxsize, yyysize;
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) }
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) {
return (Imaging) ImagingError_Mismatch(); return (Imaging) ImagingError_Mismatch();
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
@ -255,10 +267,12 @@ ImagingRotate180(Imaging imOut, Imaging imIn)
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
int x, y, xr, yr; int x, y, xr, yr;
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) }
if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) {
return (Imaging) ImagingError_Mismatch(); return (Imaging) ImagingError_Mismatch();
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
@ -267,8 +281,9 @@ ImagingRotate180(Imaging imOut, Imaging imIn)
INT* in = (INT *)imIn->image[y]; \ INT* in = (INT *)imIn->image[y]; \
INT* out = (INT *)imOut->image[yr]; \ INT* out = (INT *)imOut->image[yr]; \
xr = imIn->xsize-1; \ xr = imIn->xsize-1; \
for (x = 0; x < imIn->xsize; x++, xr--) \ for (x = 0; x < imIn->xsize; x++, xr--) { \
out[xr] = in[x]; \ out[xr] = in[x]; \
} \
} }
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
@ -299,10 +314,12 @@ ImagingRotate270(Imaging imOut, Imaging imIn)
int x, y, xx, yy, yr, xxsize, yysize; int x, y, xx, yy, yr, xxsize, yysize;
int xxx, yyy, xxxsize, yyysize; int xxx, yyy, xxxsize, yyysize;
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) }
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) {
return (Imaging) ImagingError_Mismatch(); return (Imaging) ImagingError_Mismatch();
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
@ -415,8 +432,9 @@ nearest_filter8(void* out, Imaging im, double xin, double yin)
{ {
int x = COORD(xin); int x = COORD(xin);
int y = COORD(yin); int y = COORD(yin);
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
return 0; return 0;
}
((UINT8*)out)[0] = im->image8[y][x]; ((UINT8*)out)[0] = im->image8[y][x];
return 1; return 1;
} }
@ -426,8 +444,9 @@ nearest_filter16(void* out, Imaging im, double xin, double yin)
{ {
int x = COORD(xin); int x = COORD(xin);
int y = COORD(yin); int y = COORD(yin);
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
return 0; return 0;
}
memcpy(out, im->image8[y] + x * sizeof(INT16), sizeof(INT16)); memcpy(out, im->image8[y] + x * sizeof(INT16), sizeof(INT16));
return 1; return 1;
} }
@ -437,8 +456,9 @@ nearest_filter32(void* out, Imaging im, double xin, double yin)
{ {
int x = COORD(xin); int x = COORD(xin);
int y = COORD(yin); int y = COORD(yin);
if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
return 0; return 0;
}
memcpy(out, &im->image32[y][x], sizeof(INT32)); memcpy(out, &im->image32[y][x], sizeof(INT32));
return 1; return 1;
} }
@ -455,8 +475,9 @@ nearest_filter32(void* out, Imaging im, double xin, double yin)
double v1, v2;\ double v1, v2;\
double dx, dy;\ double dx, dy;\
type* in;\ type* in;\
if (xin < 0.0 || xin >= im->xsize || yin < 0.0 || yin >= im->ysize)\ if (xin < 0.0 || xin >= im->xsize || yin < 0.0 || yin >= im->ysize) {\
return 0;\ return 0;\
}\
xin -= 0.5;\ xin -= 0.5;\
yin -= 0.5;\ yin -= 0.5;\
x = FLOOR(xin);\ x = FLOOR(xin);\
@ -472,8 +493,9 @@ nearest_filter32(void* out, Imaging im, double xin, double yin)
if (y+1 >= 0 && y+1 < im->ysize) {\ if (y+1 >= 0 && y+1 < im->ysize) {\
in = (type*) ((image)[y+1] + offset);\ in = (type*) ((image)[y+1] + offset);\
BILINEAR(v2, in[x0], in[x1], dx);\ BILINEAR(v2, in[x0], in[x1], dx);\
} else\ } else {\
v2 = v1;\ v2 = v1;\
}\
BILINEAR(v1, v1, v2, dy);\ BILINEAR(v1, v1, v2, dy);\
} }
@ -552,8 +574,9 @@ bilinear_filter32RGB(void* out, Imaging im, double xin, double yin)
double v1, v2, v3, v4;\ double v1, v2, v3, v4;\
double dx, dy;\ double dx, dy;\
type* in;\ type* in;\
if (xin < 0.0 || xin >= im->xsize || yin < 0.0 || yin >= im->ysize)\ if (xin < 0.0 || xin >= im->xsize || yin < 0.0 || yin >= im->ysize) {\
return 0;\ return 0;\
}\
xin -= 0.5;\ xin -= 0.5;\
yin -= 0.5;\ yin -= 0.5;\
x = FLOOR(xin);\ x = FLOOR(xin);\
@ -572,18 +595,21 @@ bilinear_filter32RGB(void* out, Imaging im, double xin, double yin)
if (y+1 >= 0 && y+1 < im->ysize) {\ if (y+1 >= 0 && y+1 < im->ysize) {\
in = (type*) ((image)[y+1] + offset);\ in = (type*) ((image)[y+1] + offset);\
BICUBIC(v2, in[x0], in[x1], in[x2], in[x3], dx);\ BICUBIC(v2, in[x0], in[x1], in[x2], in[x3], dx);\
} else\ } else {\
v2 = v1;\ v2 = v1;\
}\
if (y+2 >= 0 && y+2 < im->ysize) {\ if (y+2 >= 0 && y+2 < im->ysize) {\
in = (type*) ((image)[y+2] + offset);\ in = (type*) ((image)[y+2] + offset);\
BICUBIC(v3, in[x0], in[x1], in[x2], in[x3], dx);\ BICUBIC(v3, in[x0], in[x1], in[x2], in[x3], dx);\
} else\ } else {\
v3 = v2;\ v3 = v2;\
}\
if (y+3 >= 0 && y+3 < im->ysize) {\ if (y+3 >= 0 && y+3 < im->ysize) {\
in = (type*) ((image)[y+3] + offset);\ in = (type*) ((image)[y+3] + offset);\
BICUBIC(v4, in[x0], in[x1], in[x2], in[x3], dx);\ BICUBIC(v4, in[x0], in[x1], in[x2], in[x3], dx);\
} else\ } else {\
v4 = v3;\ v4 = v3;\
}\
BICUBIC(v1, v1, v2, v3, v4, dy);\ BICUBIC(v1, v1, v2, v3, v4, dy);\
} }
@ -593,12 +619,13 @@ bicubic_filter8(void* out, Imaging im, double xin, double yin)
{ {
BICUBIC_HEAD(UINT8); BICUBIC_HEAD(UINT8);
BICUBIC_BODY(UINT8, im->image8, 1, 0); BICUBIC_BODY(UINT8, im->image8, 1, 0);
if (v1 <= 0.0) if (v1 <= 0.0) {
((UINT8*)out)[0] = 0; ((UINT8*)out)[0] = 0;
else if (v1 >= 255.0) } else if (v1 >= 255.0) {
((UINT8*)out)[0] = 255; ((UINT8*)out)[0] = 255;
else } else {
((UINT8*)out)[0] = (UINT8) v1; ((UINT8*)out)[0] = (UINT8) v1;
}
return 1; return 1;
} }
@ -643,12 +670,13 @@ bicubic_filter32LA(void* out, Imaging im, double xin, double yin)
((UINT8*)out)[2] = (UINT8) v1; ((UINT8*)out)[2] = (UINT8) v1;
} }
BICUBIC_BODY(UINT8, im->image, 4, 3); BICUBIC_BODY(UINT8, im->image, 4, 3);
if (v1 <= 0.0) if (v1 <= 0.0) {
((UINT8*)out)[3] = 0; ((UINT8*)out)[3] = 0;
else if (v1 >= 255.0) } else if (v1 >= 255.0) {
((UINT8*)out)[3] = 255; ((UINT8*)out)[3] = 255;
else } else {
((UINT8*)out)[3] = (UINT8) v1; ((UINT8*)out)[3] = (UINT8) v1;
}
return 1; return 1;
} }
@ -659,12 +687,13 @@ bicubic_filter32RGB(void* out, Imaging im, double xin, double yin)
BICUBIC_HEAD(UINT8); BICUBIC_HEAD(UINT8);
for (b = 0; b < im->bands; b++) { for (b = 0; b < im->bands; b++) {
BICUBIC_BODY(UINT8, im->image, 4, b); BICUBIC_BODY(UINT8, im->image, 4, b);
if (v1 <= 0.0) if (v1 <= 0.0) {
((UINT8*)out)[b] = 0; ((UINT8*)out)[b] = 0;
else if (v1 >= 255.0) } else if (v1 >= 255.0) {
((UINT8*)out)[b] = 255; ((UINT8*)out)[b] = 255;
else } else {
((UINT8*)out)[b] = (UINT8) v1; ((UINT8*)out)[b] = (UINT8) v1;
}
} }
return 1; return 1;
} }
@ -678,7 +707,7 @@ getfilter(Imaging im, int filterid)
{ {
switch (filterid) { switch (filterid) {
case IMAGING_TRANSFORM_NEAREST: case IMAGING_TRANSFORM_NEAREST:
if (im->image8) if (im->image8) {
switch (im->type) { switch (im->type) {
case IMAGING_TYPE_UINT8: case IMAGING_TYPE_UINT8:
return nearest_filter8; return nearest_filter8;
@ -692,19 +721,21 @@ getfilter(Imaging im, int filterid)
return nearest_filter32; return nearest_filter32;
} }
} }
else } else {
return nearest_filter32; return nearest_filter32;
}
break; break;
case IMAGING_TRANSFORM_BILINEAR: case IMAGING_TRANSFORM_BILINEAR:
if (im->image8) if (im->image8) {
return bilinear_filter8; return bilinear_filter8;
else if (im->image32) { } else if (im->image32) {
switch (im->type) { switch (im->type) {
case IMAGING_TYPE_UINT8: case IMAGING_TYPE_UINT8:
if (im->bands == 2) if (im->bands == 2) {
return bilinear_filter32LA; return bilinear_filter32LA;
else } else {
return bilinear_filter32RGB; return bilinear_filter32RGB;
}
case IMAGING_TYPE_INT32: case IMAGING_TYPE_INT32:
return bilinear_filter32I; return bilinear_filter32I;
case IMAGING_TYPE_FLOAT32: case IMAGING_TYPE_FLOAT32:
@ -713,15 +744,16 @@ getfilter(Imaging im, int filterid)
} }
break; break;
case IMAGING_TRANSFORM_BICUBIC: case IMAGING_TRANSFORM_BICUBIC:
if (im->image8) if (im->image8) {
return bicubic_filter8; return bicubic_filter8;
else if (im->image32) { } else if (im->image32) {
switch (im->type) { switch (im->type) {
case IMAGING_TYPE_UINT8: case IMAGING_TYPE_UINT8:
if (im->bands == 2) if (im->bands == 2) {
return bicubic_filter32LA; return bicubic_filter32LA;
else } else {
return bicubic_filter32RGB; return bicubic_filter32RGB;
}
case IMAGING_TYPE_INT32: case IMAGING_TYPE_INT32:
return bicubic_filter32I; return bicubic_filter32I;
case IMAGING_TYPE_FLOAT32: case IMAGING_TYPE_FLOAT32:
@ -751,32 +783,39 @@ ImagingGenericTransform(
double xx, yy; double xx, yy;
ImagingTransformFilter filter = getfilter(imIn, filterid); ImagingTransformFilter filter = getfilter(imIn, filterid);
if (!filter) if (!filter) {
return (Imaging) ImagingError_ValueError("bad filter number"); return (Imaging) ImagingError_ValueError("bad filter number");
}
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
if (x0 < 0) if (x0 < 0) {
x0 = 0; x0 = 0;
if (y0 < 0) }
if (y0 < 0) {
y0 = 0; y0 = 0;
if (x1 > imOut->xsize) }
if (x1 > imOut->xsize) {
x1 = imOut->xsize; x1 = imOut->xsize;
if (y1 > imOut->ysize) }
if (y1 > imOut->ysize) {
y1 = imOut->ysize; y1 = imOut->ysize;
}
for (y = y0; y < y1; y++) { for (y = y0; y < y1; y++) {
out = imOut->image[y] + x0*imOut->pixelsize; out = imOut->image[y] + x0*imOut->pixelsize;
for (x = x0; x < x1; x++) { for (x = x0; x < x1; x++) {
if ( ! transform(&xx, &yy, x-x0, y-y0, transform_data) || if ( ! transform(&xx, &yy, x-x0, y-y0, transform_data) ||
! filter(out, imIn, xx, yy)) { ! filter(out, imIn, xx, yy)) {
if (fill) if (fill) {
memset(out, 0, imOut->pixelsize); memset(out, 0, imOut->pixelsize);
}
} }
out += imOut->pixelsize; out += imOut->pixelsize;
} }
@ -801,19 +840,24 @@ ImagingScaleAffine(Imaging imOut, Imaging imIn,
int xmin, xmax; int xmin, xmax;
int *xintab; int *xintab;
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
if (x0 < 0) if (x0 < 0) {
x0 = 0; x0 = 0;
if (y0 < 0) }
if (y0 < 0) {
y0 = 0; y0 = 0;
if (x1 > imOut->xsize) }
if (x1 > imOut->xsize) {
x1 = imOut->xsize; x1 = imOut->xsize;
if (y1 > imOut->ysize) }
if (y1 > imOut->ysize) {
y1 = imOut->ysize; y1 = imOut->ysize;
}
/* malloc check ok, uses calloc for overflow */ /* malloc check ok, uses calloc for overflow */
xintab = (int*) calloc(imOut->xsize, sizeof(int)); xintab = (int*) calloc(imOut->xsize, sizeof(int));
@ -833,8 +877,9 @@ ImagingScaleAffine(Imaging imOut, Imaging imIn,
xin = COORD(xo); xin = COORD(xo);
if (xin >= 0 && xin < (int) imIn->xsize) { if (xin >= 0 && xin < (int) imIn->xsize) {
xmax = x+1; xmax = x+1;
if (x < xmin) if (x < xmin) {
xmin = x; xmin = x;
}
xintab[x] = xin; xintab[x] = xin;
} }
xo += a[0]; xo += a[0];
@ -845,12 +890,14 @@ ImagingScaleAffine(Imaging imOut, Imaging imIn,
int yi = COORD(yo);\ int yi = COORD(yo);\
pixel *in, *out;\ pixel *in, *out;\
out = imOut->image[y];\ out = imOut->image[y];\
if (fill && x1 > x0)\ if (fill && x1 > x0) {\
memset(out+x0, 0, (x1-x0)*sizeof(pixel));\ memset(out+x0, 0, (x1-x0)*sizeof(pixel));\
}\
if (yi >= 0 && yi < imIn->ysize) {\ if (yi >= 0 && yi < imIn->ysize) {\
in = imIn->image[yi];\ in = imIn->image[yi];\
for (x = xmin; x < xmax; x++)\ for (x = xmin; x < xmax; x++) {\
out[x] = in[xintab[x]];\ out[x] = in[xintab[x]];\
}\
}\ }\
yo += a[4];\ yo += a[4];\
} }
@ -915,14 +962,16 @@ affine_fixed(Imaging imOut, Imaging imIn,
xx = a2;\ xx = a2;\
yy = a5;\ yy = a5;\
out = imOut->image[y];\ out = imOut->image[y];\
if (fill && x1 > x0)\ if (fill && x1 > x0) {\
memset(out+x0, 0, (x1-x0)*sizeof(pixel));\ memset(out+x0, 0, (x1-x0)*sizeof(pixel));\
}\
for (x = x0; x < x1; x++, out++) {\ for (x = x0; x < x1; x++, out++) {\
xin = xx >> 16;\ xin = xx >> 16;\
if (xin >= 0 && xin < xsize) {\ if (xin >= 0 && xin < xsize) {\
yin = yy >> 16;\ yin = yy >> 16;\
if (yin >= 0 && yin < ysize)\ if (yin >= 0 && yin < ysize) {\
*out = imIn->image[yin][xin];\ *out = imIn->image[yin][xin];\
}\
}\ }\
xx += a0;\ xx += a0;\
yy += a3;\ yy += a3;\
@ -933,10 +982,11 @@ affine_fixed(Imaging imOut, Imaging imIn,
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
if (imIn->image8) if (imIn->image8) {
AFFINE_TRANSFORM_FIXED(UINT8, image8) AFFINE_TRANSFORM_FIXED(UINT8, image8)
else } else {
AFFINE_TRANSFORM_FIXED(INT32, image32) AFFINE_TRANSFORM_FIXED(INT32, image32)
}
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
@ -973,24 +1023,30 @@ ImagingTransformAffine(Imaging imOut, Imaging imIn,
return ImagingScaleAffine(imOut, imIn, x0, y0, x1, y1, a, fill); return ImagingScaleAffine(imOut, imIn, x0, y0, x1, y1, a, fill);
} }
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (x0 < 0) if (x0 < 0) {
x0 = 0; x0 = 0;
if (y0 < 0) }
if (y0 < 0) {
y0 = 0; y0 = 0;
if (x1 > imOut->xsize) }
if (x1 > imOut->xsize) {
x1 = imOut->xsize; x1 = imOut->xsize;
if (y1 > imOut->ysize) }
if (y1 > imOut->ysize) {
y1 = imOut->ysize; y1 = imOut->ysize;
}
/* translate all four corners to check if they are within the /* translate all four corners to check if they are within the
range that can be represented by the fixed point arithmetics */ range that can be represented by the fixed point arithmetics */
if (check_fixed(a, 0, 0) && check_fixed(a, x1-x0, y1-y0) && if (check_fixed(a, 0, 0) && check_fixed(a, x1-x0, y1-y0) &&
check_fixed(a, 0, y1-y0) && check_fixed(a, x1-x0, 0)) check_fixed(a, 0, y1-y0) && check_fixed(a, x1-x0, 0)) {
return affine_fixed(imOut, imIn, x0, y0, x1, y1, a, filterid, fill); return affine_fixed(imOut, imIn, x0, y0, x1, y1, a, filterid, fill);
}
/* FIXME: cannot really think of any reasonable case when the /* FIXME: cannot really think of any reasonable case when the
following code is used. maybe we should fall back on the slow following code is used. maybe we should fall back on the slow
@ -1010,14 +1066,16 @@ ImagingTransformAffine(Imaging imOut, Imaging imIn,
xx = xo;\ xx = xo;\
yy = yo;\ yy = yo;\
out = imOut->image[y];\ out = imOut->image[y];\
if (fill && x1 > x0)\ if (fill && x1 > x0) {\
memset(out+x0, 0, (x1-x0)*sizeof(pixel));\ memset(out+x0, 0, (x1-x0)*sizeof(pixel));\
}\
for (x = x0; x < x1; x++, out++) {\ for (x = x0; x < x1; x++, out++) {\
xin = COORD(xx);\ xin = COORD(xx);\
if (xin >= 0 && xin < xsize) {\ if (xin >= 0 && xin < xsize) {\
yin = COORD(yy);\ yin = COORD(yy);\
if (yin >= 0 && yin < ysize)\ if (yin >= 0 && yin < ysize) {\
*out = imIn->image[yin][xin];\ *out = imIn->image[yin][xin];\
}\
}\ }\
xx += a[0];\ xx += a[0];\
yy += a[3];\ yy += a[3];\
@ -1028,10 +1086,11 @@ ImagingTransformAffine(Imaging imOut, Imaging imIn,
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
if (imIn->image8) if (imIn->image8) {
AFFINE_TRANSFORM(UINT8, image8) AFFINE_TRANSFORM(UINT8, image8)
else } else {
AFFINE_TRANSFORM(INT32, image32) AFFINE_TRANSFORM(INT32, image32)
}
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);

View File

@ -36,17 +36,21 @@ ImagingGetBBox(Imaging im, int bbox[4])
#define GETBBOX(image, mask)\ #define GETBBOX(image, mask)\
for (y = 0; y < im->ysize; y++) {\ for (y = 0; y < im->ysize; y++) {\
has_data = 0;\ has_data = 0;\
for (x = 0; x < im->xsize; x++)\ for (x = 0; x < im->xsize; x++) {\
if (im->image[y][x] & mask) {\ if (im->image[y][x] & mask) {\
has_data = 1;\ has_data = 1;\
if (x < bbox[0])\ if (x < bbox[0]) {\
bbox[0] = x;\ bbox[0] = x;\
if (x >= bbox[2])\ }\
if (x >= bbox[2]) {\
bbox[2] = x+1;\ bbox[2] = x+1;\
}\
}\ }\
}\
if (has_data) {\ if (has_data) {\
if (bbox[1] < 0)\ if (bbox[1] < 0) {\
bbox[1] = y;\ bbox[1] = y;\
}\
bbox[3] = y+1;\ bbox[3] = y+1;\
}\ }\
} }
@ -72,8 +76,9 @@ ImagingGetBBox(Imaging im, int bbox[4])
} }
/* Check that we got a box */ /* Check that we got a box */
if (bbox[1] < 0) if (bbox[1] < 0) {
return 0; /* no data */ return 0; /* no data */
}
return 1; /* ok */ return 1; /* ok */
} }
@ -94,21 +99,24 @@ ImagingGetProjection(Imaging im, UINT8* xproj, UINT8* yproj)
#define GETPROJ(image, mask)\ #define GETPROJ(image, mask)\
for (y = 0; y < im->ysize; y++) {\ for (y = 0; y < im->ysize; y++) {\
has_data = 0;\ has_data = 0;\
for (x = 0; x < im->xsize; x++)\ for (x = 0; x < im->xsize; x++) {\
if (im->image[y][x] & mask) {\ if (im->image[y][x] & mask) {\
has_data = 1;\ has_data = 1;\
xproj[x] = 1;\ xproj[x] = 1;\
}\ }\
if (has_data)\ }\
yproj[y] = 1;\ if (has_data) {\
} yproj[y] = 1;\
}\
}
if (im->image8) { if (im->image8) {
GETPROJ(image8, 0xff); GETPROJ(image8, 0xff);
} else { } else {
INT32 mask = 0xffffffff; INT32 mask = 0xffffffff;
if (im->bands == 3) if (im->bands == 3) {
((UINT8*) &mask)[3] = 0; ((UINT8*) &mask)[3] = 0;
}
GETPROJ(image32, mask); GETPROJ(image32, mask);
} }
@ -128,8 +136,9 @@ ImagingGetExtrema(Imaging im, void *extrema)
return -1; /* mismatch */ return -1; /* mismatch */
} }
if (!im->xsize || !im->ysize) if (!im->xsize || !im->ysize) {
return 0; /* zero size */ return 0; /* zero size */
}
switch (im->type) { switch (im->type) {
case IMAGING_TYPE_UINT8: case IMAGING_TYPE_UINT8:
@ -137,10 +146,11 @@ ImagingGetExtrema(Imaging im, void *extrema)
for (y = 0; y < im->ysize; y++) { for (y = 0; y < im->ysize; y++) {
UINT8* in = im->image8[y]; UINT8* in = im->image8[y];
for (x = 0; x < im->xsize; x++) { for (x = 0; x < im->xsize; x++) {
if (imin > in[x]) if (imin > in[x]) {
imin = in[x]; imin = in[x];
else if (imax < in[x]) } else if (imax < in[x]) {
imax = in[x]; imax = in[x];
}
} }
} }
((UINT8*) extrema)[0] = (UINT8) imin; ((UINT8*) extrema)[0] = (UINT8) imin;
@ -151,10 +161,11 @@ ImagingGetExtrema(Imaging im, void *extrema)
for (y = 0; y < im->ysize; y++) { for (y = 0; y < im->ysize; y++) {
INT32* in = im->image32[y]; INT32* in = im->image32[y];
for (x = 0; x < im->xsize; x++) { for (x = 0; x < im->xsize; x++) {
if (imin > in[x]) if (imin > in[x]) {
imin = in[x]; imin = in[x];
else if (imax < in[x]) } else if (imax < in[x]) {
imax = in[x]; imax = in[x];
}
} }
} }
memcpy(extrema, &imin, sizeof(imin)); memcpy(extrema, &imin, sizeof(imin));
@ -165,10 +176,11 @@ ImagingGetExtrema(Imaging im, void *extrema)
for (y = 0; y < im->ysize; y++) { for (y = 0; y < im->ysize; y++) {
FLOAT32* in = (FLOAT32*) im->image32[y]; FLOAT32* in = (FLOAT32*) im->image32[y];
for (x = 0; x < im->xsize; x++) { for (x = 0; x < im->xsize; x++) {
if (fmin > in[x]) if (fmin > in[x]) {
fmin = in[x]; fmin = in[x];
else if (fmax < in[x]) } else if (fmax < in[x]) {
fmax = in[x]; fmax = in[x];
}
} }
} }
memcpy(extrema, &fmin, sizeof(fmin)); memcpy(extrema, &fmin, sizeof(fmin));
@ -192,10 +204,11 @@ ImagingGetExtrema(Imaging im, void *extrema)
#else #else
memcpy(&v, pixel, sizeof(v)); memcpy(&v, pixel, sizeof(v));
#endif #endif
if (imin > v) if (imin > v) {
imin = v; imin = v;
else if (imax < v) } else if (imax < v) {
imax = v; imax = v;
}
} }
} }
v = (UINT16) imin; v = (UINT16) imin;
@ -264,19 +277,23 @@ getcolors32(Imaging im, int maxcolors, int* size)
/* printf("code_size=%d\n", code_size); */ /* printf("code_size=%d\n", code_size); */
/* printf("code_poly=%d\n", code_poly); */ /* printf("code_poly=%d\n", code_poly); */
if (!code_size) if (!code_size) {
return ImagingError_MemoryError(); /* just give up */ return ImagingError_MemoryError(); /* just give up */
}
if (!im->image32) if (!im->image32) {
return ImagingError_ModeError(); return ImagingError_ModeError();
}
table = calloc(code_size + 1, sizeof(ImagingColorItem)); table = calloc(code_size + 1, sizeof(ImagingColorItem));
if (!table) if (!table) {
return ImagingError_MemoryError(); return ImagingError_MemoryError();
}
pixel_mask = 0xffffffff; pixel_mask = 0xffffffff;
if (im->bands == 3) if (im->bands == 3) {
((UINT8*) &pixel_mask)[3] = 0; ((UINT8*) &pixel_mask)[3] = 0;
}
colors = 0; colors = 0;
@ -289,8 +306,9 @@ getcolors32(Imaging im, int maxcolors, int* size)
v = &table[i]; v = &table[i];
if (!v->count) { if (!v->count) {
/* add to table */ /* add to table */
if (colors++ == maxcolors) if (colors++ == maxcolors) {
goto overflow; goto overflow;
}
v->x = x; v->y = y; v->x = x; v->y = y;
v->pixel = pixel; v->pixel = pixel;
v->count = 1; v->count = 1;
@ -300,15 +318,17 @@ getcolors32(Imaging im, int maxcolors, int* size)
continue; continue;
} }
incr = (h ^ (h >> 3)) & code_mask; incr = (h ^ (h >> 3)) & code_mask;
if (!incr) if (!incr) {
incr = code_mask; incr = code_mask;
}
for (;;) { for (;;) {
i = (i + incr) & code_mask; i = (i + incr) & code_mask;
v = &table[i]; v = &table[i];
if (!v->count) { if (!v->count) {
/* add to table */ /* add to table */
if (colors++ == maxcolors) if (colors++ == maxcolors) {
goto overflow; goto overflow;
}
v->x = x; v->y = y; v->x = x; v->y = y;
v->pixel = pixel; v->pixel = pixel;
v->count = 1; v->count = 1;
@ -318,8 +338,9 @@ getcolors32(Imaging im, int maxcolors, int* size)
break; break;
} }
incr = incr << 1; incr = incr << 1;
if (incr > code_mask) if (incr > code_mask) {
incr = incr ^ code_poly; incr = incr ^ code_poly;
}
} }
} }
} }
@ -329,8 +350,9 @@ overflow:
/* pack the table */ /* pack the table */
for (x = y = 0; x < (int) code_size; x++) for (x = y = 0; x < (int) code_size; x++)
if (table[x].count) { if (table[x].count) {
if (x != y) if (x != y) {
table[y] = table[x]; table[y] = table[x];
}
y++; y++;
} }
table[y].count = 0; /* mark end of table */ table[y].count = 0; /* mark end of table */

View File

@ -52,8 +52,9 @@
default:\ default:\
return -1;\ return -1;\
}\ }\
if (state->y < state->ysize)\ if (state->y < state->ysize) {\
out = im->image8[state->y + state->yoff] + state->xoff;\ out = im->image8[state->y + state->yoff] + state->xoff;\
}\
} }
@ -70,24 +71,25 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
if (!state->state) { if (!state->state) {
/* Initialise state */ /* Initialise state */
if (context->bits < 0 || context->bits > 12) { if (context->bits < 0 || context->bits > 12) {
state->errcode = IMAGING_CODEC_CONFIG; state->errcode = IMAGING_CODEC_CONFIG;
return -1; return -1;
} }
/* Clear code */ /* Clear code */
context->clear = 1 << context->bits; context->clear = 1 << context->bits;
/* End code */ /* End code */
context->end = context->clear + 1; context->end = context->clear + 1;
/* Interlace */ /* Interlace */
if (context->interlace) { if (context->interlace) {
context->interlace = 1; context->interlace = 1;
context->step = context->repeat = 8; context->step = context->repeat = 8;
} else } else {
context->step = 1; context->step = 1;
}
state->state = 1; state->state = 1;
} }
@ -142,11 +144,13 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
/* New GIF block */ /* New GIF block */
/* We don't start decoding unless we have a full block */ /* We don't start decoding unless we have a full block */
if (bytes < 1) if (bytes < 1) {
return ptr - buffer; return ptr - buffer;
}
c = *ptr; c = *ptr;
if (bytes < c+1) if (bytes < c+1) {
return ptr - buffer; return ptr - buffer;
}
context->blocksize = c; context->blocksize = c;
@ -167,13 +171,15 @@ ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t
expanded. */ expanded. */
if (c == context->clear) { if (c == context->clear) {
if (state->state != 2) if (state->state != 2) {
state->state = 1; state->state = 1;
}
continue; continue;
} }
if (c == context->end) if (c == context->end) {
break; break;
}
i = 1; i = 1;
p = &context->lastdata; p = &context->lastdata;

View File

@ -48,12 +48,14 @@ emit(GIFENCODERSTATE *context, int byte)
/* add current block to end of flush queue */ /* add current block to end of flush queue */
if (context->block) { if (context->block) {
block = context->flush; block = context->flush;
while (block && block->next) while (block && block->next) {
block = block->next; block = block->next;
if (block) }
if (block) {
block->next = context->block; block->next = context->block;
else } else {
context->flush = context->block; context->flush = context->block;
}
} }
/* get a new block */ /* get a new block */
@ -63,8 +65,9 @@ emit(GIFENCODERSTATE *context, int byte)
} else { } else {
/* malloc check ok, small constant allocation */ /* malloc check ok, small constant allocation */
block = malloc(sizeof(GIFENCODERBLOCK)); block = malloc(sizeof(GIFENCODERBLOCK));
if (!block) if (!block) {
return 0; return 0;
}
} }
block->size = 0; block->size = 0;
@ -154,14 +157,16 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
if (context->interlace) { if (context->interlace) {
context->interlace = 1; context->interlace = 1;
context->step = 8; context->step = 8;
} else } else {
context->step = 1; context->step = 1;
}
context->last = -1; context->last = -1;
/* sanity check */ /* sanity check */
if (state->xsize <= 0 || state->ysize <= 0) if (state->xsize <= 0 || state->ysize <= 0) {
state->state = ENCODE_EOF; state->state = ENCODE_EOF;
}
} }
@ -231,9 +236,9 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
this = state->buffer[state->x++]; this = state->buffer[state->x++];
if (this == context->last) if (this == context->last) {
context->count++; context->count++;
else { } else {
EMIT_RUN(label1); EMIT_RUN(label1);
context->last = this; context->last = this;
context->count = 1; context->count = 1;
@ -263,12 +268,14 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
if (context->block) { if (context->block) {
GIFENCODERBLOCK* block; GIFENCODERBLOCK* block;
block = context->flush; block = context->flush;
while (block && block->next) while (block && block->next) {
block = block->next; block = block->next;
if (block) }
if (block) {
block->next = context->block; block->next = context->block;
else } else {
context->flush = context->block; context->flush = context->block;
}
context->block = NULL; context->block = NULL;
} }
@ -287,8 +294,9 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
if (block->size > 0) { if (block->size > 0) {
/* make sure it fits into the output buffer */ /* make sure it fits into the output buffer */
if (bytes < block->size+1) if (bytes < block->size+1) {
return ptr - buf; return ptr - buf;
}
ptr[0] = block->size; ptr[0] = block->size;
memcpy(ptr+1, block->data, block->size); memcpy(ptr+1, block->data, block->size);
@ -300,16 +308,18 @@ ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
context->flush = block->next; context->flush = block->next;
if (context->free) if (context->free) {
free(context->free); free(context->free);
}
context->free = block; context->free = block;
} }
if (state->state == EXIT) { if (state->state == EXIT) {
/* this was the last block! */ /* this was the last block! */
if (context->free) if (context->free) {
free(context->free); free(context->free);
}
state->errcode = IMAGING_CODEC_END; state->errcode = IMAGING_CODEC_END;
return ptr - buf; return ptr - buf;
} }

View File

@ -30,8 +30,9 @@ ImagingHexDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
for (;;) { for (;;) {
if (bytes < 2) if (bytes < 2) {
return ptr - buf; return ptr - buf;
}
a = HEX(ptr[0]); a = HEX(ptr[0]);
b = HEX(ptr[1]); b = HEX(ptr[1]);

View File

@ -29,8 +29,9 @@
void void
ImagingHistogramDelete(ImagingHistogram h) ImagingHistogramDelete(ImagingHistogram h)
{ {
if (h->histogram) if (h->histogram) {
free(h->histogram); free(h->histogram);
}
free(h); free(h);
} }
@ -59,15 +60,18 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax)
INT32 imin, imax; INT32 imin, imax;
FLOAT32 fmin, fmax, scale; FLOAT32 fmin, fmax, scale;
if (!im) if (!im) {
return ImagingError_ModeError(); return ImagingError_ModeError();
}
if (imMask) { if (imMask) {
/* Validate mask */ /* Validate mask */
if (im->xsize != imMask->xsize || im->ysize != imMask->ysize) if (im->xsize != imMask->xsize || im->ysize != imMask->ysize) {
return ImagingError_Mismatch(); return ImagingError_Mismatch();
if (strcmp(imMask->mode, "1") != 0 && strcmp(imMask->mode, "L") != 0) }
if (strcmp(imMask->mode, "1") != 0 && strcmp(imMask->mode, "L") != 0) {
return ImagingError_ValueError("bad transparency mask"); return ImagingError_ValueError("bad transparency mask");
}
} }
h = ImagingHistogramNew(im); h = ImagingHistogramNew(im);
@ -75,12 +79,15 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax)
if (imMask) { if (imMask) {
/* mask */ /* mask */
if (im->image8) { if (im->image8) {
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
for (y = 0; y < im->ysize; y++) for (y = 0; y < im->ysize; y++) {
for (x = 0; x < im->xsize; x++) for (x = 0; x < im->xsize; x++) {
if (imMask->image8[y][x] != 0) if (imMask->image8[y][x] != 0) {
h->histogram[im->image8[y][x]]++; h->histogram[im->image8[y][x]]++;
ImagingSectionLeave(&cookie); }
}
}
ImagingSectionLeave(&cookie);
} else { /* yes, we need the braces. C isn't Python! */ } else { /* yes, we need the braces. C isn't Python! */
if (im->type != IMAGING_TYPE_UINT8) { if (im->type != IMAGING_TYPE_UINT8) {
ImagingHistogramDelete(h); ImagingHistogramDelete(h);
@ -89,25 +96,29 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax)
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
for (y = 0; y < im->ysize; y++) { for (y = 0; y < im->ysize; y++) {
UINT8* in = (UINT8*) im->image32[y]; UINT8* in = (UINT8*) im->image32[y];
for (x = 0; x < im->xsize; x++) for (x = 0; x < im->xsize; x++) {
if (imMask->image8[y][x] != 0) { if (imMask->image8[y][x] != 0) {
h->histogram[(*in++)]++; h->histogram[(*in++)]++;
h->histogram[(*in++)+256]++; h->histogram[(*in++)+256]++;
h->histogram[(*in++)+512]++; h->histogram[(*in++)+512]++;
h->histogram[(*in++)+768]++; h->histogram[(*in++)+768]++;
} else } else {
in += 4; in += 4;
}
}
} }
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
} }
} else { } else {
/* mask not given; process pixels in image */ /* mask not given; process pixels in image */
if (im->image8) { if (im->image8) {
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
for (y = 0; y < im->ysize; y++) for (y = 0; y < im->ysize; y++) {
for (x = 0; x < im->xsize; x++) for (x = 0; x < im->xsize; x++) {
h->histogram[im->image8[y][x]]++; h->histogram[im->image8[y][x]]++;
ImagingSectionLeave(&cookie); }
}
ImagingSectionLeave(&cookie);
} else { } else {
switch (im->type) { switch (im->type) {
case IMAGING_TYPE_UINT8: case IMAGING_TYPE_UINT8:
@ -128,20 +139,23 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax)
ImagingHistogramDelete(h); ImagingHistogramDelete(h);
return ImagingError_ValueError("min/max not given"); return ImagingError_ValueError("min/max not given");
} }
if (!im->xsize || !im->ysize) if (!im->xsize || !im->ysize) {
break; break;
}
memcpy(&imin, minmax, sizeof(imin)); memcpy(&imin, minmax, sizeof(imin));
memcpy(&imax, ((char*)minmax) + sizeof(imin), sizeof(imax)); memcpy(&imax, ((char*)minmax) + sizeof(imin), sizeof(imax));
if (imin >= imax) if (imin >= imax) {
break; break;
}
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
scale = 255.0F / (imax - imin); scale = 255.0F / (imax - imin);
for (y = 0; y < im->ysize; y++) { for (y = 0; y < im->ysize; y++) {
INT32* in = im->image32[y]; INT32* in = im->image32[y];
for (x = 0; x < im->xsize; x++) { for (x = 0; x < im->xsize; x++) {
i = (int) (((*in++)-imin)*scale); i = (int) (((*in++)-imin)*scale);
if (i >= 0 && i < 256) if (i >= 0 && i < 256) {
h->histogram[i]++; h->histogram[i]++;
}
} }
} }
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
@ -151,20 +165,23 @@ ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax)
ImagingHistogramDelete(h); ImagingHistogramDelete(h);
return ImagingError_ValueError("min/max not given"); return ImagingError_ValueError("min/max not given");
} }
if (!im->xsize || !im->ysize) if (!im->xsize || !im->ysize) {
break; break;
}
memcpy(&fmin, minmax, sizeof(fmin)); memcpy(&fmin, minmax, sizeof(fmin));
memcpy(&fmax, ((char*)minmax) + sizeof(fmin), sizeof(fmax)); memcpy(&fmax, ((char*)minmax) + sizeof(fmin), sizeof(fmax));
if (fmin >= fmax) if (fmin >= fmax) {
break; break;
}
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
scale = 255.0F / (fmax - fmin); scale = 255.0F / (fmax - fmin);
for (y = 0; y < im->ysize; y++) { for (y = 0; y < im->ysize; y++) {
FLOAT32* in = (FLOAT32*) im->image32[y]; FLOAT32* in = (FLOAT32*) im->image32[y];
for (x = 0; x < im->xsize; x++) { for (x = 0; x < im->xsize; x++) {
i = (int) (((*in++)-fmin)*scale); i = (int) (((*in++)-fmin)*scale);
if (i >= 0 && i < 256) if (i >= 0 && i < 256) {
h->histogram[i]++; h->histogram[i]++;
}
} }
} }
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);

View File

@ -84,10 +84,11 @@ struct j2k_decode_unpacker {
static inline static inline
unsigned j2ku_shift(unsigned x, int n) unsigned j2ku_shift(unsigned x, int n)
{ {
if (n < 0) if (n < 0) {
return x >> -n; return x >> -n;
else } else {
return x << n; return x << n;
}
} }
static void static void
@ -104,11 +105,13 @@ j2ku_gray_l(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
unsigned x, y; unsigned x, y;
if (csiz == 3) if (csiz == 3) {
csiz = 4; csiz = 4;
}
if (shift < 0) if (shift < 0) {
offset += 1 << (-shift - 1); offset += 1 << (-shift - 1);
}
/* csiz*h*w + offset = tileinfo.datasize */ /* csiz*h*w + offset = tileinfo.datasize */
switch (csiz) { switch (csiz) {
@ -116,24 +119,27 @@ j2ku_gray_l(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
for (y = 0; y < h; ++y) { for (y = 0; y < h; ++y) {
const UINT8 *data = &tiledata[y * w]; const UINT8 *data = &tiledata[y * w];
UINT8 *row = (UINT8 *)im->image[y0 + y] + x0; UINT8 *row = (UINT8 *)im->image[y0 + y] + x0;
for (x = 0; x < w; ++x) for (x = 0; x < w; ++x) {
*row++ = j2ku_shift(offset + *data++, shift); *row++ = j2ku_shift(offset + *data++, shift);
}
} }
break; break;
case 2: case 2:
for (y = 0; y < h; ++y) { for (y = 0; y < h; ++y) {
const UINT16 *data = (const UINT16 *)&tiledata[2 * y * w]; const UINT16 *data = (const UINT16 *)&tiledata[2 * y * w];
UINT8 *row = (UINT8 *)im->image[y0 + y] + x0; UINT8 *row = (UINT8 *)im->image[y0 + y] + x0;
for (x = 0; x < w; ++x) for (x = 0; x < w; ++x) {
*row++ = j2ku_shift(offset + *data++, shift); *row++ = j2ku_shift(offset + *data++, shift);
}
} }
break; break;
case 4: case 4:
for (y = 0; y < h; ++y) { for (y = 0; y < h; ++y) {
const UINT32 *data = (const UINT32 *)&tiledata[4 * y * w]; const UINT32 *data = (const UINT32 *)&tiledata[4 * y * w];
UINT8 *row = (UINT8 *)im->image[y0 + y] + x0; UINT8 *row = (UINT8 *)im->image[y0 + y] + x0;
for (x = 0; x < w; ++x) for (x = 0; x < w; ++x) {
*row++ = j2ku_shift(offset + *data++, shift); *row++ = j2ku_shift(offset + *data++, shift);
}
} }
break; break;
} }
@ -154,35 +160,40 @@ j2ku_gray_i(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
unsigned x, y; unsigned x, y;
if (csiz == 3) if (csiz == 3) {
csiz = 4; csiz = 4;
}
if (shift < 0) if (shift < 0) {
offset += 1 << (-shift - 1); offset += 1 << (-shift - 1);
}
switch (csiz) { switch (csiz) {
case 1: case 1:
for (y = 0; y < h; ++y) { for (y = 0; y < h; ++y) {
const UINT8 *data = &tiledata[y * w]; const UINT8 *data = &tiledata[y * w];
UINT16 *row = (UINT16 *)im->image[y0 + y] + x0; UINT16 *row = (UINT16 *)im->image[y0 + y] + x0;
for (x = 0; x < w; ++x) for (x = 0; x < w; ++x) {
*row++ = j2ku_shift(offset + *data++, shift); *row++ = j2ku_shift(offset + *data++, shift);
}
} }
break; break;
case 2: case 2:
for (y = 0; y < h; ++y) { for (y = 0; y < h; ++y) {
const UINT16 *data = (const UINT16 *)&tiledata[2 * y * w]; const UINT16 *data = (const UINT16 *)&tiledata[2 * y * w];
UINT16 *row = (UINT16 *)im->image[y0 + y] + x0; UINT16 *row = (UINT16 *)im->image[y0 + y] + x0;
for (x = 0; x < w; ++x) for (x = 0; x < w; ++x) {
*row++ = j2ku_shift(offset + *data++, shift); *row++ = j2ku_shift(offset + *data++, shift);
}
} }
break; break;
case 4: case 4:
for (y = 0; y < h; ++y) { for (y = 0; y < h; ++y) {
const UINT32 *data = (const UINT32 *)&tiledata[4 * y * w]; const UINT32 *data = (const UINT32 *)&tiledata[4 * y * w];
UINT16 *row = (UINT16 *)im->image[y0 + y] + x0; UINT16 *row = (UINT16 *)im->image[y0 + y] + x0;
for (x = 0; x < w; ++x) for (x = 0; x < w; ++x) {
*row++ = j2ku_shift(offset + *data++, shift); *row++ = j2ku_shift(offset + *data++, shift);
}
} }
break; break;
} }
@ -203,11 +214,13 @@ j2ku_gray_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
unsigned x, y; unsigned x, y;
if (shift < 0) if (shift < 0) {
offset += 1 << (-shift - 1); offset += 1 << (-shift - 1);
}
if (csiz == 3) if (csiz == 3) {
csiz = 4; csiz = 4;
}
switch (csiz) { switch (csiz) {
case 1: case 1:
@ -267,15 +280,19 @@ j2ku_graya_la(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
unsigned x, y; unsigned x, y;
if (csiz == 3) if (csiz == 3) {
csiz = 4; csiz = 4;
if (acsiz == 3) }
if (acsiz == 3) {
acsiz = 4; acsiz = 4;
}
if (shift < 0) if (shift < 0) {
offset += 1 << (-shift - 1); offset += 1 << (-shift - 1);
if (ashift < 0) }
if (ashift < 0) {
aoffset += 1 << (-ashift - 1); aoffset += 1 << (-ashift - 1);
}
atiledata = tiledata + csiz * w * h; atiledata = tiledata + csiz * w * h;
@ -325,11 +342,13 @@ j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
offsets[n] = in->comps[n].sgnd ? 1 << (in->comps[n].prec - 1) : 0; offsets[n] = in->comps[n].sgnd ? 1 << (in->comps[n].prec - 1) : 0;
csiz[n] = (in->comps[n].prec + 7) >> 3; csiz[n] = (in->comps[n].prec + 7) >> 3;
if (csiz[n] == 3) if (csiz[n] == 3) {
csiz[n] = 4; csiz[n] = 4;
}
if (shifts[n] < 0) if (shifts[n] < 0) {
offsets[n] += 1 << (-shifts[n] - 1); offsets[n] += 1 << (-shifts[n] - 1);
}
cptr += csiz[n] * w * h; cptr += csiz[n] * w * h;
} }
@ -337,8 +356,9 @@ j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
for (y = 0; y < h; ++y) { for (y = 0; y < h; ++y) {
const UINT8 *data[3]; const UINT8 *data[3];
UINT8 *row = (UINT8 *)im->image[y0 + y] + x0 * 4; UINT8 *row = (UINT8 *)im->image[y0 + y] + x0 * 4;
for (n = 0; n < 3; ++n) for (n = 0; n < 3; ++n) {
data[n] = &cdata[n][csiz[n] * y * w]; data[n] = &cdata[n][csiz[n] * y * w];
}
for (x = 0; x < w; ++x) { for (x = 0; x < w; ++x) {
for (n = 0; n < 3; ++n) { for (n = 0; n < 3; ++n) {
@ -377,11 +397,13 @@ j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
offsets[n] = in->comps[n].sgnd ? 1 << (in->comps[n].prec - 1) : 0; offsets[n] = in->comps[n].sgnd ? 1 << (in->comps[n].prec - 1) : 0;
csiz[n] = (in->comps[n].prec + 7) >> 3; csiz[n] = (in->comps[n].prec + 7) >> 3;
if (csiz[n] == 3) if (csiz[n] == 3) {
csiz[n] = 4; csiz[n] = 4;
}
if (shifts[n] < 0) if (shifts[n] < 0) {
offsets[n] += 1 << (-shifts[n] - 1); offsets[n] += 1 << (-shifts[n] - 1);
}
cptr += csiz[n] * w * h; cptr += csiz[n] * w * h;
} }
@ -390,8 +412,9 @@ j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
const UINT8 *data[3]; const UINT8 *data[3];
UINT8 *row = (UINT8 *)im->image[y0 + y] + x0 * 4; UINT8 *row = (UINT8 *)im->image[y0 + y] + x0 * 4;
UINT8 *row_start = row; UINT8 *row_start = row;
for (n = 0; n < 3; ++n) for (n = 0; n < 3; ++n) {
data[n] = &cdata[n][csiz[n] * y * w]; data[n] = &cdata[n][csiz[n] * y * w];
}
for (x = 0; x < w; ++x) { for (x = 0; x < w; ++x) {
for (n = 0; n < 3; ++n) { for (n = 0; n < 3; ++n) {
@ -432,11 +455,13 @@ j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
offsets[n] = in->comps[n].sgnd ? 1 << (in->comps[n].prec - 1) : 0; offsets[n] = in->comps[n].sgnd ? 1 << (in->comps[n].prec - 1) : 0;
csiz[n] = (in->comps[n].prec + 7) >> 3; csiz[n] = (in->comps[n].prec + 7) >> 3;
if (csiz[n] == 3) if (csiz[n] == 3) {
csiz[n] = 4; csiz[n] = 4;
}
if (shifts[n] < 0) if (shifts[n] < 0) {
offsets[n] += 1 << (-shifts[n] - 1); offsets[n] += 1 << (-shifts[n] - 1);
}
cptr += csiz[n] * w * h; cptr += csiz[n] * w * h;
} }
@ -444,8 +469,9 @@ j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
for (y = 0; y < h; ++y) { for (y = 0; y < h; ++y) {
const UINT8 *data[4]; const UINT8 *data[4];
UINT8 *row = (UINT8 *)im->image[y0 + y] + x0 * 4; UINT8 *row = (UINT8 *)im->image[y0 + y] + x0 * 4;
for (n = 0; n < 4; ++n) for (n = 0; n < 4; ++n) {
data[n] = &cdata[n][csiz[n] * y * w]; data[n] = &cdata[n][csiz[n] * y * w];
}
for (x = 0; x < w; ++x) { for (x = 0; x < w; ++x) {
for (n = 0; n < 4; ++n) { for (n = 0; n < 4; ++n) {
@ -483,11 +509,13 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
offsets[n] = in->comps[n].sgnd ? 1 << (in->comps[n].prec - 1) : 0; offsets[n] = in->comps[n].sgnd ? 1 << (in->comps[n].prec - 1) : 0;
csiz[n] = (in->comps[n].prec + 7) >> 3; csiz[n] = (in->comps[n].prec + 7) >> 3;
if (csiz[n] == 3) if (csiz[n] == 3) {
csiz[n] = 4; csiz[n] = 4;
}
if (shifts[n] < 0) if (shifts[n] < 0) {
offsets[n] += 1 << (-shifts[n] - 1); offsets[n] += 1 << (-shifts[n] - 1);
}
cptr += csiz[n] * w * h; cptr += csiz[n] * w * h;
} }
@ -496,8 +524,9 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
const UINT8 *data[4]; const UINT8 *data[4];
UINT8 *row = (UINT8 *)im->image[y0 + y] + x0 * 4; UINT8 *row = (UINT8 *)im->image[y0 + y] + x0 * 4;
UINT8 *row_start = row; UINT8 *row_start = row;
for (n = 0; n < 4; ++n) for (n = 0; n < 4; ++n) {
data[n] = &cdata[n][csiz[n] * y * w]; data[n] = &cdata[n][csiz[n] * y * w];
}
for (x = 0; x < w; ++x) { for (x = 0; x < w; ++x) {
for (n = 0; n < 4; ++n) { for (n = 0; n < 4; ++n) {
@ -584,10 +613,11 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
possibly support is 4GB. We can't go larger than this, because possibly support is 4GB. We can't go larger than this, because
OpenJPEG truncates this value for the final box in the file, and OpenJPEG truncates this value for the final box in the file, and
the box lengths in OpenJPEG are currently 32 bit. */ the box lengths in OpenJPEG are currently 32 bit. */
if (context->length < 0) if (context->length < 0) {
opj_stream_set_user_data_length(stream, 0xffffffff); opj_stream_set_user_data_length(stream, 0xffffffff);
else } else {
opj_stream_set_user_data_length(stream, context->length); opj_stream_set_user_data_length(stream, context->length);
}
#endif #endif
/* Setup decompression context */ /* Setup decompression context */
@ -696,8 +726,9 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
goto quick_exit; goto quick_exit;
} }
if (!should_continue) if (!should_continue) {
break; break;
}
/* Adjust the tile co-ordinates based on the reduction (OpenJPEG /* Adjust the tile co-ordinates based on the reduction (OpenJPEG
doesn't do this for us) */ doesn't do this for us) */
@ -784,12 +815,15 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
} }
quick_exit: quick_exit:
if (codec) if (codec) {
opj_destroy_codec(codec); opj_destroy_codec(codec);
if (image) }
if (image) {
opj_image_destroy(image); opj_image_destroy(image);
if (stream) }
if (stream) {
opj_stream_destroy(stream); opj_stream_destroy(stream);
}
return -1; return -1;
} }
@ -804,8 +838,9 @@ ImagingJpeg2KDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t
return -1; return -1;
} }
if (state->state == J2K_STATE_DONE || state->state == J2K_STATE_FAILED) if (state->state == J2K_STATE_DONE || state->state == J2K_STATE_FAILED) {
return -1; return -1;
}
if (state->state == J2K_STATE_START) { if (state->state == J2K_STATE_START) {
state->state = J2K_STATE_DECODING; state->state = J2K_STATE_DECODING;

View File

@ -106,8 +106,9 @@ j2k_pack_l(Imaging im, UINT8 *buf,
unsigned x,y; unsigned x,y;
for (y = 0; y < h; ++y) { for (y = 0; y < h; ++y) {
UINT8 *data = (UINT8 *)(im->image[y + y0] + x0); UINT8 *data = (UINT8 *)(im->image[y + y0] + x0);
for (x = 0; x < w; ++x) for (x = 0; x < w; ++x) {
*ptr++ = *data++; *ptr++ = *data++;
}
} }
} }
@ -240,8 +241,9 @@ j2k_set_cinema_params(Imaging im, int components, opj_cparameters_t *params)
} else { } else {
rate = ((float)(components * im->xsize * im->ysize * 8) rate = ((float)(components * im->xsize * im->ysize * 8)
/ (params->tcp_rates[n] * 8)); / (params->tcp_rates[n] * 8));
if (rate > CINEMA_24_CS_LENGTH) if (rate > CINEMA_24_CS_LENGTH) {
params->tcp_rates[n] = max_rate; params->tcp_rates[n] = max_rate;
}
} }
} }
@ -257,8 +259,9 @@ j2k_set_cinema_params(Imaging im, int components, opj_cparameters_t *params)
} else { } else {
rate = ((float)(components * im->xsize * im->ysize * 8) rate = ((float)(components * im->xsize * im->ysize * 8)
/ (params->tcp_rates[n] * 8)); / (params->tcp_rates[n] * 8));
if (rate > CINEMA_48_CS_LENGTH) if (rate > CINEMA_48_CS_LENGTH) {
params->tcp_rates[n] = max_rate; params->tcp_rates[n] = max_rate;
}
} }
} }
@ -397,8 +400,9 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
float *pq; float *pq;
if (len) { if (len) {
if (len > sizeof(params.tcp_rates) / sizeof(params.tcp_rates[0])) if (len > sizeof(params.tcp_rates) / sizeof(params.tcp_rates[0])) {
len = sizeof(params.tcp_rates)/sizeof(params.tcp_rates[0]); len = sizeof(params.tcp_rates)/sizeof(params.tcp_rates[0]);
}
params.tcp_numlayers = (int)len; params.tcp_numlayers = (int)len;
@ -423,8 +427,9 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
params.cp_disto_alloc = 1; params.cp_disto_alloc = 1;
} }
if (context->num_resolutions) if (context->num_resolutions) {
params.numresolution = context->num_resolutions; params.numresolution = context->num_resolutions;
}
if (context->cblk_width >= 4 && context->cblk_width <= 1024 if (context->cblk_width >= 4 && context->cblk_width <= 1024
&& context->cblk_height >= 4 && context->cblk_height <= 1024 && context->cblk_height >= 4 && context->cblk_height <= 1024
@ -455,18 +460,21 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
case OPJ_CINEMA2K_24: case OPJ_CINEMA2K_24:
case OPJ_CINEMA2K_48: case OPJ_CINEMA2K_48:
params.cp_rsiz = OPJ_CINEMA2K; params.cp_rsiz = OPJ_CINEMA2K;
if (params.numresolution > 6) if (params.numresolution > 6) {
params.numresolution = 6; params.numresolution = 6;
}
break; break;
case OPJ_CINEMA4K_24: case OPJ_CINEMA4K_24:
params.cp_rsiz = OPJ_CINEMA4K; params.cp_rsiz = OPJ_CINEMA4K;
if (params.numresolution > 7) if (params.numresolution > 7) {
params.numresolution = 7; params.numresolution = 7;
}
break; break;
} }
if (context->cinema_mode != OPJ_OFF) if (context->cinema_mode != OPJ_OFF) {
j2k_set_cinema_params(im, components, &params); j2k_set_cinema_params(im, components, &params);
}
/* Set up the reference grid in the image */ /* Set up the reference grid in the image */
image->x0 = params.image_offset_x0; image->x0 = params.image_offset_x0;
@ -526,10 +534,12 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
unsigned ty1 = ty0 + tile_height; unsigned ty1 = ty0 + tile_height;
unsigned pixy, pixh; unsigned pixy, pixh;
if (ty0 < params.image_offset_y0) if (ty0 < params.image_offset_y0) {
ty0 = params.image_offset_y0; ty0 = params.image_offset_y0;
if (ty1 > ysiz) }
if (ty1 > ysiz) {
ty1 = ysiz; ty1 = ysiz;
}
pixy = ty0 - params.image_offset_y0; pixy = ty0 - params.image_offset_y0;
pixh = ty1 - ty0; pixh = ty1 - ty0;
@ -540,10 +550,12 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
unsigned pixx, pixw; unsigned pixx, pixw;
unsigned data_size; unsigned data_size;
if (tx0 < params.image_offset_x0) if (tx0 < params.image_offset_x0) {
tx0 = params.image_offset_x0; tx0 = params.image_offset_x0;
if (tx1 > xsiz) }
if (tx1 > xsiz) {
tx1 = xsiz; tx1 = xsiz;
}
pixx = tx0 - params.image_offset_x0; pixx = tx0 - params.image_offset_x0;
pixw = tx1 - tx0; pixw = tx1 - tx0;
@ -572,12 +584,15 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
ret = -1; ret = -1;
quick_exit: quick_exit:
if (codec) if (codec) {
opj_destroy_codec(codec); opj_destroy_codec(codec);
if (image) }
if (image) {
opj_image_destroy(image); opj_image_destroy(image);
if (stream) }
if (stream) {
opj_stream_destroy(stream); opj_stream_destroy(stream);
}
return ret; return ret;
} }
@ -585,8 +600,9 @@ j2k_encode_entry(Imaging im, ImagingCodecState state)
int int
ImagingJpeg2KEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) ImagingJpeg2KEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes)
{ {
if (state->state == J2K_STATE_FAILED) if (state->state == J2K_STATE_FAILED) {
return -1; return -1;
}
if (state->state == J2K_STATE_START) { if (state->state == J2K_STATE_START) {
@ -611,8 +627,9 @@ ImagingJpeg2KEncodeCleanup(ImagingCodecState state) {
context->quality_layers = NULL; context->quality_layers = NULL;
} }
if (context->error_msg) if (context->error_msg) {
free ((void *)context->error_msg); free ((void *)context->error_msg);
}
context->error_msg = NULL; context->error_msg = NULL;

View File

@ -176,8 +176,9 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t by
if (context->source.skip > 0) { if (context->source.skip > 0) {
skip_input_data(&context->cinfo, context->source.skip); skip_input_data(&context->cinfo, context->source.skip);
if (context->source.skip > 0) if (context->source.skip > 0) {
return context->source.pub.next_input_byte - buf; return context->source.pub.next_input_byte - buf;
}
} }
switch (state->state) { switch (state->state) {
@ -193,43 +194,46 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t by
} while (ok == JPEG_HEADER_TABLES_ONLY); } while (ok == JPEG_HEADER_TABLES_ONLY);
if (ok == JPEG_SUSPENDED) if (ok == JPEG_SUSPENDED) {
break; break;
}
/* Decoder settings */ /* Decoder settings */
/* jpegmode indicates whats in the file; if not set, we'll /* jpegmode indicates whats in the file; if not set, we'll
trust the decoder */ trust the decoder */
if (strcmp(context->jpegmode, "L") == 0) if (strcmp(context->jpegmode, "L") == 0) {
context->cinfo.jpeg_color_space = JCS_GRAYSCALE; context->cinfo.jpeg_color_space = JCS_GRAYSCALE;
else if (strcmp(context->jpegmode, "RGB") == 0) } else if (strcmp(context->jpegmode, "RGB") == 0) {
context->cinfo.jpeg_color_space = JCS_RGB; context->cinfo.jpeg_color_space = JCS_RGB;
else if (strcmp(context->jpegmode, "CMYK") == 0) } else if (strcmp(context->jpegmode, "CMYK") == 0) {
context->cinfo.jpeg_color_space = JCS_CMYK; context->cinfo.jpeg_color_space = JCS_CMYK;
else if (strcmp(context->jpegmode, "YCbCr") == 0) } else if (strcmp(context->jpegmode, "YCbCr") == 0) {
context->cinfo.jpeg_color_space = JCS_YCbCr; context->cinfo.jpeg_color_space = JCS_YCbCr;
else if (strcmp(context->jpegmode, "YCbCrK") == 0) { } else if (strcmp(context->jpegmode, "YCbCrK") == 0) {
context->cinfo.jpeg_color_space = JCS_YCCK; context->cinfo.jpeg_color_space = JCS_YCCK;
} }
/* rawmode indicates what we want from the decoder. if not /* rawmode indicates what we want from the decoder. if not
set, conversions are disabled */ set, conversions are disabled */
if (strcmp(context->rawmode, "L") == 0) if (strcmp(context->rawmode, "L") == 0) {
context->cinfo.out_color_space = JCS_GRAYSCALE; context->cinfo.out_color_space = JCS_GRAYSCALE;
else if (strcmp(context->rawmode, "RGB") == 0) } else if (strcmp(context->rawmode, "RGB") == 0) {
context->cinfo.out_color_space = JCS_RGB; context->cinfo.out_color_space = JCS_RGB;
}
#ifdef JCS_EXTENSIONS #ifdef JCS_EXTENSIONS
else if (strcmp(context->rawmode, "RGBX") == 0) else if (strcmp(context->rawmode, "RGBX") == 0) {
context->cinfo.out_color_space = JCS_EXT_RGBX; context->cinfo.out_color_space = JCS_EXT_RGBX;
}
#endif #endif
else if (strcmp(context->rawmode, "CMYK") == 0 || else if (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;
else if (strcmp(context->rawmode, "YCbCrK") == 0) } else if (strcmp(context->rawmode, "YCbCrK") == 0) {
context->cinfo.out_color_space = JCS_YCCK; context->cinfo.out_color_space = JCS_YCCK;
else { } else {
/* Disable decoder conversions */ /* Disable decoder conversions */
context->cinfo.jpeg_color_space = JCS_UNKNOWN; context->cinfo.jpeg_color_space = JCS_UNKNOWN;
context->cinfo.out_color_space = JCS_UNKNOWN; context->cinfo.out_color_space = JCS_UNKNOWN;
@ -251,8 +255,9 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t by
/* Set things up for decompression (this processes the entire /* Set things up for decompression (this processes the entire
file if necessary to return data line by line) */ file if necessary to return data line by line) */
if (!jpeg_start_decompress(&context->cinfo)) if (!jpeg_start_decompress(&context->cinfo)) {
break; break;
}
state->state++; state->state++;
/* fall through */ /* fall through */
@ -263,15 +268,17 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t by
ok = 1; ok = 1;
while (state->y < state->ysize) { while (state->y < state->ysize) {
ok = jpeg_read_scanlines(&context->cinfo, &state->buffer, 1); ok = jpeg_read_scanlines(&context->cinfo, &state->buffer, 1);
if (ok != 1) if (ok != 1) {
break; break;
}
state->shuffle((UINT8*) im->image[state->y + state->yoff] + state->shuffle((UINT8*) im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->buffer, state->xoff * im->pixelsize, state->buffer,
state->xsize); state->xsize);
state->y++; state->y++;
} }
if (ok != 1) if (ok != 1) {
break; break;
}
state->state++; state->state++;
/* fall through */ /* fall through */
@ -280,8 +287,9 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t by
/* Finish decompression */ /* Finish decompression */
if (!jpeg_finish_decompress(&context->cinfo)) { if (!jpeg_finish_decompress(&context->cinfo)) {
/* FIXME: add strictness mode test */ /* FIXME: add strictness mode test */
if (state->y < state->ysize) if (state->y < state->ysize) {
break; break;
}
} }
/* Clean up */ /* Clean up */

View File

@ -127,17 +127,19 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
break; break;
case 24: case 24:
context->cinfo.input_components = 3; context->cinfo.input_components = 3;
if (strcmp(im->mode, "YCbCr") == 0) if (strcmp(im->mode, "YCbCr") == 0) {
context->cinfo.in_color_space = JCS_YCbCr; context->cinfo.in_color_space = JCS_YCbCr;
else } else {
context->cinfo.in_color_space = JCS_RGB; context->cinfo.in_color_space = JCS_RGB;
}
break; break;
case 32: case 32:
context->cinfo.input_components = 4; context->cinfo.input_components = 4;
context->cinfo.in_color_space = JCS_CMYK; context->cinfo.in_color_space = JCS_CMYK;
#ifdef JCS_EXTENSIONS #ifdef JCS_EXTENSIONS
if (strcmp(context->rawmode, "RGBX") == 0) if (strcmp(context->rawmode, "RGBX") == 0) {
context->cinfo.in_color_space = JCS_EXT_RGBX; context->cinfo.in_color_space = JCS_EXT_RGBX;
}
#endif #endif
break; break;
default: default:
@ -214,8 +216,9 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
break; break;
} }
} }
if (context->progressive) if (context->progressive) {
jpeg_simple_progression(&context->cinfo); jpeg_simple_progression(&context->cinfo);
}
context->cinfo.smoothing_factor = context->smooth; context->cinfo.smoothing_factor = context->smooth;
context->cinfo.optimize_coding = (boolean) context->optimize; context->cinfo.optimize_coding = (boolean) context->optimize;
if (context->xdpi > 0 && context->ydpi > 0) { if (context->xdpi > 0 && context->ydpi > 0) {
@ -261,19 +264,22 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
if (context->extra) { if (context->extra) {
/* copy extra buffer to output buffer */ /* copy extra buffer to output buffer */
unsigned int n = context->extra_size - context->extra_offset; unsigned int n = context->extra_size - context->extra_offset;
if (n > context->destination.pub.free_in_buffer) if (n > context->destination.pub.free_in_buffer) {
n = context->destination.pub.free_in_buffer; n = context->destination.pub.free_in_buffer;
}
memcpy(context->destination.pub.next_output_byte, memcpy(context->destination.pub.next_output_byte,
context->extra + context->extra_offset, n); context->extra + context->extra_offset, 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;
if (context->extra_offset >= context->extra_size) if (context->extra_offset >= context->extra_size) {
state->state++; state->state++;
else } else {
break; break;
} else }
} else {
state->state++; state->state++;
}
case 4: case 4:
if (1024 > context->destination.pub.free_in_buffer){ if (1024 > context->destination.pub.free_in_buffer){
@ -286,21 +292,24 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
(UINT8*) im->image[state->y + state->yoff] + (UINT8*) im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xsize); state->xoff * im->pixelsize, 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;
}
state->y++; state->y++;
} }
if (ok != 1) if (ok != 1) {
break; break;
}
state->state++; state->state++;
/* fall through */ /* fall through */
case 5: case 5:
/* Finish compression */ /* Finish compression */
if (context->destination.pub.free_in_buffer < 100) if (context->destination.pub.free_in_buffer < 100) {
break; break;
}
jpeg_finish_compress(&context->cinfo); jpeg_finish_compress(&context->cinfo);
/* Clean up */ /* Clean up */

View File

@ -27,14 +27,16 @@ ImagingConvertMatrix(Imaging im, const char *mode, float m[])
int x, y; int x, y;
/* Assume there's enough data in the buffer */ /* Assume there's enough data in the buffer */
if (!im) if (!im) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (strcmp(mode, "L") == 0 && im->bands == 3) { if (strcmp(mode, "L") == 0 && im->bands == 3) {
imOut = ImagingNewDirty("L", im->xsize, im->ysize); imOut = ImagingNewDirty("L", im->xsize, im->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
for (y = 0; y < im->ysize; y++) { for (y = 0; y < im->ysize; y++) {
UINT8* in = (UINT8*) im->image[y]; UINT8* in = (UINT8*) im->image[y];
@ -50,8 +52,9 @@ ImagingConvertMatrix(Imaging im, const char *mode, float m[])
} else if (strlen(mode) == 3 && im->bands == 3) { } else if (strlen(mode) == 3 && im->bands == 3) {
imOut = ImagingNewDirty(mode, im->xsize, im->ysize); imOut = ImagingNewDirty(mode, im->xsize, im->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
for (y = 0; y < im->ysize; y++) { for (y = 0; y < im->ysize; y++) {
UINT8* in = (UINT8*) im->image[y]; UINT8* in = (UINT8*) im->image[y];
@ -67,8 +70,9 @@ ImagingConvertMatrix(Imaging im, const char *mode, float m[])
in += 4; out += 4; in += 4; out += 4;
} }
} }
} else } else {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
return imOut; return imOut;
} }

View File

@ -25,12 +25,14 @@ ImagingModeFilter(Imaging im, int size)
UINT8 maxpixel; UINT8 maxpixel;
int histogram[256]; int histogram[256];
if (!im || im->bands != 1 || im->type != IMAGING_TYPE_UINT8) if (!im || im->bands != 1 || im->type != IMAGING_TYPE_UINT8) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize); imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
size = size / 2; size = size / 2;
@ -46,27 +48,32 @@ ImagingModeFilter(Imaging im, int size)
the added complexity... */ the added complexity... */
memset(histogram, 0, sizeof(histogram)); memset(histogram, 0, sizeof(histogram));
for (yy = y - size; yy <= y + size; yy++) for (yy = y - size; yy <= y + size; yy++) {
if (yy >= 0 && yy < imOut->ysize) { if (yy >= 0 && yy < imOut->ysize) {
UINT8* in = &IMAGING_PIXEL_L(im, 0, yy); UINT8* in = &IMAGING_PIXEL_L(im, 0, yy);
for (xx = x - size; xx <= x + size; xx++) for (xx = x - size; xx <= x + size; xx++) {
if (xx >= 0 && xx < imOut->xsize) if (xx >= 0 && xx < imOut->xsize) {
histogram[in[xx]]++; histogram[in[xx]]++;
}
}
} }
}
/* find most frequent pixel value in this region */ /* find most frequent pixel value in this region */
maxpixel = 0; maxpixel = 0;
maxcount = histogram[maxpixel]; maxcount = histogram[maxpixel];
for (i = 1; i < 256; i++) for (i = 1; i < 256; i++) {
if (histogram[i] > maxcount) { if (histogram[i] > maxcount) {
maxcount = histogram[i]; maxcount = histogram[i];
maxpixel = (UINT8) i; maxpixel = (UINT8) i;
} }
}
if (maxcount > 2) if (maxcount > 2) {
out[x] = maxpixel; out[x] = maxpixel;
else } else {
out[x] = IMAGING_PIXEL_L(im, x, y); out[x] = IMAGING_PIXEL_L(im, x, y);
}
} }

View File

@ -26,16 +26,20 @@ ImagingNegative(Imaging im)
Imaging imOut; Imaging imOut;
int x, y; int x, y;
if (!im) if (!im) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize); imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
for (y = 0; y < im->ysize; y++) for (y = 0; y < im->ysize; y++) {
for (x = 0; x < im->linesize; x++) for (x = 0; x < im->linesize; x++) {
imOut->image[y][x] = ~im->image[y][x]; imOut->image[y][x] = ~im->image[y][x];
}
}
return imOut; return imOut;
} }

View File

@ -24,38 +24,44 @@ ImagingOffset(Imaging im, int xoffset, int yoffset)
int x, y; int x, y;
Imaging imOut; Imaging imOut;
if (!im) if (!im) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize); imOut = ImagingNewDirty(im->mode, im->xsize, im->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
ImagingCopyPalette(imOut, im); ImagingCopyPalette(imOut, im);
/* make offsets positive to avoid negative coordinates */ /* make offsets positive to avoid negative coordinates */
xoffset %= im->xsize; xoffset %= im->xsize;
xoffset = im->xsize - xoffset; xoffset = im->xsize - xoffset;
if (xoffset < 0) if (xoffset < 0) {
xoffset += im->xsize; xoffset += im->xsize;
}
yoffset %= im->ysize; yoffset %= im->ysize;
yoffset = im->ysize - yoffset; yoffset = im->ysize - yoffset;
if (yoffset < 0) if (yoffset < 0) {
yoffset += im->ysize; yoffset += im->ysize;
}
#define OFFSET(image)\ #define OFFSET(image)\
for (y = 0; y < im->ysize; y++)\ for (y = 0; y < im->ysize; y++) {\
for (x = 0; x < im->xsize; x++) {\ for (x = 0; x < im->xsize; x++) {\
int yi = (y + yoffset) % im->ysize;\ int yi = (y + yoffset) % im->ysize;\
int xi = (x + xoffset) % im->xsize;\ int xi = (x + xoffset) % im->xsize;\
imOut->image[y][x] = im->image[yi][xi];\ imOut->image[y][x] = im->image[yi][xi];\
}\
} }
if (im->image8) if (im->image8) {
OFFSET(image8) OFFSET(image8)
else } else {
OFFSET(image32) OFFSET(image32)
}
return imOut; return imOut;
} }

View File

@ -80,16 +80,18 @@ pack1(UINT8* out, const UINT8* in, int pixels)
/* bilevel (black is 0) */ /* bilevel (black is 0) */
b = 0; m = 128; b = 0; m = 128;
for (i = 0; i < pixels; i++) { for (i = 0; i < pixels; i++) {
if (in[i] != 0) if (in[i] != 0) {
b |= m; b |= m;
}
m >>= 1; m >>= 1;
if (m == 0) { if (m == 0) {
*out++ = b; *out++ = b;
b = 0; m = 128; b = 0; m = 128;
} }
} }
if (m != 128) if (m != 128) {
*out++ = b; *out++ = b;
}
} }
static void static void
@ -99,16 +101,18 @@ pack1I(UINT8* out, const UINT8* in, int pixels)
/* bilevel (black is 1) */ /* bilevel (black is 1) */
b = 0; m = 128; b = 0; m = 128;
for (i = 0; i < pixels; i++) { for (i = 0; i < pixels; i++) {
if (in[i] == 0) if (in[i] == 0) {
b |= m; b |= m;
}
m >>= 1; m >>= 1;
if (m == 0) { if (m == 0) {
*out++ = b; *out++ = b;
b = 0; m = 128; b = 0; m = 128;
} }
} }
if (m != 128) if (m != 128) {
*out++ = b; *out++ = b;
}
} }
static void static void
@ -118,16 +122,18 @@ pack1R(UINT8* out, const UINT8* in, int pixels)
/* bilevel, lsb first (black is 0) */ /* bilevel, lsb first (black is 0) */
b = 0; m = 1; b = 0; m = 1;
for (i = 0; i < pixels; i++) { for (i = 0; i < pixels; i++) {
if (in[i] != 0) if (in[i] != 0) {
b |= m; b |= m;
}
m <<= 1; m <<= 1;
if (m == 256){ if (m == 256){
*out++ = b; *out++ = b;
b = 0; m = 1; b = 0; m = 1;
} }
} }
if (m != 1) if (m != 1) {
*out++ = b; *out++ = b;
}
} }
static void static void
@ -137,16 +143,18 @@ pack1IR(UINT8* out, const UINT8* in, int pixels)
/* bilevel, lsb first (black is 1) */ /* bilevel, lsb first (black is 1) */
b = 0; m = 1; b = 0; m = 1;
for (i = 0; i < pixels; i++) { for (i = 0; i < pixels; i++) {
if (in[i] == 0) if (in[i] == 0) {
b |= m; b |= m;
}
m <<= 1; m <<= 1;
if (m == 256){ if (m == 256){
*out++ = b; *out++ = b;
b = 0; m = 1; b = 0; m = 1;
} }
} }
if (m != 1) if (m != 1) {
*out++ = b; *out++ = b;
}
} }
static void static void
@ -154,8 +162,9 @@ pack1L(UINT8* out, const UINT8* in, int pixels)
{ {
int i; int i;
/* bilevel, stored as bytes */ /* bilevel, stored as bytes */
for (i = 0; i < pixels; i++) for (i = 0; i < pixels; i++) {
out[i] = (in[i] != 0) ? 255 : 0; out[i] = (in[i] != 0) ? 255 : 0;
}
} }
static void static void
@ -167,8 +176,9 @@ packP4(UINT8* out, const UINT8* in, int pixels)
in += 2; pixels -= 2; in += 2; pixels -= 2;
} }
if (pixels) if (pixels) {
out[0] = (in[0] << 4); out[0] = (in[0] << 4);
}
} }
static void static void
@ -407,12 +417,13 @@ packI16B(UINT8* out, const UINT8* in_, int pixels)
for (i = 0; i < pixels; i++) { for (i = 0; i < pixels; i++) {
INT32 in; INT32 in;
memcpy(&in, in_, sizeof(in)); memcpy(&in, in_, sizeof(in));
if (in <= 0) if (in <= 0) {
tmp_ = 0; tmp_ = 0;
else if (in > 65535) } else if (in > 65535) {
tmp_ = 65535; tmp_ = 65535;
else } else {
tmp_ = in; tmp_ = in;
}
C16B; C16B;
out += 2; in_ += sizeof(in); out += 2; in_ += sizeof(in);
} }
@ -496,40 +507,45 @@ copy4I(UINT8* out, const UINT8* in, int pixels)
{ {
/* RGBA, CMYK quadruples, inverted */ /* RGBA, CMYK quadruples, inverted */
int i; int i;
for (i = 0; i < pixels*4; i++) for (i = 0; i < pixels*4; i++) {
out[i] = ~in[i]; out[i] = ~in[i];
}
} }
static void static void
band0(UINT8* out, const UINT8* in, int pixels) band0(UINT8* out, const UINT8* in, int pixels)
{ {
int i; int i;
for (i = 0; i < pixels; i++, in += 4) for (i = 0; i < pixels; i++, in += 4) {
out[i] = in[0]; out[i] = in[0];
}
} }
static void static void
band1(UINT8* out, const UINT8* in, int pixels) band1(UINT8* out, const UINT8* in, int pixels)
{ {
int i; int i;
for (i = 0; i < pixels; i++, in += 4) for (i = 0; i < pixels; i++, in += 4) {
out[i] = in[1]; out[i] = in[1];
}
} }
static void static void
band2(UINT8* out, const UINT8* in, int pixels) band2(UINT8* out, const UINT8* in, int pixels)
{ {
int i; int i;
for (i = 0; i < pixels; i++, in += 4) for (i = 0; i < pixels; i++, in += 4) {
out[i] = in[2]; out[i] = in[2];
}
} }
static void static void
band3(UINT8* out, const UINT8* in, int pixels) band3(UINT8* out, const UINT8* in, int pixels)
{ {
int i; int i;
for (i = 0; i < pixels; i++, in += 4) for (i = 0; i < pixels; i++, in += 4) {
out[i] = in[3]; out[i] = in[3];
}
} }
static struct { static struct {
@ -673,12 +689,14 @@ ImagingFindPacker(const char* mode, const char* rawmode, int* bits_out)
int i; int i;
/* find a suitable pixel packer */ /* find a suitable pixel packer */
for (i = 0; packers[i].rawmode; i++) for (i = 0; packers[i].rawmode; i++) {
if (strcmp(packers[i].mode, mode) == 0 && if (strcmp(packers[i].mode, mode) == 0 &&
strcmp(packers[i].rawmode, rawmode) == 0) { strcmp(packers[i].rawmode, rawmode) == 0) {
if (bits_out) if (bits_out) {
*bits_out = packers[i].bits; *bits_out = packers[i].bits;
}
return packers[i].pack; return packers[i].pack;
} }
}
return NULL; return NULL;
} }

View File

@ -28,8 +28,9 @@ ImagingPackbitsDecode(Imaging im, ImagingCodecState state,
for (;;) { for (;;) {
if (bytes < 1) if (bytes < 1) {
return ptr - buf; return ptr - buf;
}
if (ptr[0] & 0x80) { if (ptr[0] & 0x80) {
@ -40,8 +41,9 @@ ImagingPackbitsDecode(Imaging im, ImagingCodecState state,
} }
/* Run */ /* Run */
if (bytes < 2) if (bytes < 2) {
return ptr - buf; return ptr - buf;
}
for (n = 257 - ptr[0]; n > 0; n--) { for (n = 257 - ptr[0]; n > 0; n--) {
if (state->x >= state->bytes) { if (state->x >= state->bytes) {
@ -58,8 +60,9 @@ ImagingPackbitsDecode(Imaging im, ImagingCodecState state,
/* Literal */ /* Literal */
n = ptr[0]+2; n = ptr[0]+2;
if (bytes < n) if (bytes < n) {
return ptr - buf; return ptr - buf;
}
for (i = 1; i < n; i++) { for (i = 1; i < n; i++) {
if (state->x >= state->bytes) { if (state->x >= state->bytes) {

View File

@ -30,12 +30,14 @@ ImagingPaletteNew(const char* mode)
int i; int i;
ImagingPalette palette; ImagingPalette palette;
if (strcmp(mode, "RGB") && strcmp(mode, "RGBA")) if (strcmp(mode, "RGB") && strcmp(mode, "RGBA")) {
return (ImagingPalette) ImagingError_ModeError(); return (ImagingPalette) ImagingError_ModeError();
}
palette = calloc(1, sizeof(struct ImagingPaletteInstance)); palette = calloc(1, sizeof(struct ImagingPaletteInstance));
if (!palette) if (!palette) {
return (ImagingPalette) ImagingError_MemoryError(); return (ImagingPalette) ImagingError_MemoryError();
}
strncpy(palette->mode, mode, IMAGING_MODE_LENGTH-1); strncpy(palette->mode, mode, IMAGING_MODE_LENGTH-1);
palette->mode[IMAGING_MODE_LENGTH-1] = 0; palette->mode[IMAGING_MODE_LENGTH-1] = 0;
@ -60,8 +62,9 @@ ImagingPaletteNewBrowser(void)
ImagingPalette palette; ImagingPalette palette;
palette = ImagingPaletteNew("RGB"); palette = ImagingPaletteNew("RGB");
if (!palette) if (!palette) {
return NULL; return NULL;
}
/* Blank out unused entries */ /* Blank out unused entries */
/* FIXME: Add 10-level windows palette here? */ /* FIXME: Add 10-level windows palette here? */
@ -74,14 +77,16 @@ ImagingPaletteNewBrowser(void)
/* Simple 6x6x6 colour cube */ /* Simple 6x6x6 colour cube */
for (b = 0; b < 256; b += 51) for (b = 0; b < 256; b += 51) {
for (g = 0; g < 256; g += 51) for (g = 0; g < 256; g += 51) {
for (r = 0; r < 256; r += 51) { for (r = 0; r < 256; r += 51) {
palette->palette[i*4+0] = r; palette->palette[i*4+0] = r;
palette->palette[i*4+1] = g; palette->palette[i*4+1] = g;
palette->palette[i*4+2] = b; palette->palette[i*4+2] = b;
i++; i++;
} }
}
}
/* Blank out unused entries */ /* Blank out unused entries */
/* FIXME: add 30-level greyscale wedge here? */ /* FIXME: add 30-level greyscale wedge here? */
@ -102,12 +107,14 @@ ImagingPaletteDuplicate(ImagingPalette palette)
ImagingPalette new_palette; ImagingPalette new_palette;
if (!palette) if (!palette) {
return NULL; return NULL;
}
/* malloc check ok, small constant allocation */ /* malloc check ok, small constant allocation */
new_palette = malloc(sizeof(struct ImagingPaletteInstance)); new_palette = malloc(sizeof(struct ImagingPaletteInstance));
if (!new_palette) if (!new_palette) {
return (ImagingPalette) ImagingError_MemoryError(); return (ImagingPalette) ImagingError_MemoryError();
}
memcpy(new_palette, palette, sizeof(struct ImagingPaletteInstance)); memcpy(new_palette, palette, sizeof(struct ImagingPaletteInstance));
@ -123,8 +130,9 @@ ImagingPaletteDelete(ImagingPalette palette)
/* Destroy palette object */ /* Destroy palette object */
if (palette) { if (palette) {
if (palette->cache) if (palette->cache) {
free(palette->cache); free(palette->cache);
}
free(palette); free(palette);
} }
} }
@ -209,8 +217,9 @@ ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
tmax += (b <= bc) ? BDIST(b, b1) : BDIST(b, b0); tmax += (b <= bc) ? BDIST(b, b1) : BDIST(b, b0);
dmin[i] = tmin; dmin[i] = tmin;
if (tmax < dmax) if (tmax < dmax) {
dmax = tmax; /* keep the smallest max distance only */ dmax = tmax; /* keep the smallest max distance only */
}
} }
@ -220,10 +229,11 @@ ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
* all slots in that box. We only check boxes for which the min * all slots in that box. We only check boxes for which the min
* distance is less than or equal the smallest max distance */ * distance is less than or equal the smallest max distance */
for (i = 0; i < BOXVOLUME; i++) for (i = 0; i < BOXVOLUME; i++) {
d[i] = (unsigned int) ~0; d[i] = (unsigned int) ~0;
}
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++) {
if (dmin[i] <= dmax) { if (dmin[i] <= dmax) {
@ -262,6 +272,7 @@ ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
rx += 2 * RSTEP * RSTEP; rx += 2 * RSTEP * RSTEP;
} }
} }
}
/* Step 3 -- Update cache */ /* Step 3 -- Update cache */
@ -269,10 +280,13 @@ ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
* cache slot in the box. Update the cache. */ * cache slot in the box. Update the cache. */
j = 0; j = 0;
for (r = r0; r < r1; r+=4) for (r = r0; r < r1; r+=4) {
for (g = g0; g < g1; g+=4) for (g = g0; g < g1; g+=4) {
for (b = b0; b < b1; b+=4) for (b = b0; b < b1; b+=4) {
ImagingPaletteCache(palette, r, g, b) = c[j++]; ImagingPaletteCache(palette, r, g, b) = c[j++];
}
}
}
} }
@ -297,8 +311,9 @@ ImagingPaletteCachePrepare(ImagingPalette palette)
} }
/* Mark all entries as empty */ /* Mark all entries as empty */
for (i = 0; i < entries; i++) for (i = 0; i < entries; i++) {
palette->cache[i] = 0x100; palette->cache[i] = 0x100;
}
} }

View File

@ -37,8 +37,9 @@ paste(Imaging imOut, Imaging imIn, int dx, int dy, int sx, int sy,
xsize *= pixelsize; xsize *= pixelsize;
for (y = 0; y < ysize; y++) for (y = 0; y < ysize; y++) {
memcpy(imOut->image[y+dy]+dx, imIn->image[y+sy]+sx, xsize); memcpy(imOut->image[y+dy]+dx, imIn->image[y+sy]+sx, xsize);
}
} }
static inline void static inline void
@ -57,8 +58,9 @@ paste_mask_1(Imaging imOut, Imaging imIn, Imaging imMask,
UINT8* in = imIn->image8[y+sy]+sx; UINT8* in = imIn->image8[y+sy]+sx;
UINT8* mask = imMask->image8[y+sy]+sx; UINT8* mask = imMask->image8[y+sy]+sx;
for (x = 0; x < xsize; x++) { for (x = 0; x < xsize; x++) {
if (*mask++) if (*mask++) {
*out = *in; *out = *in;
}
out++, in++; out++, in++;
} }
} }
@ -70,8 +72,9 @@ paste_mask_1(Imaging imOut, Imaging imIn, Imaging imMask,
INT32* in = imIn->image32[y+sy]+sx; INT32* in = imIn->image32[y+sy]+sx;
UINT8* mask = imMask->image8[y+sy]+sx; UINT8* mask = imMask->image8[y+sy]+sx;
for (x = 0; x < xsize; x++) { for (x = 0; x < xsize; x++) {
if (*mask++) if (*mask++) {
*out = *in; *out = *in;
}
out++, in++; out++, in++;
} }
} }
@ -231,17 +234,22 @@ ImagingPaste(Imaging imOut, Imaging imIn, Imaging imMask,
/* Determine which region to copy */ /* Determine which region to copy */
sx0 = sy0 = 0; sx0 = sy0 = 0;
if (dx0 < 0) if (dx0 < 0) {
xsize += dx0, sx0 = -dx0, dx0 = 0; xsize += dx0, sx0 = -dx0, dx0 = 0;
if (dx0 + xsize > imOut->xsize) }
if (dx0 + xsize > imOut->xsize) {
xsize = imOut->xsize - dx0; xsize = imOut->xsize - dx0;
if (dy0 < 0) }
if (dy0 < 0) {
ysize += dy0, sy0 = -dy0, dy0 = 0; ysize += dy0, sy0 = -dy0, dy0 = 0;
if (dy0 + ysize > imOut->ysize) }
if (dy0 + ysize > imOut->ysize) {
ysize = imOut->ysize - dy0; ysize = imOut->ysize - dy0;
}
if (xsize <= 0 || ysize <= 0) if (xsize <= 0 || ysize <= 0) {
return 0; return 0;
}
if (!imMask) { if (!imMask) {
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
@ -297,15 +305,17 @@ fill(Imaging imOut, const void* ink_, int dx, int dy,
dx *= pixelsize; dx *= pixelsize;
xsize *= pixelsize; xsize *= pixelsize;
for (y = 0; y < ysize; y++) for (y = 0; y < ysize; y++) {
memset(imOut->image[y+dy]+dx, ink8, xsize); memset(imOut->image[y+dy]+dx, ink8, xsize);
}
} else { } else {
for (y = 0; y < ysize; y++) { for (y = 0; y < ysize; y++) {
INT32* out = imOut->image32[y+dy]+dx; INT32* out = imOut->image32[y+dy]+dx;
for (x = 0; x < xsize; x++) for (x = 0; x < xsize; x++) {
out[x] = ink32; out[x] = ink32;
}
} }
} }
@ -331,8 +341,9 @@ fill_mask_1(Imaging imOut, const void* ink_, Imaging imMask,
UINT8* out = imOut->image8[y+dy]+dx; UINT8* out = imOut->image8[y+dy]+dx;
UINT8* mask = imMask->image8[y+sy]+sx; UINT8* mask = imMask->image8[y+sy]+sx;
for (x = 0; x < xsize; x++) { for (x = 0; x < xsize; x++) {
if (*mask++) if (*mask++) {
*out = ink8; *out = ink8;
}
out++; out++;
} }
} }
@ -343,8 +354,9 @@ fill_mask_1(Imaging imOut, const void* ink_, Imaging imMask,
INT32* out = imOut->image32[y+dy]+dx; INT32* out = imOut->image32[y+dy]+dx;
UINT8* mask = imMask->image8[y+sy]+sx; UINT8* mask = imMask->image8[y+sy]+sx;
for (x = 0; x < xsize; x++) { for (x = 0; x < xsize; x++) {
if (*mask++) if (*mask++) {
*out = ink32; *out = ink32;
}
out++; out++;
} }
} }
@ -494,17 +506,22 @@ ImagingFill2(Imaging imOut, const void* ink, Imaging imMask,
/* Determine which region to fill */ /* Determine which region to fill */
sx0 = sy0 = 0; sx0 = sy0 = 0;
if (dx0 < 0) if (dx0 < 0) {
xsize += dx0, sx0 = -dx0, dx0 = 0; xsize += dx0, sx0 = -dx0, dx0 = 0;
if (dx0 + xsize > imOut->xsize) }
if (dx0 + xsize > imOut->xsize) {
xsize = imOut->xsize - dx0; xsize = imOut->xsize - dx0;
if (dy0 < 0) }
if (dy0 < 0) {
ysize += dy0, sy0 = -dy0, dy0 = 0; ysize += dy0, sy0 = -dy0, dy0 = 0;
if (dy0 + ysize > imOut->ysize) }
if (dy0 + ysize > imOut->ysize) {
ysize = imOut->ysize - dy0; ysize = imOut->ysize - dy0;
}
if (xsize <= 0 || ysize <= 0) if (xsize <= 0 || ysize <= 0) {
return 0; return 0;
}
if (!imMask) { if (!imMask) {
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);

View File

@ -38,8 +38,9 @@ ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
for (;;) { for (;;) {
/* We need data for two full lines before we can do anything */ /* We need data for two full lines before we can do anything */
if (bytes < chunk) if (bytes < chunk) {
return ptr - buf; return ptr - buf;
}
/* Unpack first line */ /* Unpack first line */
out = state->buffer; out = state->buffer;
@ -53,8 +54,9 @@ ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
state->shuffle((UINT8*) im->image[state->y], state->shuffle((UINT8*) im->image[state->y],
state->buffer, state->xsize); state->buffer, state->xsize);
if (++state->y >= state->ysize) if (++state->y >= state->ysize) {
return -1; /* This can hardly happen */ return -1; /* This can hardly happen */
}
/* Unpack second line */ /* Unpack second line */
out = state->buffer; out = state->buffer;
@ -68,8 +70,9 @@ ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
state->shuffle((UINT8*) im->image[state->y], state->shuffle((UINT8*) im->image[state->y],
state->buffer, state->xsize); state->buffer, state->xsize);
if (++state->y >= state->ysize) if (++state->y >= state->ysize) {
return -1; return -1;
}
ptr += chunk; ptr += chunk;
bytes -= chunk; bytes -= chunk;

View File

@ -31,14 +31,16 @@ ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
for (;;) { for (;;) {
if (bytes < 1) if (bytes < 1) {
return ptr - buf; return ptr - buf;
}
if ((*ptr & 0xC0) == 0xC0) { if ((*ptr & 0xC0) == 0xC0) {
/* Run */ /* Run */
if (bytes < 2) if (bytes < 2) {
return ptr - buf; return ptr - buf;
}
n = ptr[0] & 0x3F; n = ptr[0] & 0x3F;

View File

@ -35,8 +35,9 @@ im_point_8_8(Imaging imOut, Imaging imIn, im_point_context* context)
for (y = 0; y < imIn->ysize; y++) { for (y = 0; y < imIn->ysize; y++) {
UINT8* in = imIn->image8[y]; UINT8* in = imIn->image8[y];
UINT8* out = imOut->image8[y]; UINT8* out = imOut->image8[y];
for (x = 0; x < imIn->xsize; x++) for (x = 0; x < imIn->xsize; x++) {
out[x] = table[in[x]]; out[x] = table[in[x]];
}
} }
} }
@ -103,8 +104,9 @@ im_point_8_32(Imaging imOut, Imaging imIn, im_point_context* context)
for (y = 0; y < imIn->ysize; y++) { for (y = 0; y < imIn->ysize; y++) {
UINT8* in = imIn->image8[y]; UINT8* in = imIn->image8[y];
INT32* out = imOut->image32[y]; INT32* out = imOut->image32[y];
for (x = 0; x < imIn->xsize; x++) for (x = 0; x < imIn->xsize; x++) {
memcpy(out + x, table + in[x] * sizeof(INT32), sizeof(INT32)); memcpy(out + x, table + in[x] * sizeof(INT32), sizeof(INT32));
}
} }
} }
@ -119,10 +121,11 @@ im_point_32_8(Imaging imOut, Imaging imIn, im_point_context* context)
UINT8* out = imOut->image8[y]; UINT8* out = imOut->image8[y];
for (x = 0; x < imIn->xsize; x++) { for (x = 0; x < imIn->xsize; x++) {
int v = in[x]; int v = in[x];
if (v < 0) if (v < 0) {
v = 0; v = 0;
else if (v > 65535) } else if (v > 65535) {
v = 65535; v = 65535;
}
out[x] = table[v]; out[x] = table[v];
} }
} }
@ -138,21 +141,26 @@ ImagingPoint(Imaging imIn, const char* mode, const void* table)
im_point_context context; im_point_context context;
void (*point)(Imaging imIn, Imaging imOut, im_point_context* context); void (*point)(Imaging imIn, Imaging imOut, im_point_context* context);
if (!imIn) if (!imIn) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (!mode) if (!mode) {
mode = imIn->mode; mode = imIn->mode;
}
if (imIn->type != IMAGING_TYPE_UINT8) { if (imIn->type != IMAGING_TYPE_UINT8) {
if (imIn->type != IMAGING_TYPE_INT32 || strcmp(mode, "L") != 0) if (imIn->type != IMAGING_TYPE_INT32 || strcmp(mode, "L") != 0) {
goto mode_mismatch; goto mode_mismatch;
} else if (!imIn->image8 && strcmp(imIn->mode, mode) != 0) }
} else if (!imIn->image8 && strcmp(imIn->mode, mode) != 0) {
goto mode_mismatch; goto mode_mismatch;
}
imOut = ImagingNew(mode, imIn->xsize, imIn->ysize); imOut = ImagingNew(mode, imIn->xsize, imIn->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
/* find appropriate handler */ /* find appropriate handler */
if (imIn->type == IMAGING_TYPE_UINT8) { if (imIn->type == IMAGING_TYPE_UINT8) {
@ -175,10 +183,12 @@ ImagingPoint(Imaging imIn, const char* mode, const void* table)
point = im_point_8_8; point = im_point_8_8;
break; break;
} }
} else } else {
point = im_point_8_32; point = im_point_8_32;
} else }
} else {
point = im_point_32_8; point = im_point_32_8;
}
ImagingCopyPalette(imOut, imIn); ImagingCopyPalette(imOut, imIn);
@ -209,12 +219,14 @@ ImagingPointTransform(Imaging imIn, double scale, double offset)
if (!imIn || (strcmp(imIn->mode, "I") != 0 && if (!imIn || (strcmp(imIn->mode, "I") != 0 &&
strcmp(imIn->mode, "I;16") != 0 && strcmp(imIn->mode, "I;16") != 0 &&
strcmp(imIn->mode, "F") != 0)) strcmp(imIn->mode, "F") != 0)) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
switch (imIn->type) { switch (imIn->type) {
case IMAGING_TYPE_INT32: case IMAGING_TYPE_INT32:
@ -223,8 +235,9 @@ ImagingPointTransform(Imaging imIn, double scale, double offset)
INT32* in = imIn->image32[y]; INT32* in = imIn->image32[y];
INT32* out = imOut->image32[y]; INT32* out = imOut->image32[y];
/* FIXME: add clipping? */ /* FIXME: add clipping? */
for (x = 0; x < imIn->xsize; x++) for (x = 0; x < imIn->xsize; x++) {
out[x] = in[x] * scale + offset; out[x] = in[x] * scale + offset;
}
} }
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
break; break;
@ -233,8 +246,9 @@ ImagingPointTransform(Imaging imIn, double scale, double offset)
for (y = 0; y < imIn->ysize; y++) { for (y = 0; y < imIn->ysize; y++) {
FLOAT32* in = (FLOAT32*) imIn->image32[y]; FLOAT32* in = (FLOAT32*) imIn->image32[y];
FLOAT32* out = (FLOAT32*) imOut->image32[y]; FLOAT32* out = (FLOAT32*) imOut->image32[y];
for (x = 0; x < imIn->xsize; x++) for (x = 0; x < imIn->xsize; x++) {
out[x] = in[x] * scale + offset; out[x] = in[x] * scale + offset;
}
} }
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
break; break;

View File

@ -157,7 +157,9 @@ create_pixel_hash(Pixel *pixelData,uint32_t nPixels)
/* malloc check ok, small constant allocation */ /* malloc check ok, small constant allocation */
d=malloc(sizeof(PixelHashData)); d=malloc(sizeof(PixelHashData));
if (!d) return NULL; if (!d) {
return NULL;
}
hash=hashtable_new(pixel_hash,pixel_cmp); hash=hashtable_new(pixel_hash,pixel_cmp);
hashtable_set_user_data(hash,d); hashtable_set_user_data(hash,d);
d->scale=0; d->scale=0;
@ -197,7 +199,9 @@ static void
destroy_pixel_hash(HashTable *hash) destroy_pixel_hash(HashTable *hash)
{ {
PixelHashData *d=(PixelHashData *)hashtable_get_user_data(hash); PixelHashData *d=(PixelHashData *)hashtable_get_user_data(hash);
if (d) free(d); if (d) {
free(d);
}
hashtable_free(hash); hashtable_free(hash);
} }
@ -214,7 +218,9 @@ static int
compute_box_volume(BoxNode *b) compute_box_volume(BoxNode *b)
{ {
unsigned char rl,rh,gl,gh,bl,bh; unsigned char rl,rh,gl,gh,bl,bh;
if (b->volume>=0) return b->volume; if (b->volume>=0) {
return b->volume;
}
if (!b->head[0]) { if (!b->head[0]) {
b->volume=0; b->volume=0;
} else { } else {
@ -242,7 +248,9 @@ hash_to_list(const HashTable *h, const Pixel pixel, const uint32_t count, void *
/* malloc check ok, small constant allocation */ /* malloc check ok, small constant allocation */
p=malloc(sizeof(PixelList)); p=malloc(sizeof(PixelList));
if (!p) return; if (!p) {
return;
}
p->flag=0; p->flag=0;
p->p=q; p->p=q;
@ -250,7 +258,9 @@ hash_to_list(const HashTable *h, const Pixel pixel, const uint32_t count, void *
for (i=0;i<3;i++) { for (i=0;i<3;i++) {
p->next[i]=pl[i]; p->next[i]=pl[i];
p->prev[i]=NULL; p->prev[i]=NULL;
if (pl[i]) pl[i]->prev[i]=p; if (pl[i]) {
pl[i]->prev[i]=p;
}
pl[i]=p; pl[i]=p;
} }
} }
@ -268,7 +278,9 @@ mergesort_pixels(PixelList *head, int i)
} }
for (c=t=head;c&&t;c=c->next[i],t=(t->next[i])?t->next[i]->next[i]:NULL); for (c=t=head;c&&t;c=c->next[i],t=(t->next[i])?t->next[i]->next[i]:NULL);
if (c) { if (c) {
if (c->prev[i]) c->prev[i]->next[i]=NULL; if (c->prev[i]) {
c->prev[i]->next[i]=NULL;
}
c->prev[i]=NULL; c->prev[i]=NULL;
} }
a=mergesort_pixels(head,i); a=mergesort_pixels(head,i);
@ -285,9 +297,13 @@ mergesort_pixels(PixelList *head, int i)
} }
c->prev[i]=p; c->prev[i]=p;
c->next[i]=NULL; c->next[i]=NULL;
if (p) p->next[i]=c; if (p) {
p->next[i]=c;
}
p=c; p=c;
if (!head) head=c; if (!head) {
head=c;
}
} }
if (a) { if (a) {
c->next[i]=a; c->next[i]=a;
@ -442,17 +458,29 @@ splitlists(PixelList *h[3],
for (c=h[i];c;c=n) { for (c=h[i];c;c=n) {
n=c->next[i]; n=c->next[i];
if (c->flag) { /* move pixel to right list*/ if (c->flag) { /* move pixel to right list*/
if (r) r->next[i]=c; else nh[1][i]=c; if (r) {
r->next[i]=c;
} else {
nh[1][i]=c;
}
c->prev[i]=r; c->prev[i]=r;
r=c; r=c;
} else { /* move pixel to left list */ } else { /* move pixel to left list */
if (l) l->next[i]=c; else nh[0][i]=c; if (l) {
l->next[i]=c;
} else {
nh[0][i]=c;
}
c->prev[i]=l; c->prev[i]=l;
l=c; l=c;
} }
} }
if (l) l->next[i]=NULL; if (l) {
if (r) r->next[i]=NULL; l->next[i]=NULL;
}
if (r) {
r->next[i]=NULL;
}
nt[0][i]=l; nt[0][i]=l;
nt[1][i]=r; nt[1][i]=r;
} }
@ -661,8 +689,12 @@ static void
free_box_tree(BoxNode *n) free_box_tree(BoxNode *n)
{ {
PixelList *p,*pp; PixelList *p,*pp;
if (n->l) free_box_tree(n->l); if (n->l) {
if (n->r) free_box_tree(n->r); free_box_tree(n->l);
}
if (n->r) {
free_box_tree(n->r);
}
for (p=n->head[0];p;p=pp) { for (p=n->head[0];p;p=pp) {
pp=p->next[0]; pp=p->next[0];
free(p); free(p);
@ -720,7 +752,9 @@ annotate_hash_table(BoxNode *n,HashTable *h,uint32_t *box)
return 0; return 0;
} }
} }
if (n->head[0]) (*box)++; if (n->head[0]) {
(*box)++;
}
return 1; return 1;
} }
@ -756,7 +790,9 @@ resort_distance_tables(uint32_t *avgDist,
for (k=j;k&&(*(skRow[k-1])>*(skRow[k]));k--) { for (k=j;k&&(*(skRow[k-1])>*(skRow[k]));k--) {
skRow[k]=skRow[k-1]; skRow[k]=skRow[k-1];
} }
if (k!=j) skRow[k]=skElt; if (k!=j) {
skRow[k]=skElt;
}
} }
} }
return 1; return 1;
@ -976,7 +1012,9 @@ compute_palette_from_median_cut(
/* malloc check ok, using calloc */ /* malloc check ok, using calloc */
if (!(avg[i]=calloc(nPaletteEntries, sizeof(uint32_t)))) { if (!(avg[i]=calloc(nPaletteEntries, sizeof(uint32_t)))) {
for(i=0;i<3;i++) { for(i=0;i<3;i++) {
if (avg[i]) free (avg[i]); if (avg[i]) {
free (avg[i]);
}
} }
free(count); free(count);
return 0; return 0;
@ -987,7 +1025,9 @@ compute_palette_from_median_cut(
if (!(i%100)) { printf ("%05d\r",i); fflush(stdout); } if (!(i%100)) { printf ("%05d\r",i); fflush(stdout); }
if (checkContained(root,pixelData+i)>1) { if (checkContained(root,pixelData+i)>1) {
printf ("pixel in two boxes\n"); printf ("pixel in two boxes\n");
for(i=0;i<3;i++) free (avg[i]); for(i=0;i<3;i++) {
free (avg[i]);
}
free(count); free(count);
return 0; return 0;
} }
@ -996,7 +1036,9 @@ compute_palette_from_median_cut(
#ifndef NO_OUTPUT #ifndef NO_OUTPUT
printf ("pixel lookup failed\n"); printf ("pixel lookup failed\n");
#endif #endif
for(i=0;i<3;i++) free (avg[i]); for(i=0;i<3;i++) {
free (avg[i]);
}
free(count); free(count);
return 0; return 0;
} }
@ -1004,7 +1046,9 @@ compute_palette_from_median_cut(
#ifndef NO_OUTPUT #ifndef NO_OUTPUT
printf ("panic - paletteEntry>=nPaletteEntries (%d>=%d)\n",(int)paletteEntry,(int)nPaletteEntries); printf ("panic - paletteEntry>=nPaletteEntries (%d>=%d)\n",(int)paletteEntry,(int)nPaletteEntries);
#endif #endif
for(i=0;i<3;i++) free (avg[i]); for(i=0;i<3;i++) {
free (avg[i]);
}
free(count); free(count);
return 0; return 0;
} }
@ -1016,7 +1060,9 @@ compute_palette_from_median_cut(
/* malloc check ok, using calloc */ /* malloc check ok, using calloc */
p=calloc(nPaletteEntries, sizeof(Pixel)); p=calloc(nPaletteEntries, sizeof(Pixel));
if (!p) { if (!p) {
for(i=0;i<3;i++) free (avg[i]); for(i=0;i<3;i++) {
free (avg[i]);
}
free(count); free(count);
return 0; return 0;
} }
@ -1026,7 +1072,9 @@ compute_palette_from_median_cut(
p[i].c.b=(int)(.5+(double)avg[2][i]/(double)count[i]); p[i].c.b=(int)(.5+(double)avg[2][i]/(double)count[i]);
} }
*palette=p; *palette=p;
for(i=0;i<3;i++) free (avg[i]); for(i=0;i<3;i++) {
free (avg[i]);
}
free(count); free(count);
return 1; return 1;
} }
@ -1156,24 +1204,46 @@ k_means(Pixel *pixelData,
#ifndef NO_OUTPUT #ifndef NO_OUTPUT
printf (".(%d)",changes);fflush(stdout); printf (".(%d)",changes);fflush(stdout);
#endif #endif
if (changes<=threshold) break; if (changes<=threshold) {
break;
}
} }
#ifndef NO_OUTPUT #ifndef NO_OUTPUT
printf("]\n"); printf("]\n");
#endif #endif
if (avgDistSortKey) free(avgDistSortKey); if (avgDistSortKey) {
if (avgDist) free(avgDist); free(avgDistSortKey);
for(i=0;i<3;i++) if (avg[i]) free (avg[i]); }
if (count) free(count); if (avgDist) {
free(avgDist);
}
for(i=0;i<3;i++) {
if (avg[i]) {
free (avg[i]);
}
}
if (count) {
free(count);
}
return 1; return 1;
error_3: error_3:
if (avgDistSortKey) free(avgDistSortKey); if (avgDistSortKey) {
free(avgDistSortKey);
}
error_2: error_2:
if (avgDist) free(avgDist); if (avgDist) {
free(avgDist);
}
error_1: error_1:
for(i=0;i<3;i++) if (avg[i]) free (avg[i]); for(i=0;i<3;i++) {
if (count) free(count); if (avg[i]) {
free (avg[i]);
}
}
if (count) {
free(count);
}
return 0; return 0;
} }
@ -1345,7 +1415,9 @@ quantize(Pixel *pixelData,
#ifndef NO_OUTPUT #ifndef NO_OUTPUT
printf ("k means...\n"); fflush(stdout); timer=clock(); printf ("k means...\n"); fflush(stdout); timer=clock();
#endif #endif
if (kmeans) k_means(pixelData,nPixels,p,nPaletteEntries,qp,kmeans-1); if (kmeans) {
k_means(pixelData,nPixels,p,nPaletteEntries,qp,kmeans-1);
}
#ifndef NO_OUTPUT #ifndef NO_OUTPUT
printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC); printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC);
#endif #endif
@ -1357,8 +1429,12 @@ quantize(Pixel *pixelData,
#ifndef NO_OUTPUT #ifndef NO_OUTPUT
printf ("cleanup..."); fflush(stdout); timer=clock(); printf ("cleanup..."); fflush(stdout); timer=clock();
#endif #endif
if (avgDist) free(avgDist); if (avgDist) {
if (avgDistSortKey) free(avgDistSortKey); free(avgDist);
}
if (avgDistSortKey) {
free(avgDistSortKey);
}
destroy_pixel_hash(h); destroy_pixel_hash(h);
#ifndef NO_OUTPUT #ifndef NO_OUTPUT
printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC); printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC);
@ -1367,15 +1443,25 @@ quantize(Pixel *pixelData,
return 1; return 1;
error_7: error_7:
if (avgDistSortKey) free(avgDistSortKey); if (avgDistSortKey) {
free(avgDistSortKey);
}
error_6: error_6:
if (avgDist) free(avgDist); if (avgDist) {
free(avgDist);
}
error_5: error_5:
if (qp) free(qp); if (qp) {
free(qp);
}
error_4: error_4:
if (p) free(p); if (p) {
free(p);
}
error_3: error_3:
if (root) free_box_tree(root); if (root) {
free_box_tree(root);
}
error_1: error_1:
destroy_pixel_hash(h); destroy_pixel_hash(h);
error_0: error_0:
@ -1430,7 +1516,9 @@ quantize2(Pixel *pixelData,
/* malloc check ok, using calloc */ /* malloc check ok, using calloc */
p=calloc(nQuantPixels, sizeof(Pixel)); p=calloc(nQuantPixels, sizeof(Pixel));
if (!p) return 0; if (!p) {
return 0;
}
mean[0]=mean[1]=mean[2]=0; mean[0]=mean[1]=mean[2]=0;
h=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp); h=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp);
for (i=0;i<nPixels;i++) { for (i=0;i<nPixels;i++) {
@ -1474,7 +1562,9 @@ quantize2(Pixel *pixelData,
if (!map_image_pixels(pixelData,nPixels,p,nQuantPixels,avgDist,avgDistSortKey,qp)) { if (!map_image_pixels(pixelData,nPixels,p,nQuantPixels,avgDist,avgDistSortKey,qp)) {
goto error_4; goto error_4;
} }
if (kmeans) k_means(pixelData,nPixels,p,nQuantPixels,qp,kmeans-1); if (kmeans) {
k_means(pixelData,nPixels,p,nQuantPixels,qp,kmeans-1);
}
*paletteLength=nQuantPixels; *paletteLength=nQuantPixels;
*palette=p; *palette=p;
@ -1509,28 +1599,33 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
int withAlpha = 0; int withAlpha = 0;
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
if (!im) if (!im) {
return ImagingError_ModeError(); return ImagingError_ModeError();
if (colors < 1 || colors > 256) }
if (colors < 1 || colors > 256) {
/* FIXME: for colors > 256, consider returning an RGB image /* FIXME: for colors > 256, consider returning an RGB image
instead (see @PIL205) */ instead (see @PIL205) */
return (Imaging) ImagingError_ValueError("bad number of colors"); return (Imaging) ImagingError_ValueError("bad number of colors");
}
if (strcmp(im->mode, "L") != 0 && strcmp(im->mode, "P") != 0 && if (strcmp(im->mode, "L") != 0 && strcmp(im->mode, "P") != 0 &&
strcmp(im->mode, "RGB") != 0 && strcmp(im->mode, "RGBA") !=0) strcmp(im->mode, "RGB") != 0 && strcmp(im->mode, "RGBA") !=0) {
return ImagingError_ModeError(); return ImagingError_ModeError();
}
/* only octree and imagequant supports RGBA */ /* only octree and imagequant supports RGBA */
if (!strcmp(im->mode, "RGBA") && mode != 2 && mode != 3) if (!strcmp(im->mode, "RGBA") && mode != 2 && mode != 3) {
return ImagingError_ModeError(); return ImagingError_ModeError();
}
if (im->xsize > INT_MAX / im->ysize) { if (im->xsize > INT_MAX / im->ysize) {
return ImagingError_MemoryError(); return ImagingError_MemoryError();
} }
/* malloc check ok, using calloc for final overflow, x*y above */ /* malloc check ok, using calloc for final overflow, x*y above */
p = calloc(im->xsize * im->ysize, sizeof(Pixel)); p = calloc(im->xsize * im->ysize, sizeof(Pixel));
if (!p) if (!p) {
return ImagingError_MemoryError(); return ImagingError_MemoryError();
}
/* collect statistics */ /* collect statistics */
@ -1543,18 +1638,19 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
/* FIXME: converting a "L" image to "P" with 256 colors /* FIXME: converting a "L" image to "P" with 256 colors
should be done by a simple copy... */ should be done by a simple copy... */
for (i = y = 0; y < im->ysize; y++) for (i = y = 0; y < im->ysize; y++) {
for (x = 0; x < im->xsize; x++, i++) { for (x = 0; x < im->xsize; x++, i++) {
p[i].c.r = p[i].c.g = p[i].c.b = im->image8[y][x]; p[i].c.r = p[i].c.g = p[i].c.b = im->image8[y][x];
p[i].c.a = 255; p[i].c.a = 255;
} }
}
} else if (!strcmp(im->mode, "P")) { } else if (!strcmp(im->mode, "P")) {
/* palette */ /* palette */
pp = im->palette->palette; pp = im->palette->palette;
for (i = y = 0; y < im->ysize; y++) for (i = y = 0; y < im->ysize; y++) {
for (x = 0; x < im->xsize; x++, i++) { for (x = 0; x < im->xsize; x++, i++) {
v = im->image8[y][x]; v = im->image8[y][x];
p[i].c.r = pp[v*4+0]; p[i].c.r = pp[v*4+0];
@ -1562,13 +1658,16 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
p[i].c.b = pp[v*4+2]; p[i].c.b = pp[v*4+2];
p[i].c.a = pp[v*4+3]; p[i].c.a = pp[v*4+3];
} }
}
} else if (!strcmp(im->mode, "RGB") || !strcmp(im->mode, "RGBA")) { } else if (!strcmp(im->mode, "RGB") || !strcmp(im->mode, "RGBA")) {
/* true colour */ /* true colour */
for (i = y = 0; y < im->ysize; y++) for (i = y = 0; y < im->ysize; y++) {
for (x = 0; x < im->xsize; x++, i++) for (x = 0; x < im->xsize; x++, i++) {
p[i].v = im->image32[y][x]; p[i].v = im->image32[y][x];
}
}
} else { } else {
free(p); free(p);
@ -1647,9 +1746,11 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
imOut = ImagingNewDirty("P", im->xsize, im->ysize); imOut = ImagingNewDirty("P", im->xsize, im->ysize);
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
for (i = y = 0; y < im->ysize; y++) for (i = y = 0; y < im->ysize; y++) {
for (x = 0; x < im->xsize; x++) for (x = 0; x < im->xsize; x++) {
imOut->image8[y][x] = (unsigned char) newData[i++]; imOut->image8[y][x] = (unsigned char) newData[i++];
}
}
free(newData); free(newData);

View File

@ -67,7 +67,9 @@ static uint32_t _findPrime(uint32_t start,int dir) {
continue; continue;
} }
for (t=2;t<sqrt((double)start);t++) { for (t=2;t<sqrt((double)start);t++) {
if (!start%t) break; if (!start%t) {
break;
}
} }
if (t>=sqrt((double)start)) { if (t>=sqrt((double)start)) {
break; break;
@ -144,7 +146,9 @@ static int _hashtable_insert_node(HashTable *h,HashNode *node,int resize,int upd
node->next=*n; node->next=*n;
*n=node; *n=node;
h->count++; h->count++;
if (resize) _hashtable_resize(h); if (resize) {
_hashtable_resize(h);
}
return 1; return 1;
} else { } else {
return 0; return 0;
@ -169,13 +173,17 @@ static int _hashtable_insert(HashTable *h,HashKey_t key,HashVal_t val,int resize
} }
if (!update) { if (!update) {
t=malloc(sizeof(HashNode)); t=malloc(sizeof(HashNode));
if (!t) return 0; if (!t) {
return 0;
}
t->next=*n; t->next=*n;
*n=t; *n=t;
t->key=key; t->key=key;
t->value=val; t->value=val;
h->count++; h->count++;
if (resize) _hashtable_resize(h); if (resize) {
_hashtable_resize(h);
}
return 1; return 1;
} else { } else {
return 0; return 0;
@ -206,7 +214,9 @@ int hashtable_insert_or_update_computed(HashTable *h,
} }
} }
t=malloc(sizeof(HashNode)); t=malloc(sizeof(HashNode));
if (!t) return 0; if (!t) {
return 0;
}
t->key=key; t->key=key;
t->next=*n; t->next=*n;
*n=t; *n=t;

View File

@ -46,15 +46,21 @@ void ImagingQuantHeapFree(Heap *h) {
static int _heap_grow(Heap *h,unsigned int newsize) { static int _heap_grow(Heap *h,unsigned int newsize) {
void *newheap; void *newheap;
if (!newsize) newsize=h->heapsize<<1; if (!newsize) {
if (newsize<h->heapsize) return 0; newsize=h->heapsize<<1;
}
if (newsize<h->heapsize) {
return 0;
}
if (newsize > INT_MAX / sizeof(void *)){ if (newsize > INT_MAX / sizeof(void *)){
return 0; return 0;
} }
/* malloc check ok, using calloc for overflow, also checking /* malloc check ok, using calloc for overflow, also checking
above due to memcpy below*/ above due to memcpy below*/
newheap=calloc(newsize, sizeof(void *)); newheap=calloc(newsize, sizeof(void *));
if (!newheap) return 0; if (!newheap) {
return 0;
}
memcpy(newheap,h->heap,sizeof(void *)*h->heapsize); memcpy(newheap,h->heap,sizeof(void *)*h->heapsize);
free(h->heap); free(h->heap);
h->heap=newheap; h->heap=newheap;
@ -140,7 +146,9 @@ Heap *ImagingQuantHeapNew(HeapCmpFunc cf) {
/* malloc check ok, small constant allocation */ /* malloc check ok, small constant allocation */
h=malloc(sizeof(Heap)); h=malloc(sizeof(Heap));
if (!h) return NULL; if (!h) {
return NULL;
}
h->heapsize=INITIAL_SIZE; h->heapsize=INITIAL_SIZE;
/* malloc check ok, using calloc for overflow */ /* malloc check ok, using calloc for overflow */
h->heap=calloc(h->heapsize, sizeof(void *)); h->heap=calloc(h->heapsize, sizeof(void *));

View File

@ -56,7 +56,9 @@ new_color_cube(int r, int g, int b, int a) {
/* malloc check ok, small constant allocation */ /* malloc check ok, small constant allocation */
cube = malloc(sizeof(struct _ColorCube)); cube = malloc(sizeof(struct _ColorCube));
if (!cube) return NULL; if (!cube) {
return NULL;
}
cube->rBits = MAX(r, 0); cube->rBits = MAX(r, 0);
cube->gBits = MAX(g, 0); cube->gBits = MAX(g, 0);
@ -175,7 +177,9 @@ create_sorted_color_palette(const ColorCube cube) {
} }
/* malloc check ok, calloc + overflow check above for memcpy */ /* malloc check ok, calloc + overflow check above for memcpy */
buckets = calloc(cube->size, sizeof(struct _ColorBucket)); buckets = calloc(cube->size, sizeof(struct _ColorBucket));
if (!buckets) return NULL; if (!buckets) {
return NULL;
}
memcpy(buckets, cube->buckets, sizeof(struct _ColorBucket)*cube->size); memcpy(buckets, cube->buckets, sizeof(struct _ColorBucket)*cube->size);
qsort(buckets, cube->size, sizeof(struct _ColorBucket), qsort(buckets, cube->size, sizeof(struct _ColorBucket),
@ -203,7 +207,9 @@ static ColorCube copy_color_cube(const ColorCube cube,
ColorCube result; ColorCube result;
result = new_color_cube(rBits, gBits, bBits, aBits); result = new_color_cube(rBits, gBits, bBits, aBits);
if (!result) return NULL; if (!result) {
return NULL;
}
if (cube->rBits > rBits) { if (cube->rBits > rBits) {
dst_reduce[0] = cube->rBits - result->rBits; dst_reduce[0] = cube->rBits - result->rBits;
@ -268,7 +274,9 @@ subtract_color_buckets(ColorCube cube, ColorBucket buckets, long nBuckets) {
subtrahend = &buckets[i]; subtrahend = &buckets[i];
// If the subtrahend contains no buckets, there is nothing to subtract. // If the subtrahend contains no buckets, there is nothing to subtract.
if (subtrahend->count == 0) continue; if (subtrahend->count == 0) {
continue;
}
avg_color_from_color_bucket(subtrahend, &p); avg_color_from_color_bucket(subtrahend, &p);
minuend = color_bucket_from_cube(cube, &p); minuend = color_bucket_from_cube(cube, &p);
@ -325,7 +333,9 @@ create_palette_array(const ColorBucket palette, unsigned int paletteLength) {
/* malloc check ok, calloc for overflow */ /* malloc check ok, calloc for overflow */
paletteArray = calloc(paletteLength, sizeof(Pixel)); paletteArray = calloc(paletteLength, sizeof(Pixel));
if (!paletteArray) return NULL; if (!paletteArray) {
return NULL;
}
for (i=0; i<paletteLength; i++) { for (i=0; i<paletteLength; i++) {
avg_color_from_color_bucket(&palette[i], &paletteArray[i]); avg_color_from_color_bucket(&palette[i], &paletteArray[i]);
@ -393,7 +403,9 @@ int quantize_octree(Pixel *pixelData,
/* create fine cube */ /* create fine cube */
fineCube = new_color_cube(cubeBits[0], cubeBits[1], fineCube = new_color_cube(cubeBits[0], cubeBits[1],
cubeBits[2], cubeBits[3]); cubeBits[2], cubeBits[3]);
if (!fineCube) goto error; if (!fineCube) {
goto error;
}
for (i=0; i<nPixels; i++) { for (i=0; i<nPixels; i++) {
add_color_to_color_cube(fineCube, &pixelData[i]); add_color_to_color_cube(fineCube, &pixelData[i]);
} }
@ -401,19 +413,24 @@ int quantize_octree(Pixel *pixelData,
/* create coarse cube */ /* create coarse cube */
coarseCube = copy_color_cube(fineCube, cubeBits[4], cubeBits[5], coarseCube = copy_color_cube(fineCube, cubeBits[4], cubeBits[5],
cubeBits[6], cubeBits[7]); cubeBits[6], cubeBits[7]);
if (!coarseCube) goto error; if (!coarseCube) {
goto error;
}
nCoarseColors = count_used_color_buckets(coarseCube); nCoarseColors = count_used_color_buckets(coarseCube);
/* limit to nQuantPixels */ /* limit to nQuantPixels */
if (nCoarseColors > nQuantPixels) if (nCoarseColors > nQuantPixels) {
nCoarseColors = nQuantPixels; nCoarseColors = nQuantPixels;
}
/* how many space do we have in our palette for fine colors? */ /* how many space do we have in our palette for fine colors? */
nFineColors = nQuantPixels - nCoarseColors; nFineColors = nQuantPixels - nCoarseColors;
/* create fine color palette */ /* create fine color palette */
paletteBucketsFine = create_sorted_color_palette(fineCube); paletteBucketsFine = create_sorted_color_palette(fineCube);
if (!paletteBucketsFine) goto error; if (!paletteBucketsFine) {
goto error;
}
/* remove the used fine colors from the coarse cube */ /* remove the used fine colors from the coarse cube */
subtract_color_buckets(coarseCube, paletteBucketsFine, nFineColors); subtract_color_buckets(coarseCube, paletteBucketsFine, nFineColors);
@ -430,7 +447,9 @@ int quantize_octree(Pixel *pixelData,
/* create our palette buckets with fine and coarse combined */ /* create our palette buckets with fine and coarse combined */
paletteBucketsCoarse = create_sorted_color_palette(coarseCube); paletteBucketsCoarse = create_sorted_color_palette(coarseCube);
if (!paletteBucketsCoarse) goto error; if (!paletteBucketsCoarse) {
goto error;
}
paletteBuckets = combined_palette(paletteBucketsCoarse, nCoarseColors, paletteBuckets = combined_palette(paletteBucketsCoarse, nCoarseColors,
paletteBucketsFine, nFineColors); paletteBucketsFine, nFineColors);
@ -438,19 +457,25 @@ int quantize_octree(Pixel *pixelData,
paletteBucketsFine = NULL; paletteBucketsFine = NULL;
free(paletteBucketsCoarse); free(paletteBucketsCoarse);
paletteBucketsCoarse = NULL; paletteBucketsCoarse = NULL;
if (!paletteBuckets) goto error; if (!paletteBuckets) {
goto error;
}
/* add all coarse colors to our coarse lookup cube. */ /* add all coarse colors to our coarse lookup cube. */
coarseLookupCube = new_color_cube(cubeBits[4], cubeBits[5], coarseLookupCube = new_color_cube(cubeBits[4], cubeBits[5],
cubeBits[6], cubeBits[7]); cubeBits[6], cubeBits[7]);
if (!coarseLookupCube) goto error; if (!coarseLookupCube) {
goto error;
}
add_lookup_buckets(coarseLookupCube, paletteBuckets, nCoarseColors, 0); add_lookup_buckets(coarseLookupCube, paletteBuckets, nCoarseColors, 0);
/* 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(coarseLookupCube, cubeBits[0], cubeBits[1], lookupCube = copy_color_cube(coarseLookupCube, cubeBits[0], cubeBits[1],
cubeBits[2], cubeBits[3]); cubeBits[2], cubeBits[3]);
if (!lookupCube) goto error; if (!lookupCube) {
goto error;
}
/* add fine colors to the lookup cube */ /* add fine colors to the lookup cube */
add_lookup_buckets(lookupCube, paletteBuckets, nFineColors, nCoarseColors); add_lookup_buckets(lookupCube, paletteBuckets, nFineColors, nCoarseColors);
@ -458,12 +483,16 @@ int quantize_octree(Pixel *pixelData,
/* create result pixels and map palette indices */ /* create result pixels and map palette indices */
/* malloc check ok, calloc for overflow */ /* malloc check ok, calloc for overflow */
qp = calloc(nPixels, sizeof(Pixel)); qp = calloc(nPixels, sizeof(Pixel));
if (!qp) goto error; if (!qp) {
goto error;
}
map_image_pixels(pixelData, nPixels, lookupCube, qp); map_image_pixels(pixelData, nPixels, lookupCube, qp);
/* convert palette buckets to RGB pixel palette */ /* convert palette buckets to RGB pixel palette */
*palette = create_palette_array(paletteBuckets, nQuantPixels); *palette = create_palette_array(paletteBuckets, nQuantPixels);
if (!(*palette)) goto error; if (!(*palette)) {
goto error;
}
*quantizedPixels = qp; *quantizedPixels = qp;
*paletteLength = nQuantPixels; *paletteLength = nQuantPixels;

View File

@ -95,9 +95,15 @@ quantize_pngquant(
result = 1; result = 1;
err: err:
if (attr) liq_attr_destroy(attr); if (attr) {
if (image) liq_image_destroy(image); liq_attr_destroy(attr);
if (remap) liq_result_destroy(remap); }
if (image) {
liq_image_destroy(image);
}
if (remap) {
liq_result_destroy(remap);
}
free(charMatrix); free(charMatrix);
free(charMatrixRows); free(charMatrixRows);
if (!result) { if (!result) {

View File

@ -30,15 +30,23 @@ static type Rank##type(type a[], int n, int k)\
i = l;\ i = l;\
j = m;\ j = m;\
do {\ do {\
while (a[i] < x) i++;\ while (a[i] < x) {\
while (x < a[j]) j--;\ i++;\
}\
while (x < a[j]) {\
j--;\
}\
if (i <= j) {\ if (i <= j) {\
SWAP(type, a[i], a[j]);\ SWAP(type, a[i], a[j]);\
i++; j--;\ i++; j--;\
}\ }\
} while (i <= j);\ } while (i <= j);\
if (j < k) l = i;\ if (j < k) {\
if (k < i) m = j;\ l = i;\
}\
if (k < i) {\
m = j;\
}\
}\ }\
return a[k];\ return a[k];\
} }
@ -54,11 +62,13 @@ ImagingRankFilter(Imaging im, int size, int rank)
int x, y; int x, y;
int i, margin, size2; int i, margin, size2;
if (!im || im->bands != 1 || im->type == IMAGING_TYPE_SPECIAL) if (!im || im->bands != 1 || im->type == IMAGING_TYPE_SPECIAL) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (!(size & 1)) if (!(size & 1)) {
return (Imaging) ImagingError_ValueError("bad filter size"); return (Imaging) ImagingError_ValueError("bad filter size");
}
/* malloc check ok, for overflow in the define below */ /* malloc check ok, for overflow in the define below */
if (size > INT_MAX / size || if (size > INT_MAX / size ||
@ -69,35 +79,40 @@ ImagingRankFilter(Imaging im, int size, int rank)
size2 = size * size; size2 = size * size;
margin = (size-1) / 2; margin = (size-1) / 2;
if (rank < 0 || rank >= size2) if (rank < 0 || rank >= size2) {
return (Imaging) ImagingError_ValueError("bad rank value"); return (Imaging) ImagingError_ValueError("bad rank value");
}
imOut = ImagingNew(im->mode, im->xsize - 2*margin, im->ysize - 2*margin); imOut = ImagingNew(im->mode, im->xsize - 2*margin, im->ysize - 2*margin);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
/* malloc check ok, checked above */ /* malloc check ok, checked above */
#define RANK_BODY(type) do {\ #define RANK_BODY(type) do {\
type* buf = malloc(size2 * sizeof(type));\ type* buf = malloc(size2 * sizeof(type));\
if (!buf)\ if (!buf) {\
goto nomemory;\ goto nomemory;\
for (y = 0; y < imOut->ysize; y++)\ }\
for (y = 0; y < imOut->ysize; y++) {\
for (x = 0; x < imOut->xsize; x++) {\ for (x = 0; x < imOut->xsize; x++) {\
for (i = 0; i < size; i++)\ for (i = 0; i < size; i++) {\
memcpy(buf + i*size, &IMAGING_PIXEL_##type(im, x, y+i),\ memcpy(buf + i*size, &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);\
}\ }\
}\
free(buf); \ free(buf); \
} while (0) } while (0)
if (im->image8) if (im->image8) {
RANK_BODY(UINT8); RANK_BODY(UINT8);
else if (im->type == IMAGING_TYPE_INT32) } else if (im->type == IMAGING_TYPE_INT32) {
RANK_BODY(INT32); RANK_BODY(INT32);
else if (im->type == IMAGING_TYPE_FLOAT32) } else if (im->type == IMAGING_TYPE_FLOAT32) {
RANK_BODY(FLOAT32); RANK_BODY(FLOAT32);
else { } else {
/* safety net (we shouldn't end up here) */ /* safety net (we shouldn't end up here) */
ImagingDelete(imOut); ImagingDelete(imOut);
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();

View File

@ -47,8 +47,9 @@ ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
if (state->ystep < 0) { if (state->ystep < 0) {
state->y = state->ysize-1; state->y = state->ysize-1;
state->ystep = -1; state->ystep = -1;
} else } else {
state->ystep = 1; state->ystep = 1;
}
state->state = LINE; state->state = LINE;
@ -62,8 +63,9 @@ ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
/* Skip padding between lines */ /* Skip padding between lines */
if (bytes < rawstate->skip) if (bytes < rawstate->skip) {
return ptr - buf; return ptr - buf;
}
ptr += rawstate->skip; ptr += rawstate->skip;
bytes -= rawstate->skip; bytes -= rawstate->skip;
@ -72,8 +74,9 @@ ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
} }
if (bytes < state->bytes) if (bytes < state->bytes) {
return ptr - buf; return ptr - buf;
}
/* Unpack data */ /* Unpack data */
state->shuffle((UINT8*) im->image[state->y + state->yoff] + state->shuffle((UINT8*) im->image[state->y + state->yoff] +

View File

@ -41,16 +41,18 @@ ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
} }
state->count = state->bytes; state->count = state->bytes;
state->bytes = bytes; state->bytes = bytes;
} else } else {
state->count = state->bytes; state->count = state->bytes;
}
/* The "ystep" field specifies the orientation */ /* The "ystep" field specifies the orientation */
if (state->ystep < 0) { if (state->ystep < 0) {
state->y = state->ysize-1; state->y = state->ysize-1;
state->ystep = -1; state->ystep = -1;
} else } else {
state->ystep = 1; state->ystep = 1;
}
state->state = 1; state->state = 1;
@ -68,9 +70,10 @@ ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
state->shuffle(ptr, (UINT8*) im->image[state->y + state->yoff] + state->shuffle(ptr, (UINT8*) im->image[state->y + state->yoff] +
state->xoff * im->pixelsize, state->xsize); state->xoff * im->pixelsize, state->xsize);
if (state->bytes > state->count) if (state->bytes > state->count) {
/* zero-pad the buffer, if necessary */ /* zero-pad the buffer, if necessary */
memset(ptr + state->count, 0, state->bytes - state->count); memset(ptr + state->count, 0, state->bytes - state->count);
}
ptr += state->bytes; ptr += state->bytes;
bytes -= state->bytes; bytes -= state->bytes;

View File

@ -1374,11 +1374,13 @@ ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4])
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
Imaging imOut = NULL; Imaging imOut = NULL;
if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "1") == 0) if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "1") == 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (imIn->type == IMAGING_TYPE_SPECIAL) if (imIn->type == IMAGING_TYPE_SPECIAL) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
imOut = ImagingNewDirty(imIn->mode, imOut = ImagingNewDirty(imIn->mode,
(box[2] + xscale - 1) / xscale, (box[2] + xscale - 1) / xscale,

View File

@ -13,28 +13,34 @@ struct filter {
static inline double box_filter(double x) static inline double box_filter(double x)
{ {
if (x > -0.5 && x <= 0.5) if (x > -0.5 && x <= 0.5) {
return 1.0; return 1.0;
}
return 0.0; return 0.0;
} }
static inline double bilinear_filter(double x) static inline double bilinear_filter(double x)
{ {
if (x < 0.0) if (x < 0.0) {
x = -x; x = -x;
if (x < 1.0) }
if (x < 1.0) {
return 1.0-x; return 1.0-x;
}
return 0.0; return 0.0;
} }
static inline double hamming_filter(double x) static inline double hamming_filter(double x)
{ {
if (x < 0.0) if (x < 0.0) {
x = -x; x = -x;
if (x == 0.0) }
if (x == 0.0) {
return 1.0; return 1.0;
if (x >= 1.0) }
if (x >= 1.0) {
return 0.0; return 0.0;
}
x = x * M_PI; x = x * M_PI;
return sin(x) / x * (0.54f + 0.46f * cos(x)); return sin(x) / x * (0.54f + 0.46f * cos(x));
} }
@ -43,20 +49,24 @@ static inline double bicubic_filter(double x)
{ {
/* https://en.wikipedia.org/wiki/Bicubic_interpolation#Bicubic_convolution_algorithm */ /* https://en.wikipedia.org/wiki/Bicubic_interpolation#Bicubic_convolution_algorithm */
#define a -0.5 #define a -0.5
if (x < 0.0) if (x < 0.0) {
x = -x; x = -x;
if (x < 1.0) }
if (x < 1.0) {
return ((a + 2.0) * x - (a + 3.0)) * x*x + 1; return ((a + 2.0) * x - (a + 3.0)) * x*x + 1;
if (x < 2.0) }
if (x < 2.0) {
return (((x - 5) * x + 8) * x - 4) * a; return (((x - 5) * x + 8) * x - 4) * a;
}
return 0.0; return 0.0;
#undef a #undef a
} }
static inline double sinc_filter(double x) static inline double sinc_filter(double x)
{ {
if (x == 0.0) if (x == 0.0) {
return 1.0; return 1.0;
}
x = x * M_PI; x = x * M_PI;
return sin(x) / x; return sin(x) / x;
} }
@ -64,8 +74,9 @@ static inline double sinc_filter(double x)
static inline double lanczos_filter(double x) static inline double lanczos_filter(double x)
{ {
/* truncated sinc */ /* truncated sinc */
if (-3.0 <= x && x < 3.0) if (-3.0 <= x && x < 3.0) {
return sinc_filter(x) * sinc_filter(x/3); return sinc_filter(x) * sinc_filter(x/3);
}
return 0.0; return 0.0;
} }
@ -224,12 +235,14 @@ precompute_coeffs(int inSize, float in0, float in1, int outSize,
ss = 1.0 / filterscale; ss = 1.0 / filterscale;
// Round the value // Round the value
xmin = (int) (center - support + 0.5); xmin = (int) (center - support + 0.5);
if (xmin < 0) if (xmin < 0) {
xmin = 0; xmin = 0;
}
// Round the value // Round the value
xmax = (int) (center + support + 0.5); xmax = (int) (center + support + 0.5);
if (xmax > inSize) if (xmax > inSize) {
xmax = inSize; xmax = inSize;
}
xmax -= xmin; xmax -= xmin;
k = &kk[xx * ksize]; k = &kk[xx * ksize];
for (x = 0; x < xmax; x++) { for (x = 0; x < xmax; x++) {
@ -238,8 +251,9 @@ precompute_coeffs(int inSize, float in0, float in1, int outSize,
ww += w; ww += w;
} }
for (x = 0; x < xmax; x++) { for (x = 0; x < xmax; x++) {
if (ww != 0.0) if (ww != 0.0) {
k[x] /= ww; k[x] /= ww;
}
} }
// Remaining values should stay empty if they are used despite of xmax. // Remaining values should stay empty if they are used despite of xmax.
for (; x < ksize; x++) { for (; x < ksize; x++) {
@ -295,8 +309,9 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, int offset,
xmax = bounds[xx * 2 + 1]; xmax = bounds[xx * 2 + 1];
k = &kk[xx * ksize]; k = &kk[xx * ksize];
ss0 = 1 << (PRECISION_BITS -1); ss0 = 1 << (PRECISION_BITS -1);
for (x = 0; x < xmax; x++) for (x = 0; x < xmax; x++) {
ss0 += ((UINT8) imIn->image8[yy + offset][x + xmin]) * k[x]; ss0 += ((UINT8) imIn->image8[yy + offset][x + xmin]) * k[x];
}
imOut->image8[yy][xx] = clip8(ss0); imOut->image8[yy][xx] = clip8(ss0);
} }
} }
@ -379,8 +394,9 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, int offset,
ymax = bounds[yy * 2 + 1]; ymax = bounds[yy * 2 + 1];
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
ss0 = 1 << (PRECISION_BITS -1); ss0 = 1 << (PRECISION_BITS -1);
for (y = 0; y < ymax; y++) for (y = 0; y < ymax; y++) {
ss0 += ((UINT8) imIn->image8[y + ymin][xx]) * k[y]; ss0 += ((UINT8) imIn->image8[y + ymin][xx]) * k[y];
}
imOut->image8[yy][xx] = clip8(ss0); imOut->image8[yy][xx] = clip8(ss0);
} }
} }
@ -460,8 +476,9 @@ ImagingResampleHorizontal_32bpc(Imaging imOut, Imaging imIn, int offset,
xmax = bounds[xx * 2 + 1]; xmax = bounds[xx * 2 + 1];
k = &kk[xx * ksize]; k = &kk[xx * ksize];
ss = 0.0; ss = 0.0;
for (x = 0; x < xmax; x++) for (x = 0; x < xmax; x++) {
ss += IMAGING_PIXEL_I(imIn, x + xmin, yy + offset) * k[x]; ss += IMAGING_PIXEL_I(imIn, x + xmin, yy + offset) * k[x];
}
IMAGING_PIXEL_I(imOut, xx, yy) = ROUND_UP(ss); IMAGING_PIXEL_I(imOut, xx, yy) = ROUND_UP(ss);
} }
} }
@ -474,8 +491,9 @@ ImagingResampleHorizontal_32bpc(Imaging imOut, Imaging imIn, int offset,
xmax = bounds[xx * 2 + 1]; xmax = bounds[xx * 2 + 1];
k = &kk[xx * ksize]; k = &kk[xx * ksize];
ss = 0.0; ss = 0.0;
for (x = 0; x < xmax; x++) for (x = 0; x < xmax; x++) {
ss += IMAGING_PIXEL_F(imIn, x + xmin, yy + offset) * k[x]; ss += IMAGING_PIXEL_F(imIn, x + xmin, yy + offset) * k[x];
}
IMAGING_PIXEL_F(imOut, xx, yy) = ss; IMAGING_PIXEL_F(imOut, xx, yy) = ss;
} }
} }
@ -503,8 +521,9 @@ ImagingResampleVertical_32bpc(Imaging imOut, Imaging imIn, int offset,
k = &kk[yy * ksize]; k = &kk[yy * ksize];
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
ss = 0.0; ss = 0.0;
for (y = 0; y < ymax; y++) for (y = 0; y < ymax; y++) {
ss += IMAGING_PIXEL_I(imIn, xx, y + ymin) * k[y]; ss += IMAGING_PIXEL_I(imIn, xx, y + ymin) * k[y];
}
IMAGING_PIXEL_I(imOut, xx, yy) = ROUND_UP(ss); IMAGING_PIXEL_I(imOut, xx, yy) = ROUND_UP(ss);
} }
} }
@ -517,8 +536,9 @@ ImagingResampleVertical_32bpc(Imaging imOut, Imaging imIn, int offset,
k = &kk[yy * ksize]; k = &kk[yy * ksize];
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
ss = 0.0; ss = 0.0;
for (y = 0; y < ymax; y++) for (y = 0; y < ymax; y++) {
ss += IMAGING_PIXEL_F(imIn, xx, y + ymin) * k[y]; ss += IMAGING_PIXEL_F(imIn, xx, y + ymin) * k[y];
}
IMAGING_PIXEL_F(imOut, xx, yy) = ss; IMAGING_PIXEL_F(imOut, xx, yy) = ss;
} }
} }
@ -546,8 +566,9 @@ ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4])
ResampleFunction ResampleHorizontal; ResampleFunction ResampleHorizontal;
ResampleFunction ResampleVertical; ResampleFunction ResampleVertical;
if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "1") == 0) if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "1") == 0) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
}
if (imIn->type == IMAGING_TYPE_SPECIAL) { if (imIn->type == IMAGING_TYPE_SPECIAL) {
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();

View File

@ -33,11 +33,13 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize)
for (;n > 0; n--) for (;n > 0; n--)
{ {
pixel = *src++; pixel = *src++;
if (n == 1 && pixel != 0) if (n == 1 && pixel != 0) {
return n; return n;
}
count = pixel & RLE_MAX_RUN; count = pixel & RLE_MAX_RUN;
if (!count) if (!count) {
return count; return count;
}
if (x + count > xsize) { if (x + count > xsize) {
return -1; return -1;
} }
@ -71,11 +73,13 @@ static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize)
{ {
pixel = src[1]; pixel = src[1];
src+=2; src+=2;
if (n == 1 && pixel != 0) if (n == 1 && pixel != 0) {
return n; return n;
}
count = pixel & RLE_MAX_RUN; count = pixel & RLE_MAX_RUN;
if (!count) if (!count) {
return count; return count;
}
if (x + count > xsize) { if (x + count > xsize) {
return -1; return -1;
} }
@ -151,11 +155,13 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
goto sgi_finish_decode; goto sgi_finish_decode;
} }
/* populate offsets table */ /* populate offsets table */
for (c->tabindex = 0, c->bufindex = 0; c->tabindex < c->tablen; c->tabindex++, c->bufindex+=4) for (c->tabindex = 0, c->bufindex = 0; c->tabindex < c->tablen; c->tabindex++, c->bufindex+=4) {
read4B(&c->starttab[c->tabindex], &ptr[c->bufindex]); read4B(&c->starttab[c->tabindex], &ptr[c->bufindex]);
}
/* populate lengths table */ /* populate lengths table */
for (c->tabindex = 0, c->bufindex = c->tablen * sizeof(UINT32); c->tabindex < c->tablen; c->tabindex++, c->bufindex+=4) for (c->tabindex = 0, c->bufindex = c->tablen * sizeof(UINT32); c->tabindex < c->tablen; c->tabindex++, c->bufindex+=4) {
read4B(&c->lengthtab[c->tabindex], &ptr[c->bufindex]); read4B(&c->lengthtab[c->tabindex], &ptr[c->bufindex]);
}
state->count += c->tablen * sizeof(UINT32) * 2; state->count += c->tablen * sizeof(UINT32) * 2;

View File

@ -244,17 +244,21 @@ ImagingNewPrologue(const char *mode, int xsize, int ysize)
void void
ImagingDelete(Imaging im) ImagingDelete(Imaging im)
{ {
if (!im) if (!im) {
return; return;
}
if (im->palette) if (im->palette) {
ImagingPaletteDelete(im->palette); ImagingPaletteDelete(im->palette);
}
if (im->destroy) if (im->destroy) {
im->destroy(im); im->destroy(im);
}
if (im->image) if (im->image) {
free(im->image); free(im->image);
}
free(im); free(im);
} }
@ -399,8 +403,9 @@ ImagingAllocateArray(Imaging im, int dirty, int block_size)
aligned_linesize = (im->linesize + arena->alignment - 1) & -arena->alignment; aligned_linesize = (im->linesize + arena->alignment - 1) & -arena->alignment;
lines_per_block = (block_size - (arena->alignment - 1)) / aligned_linesize; lines_per_block = (block_size - (arena->alignment - 1)) / aligned_linesize;
if (lines_per_block == 0) if (lines_per_block == 0) {
lines_per_block = 1; lines_per_block = 1;
}
blocks_count = (im->ysize + lines_per_block - 1) / lines_per_block; blocks_count = (im->ysize + lines_per_block - 1) / lines_per_block;
// printf("NEW size: %dx%d, ls: %d, lpb: %d, blocks: %d\n", // printf("NEW size: %dx%d, ls: %d, lpb: %d, blocks: %d\n",
// im->xsize, im->ysize, aligned_linesize, lines_per_block, blocks_count); // im->xsize, im->ysize, aligned_linesize, lines_per_block, blocks_count);
@ -457,8 +462,9 @@ ImagingAllocateArray(Imaging im, int dirty, int block_size)
static void static void
ImagingDestroyBlock(Imaging im) ImagingDestroyBlock(Imaging im)
{ {
if (im->block) if (im->block) {
free(im->block); free(im->block);
}
} }
Imaging Imaging
@ -510,8 +516,9 @@ ImagingNewInternal(const char* mode, int xsize, int ysize, int dirty)
} }
im = ImagingNewPrologue(mode, xsize, ysize); im = ImagingNewPrologue(mode, xsize, ysize);
if ( ! im) if ( ! im) {
return NULL; return NULL;
}
if (ImagingAllocateArray(im, dirty, ImagingDefaultArena.block_size)) { if (ImagingAllocateArray(im, dirty, ImagingDefaultArena.block_size)) {
return im; return im;
@ -550,8 +557,9 @@ ImagingNewBlock(const char* mode, int xsize, int ysize)
} }
im = ImagingNewPrologue(mode, xsize, ysize); im = ImagingNewPrologue(mode, xsize, ysize);
if ( ! im) if ( ! im) {
return NULL; return NULL;
}
if (ImagingAllocateBlock(im)) { if (ImagingAllocateBlock(im)) {
return im; return im;
@ -576,8 +584,9 @@ ImagingNew2Dirty(const char* mode, Imaging imOut, Imaging imIn)
} else { } else {
/* create new image */ /* create new image */
imOut = ImagingNewDirty(mode, imIn->xsize, imIn->ysize); imOut = ImagingNewDirty(mode, imIn->xsize, imIn->ysize);
if (!imOut) if (!imOut) {
return NULL; return NULL;
}
} }
return imOut; return imOut;
@ -587,8 +596,9 @@ void
ImagingCopyPalette(Imaging destination, Imaging source) ImagingCopyPalette(Imaging destination, Imaging source)
{ {
if (source->palette) { if (source->palette) {
if (destination->palette) if (destination->palette) {
ImagingPaletteDelete(destination->palette); ImagingPaletteDelete(destination->palette);
}
destination->palette = ImagingPaletteDuplicate(source->palette); destination->palette = ImagingPaletteDuplicate(source->palette);
} }
} }

View File

@ -31,13 +31,15 @@ ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t
for (;;) { for (;;) {
if (bytes < 1) if (bytes < 1) {
return ptr - buf; return ptr - buf;
}
if (ptr[0] == 0x80) { if (ptr[0] == 0x80) {
if (bytes < 2) if (bytes < 2) {
break; break;
}
n = ptr[1]; n = ptr[1];
@ -55,8 +57,9 @@ ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t
} else { } else {
/* Run (3 bytes) */ /* Run (3 bytes) */
if (bytes < 3) if (bytes < 3) {
break; break;
}
/* from (https://www.fileformat.info/format/sunraster/egff.htm) /* from (https://www.fileformat.info/format/sunraster/egff.htm)

View File

@ -33,8 +33,9 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
if (state->ystep < 0) { if (state->ystep < 0) {
state->y = state->ysize-1; state->y = state->ysize-1;
state->ystep = -1; state->ystep = -1;
} else } else {
state->ystep = 1; state->ystep = 1;
}
state->state = 1; state->state = 1;
@ -44,15 +45,17 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
for (;;) { for (;;) {
if (bytes < 1) if (bytes < 1) {
return ptr - buf; return ptr - buf;
}
if (ptr[0] & 0x80) { if (ptr[0] & 0x80) {
/* Run (1 + pixelsize bytes) */ /* Run (1 + pixelsize bytes) */
if (bytes < 1 + depth) if (bytes < 1 + depth) {
break; break;
}
n = depth * ((ptr[0] & 0x7f) + 1); n = depth * ((ptr[0] & 0x7f) + 1);
@ -61,12 +64,13 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
return -1; return -1;
} }
if (depth == 1) if (depth == 1) {
memset(state->buffer + state->x, ptr[1], n); memset(state->buffer + state->x, ptr[1], n);
else { } else {
int i; int i;
for (i = 0; i < n; i += depth) for (i = 0; i < n; i += depth) {
memcpy(state->buffer + state->x + i, ptr+1, depth); memcpy(state->buffer + state->x + i, ptr+1, depth);
}
} }
ptr += 1 + depth; ptr += 1 + depth;
@ -77,8 +81,9 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
/* Literal (1+n+1 bytes block) */ /* Literal (1+n+1 bytes block) */
n = depth * (ptr[0] + 1); n = depth * (ptr[0] + 1);
if (bytes < 1 + n) if (bytes < 1 + n) {
break; break;
}
if (state->x + n > state->bytes) { if (state->x + n > state->bytes) {
state->errcode = IMAGING_CODEC_OVERRUN; state->errcode = IMAGING_CODEC_OVERRUN;

View File

@ -22,8 +22,9 @@ ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
if (state->ystep < 0) { if (state->ystep < 0) {
state->ystep = -1; state->ystep = -1;
state->y = state->ysize - 1; state->y = state->ysize - 1;
} else } else {
state->ystep = 1; state->ystep = 1;
}
state->state = 1; state->state = 1;
} }
@ -46,8 +47,9 @@ ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
assert(state->x <= state->xsize); assert(state->x <= state->xsize);
/* Make sure we have space for the descriptor. */ /* Make sure we have space for the descriptor. */
if (bytes < 1) if (bytes < 1) {
break; break;
}
if (state->x == state->xsize) { if (state->x == state->xsize) {
state->x = 0; state->x = 0;
@ -59,12 +61,13 @@ ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
} }
} }
if (state->x == 0) if (state->x == 0) {
state->shuffle( state->shuffle(
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;
@ -87,28 +90,32 @@ ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
*/ */
maxLookup = state->x + 126; maxLookup = state->x + 126;
/* A packet must not span multiple rows. */ /* A packet must not span multiple rows. */
if (maxLookup > state->xsize - 1) if (maxLookup > state->xsize - 1) {
maxLookup = state->xsize - 1; maxLookup = state->xsize - 1;
}
if (isRaw) { if (isRaw) {
while (state->x < maxLookup) while (state->x < maxLookup) {
if (!comparePixels(row, state->x, bytesPerPixel)) if (!comparePixels(row, state->x, bytesPerPixel)) {
++state->x; ++state->x;
else { } else {
/* Two identical pixels will go to RLE packet. */ /* Two identical pixels will go to RLE packet. */
--state->x; --state->x;
break; break;
} }
}
state->count += (state->x - startX) * bytesPerPixel; state->count += (state->x - startX) * bytesPerPixel;
} else { } else {
descriptor |= 0x80; descriptor |= 0x80;
while (state->x < maxLookup) while (state->x < maxLookup) {
if (comparePixels(row, state->x, bytesPerPixel)) if (comparePixels(row, state->x, bytesPerPixel)) {
++state->x; ++state->x;
else } else {
break; break;
}
}
} }
} }
@ -132,12 +139,14 @@ ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
assert(state->x > 0); assert(state->x > 0);
assert(state->count <= state->x * bytesPerPixel); assert(state->count <= state->x * bytesPerPixel);
if (bytes == 0) if (bytes == 0) {
break; break;
}
flushCount = state->count; flushCount = state->count;
if (flushCount > bytes) if (flushCount > bytes) {
flushCount = bytes; flushCount = bytes;
}
memcpy( memcpy(
dst, dst,

View File

@ -350,8 +350,9 @@ unpackLI(UINT8* out, const UINT8* in, int pixels)
{ {
/* negative */ /* negative */
int i; int i;
for (i = 0; i < pixels; i++) for (i = 0; i < pixels; i++) {
out[i] = ~in[i]; out[i] = ~in[i];
}
} }
static void static void
@ -1115,8 +1116,9 @@ static void NAME(UINT8* out_, const UINT8* in, int pixels)\
{\ {\
int i;\ int i;\
OUTTYPE* out = (OUTTYPE*) out_;\ OUTTYPE* out = (OUTTYPE*) out_;\
for (i = 0; i < pixels; i++, in += sizeof(INTYPE))\ for (i = 0; i < pixels; i++, in += sizeof(INTYPE)) {\
out[i] = (OUTTYPE) ((INTYPE) GET);\ out[i] = (OUTTYPE) ((INTYPE) GET);\
}\
} }
#define UNPACK(NAME, COPY, INTYPE, OUTTYPE)\ #define UNPACK(NAME, COPY, INTYPE, OUTTYPE)\
@ -1521,13 +1523,15 @@ ImagingFindUnpacker(const char* mode, const char* rawmode, int* bits_out)
int i; int i;
/* find a suitable pixel unpacker */ /* find a suitable pixel unpacker */
for (i = 0; unpackers[i].rawmode; i++) for (i = 0; unpackers[i].rawmode; i++) {
if (strcmp(unpackers[i].mode, mode) == 0 && if (strcmp(unpackers[i].mode, mode) == 0 &&
strcmp(unpackers[i].rawmode, rawmode) == 0) { strcmp(unpackers[i].rawmode, rawmode) == 0) {
if (bits_out) if (bits_out) {
*bits_out = unpackers[i].bits; *bits_out = unpackers[i].bits;
}
return unpackers[i].unpack; return unpackers[i].unpack;
} }
}
/* FIXME: configure a general unpacker based on the type codes... */ /* FIXME: configure a general unpacker based on the type codes... */

View File

@ -14,10 +14,12 @@ typedef UINT8 pixel[4];
static inline UINT8 clip8(int in) static inline UINT8 clip8(int in)
{ {
if (in >= 255) if (in >= 255) {
return 255; return 255;
if (in <= 0) }
if (in <= 0) {
return 0; return 0;
}
return (UINT8) in; return (UINT8) in;
} }
@ -39,8 +41,9 @@ ImagingUnsharpMask(Imaging imOut, Imaging imIn, float radius, int percent,
/* First, do a gaussian blur on the image, putting results in imOut /* First, do a gaussian blur on the image, putting results in imOut
temporarily. All format checks are in gaussian blur. */ temporarily. All format checks are in gaussian blur. */
result = ImagingGaussianBlur(imOut, imIn, radius, 3); result = ImagingGaussianBlur(imOut, imIn, radius, 3);
if (!result) if (!result) {
return NULL; return NULL;
}
/* Now, go through each pixel, compare "normal" pixel to blurred /* Now, go through each pixel, compare "normal" pixel to blurred
pixel. If the difference is more than threshold values, apply pixel. If the difference is more than threshold values, apply

View File

@ -27,8 +27,9 @@ ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
UINT8* ptr; UINT8* ptr;
if (!state->state) if (!state->state) {
state->state = SKIP; state->state = SKIP;
}
ptr = buf; ptr = buf;
@ -39,21 +40,24 @@ ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
/* Skip forward until next 'x' */ /* Skip forward until next 'x' */
while (bytes > 0) { while (bytes > 0) {
if (*ptr == 'x') if (*ptr == 'x') {
break; break;
}
ptr++; ptr++;
bytes--; bytes--;
} }
if (bytes == 0) if (bytes == 0) {
return ptr - buf; return ptr - buf;
}
state->state = BYTE; state->state = BYTE;
} }
if (bytes < 3) if (bytes < 3) {
return ptr - buf; return ptr - buf;
}
state->buffer[state->x] = (HEX(ptr[1])<<4) + HEX(ptr[2]); state->buffer[state->x] = (HEX(ptr[1])<<4) + HEX(ptr[2]);

View File

@ -90,8 +90,9 @@ ImagingXbmEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
bytes--; bytes--;
state->count = 0; state->count = 0;
} }
} else } else {
*ptr++ = '\n'; *ptr++ = '\n';
}
bytes -= 5; bytes -= 5;

View File

@ -53,8 +53,9 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
if (!state->state) { if (!state->state) {
/* Initialization */ /* Initialization */
if (context->mode == ZIP_PNG || context->mode == ZIP_PNG_PALETTE) if (context->mode == ZIP_PNG || context->mode == ZIP_PNG_PALETTE) {
context->prefix = 1; /* PNG */ context->prefix = 1; /* PNG */
}
/* overflow check for malloc */ /* overflow check for malloc */
if (state->bytes > INT_MAX - 1) { if (state->bytes > INT_MAX - 1) {
@ -121,12 +122,13 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
if (err < 0) { if (err < 0) {
/* Something went wrong inside the compression library */ /* Something went wrong inside the compression library */
if (err == Z_DATA_ERROR) if (err == Z_DATA_ERROR) {
state->errcode = IMAGING_CODEC_BROKEN; state->errcode = IMAGING_CODEC_BROKEN;
else if (err == Z_MEM_ERROR) } else if (err == Z_MEM_ERROR) {
state->errcode = IMAGING_CODEC_MEMORY; state->errcode = IMAGING_CODEC_MEMORY;
else } else {
state->errcode = IMAGING_CODEC_CONFIG; state->errcode = IMAGING_CODEC_CONFIG;
}
free(context->previous); free(context->previous);
context->previous = NULL; context->previous = NULL;
inflateEnd(&context->z_stream); inflateEnd(&context->z_stream);
@ -149,28 +151,33 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
case 1: case 1:
/* prior */ /* prior */
bpp = (state->bits + 7) / 8; bpp = (state->bits + 7) / 8;
for (i = bpp+1; i <= row_len; i++) for (i = bpp+1; i <= row_len; i++) {
state->buffer[i] += state->buffer[i-bpp]; state->buffer[i] += state->buffer[i-bpp];
}
break; break;
case 2: case 2:
/* up */ /* up */
for (i = 1; i <= row_len; i++) for (i = 1; i <= row_len; i++) {
state->buffer[i] += context->previous[i]; state->buffer[i] += context->previous[i];
}
break; break;
case 3: case 3:
/* average */ /* average */
bpp = (state->bits + 7) / 8; bpp = (state->bits + 7) / 8;
for (i = 1; i <= bpp; i++) for (i = 1; i <= bpp; i++) {
state->buffer[i] += context->previous[i]/2; state->buffer[i] += context->previous[i]/2;
for (; i <= row_len; i++) }
for (; i <= row_len; i++) {
state->buffer[i] += state->buffer[i] +=
(state->buffer[i-bpp] + context->previous[i])/2; (state->buffer[i-bpp] + context->previous[i])/2;
}
break; break;
case 4: case 4:
/* paeth filtering */ /* paeth filtering */
bpp = (state->bits + 7) / 8; bpp = (state->bits + 7) / 8;
for (i = 1; i <= bpp; i++) for (i = 1; i <= bpp; i++) {
state->buffer[i] += context->previous[i]; state->buffer[i] += context->previous[i];
}
for (; i <= row_len; i++) { for (; i <= row_len; i++) {
int a, b, c; int a, b, c;
int pa, pb, pc; int pa, pb, pc;
@ -201,8 +208,9 @@ ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
break; break;
case ZIP_TIFF_PREDICTOR: case ZIP_TIFF_PREDICTOR:
bpp = (state->bits + 7) / 8; bpp = (state->bits + 7) / 8;
for (i = bpp+1; i <= row_len; i++) for (i = bpp+1; i <= row_len; i++) {
state->buffer[i] += state->buffer[i-bpp]; state->buffer[i] += state->buffer[i-bpp];
}
break; break;
} }

View File

@ -128,12 +128,13 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
if (err < 0) { if (err < 0) {
/* Something went wrong inside the compression library */ /* Something went wrong inside the compression library */
if (err == Z_DATA_ERROR) if (err == Z_DATA_ERROR) {
state->errcode = IMAGING_CODEC_BROKEN; state->errcode = IMAGING_CODEC_BROKEN;
else if (err == Z_MEM_ERROR) } else if (err == Z_MEM_ERROR) {
state->errcode = IMAGING_CODEC_MEMORY; state->errcode = IMAGING_CODEC_MEMORY;
else } else {
state->errcode = IMAGING_CODEC_CONFIG; state->errcode = IMAGING_CODEC_CONFIG;
}
free(context->paeth); free(context->paeth);
free(context->average); free(context->average);
free(context->up); free(context->up);
@ -282,12 +283,13 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
if (err < 0) { if (err < 0) {
/* Something went wrong inside the compression library */ /* Something went wrong inside the compression library */
if (err == Z_DATA_ERROR) if (err == Z_DATA_ERROR) {
state->errcode = IMAGING_CODEC_BROKEN; state->errcode = IMAGING_CODEC_BROKEN;
else if (err == Z_MEM_ERROR) } else if (err == Z_MEM_ERROR) {
state->errcode = IMAGING_CODEC_MEMORY; state->errcode = IMAGING_CODEC_MEMORY;
else } else {
state->errcode = IMAGING_CODEC_CONFIG; state->errcode = IMAGING_CODEC_CONFIG;
}
free(context->paeth); free(context->paeth);
free(context->average); free(context->average);
free(context->up); free(context->up);
@ -305,8 +307,9 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
} }
if (context->z_stream.avail_out == 0) if (context->z_stream.avail_out == 0) {
break; /* Buffer full */ break; /* Buffer full */
}
case 2: case 2:
@ -331,8 +334,9 @@ ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
break; break;
} }
if (context->z_stream.avail_out == 0) if (context->z_stream.avail_out == 0) {
break; /* Buffer full */ break; /* Buffer full */
}
} }

View File

@ -47,12 +47,14 @@ PyImaging_MapperNew(const char* filename, int readonly)
{ {
ImagingMapperObject *mapper; ImagingMapperObject *mapper;
if (PyType_Ready(&ImagingMapperType) < 0) if (PyType_Ready(&ImagingMapperType) < 0) {
return NULL; return NULL;
}
mapper = PyObject_New(ImagingMapperObject, &ImagingMapperType); mapper = PyObject_New(ImagingMapperObject, &ImagingMapperType);
if (mapper == NULL) if (mapper == NULL) {
return NULL; return NULL;
}
mapper->base = NULL; mapper->base = NULL;
mapper->size = mapper->offset = 0; mapper->size = mapper->offset = 0;
@ -101,12 +103,15 @@ static void
mapping_dealloc(ImagingMapperObject* mapper) mapping_dealloc(ImagingMapperObject* mapper)
{ {
#ifdef _WIN32 #ifdef _WIN32
if (mapper->base != 0) if (mapper->base != 0) {
UnmapViewOfFile(mapper->base); UnmapViewOfFile(mapper->base);
if (mapper->hMap != (HANDLE)-1) }
if (mapper->hMap != (HANDLE)-1) {
CloseHandle(mapper->hMap); CloseHandle(mapper->hMap);
if (mapper->hFile != (HANDLE)-1) }
if (mapper->hFile != (HANDLE)-1) {
CloseHandle(mapper->hFile); CloseHandle(mapper->hFile);
}
mapper->base = 0; mapper->base = 0;
mapper->hMap = mapper->hFile = (HANDLE)-1; mapper->hMap = mapper->hFile = (HANDLE)-1;
#endif #endif
@ -122,18 +127,22 @@ mapping_read(ImagingMapperObject* mapper, PyObject* args)
PyObject* buf; PyObject* buf;
int size = -1; int size = -1;
if (!PyArg_ParseTuple(args, "|i", &size)) if (!PyArg_ParseTuple(args, "|i", &size)) {
return NULL; return NULL;
}
/* check size */ /* check size */
if (size < 0 || mapper->offset + size > mapper->size) if (size < 0 || mapper->offset + size > mapper->size) {
size = mapper->size - mapper->offset; size = mapper->size - mapper->offset;
if (size < 0) }
if (size < 0) {
size = 0; size = 0;
}
buf = PyBytes_FromStringAndSize(NULL, size); buf = PyBytes_FromStringAndSize(NULL, size);
if (!buf) if (!buf) {
return NULL; return NULL;
}
if (size > 0) { if (size > 0) {
memcpy(PyBytes_AsString(buf), mapper->base + mapper->offset, size); memcpy(PyBytes_AsString(buf), mapper->base + mapper->offset, size);
@ -148,8 +157,9 @@ mapping_seek(ImagingMapperObject* mapper, PyObject* args)
{ {
int offset; int offset;
int whence = 0; int whence = 0;
if (!PyArg_ParseTuple(args, "i|i", &offset, &whence)) if (!PyArg_ParseTuple(args, "i|i", &offset, &whence)) {
return NULL; return NULL;
}
switch (whence) { switch (whence) {
case 0: /* SEEK_SET */ case 0: /* SEEK_SET */
@ -193,17 +203,19 @@ mapping_readimage(ImagingMapperObject* mapper, PyObject* args)
int stride; int stride;
int orientation; int orientation;
if (!PyArg_ParseTuple(args, "s(ii)ii", &mode, &xsize, &ysize, if (!PyArg_ParseTuple(args, "s(ii)ii", &mode, &xsize, &ysize,
&stride, &orientation)) &stride, &orientation)) {
return NULL; return NULL;
}
if (stride <= 0) { if (stride <= 0) {
/* FIXME: maybe we should call ImagingNewPrologue instead */ /* FIXME: maybe we should call ImagingNewPrologue instead */
if (!strcmp(mode, "L") || !strcmp(mode, "P")) if (!strcmp(mode, "L") || !strcmp(mode, "P")) {
stride = xsize; stride = xsize;
else if (!strcmp(mode, "I;16") || !strcmp(mode, "I;16B")) } else if (!strcmp(mode, "I;16") || !strcmp(mode, "I;16B")) {
stride = xsize * 2; stride = xsize * 2;
else } else {
stride = xsize * 4; stride = xsize * 4;
}
} }
size = ysize * stride; size = ysize * stride;
@ -214,16 +226,20 @@ mapping_readimage(ImagingMapperObject* mapper, PyObject* args)
} }
im = ImagingNewPrologue(mode, xsize, ysize); im = ImagingNewPrologue(mode, xsize, ysize);
if (!im) if (!im) {
return NULL; return NULL;
}
/* setup file pointers */ /* setup file pointers */
if (orientation > 0) if (orientation > 0) {
for (y = 0; y < ysize; y++) for (y = 0; y < ysize; y++) {
im->image[y] = mapper->base + mapper->offset + y * stride; im->image[y] = mapper->base + mapper->offset + y * stride;
else }
for (y = 0; y < ysize; y++) } else {
for (y = 0; y < ysize; y++) {
im->image[ysize-y-1] = mapper->base + mapper->offset + y * stride; im->image[ysize-y-1] = mapper->base + mapper->offset + y * stride;
}
}
im->destroy = ImagingDestroyMap; im->destroy = ImagingDestroyMap;
@ -279,8 +295,9 @@ PyObject*
PyImaging_Mapper(PyObject* self, PyObject* args) PyImaging_Mapper(PyObject* self, PyObject* args)
{ {
char* filename; char* filename;
if (!PyArg_ParseTuple(args, "s", &filename)) if (!PyArg_ParseTuple(args, "s", &filename)) {
return NULL; return NULL;
}
return (PyObject*) PyImaging_MapperNew(filename, 1); return (PyObject*) PyImaging_MapperNew(filename, 1);
} }
@ -319,8 +336,9 @@ PyImaging_MapBuffer(PyObject* self, PyObject* args)
int ystep; int ystep;
if (!PyArg_ParseTuple(args, "O(ii)sn(sii)", &target, &xsize, &ysize, if (!PyArg_ParseTuple(args, "O(ii)sn(sii)", &target, &xsize, &ysize,
&codec, &offset, &mode, &stride, &ystep)) &codec, &offset, &mode, &stride, &ystep)) {
return NULL; return NULL;
}
if (!PyImaging_CheckBuffer(target)) { if (!PyImaging_CheckBuffer(target)) {
PyErr_SetString(PyExc_TypeError, "expected string or buffer"); PyErr_SetString(PyExc_TypeError, "expected string or buffer");
@ -328,12 +346,13 @@ PyImaging_MapBuffer(PyObject* self, PyObject* args)
} }
if (stride <= 0) { if (stride <= 0) {
if (!strcmp(mode, "L") || !strcmp(mode, "P")) if (!strcmp(mode, "L") || !strcmp(mode, "P")) {
stride = xsize; stride = xsize;
else if (!strncmp(mode, "I;16", 4)) } else if (!strncmp(mode, "I;16", 4)) {
stride = xsize * 2; stride = xsize * 2;
else } else {
stride = xsize * 4; stride = xsize * 4;
}
} }
if (stride > 0 && ysize > PY_SSIZE_T_MAX / stride) { if (stride > 0 && ysize > PY_SSIZE_T_MAX / stride) {
@ -349,8 +368,9 @@ PyImaging_MapBuffer(PyObject* self, PyObject* args)
} }
/* check buffer size */ /* check buffer size */
if (PyImaging_GetBuffer(target, &view) < 0) if (PyImaging_GetBuffer(target, &view) < 0) {
return NULL; return NULL;
}
if (view.len < 0) { if (view.len < 0) {
PyErr_SetString(PyExc_ValueError, "buffer has negative size"); PyErr_SetString(PyExc_ValueError, "buffer has negative size");
@ -371,12 +391,15 @@ PyImaging_MapBuffer(PyObject* self, PyObject* args)
} }
/* setup file pointers */ /* setup file pointers */
if (ystep > 0) if (ystep > 0) {
for (y = 0; y < ysize; y++) for (y = 0; y < ysize; y++) {
im->image[y] = (char*)view.buf + offset + y * stride; im->image[y] = (char*)view.buf + offset + y * stride;
else }
for (y = 0; y < ysize; y++) } else {
for (y = 0; y < ysize; y++) {
im->image[ysize-y-1] = (char*)view.buf + offset + y * stride; im->image[ysize-y-1] = (char*)view.buf + offset + y * stride;
}
}
im->destroy = mapping_destroy_buffer; im->destroy = mapping_destroy_buffer;

View File

@ -39,12 +39,14 @@ _outline_new(void)
{ {
OutlineObject *self; OutlineObject *self;
if (PyType_Ready(&OutlineType) < 0) if (PyType_Ready(&OutlineType) < 0) {
return NULL; return NULL;
}
self = PyObject_New(OutlineObject, &OutlineType); self = PyObject_New(OutlineObject, &OutlineType);
if (self == NULL) if (self == NULL) {
return NULL; return NULL;
}
self->outline = ImagingOutlineNew(); self->outline = ImagingOutlineNew();
@ -61,8 +63,9 @@ _outline_dealloc(OutlineObject* self)
ImagingOutline ImagingOutline
PyOutline_AsOutline(PyObject* outline) PyOutline_AsOutline(PyObject* outline)
{ {
if (PyOutline_Check(outline)) if (PyOutline_Check(outline)) {
return ((OutlineObject*) outline)->outline; return ((OutlineObject*) outline)->outline;
}
return NULL; return NULL;
} }
@ -74,8 +77,9 @@ PyOutline_AsOutline(PyObject* outline)
PyObject* PyObject*
PyOutline_Create(PyObject* self, PyObject* args) PyOutline_Create(PyObject* self, PyObject* args)
{ {
if (!PyArg_ParseTuple(args, ":outline")) if (!PyArg_ParseTuple(args, ":outline")) {
return NULL; return NULL;
}
return (PyObject*) _outline_new(); return (PyObject*) _outline_new();
} }
@ -88,8 +92,9 @@ static PyObject*
_outline_move(OutlineObject* self, PyObject* args) _outline_move(OutlineObject* self, PyObject* args)
{ {
float x0, y0; float x0, y0;
if (!PyArg_ParseTuple(args, "ff", &x0, &y0)) if (!PyArg_ParseTuple(args, "ff", &x0, &y0)) {
return NULL; return NULL;
}
ImagingOutlineMove(self->outline, x0, y0); ImagingOutlineMove(self->outline, x0, y0);
@ -101,8 +106,9 @@ static PyObject*
_outline_line(OutlineObject* self, PyObject* args) _outline_line(OutlineObject* self, PyObject* args)
{ {
float x1, y1; float x1, y1;
if (!PyArg_ParseTuple(args, "ff", &x1, &y1)) if (!PyArg_ParseTuple(args, "ff", &x1, &y1)) {
return NULL; return NULL;
}
ImagingOutlineLine(self->outline, x1, y1); ImagingOutlineLine(self->outline, x1, y1);
@ -114,8 +120,9 @@ static PyObject*
_outline_curve(OutlineObject* self, PyObject* args) _outline_curve(OutlineObject* self, PyObject* args)
{ {
float x1, y1, x2, y2, x3, y3; float x1, y1, x2, y2, x3, y3;
if (!PyArg_ParseTuple(args, "ffffff", &x1, &y1, &x2, &y2, &x3, &y3)) if (!PyArg_ParseTuple(args, "ffffff", &x1, &y1, &x2, &y2, &x3, &y3)) {
return NULL; return NULL;
}
ImagingOutlineCurve(self->outline, x1, y1, x2, y2, x3, y3); ImagingOutlineCurve(self->outline, x1, y1, x2, y2, x3, y3);
@ -126,8 +133,9 @@ _outline_curve(OutlineObject* self, PyObject* args)
static PyObject* static PyObject*
_outline_close(OutlineObject* self, PyObject* args) _outline_close(OutlineObject* self, PyObject* args)
{ {
if (!PyArg_ParseTuple(args, ":close")) if (!PyArg_ParseTuple(args, ":close")) {
return NULL; return NULL;
}
ImagingOutlineClose(self->outline); ImagingOutlineClose(self->outline);
@ -139,8 +147,9 @@ static PyObject*
_outline_transform(OutlineObject* self, PyObject* args) _outline_transform(OutlineObject* self, PyObject* args)
{ {
double a[6]; double a[6];
if (!PyArg_ParseTuple(args, "(dddddd)", a+0, a+1, a+2, a+3, a+4, a+5)) if (!PyArg_ParseTuple(args, "(dddddd)", a+0, a+1, a+2, a+3, a+4, a+5)) {
return NULL; return NULL;
}
ImagingOutlineTransform(self->outline, a); ImagingOutlineTransform(self->outline, a);

View File

@ -61,8 +61,9 @@ alloc_array(Py_ssize_t count)
return NULL; return NULL;
} }
xy = malloc(2 * count * sizeof(double) + 1); xy = malloc(2 * count * sizeof(double) + 1);
if (!xy) if (!xy) {
PyErr_NoMemory(); PyErr_NoMemory();
}
return xy; return xy;
} }
@ -74,8 +75,9 @@ path_new(Py_ssize_t count, double* xy, int duplicate)
if (duplicate) { if (duplicate) {
/* duplicate path */ /* duplicate path */
double* p = alloc_array(count); double* p = alloc_array(count);
if (!p) if (!p) {
return NULL; return NULL;
}
memcpy(p, xy, count * 2 * sizeof(double)); memcpy(p, xy, count * 2 * sizeof(double));
xy = p; xy = p;
} }
@ -120,8 +122,9 @@ PyPath_Flatten(PyObject* data, double **pxy)
/* This was another path object. */ /* This was another path object. */
PyPathObject *path = (PyPathObject*) data; PyPathObject *path = (PyPathObject*) data;
xy = alloc_array(path->count); xy = alloc_array(path->count);
if (!xy) if (!xy) {
return -1; return -1;
}
memcpy(xy, path->xy, 2 * path->count * sizeof(double)); memcpy(xy, path->xy, 2 * path->count * sizeof(double));
*pxy = xy; *pxy = xy;
return path->count; return path->count;
@ -134,10 +137,12 @@ PyPath_Flatten(PyObject* data, double **pxy)
float *ptr = (float*) buffer.buf; float *ptr = (float*) buffer.buf;
n = buffer.len / (2 * sizeof(float)); n = buffer.len / (2 * sizeof(float));
xy = alloc_array(n); xy = alloc_array(n);
if (!xy) if (!xy) {
return -1; return -1;
for (i = 0; i < n+n; i++) }
for (i = 0; i < n+n; i++) {
xy[i] = ptr[i]; xy[i] = ptr[i];
}
*pxy = xy; *pxy = xy;
PyBuffer_Release(&buffer); PyBuffer_Release(&buffer);
return n; return n;
@ -153,26 +158,28 @@ PyPath_Flatten(PyObject* data, double **pxy)
j = 0; j = 0;
n = PyObject_Length(data); n = PyObject_Length(data);
/* Just in case __len__ breaks (or doesn't exist) */ /* Just in case __len__ breaks (or doesn't exist) */
if (PyErr_Occurred()) if (PyErr_Occurred()) {
return -1; return -1;
}
/* Allocate for worst case */ /* Allocate for worst case */
xy = alloc_array(n); xy = alloc_array(n);
if (!xy) if (!xy) {
return -1; return -1;
}
/* 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_GET_ITEM(data, i);
if (PyFloat_Check(op)) if (PyFloat_Check(op)) {
xy[j++] = PyFloat_AS_DOUBLE(op); xy[j++] = PyFloat_AS_DOUBLE(op);
else if (PyLong_Check(op)) } else if (PyLong_Check(op)) {
xy[j++] = (float) PyLong_AS_LONG(op); xy[j++] = (float) PyLong_AS_LONG(op);
else if (PyNumber_Check(op)) } else if (PyNumber_Check(op)) {
xy[j++] = PyFloat_AsDouble(op); xy[j++] = PyFloat_AsDouble(op);
else if (PyArg_ParseTuple(op, "dd", &x, &y)) { } else if (PyArg_ParseTuple(op, "dd", &x, &y)) {
xy[j++] = x; xy[j++] = x;
xy[j++] = y; xy[j++] = y;
} else { } else {
@ -184,13 +191,13 @@ PyPath_Flatten(PyObject* data, double **pxy)
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
double x, y; double x, y;
PyObject *op = PyTuple_GET_ITEM(data, i); PyObject *op = PyTuple_GET_ITEM(data, i);
if (PyFloat_Check(op)) if (PyFloat_Check(op)) {
xy[j++] = PyFloat_AS_DOUBLE(op); xy[j++] = PyFloat_AS_DOUBLE(op);
else if (PyLong_Check(op)) } else if (PyLong_Check(op)) {
xy[j++] = (float) PyLong_AS_LONG(op); xy[j++] = (float) PyLong_AS_LONG(op);
else if (PyNumber_Check(op)) } else if (PyNumber_Check(op)) {
xy[j++] = PyFloat_AsDouble(op); xy[j++] = PyFloat_AsDouble(op);
else if (PyArg_ParseTuple(op, "dd", &x, &y)) { } else if (PyArg_ParseTuple(op, "dd", &x, &y)) {
xy[j++] = x; xy[j++] = x;
xy[j++] = y; xy[j++] = y;
} else { } else {
@ -213,13 +220,13 @@ PyPath_Flatten(PyObject* data, double **pxy)
return -1; return -1;
} }
} }
if (PyFloat_Check(op)) if (PyFloat_Check(op)) {
xy[j++] = PyFloat_AS_DOUBLE(op); xy[j++] = PyFloat_AS_DOUBLE(op);
else if (PyLong_Check(op)) } else if (PyLong_Check(op)) {
xy[j++] = (float) PyLong_AS_LONG(op); xy[j++] = (float) PyLong_AS_LONG(op);
else if (PyNumber_Check(op)) } else if (PyNumber_Check(op)) {
xy[j++] = PyFloat_AsDouble(op); xy[j++] = PyFloat_AsDouble(op);
else if (PyArg_ParseTuple(op, "dd", &x, &y)) { } else if (PyArg_ParseTuple(op, "dd", &x, &y)) {
xy[j++] = x; xy[j++] = x;
xy[j++] = y; xy[j++] = y;
} else { } else {
@ -257,19 +264,22 @@ PyPath_Create(PyObject* self, PyObject* args)
/* number of vertices */ /* number of vertices */
xy = alloc_array(count); xy = alloc_array(count);
if (!xy) if (!xy) {
return NULL; return NULL;
}
} else { } else {
/* sequence or other path */ /* sequence or other path */
PyErr_Clear(); PyErr_Clear();
if (!PyArg_ParseTuple(args, "O", &data)) if (!PyArg_ParseTuple(args, "O", &data)) {
return NULL; return NULL;
}
count = PyPath_Flatten(data, &xy); count = PyPath_Flatten(data, &xy);
if (count < 0) if (count < 0) {
return NULL; return NULL;
}
} }
return (PyObject*) path_new(count, xy, 0); return (PyObject*) path_new(count, xy, 0);
@ -291,8 +301,9 @@ path_compact(PyPathObject* self, PyObject* args)
double cityblock = 2.0; double cityblock = 2.0;
if (!PyArg_ParseTuple(args, "|d:compact", &cityblock)) if (!PyArg_ParseTuple(args, "|d:compact", &cityblock)) {
return NULL; return NULL;
}
xy = self->xy; xy = self->xy;
@ -323,8 +334,9 @@ path_getbbox(PyPathObject* self, PyObject* args)
double *xy; double *xy;
double x0, y0, x1, y1; double x0, y0, x1, y1;
if (!PyArg_ParseTuple(args, ":getbbox")) if (!PyArg_ParseTuple(args, ":getbbox")) {
return NULL; return NULL;
}
xy = self->xy; xy = self->xy;
@ -332,14 +344,18 @@ path_getbbox(PyPathObject* self, PyObject* args)
y0 = y1 = xy[1]; y0 = y1 = xy[1];
for (i = 1; i < self->count; i++) { for (i = 1; i < self->count; i++) {
if (xy[i+i] < x0) if (xy[i+i] < x0) {
x0 = xy[i+i]; x0 = xy[i+i];
if (xy[i+i] > x1) }
if (xy[i+i] > x1) {
x1 = xy[i+i]; x1 = xy[i+i];
if (xy[i+i+1] < y0) }
if (xy[i+i+1] < y0) {
y0 = xy[i+i+1]; y0 = xy[i+i+1];
if (xy[i+i+1] > y1) }
if (xy[i+i+1] > y1) {
y1 = xy[i+i+1]; y1 = xy[i+i+1];
}
} }
return Py_BuildValue("dddd", x0, y0, x1, y1); return Py_BuildValue("dddd", x0, y0, x1, y1);
@ -348,8 +364,9 @@ path_getbbox(PyPathObject* self, PyObject* args)
static PyObject* static PyObject*
path_getitem(PyPathObject* self, Py_ssize_t i) path_getitem(PyPathObject* self, Py_ssize_t i)
{ {
if (i < 0) if (i < 0) {
i = self->count + i; i = self->count + i;
}
if (i < 0 || i >= self->count) { if (i < 0 || i >= self->count) {
PyErr_SetString(PyExc_IndexError, "path index out of range"); PyErr_SetString(PyExc_IndexError, "path index out of range");
return NULL; return NULL;
@ -362,16 +379,19 @@ static PyObject*
path_getslice(PyPathObject* self, Py_ssize_t ilow, Py_ssize_t ihigh) path_getslice(PyPathObject* self, Py_ssize_t ilow, Py_ssize_t ihigh)
{ {
/* adjust arguments */ /* adjust arguments */
if (ilow < 0) if (ilow < 0) {
ilow = 0; ilow = 0;
else if (ilow >= self->count) } else if (ilow >= self->count) {
ilow = self->count; ilow = self->count;
if (ihigh < 0) }
if (ihigh < 0) {
ihigh = 0; ihigh = 0;
if (ihigh < ilow) }
if (ihigh < ilow) {
ihigh = ilow; ihigh = ilow;
else if (ihigh > self->count) } else if (ihigh > self->count) {
ihigh = self->count; ihigh = self->count;
}
return (PyObject*) path_new(ihigh - ilow, self->xy + ilow * 2, 1); return (PyObject*) path_new(ihigh - ilow, self->xy + ilow * 2, 1);
} }
@ -390,8 +410,9 @@ path_map(PyPathObject* self, PyObject* args)
double *xy; double *xy;
PyObject* function; PyObject* function;
if (!PyArg_ParseTuple(args, "O:map", &function)) if (!PyArg_ParseTuple(args, "O:map", &function)) {
return NULL; return NULL;
}
xy = self->xy; xy = self->xy;
@ -432,8 +453,9 @@ path_setitem(PyPathObject* self, Py_ssize_t i, PyObject* op)
xy = &self->xy[i+i]; xy = &self->xy[i+i];
if (!PyArg_ParseTuple(op, "dd", &xy[0], &xy[1])) if (!PyArg_ParseTuple(op, "dd", &xy[0], &xy[1])) {
return -1; return -1;
}
return 0; return 0;
} }
@ -445,16 +467,18 @@ path_tolist(PyPathObject* self, PyObject* args)
Py_ssize_t i; Py_ssize_t i;
int flat = 0; int flat = 0;
if (!PyArg_ParseTuple(args, "|i:tolist", &flat)) if (!PyArg_ParseTuple(args, "|i:tolist", &flat)) {
return NULL; return NULL;
}
if (flat) { if (flat) {
list = PyList_New(self->count*2); list = PyList_New(self->count*2);
for (i = 0; i < self->count*2; i++) { for (i = 0; i < self->count*2; i++) {
PyObject* item; PyObject* item;
item = PyFloat_FromDouble(self->xy[i]); item = PyFloat_FromDouble(self->xy[i]);
if (!item) if (!item) {
goto error; goto error;
}
PyList_SetItem(list, i, item); PyList_SetItem(list, i, item);
} }
} else { } else {
@ -462,8 +486,9 @@ path_tolist(PyPathObject* self, PyObject* args)
for (i = 0; i < self->count; i++) { for (i = 0; i < self->count; i++) {
PyObject* item; PyObject* item;
item = Py_BuildValue("dd", self->xy[i+i], self->xy[i+i+1]); item = Py_BuildValue("dd", self->xy[i+i], self->xy[i+i+1]);
if (!item) if (!item) {
goto error; goto error;
}
PyList_SetItem(list, i, item); PyList_SetItem(list, i, item);
} }
} }
@ -487,19 +512,20 @@ path_transform(PyPathObject* self, PyObject* args)
if (!PyArg_ParseTuple(args, "(dddddd)|d:transform", if (!PyArg_ParseTuple(args, "(dddddd)|d:transform",
&a, &b, &c, &d, &e, &f, &a, &b, &c, &d, &e, &f,
&wrap)) &wrap)) {
return NULL; return NULL;
}
xy = self->xy; xy = self->xy;
/* transform the coordinate set */ /* transform the coordinate set */
if (b == 0.0 && d == 0.0) if (b == 0.0 && d == 0.0) {
/* scaling */ /* scaling */
for (i = 0; i < self->count; i++) { for (i = 0; i < self->count; i++) {
xy[i+i] = a*xy[i+i]+c; xy[i+i] = a*xy[i+i]+c;
xy[i+i+1] = e*xy[i+i+1]+f; xy[i+i+1] = e*xy[i+i+1]+f;
} }
else } else {
/* affine transform */ /* affine transform */
for (i = 0; i < self->count; i++) { for (i = 0; i < self->count; i++) {
double x = xy[i+i]; double x = xy[i+i];
@ -507,11 +533,14 @@ path_transform(PyPathObject* self, PyObject* args)
xy[i+i] = a*x+b*y+c; xy[i+i] = a*x+b*y+c;
xy[i+i+1] = d*x+e*y+f; xy[i+i+1] = d*x+e*y+f;
} }
}
/* special treatment of geographical map data */ /* special treatment of geographical map data */
if (wrap != 0.0) if (wrap != 0.0) {
for (i = 0; i < self->count; i++) for (i = 0; i < self->count; i++) {
xy[i+i] = fmod(xy[i+i], wrap); xy[i+i] = fmod(xy[i+i], wrap);
}
}
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
@ -542,16 +571,18 @@ path_subscript(PyPathObject* self, PyObject* item) {
if (PyIndex_Check(item)) { if (PyIndex_Check(item)) {
Py_ssize_t i; Py_ssize_t i;
i = PyNumber_AsSsize_t(item, PyExc_IndexError); i = PyNumber_AsSsize_t(item, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) if (i == -1 && PyErr_Occurred()) {
return NULL; return NULL;
}
return path_getitem(self, i); return path_getitem(self, i);
} }
if (PySlice_Check(item)) { if (PySlice_Check(item)) {
int len = 4; int len = 4;
Py_ssize_t start, stop, step, slicelength; Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, len, &start, &stop, &step, &slicelength) < 0) if (PySlice_GetIndicesEx(item, len, &start, &stop, &step, &slicelength) < 0) {
return NULL; return NULL;
}
if (slicelength <= 0) { if (slicelength <= 0) {
double *xy = alloc_array(0); double *xy = alloc_array(0);

View File

@ -170,9 +170,9 @@ deps = {
"libs": [r"output\release-static\{architecture}\lib\*.lib"], "libs": [r"output\release-static\{architecture}\lib\*.lib"],
}, },
"freetype": { "freetype": {
"url": "https://download.savannah.gnu.org/releases/freetype/freetype-2.10.1.tar.gz", # noqa: E501 "url": "https://download.savannah.gnu.org/releases/freetype/freetype-2.10.2.tar.gz", # noqa: E501
"filename": "freetype-2.10.1.tar.gz", "filename": "freetype-2.10.2.tar.gz",
"dir": "freetype-2.10.1", "dir": "freetype-2.10.2",
"patch": { "patch": {
r"builds\windows\vc2010\freetype.vcxproj": { r"builds\windows\vc2010\freetype.vcxproj": {
# freetype setting is /MD for .dll and /MT for .lib, we need /MD # freetype setting is /MD for .dll and /MT for .lib, we need /MD