mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 18:06:18 +03:00
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:
commit
9640b48040
|
@ -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$)
|
||||||
|
|
67
CHANGES.rst
67
CHANGES.rst
|
@ -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,
|
||||||
|
|
BIN
Tests/images/icc-after-SOF.jpg
Normal file
BIN
Tests/images/icc-after-SOF.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 212 B |
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 |
|
||||||
| +------------------------------+--------------------------------+ +
|
| +------------------------------+--------------------------------+ +
|
||||||
|
|
|
@ -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
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -10,3 +10,4 @@ multi_line_output = 3
|
||||||
|
|
||||||
[tool:pytest]
|
[tool:pytest]
|
||||||
addopts = -rs
|
addopts = -rs
|
||||||
|
testpaths = Tests
|
||||||
|
|
6
setup.py
6
setup.py
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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 == "<":
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
585
src/_imaging.c
585
src/_imaging.c
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||||
|
|
||||||
|
|
126
src/_imagingft.c
126
src/_imagingft.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
21
src/_webp.c
21
src/_webp.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
168
src/decode.c
168
src/decode.c
|
@ -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;
|
||||||
|
|
134
src/display.c
134
src/display.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
163
src/encode.c
163
src/encode.c
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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, ¶ms);
|
j2k_set_cinema_params(im, components, ¶ms);
|
||||||
|
}
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 *));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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] +
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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... */
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
81
src/map.c
81
src/map.c
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
123
src/path.c
123
src/path.c
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user