mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-25 00:34:14 +03:00
Merge remote-tracking branch 'upstream/master' into pytest
This commit is contained in:
commit
9087599e60
|
@ -5,6 +5,9 @@ Changelog (Pillow)
|
|||
7.1.0 (unreleased)
|
||||
------------------
|
||||
|
||||
- Only draw each polygon pixel once #4333
|
||||
[radarhere]
|
||||
|
||||
- Add support for shooting situation Exif IFD tags #4398
|
||||
[alexagv]
|
||||
|
||||
|
|
|
@ -61,15 +61,19 @@ To report a security vulnerability, please follow the procedure described in the
|
|||
:alt: AppVeyor CI build status (Windows)
|
||||
|
||||
.. |gha_lint| image:: https://github.com/python-pillow/Pillow/workflows/Lint/badge.svg
|
||||
:target: https://github.com/python-pillow/Pillow/actions?query=workflow%3ALint
|
||||
:alt: GitHub Actions build status (Lint)
|
||||
|
||||
.. |gha_docker| image:: https://github.com/python-pillow/Pillow/workflows/Test%20Docker/badge.svg
|
||||
:target: https://github.com/python-pillow/Pillow/actions?query=workflow%3A%22Test+Docker%22
|
||||
:alt: GitHub Actions build status (Test Docker)
|
||||
|
||||
.. |gha| image:: https://github.com/python-pillow/Pillow/workflows/Test/badge.svg
|
||||
:target: https://github.com/python-pillow/Pillow/actions?query=workflow%3ATest
|
||||
:alt: GitHub Actions build status (Test Linux and macOS)
|
||||
|
||||
.. |gha_windows| image:: https://github.com/python-pillow/Pillow/workflows/Test%20Windows/badge.svg
|
||||
:target: https://github.com/python-pillow/Pillow/actions?query=workflow%3A%22Test+Windows%22
|
||||
:alt: GitHub Actions build status (Test Windows)
|
||||
|
||||
.. |coverage| image:: https://codecov.io/gh/python-pillow/Pillow/branch/master/graph/badge.svg
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Main Release
|
||||
|
||||
Released quarterly on the first day of January, April, July, October.
|
||||
Released quarterly on January 2nd, April 1st, July 1st and October 15th.
|
||||
|
||||
* [ ] Open a release ticket e.g. https://github.com/python-pillow/Pillow/issues/3154
|
||||
* [ ] Develop and prepare release in `master` branch.
|
||||
|
|
|
@ -4,6 +4,7 @@ Helper functions.
|
|||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
@ -191,9 +192,12 @@ class PillowTestCase(unittest.TestCase):
|
|||
raise OSError()
|
||||
|
||||
outfile = self.tempfile("temp.png")
|
||||
if command_succeeds([IMCONVERT, f, outfile]):
|
||||
return Image.open(outfile)
|
||||
raise OSError()
|
||||
rc = subprocess.call(
|
||||
[IMCONVERT, f, outfile], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
|
||||
)
|
||||
if rc:
|
||||
raise OSError
|
||||
return Image.open(outfile)
|
||||
|
||||
|
||||
@unittest.skipIf(sys.platform.startswith("win32"), "requires Unix or macOS")
|
||||
|
@ -268,34 +272,20 @@ def hopper(mode=None, cache={}):
|
|||
return im.copy()
|
||||
|
||||
|
||||
def command_succeeds(cmd):
|
||||
"""
|
||||
Runs the command, which must be a list of strings. Returns True if the
|
||||
command succeeds, or False if an OSError was raised by subprocess.Popen.
|
||||
"""
|
||||
try:
|
||||
subprocess.call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
||||
except OSError:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def djpeg_available():
|
||||
return command_succeeds(["djpeg", "-version"])
|
||||
return bool(shutil.which("djpeg"))
|
||||
|
||||
|
||||
def cjpeg_available():
|
||||
return command_succeeds(["cjpeg", "-version"])
|
||||
return bool(shutil.which("cjpeg"))
|
||||
|
||||
|
||||
def netpbm_available():
|
||||
return command_succeeds(["ppmquant", "--version"]) and command_succeeds(
|
||||
["ppmtogif", "--version"]
|
||||
)
|
||||
return bool(shutil.which("ppmquant") and shutil.which("ppmtogif"))
|
||||
|
||||
|
||||
def imagemagick_available():
|
||||
return IMCONVERT and command_succeeds([IMCONVERT, "-version"])
|
||||
return bool(IMCONVERT and shutil.which(IMCONVERT))
|
||||
|
||||
|
||||
def on_appveyor():
|
||||
|
|
BIN
Tests/images/imagedraw_chord_zero_width.png
Normal file
BIN
Tests/images/imagedraw_chord_zero_width.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 427 B |
BIN
Tests/images/imagedraw_ellipse_translucent.png
Normal file
BIN
Tests/images/imagedraw_ellipse_translucent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 390 B |
BIN
Tests/images/imagedraw_ellipse_zero_width.png
Normal file
BIN
Tests/images/imagedraw_ellipse_zero_width.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 339 B |
BIN
Tests/images/imagedraw_pieslice_zero_width.png
Normal file
BIN
Tests/images/imagedraw_pieslice_zero_width.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 403 B |
BIN
Tests/images/imagedraw_rectangle_zero_width.png
Normal file
BIN
Tests/images/imagedraw_rectangle_zero_width.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 212 B |
|
@ -20,7 +20,7 @@ def test_isatty():
|
|||
def test_seek_mode_0():
|
||||
# Arrange
|
||||
mode = 0
|
||||
with open(TEST_FILE) as fh:
|
||||
with open(TEST_FILE, "rb") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
|
||||
# Act
|
||||
|
@ -34,7 +34,7 @@ def test_seek_mode_0():
|
|||
def test_seek_mode_1():
|
||||
# Arrange
|
||||
mode = 1
|
||||
with open(TEST_FILE) as fh:
|
||||
with open(TEST_FILE, "rb") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
|
||||
# Act
|
||||
|
@ -48,7 +48,7 @@ def test_seek_mode_1():
|
|||
def test_seek_mode_2():
|
||||
# Arrange
|
||||
mode = 2
|
||||
with open(TEST_FILE) as fh:
|
||||
with open(TEST_FILE, "rb") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
|
||||
# Act
|
||||
|
@ -61,73 +61,87 @@ def test_seek_mode_2():
|
|||
|
||||
def test_read_n0():
|
||||
# Arrange
|
||||
with open(TEST_FILE) as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
for bytesmode in (True, False):
|
||||
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
|
||||
# Act
|
||||
container.seek(81)
|
||||
data = container.read()
|
||||
# Act
|
||||
container.seek(81)
|
||||
data = container.read()
|
||||
|
||||
# Assert
|
||||
assert data == "7\nThis is line 8\n"
|
||||
# Assert
|
||||
if bytesmode:
|
||||
data = data.decode()
|
||||
assert data == "7\nThis is line 8\n"
|
||||
|
||||
|
||||
def test_read_n():
|
||||
# Arrange
|
||||
with open(TEST_FILE) as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
for bytesmode in (True, False):
|
||||
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
|
||||
# Act
|
||||
container.seek(81)
|
||||
data = container.read(3)
|
||||
# Act
|
||||
container.seek(81)
|
||||
data = container.read(3)
|
||||
|
||||
# Assert
|
||||
assert data == "7\nT"
|
||||
# Assert
|
||||
if bytesmode:
|
||||
data = data.decode()
|
||||
assert data == "7\nT"
|
||||
|
||||
|
||||
def test_read_eof():
|
||||
# Arrange
|
||||
with open(TEST_FILE) as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
for bytesmode in (True, False):
|
||||
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
|
||||
# Act
|
||||
container.seek(100)
|
||||
data = container.read()
|
||||
# Act
|
||||
container.seek(100)
|
||||
data = container.read()
|
||||
|
||||
# Assert
|
||||
assert data == ""
|
||||
# Assert
|
||||
if bytesmode:
|
||||
data = data.decode()
|
||||
assert data == ""
|
||||
|
||||
|
||||
def test_readline():
|
||||
# Arrange
|
||||
with open(TEST_FILE) as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 0, 120)
|
||||
for bytesmode in (True, False):
|
||||
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 0, 120)
|
||||
|
||||
# Act
|
||||
data = container.readline()
|
||||
# Act
|
||||
data = container.readline()
|
||||
|
||||
# Assert
|
||||
assert data == "This is line 1\n"
|
||||
# Assert
|
||||
if bytesmode:
|
||||
data = data.decode()
|
||||
assert data == "This is line 1\n"
|
||||
|
||||
|
||||
def test_readlines():
|
||||
# Arrange
|
||||
expected = [
|
||||
"This is line 1\n",
|
||||
"This is line 2\n",
|
||||
"This is line 3\n",
|
||||
"This is line 4\n",
|
||||
"This is line 5\n",
|
||||
"This is line 6\n",
|
||||
"This is line 7\n",
|
||||
"This is line 8\n",
|
||||
]
|
||||
with open(TEST_FILE) as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 0, 120)
|
||||
for bytesmode in (True, False):
|
||||
expected = [
|
||||
"This is line 1\n",
|
||||
"This is line 2\n",
|
||||
"This is line 3\n",
|
||||
"This is line 4\n",
|
||||
"This is line 5\n",
|
||||
"This is line 6\n",
|
||||
"This is line 7\n",
|
||||
"This is line 8\n",
|
||||
]
|
||||
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 0, 120)
|
||||
|
||||
# Act
|
||||
data = container.readlines()
|
||||
# Act
|
||||
data = container.readlines()
|
||||
|
||||
# Assert
|
||||
|
||||
assert data == expected
|
||||
# Assert
|
||||
if bytesmode:
|
||||
data = [line.decode() for line in data]
|
||||
assert data == expected
|
||||
|
|
|
@ -228,6 +228,19 @@ def test_chord_width_fill():
|
|||
assert_image_similar(im, Image.open(expected), 1)
|
||||
|
||||
|
||||
def test_chord_zero_width():
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
||||
# Act
|
||||
draw.chord(BBOX1, 10, 260, fill="red", outline="yellow", width=0)
|
||||
|
||||
# Assert
|
||||
with Image.open("Tests/images/imagedraw_chord_zero_width.png") as expected:
|
||||
assert_image_equal(im, expected)
|
||||
|
||||
|
||||
def helper_ellipse(mode, bbox):
|
||||
# Arrange
|
||||
im = Image.new(mode, (W, H))
|
||||
|
@ -310,6 +323,19 @@ def test_ellipse_width_fill():
|
|||
assert_image_similar(im, Image.open(expected), 1)
|
||||
|
||||
|
||||
def test_ellipse_zero_width():
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
||||
# Act
|
||||
draw.ellipse(BBOX1, fill="green", outline="blue", width=0)
|
||||
|
||||
# Assert
|
||||
with Image.open("Tests/images/imagedraw_ellipse_zero_width.png") as expected:
|
||||
assert_image_equal(im, expected)
|
||||
|
||||
|
||||
def helper_line(points):
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
|
@ -420,6 +446,19 @@ def test_pieslice_width_fill():
|
|||
assert_image_similar(im, Image.open(expected), 1)
|
||||
|
||||
|
||||
def test_pieslice_zero_width():
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
||||
# Act
|
||||
draw.pieslice(BBOX1, 10, 260, fill="white", outline="blue", width=0)
|
||||
|
||||
# Assert
|
||||
with Image.open("Tests/images/imagedraw_pieslice_zero_width.png") as expected:
|
||||
assert_image_equal(im, expected)
|
||||
|
||||
|
||||
def helper_point(points):
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
|
@ -537,6 +576,19 @@ def test_rectangle_width_fill():
|
|||
assert_image_equal(im, Image.open(expected))
|
||||
|
||||
|
||||
def test_rectangle_zero_width():
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
||||
# Act
|
||||
draw.rectangle(BBOX1, fill="blue", outline="green", width=0)
|
||||
|
||||
# Assert
|
||||
with Image.open("Tests/images/imagedraw_rectangle_zero_width.png") as expected:
|
||||
assert_image_equal(im, expected)
|
||||
|
||||
|
||||
def test_rectangle_I16():
|
||||
# Arrange
|
||||
im = Image.new("I;16", (W, H))
|
||||
|
|
|
@ -154,7 +154,7 @@ Methods
|
|||
To paste pixel data into an image, use the
|
||||
:py:meth:`~PIL.Image.Image.paste` method on the image itself.
|
||||
|
||||
.. py:method:: PIL.ImageDraw.ImageDraw.chord(xy, start, end, fill=None, outline=None, width=0)
|
||||
.. py:method:: PIL.ImageDraw.ImageDraw.chord(xy, start, end, fill=None, outline=None, width=1)
|
||||
|
||||
Same as :py:meth:`~PIL.ImageDraw.ImageDraw.arc`, but connects the end points
|
||||
with a straight line.
|
||||
|
@ -168,7 +168,7 @@ Methods
|
|||
|
||||
.. versionadded:: 5.3.0
|
||||
|
||||
.. py:method:: PIL.ImageDraw.ImageDraw.ellipse(xy, fill=None, outline=None, width=0)
|
||||
.. py:method:: PIL.ImageDraw.ImageDraw.ellipse(xy, fill=None, outline=None, width=1)
|
||||
|
||||
Draws an ellipse inside the given bounding box.
|
||||
|
||||
|
@ -198,7 +198,7 @@ Methods
|
|||
|
||||
.. versionadded:: 5.3.0
|
||||
|
||||
.. py:method:: PIL.ImageDraw.ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=0)
|
||||
.. py:method:: PIL.ImageDraw.ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=1)
|
||||
|
||||
Same as arc, but also draws straight lines between the end points and the
|
||||
center of the bounding box.
|
||||
|
@ -236,7 +236,7 @@ Methods
|
|||
:param outline: Color to use for the outline.
|
||||
:param fill: Color to use for the fill.
|
||||
|
||||
.. py:method:: PIL.ImageDraw.ImageDraw.rectangle(xy, fill=None, outline=None, width=0)
|
||||
.. py:method:: PIL.ImageDraw.ImageDraw.rectangle(xy, fill=None, outline=None, width=1)
|
||||
|
||||
Draws a rectangle.
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ class ContainerIO:
|
|||
else:
|
||||
n = self.length - self.pos
|
||||
if not n: # EOF
|
||||
return ""
|
||||
return b"" if "b" in self.fh.mode else ""
|
||||
self.pos = self.pos + n
|
||||
return self.fh.read(n)
|
||||
|
||||
|
@ -92,13 +92,14 @@ class ContainerIO:
|
|||
|
||||
:returns: An 8-bit string.
|
||||
"""
|
||||
s = ""
|
||||
s = b"" if "b" in self.fh.mode else ""
|
||||
newline_character = b"\n" if "b" in self.fh.mode else "\n"
|
||||
while True:
|
||||
c = self.read(1)
|
||||
if not c:
|
||||
break
|
||||
s = s + c
|
||||
if c == "\n":
|
||||
if c == newline_character:
|
||||
break
|
||||
return s
|
||||
|
||||
|
|
|
@ -134,20 +134,20 @@ class ImageDraw:
|
|||
if ink is not None:
|
||||
self.draw.draw_bitmap(xy, bitmap.im, ink)
|
||||
|
||||
def chord(self, xy, start, end, fill=None, outline=None, width=0):
|
||||
def chord(self, xy, start, end, fill=None, outline=None, width=1):
|
||||
"""Draw a chord."""
|
||||
ink, fill = self._getink(outline, fill)
|
||||
if fill is not None:
|
||||
self.draw.draw_chord(xy, start, end, fill, 1)
|
||||
if ink is not None and ink != fill:
|
||||
if ink is not None and ink != fill and width != 0:
|
||||
self.draw.draw_chord(xy, start, end, ink, 0, width)
|
||||
|
||||
def ellipse(self, xy, fill=None, outline=None, width=0):
|
||||
def ellipse(self, xy, fill=None, outline=None, width=1):
|
||||
"""Draw an ellipse."""
|
||||
ink, fill = self._getink(outline, fill)
|
||||
if fill is not None:
|
||||
self.draw.draw_ellipse(xy, fill, 1)
|
||||
if ink is not None and ink != fill:
|
||||
if ink is not None and ink != fill and width != 0:
|
||||
self.draw.draw_ellipse(xy, ink, 0, width)
|
||||
|
||||
def line(self, xy, fill=None, width=0, joint=None):
|
||||
|
@ -219,12 +219,12 @@ class ImageDraw:
|
|||
if ink is not None and ink != fill:
|
||||
self.draw.draw_outline(shape, ink, 0)
|
||||
|
||||
def pieslice(self, xy, start, end, fill=None, outline=None, width=0):
|
||||
def pieslice(self, xy, start, end, fill=None, outline=None, width=1):
|
||||
"""Draw a pieslice."""
|
||||
ink, fill = self._getink(outline, fill)
|
||||
if fill is not None:
|
||||
self.draw.draw_pieslice(xy, start, end, fill, 1)
|
||||
if ink is not None and ink != fill:
|
||||
if ink is not None and ink != fill and width != 0:
|
||||
self.draw.draw_pieslice(xy, start, end, ink, 0, width)
|
||||
|
||||
def point(self, xy, fill=None):
|
||||
|
@ -241,12 +241,12 @@ class ImageDraw:
|
|||
if ink is not None and ink != fill:
|
||||
self.draw.draw_polygon(xy, ink, 0)
|
||||
|
||||
def rectangle(self, xy, fill=None, outline=None, width=0):
|
||||
def rectangle(self, xy, fill=None, outline=None, width=1):
|
||||
"""Draw a rectangle."""
|
||||
ink, fill = self._getink(outline, fill)
|
||||
if fill is not None:
|
||||
self.draw.draw_rectangle(xy, fill, 1)
|
||||
if ink is not None and ink != fill:
|
||||
if ink is not None and ink != fill and width != 0:
|
||||
self.draw.draw_rectangle(xy, ink, 0, width)
|
||||
|
||||
def _multiline_check(self, text):
|
||||
|
|
|
@ -415,6 +415,35 @@ x_cmp(const void *x0, const void *x1)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
draw_horizontal_lines(Imaging im, int n, Edge *e, int ink, int *x_pos, int y, hline_handler hline)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (e[i].ymin == y && e[i].ymin == e[i].ymax) {
|
||||
int xmax;
|
||||
int xmin = e[i].xmin;
|
||||
if (*x_pos < xmin) {
|
||||
// Line would be after the current position
|
||||
continue;
|
||||
}
|
||||
|
||||
xmax = e[i].xmax;
|
||||
if (*x_pos > xmin) {
|
||||
// Line would be partway through x_pos, so increase the starting point
|
||||
xmin = *x_pos;
|
||||
if (xmax < xmin) {
|
||||
// Line would now end before it started
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
(*hline)(im, xmin, e[i].ymin, xmax, ink);
|
||||
*x_pos = xmax+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Filled polygon draw function using scan line algorithm.
|
||||
*/
|
||||
|
@ -442,10 +471,7 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill,
|
|||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
/* This causes the pixels of horizontal edges to be drawn twice :(
|
||||
* but without it there are inconsistencies in ellipses */
|
||||
if (e[i].ymin == e[i].ymax) {
|
||||
(*hline)(im, e[i].xmin, e[i].ymin, e[i].xmax, ink);
|
||||
continue;
|
||||
}
|
||||
if (ymin > e[i].ymin) {
|
||||
|
@ -472,6 +498,7 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill,
|
|||
}
|
||||
for (; ymin <= ymax; ymin++) {
|
||||
int j = 0;
|
||||
int x_pos = 0;
|
||||
for (i = 0; i < edge_count; i++) {
|
||||
Edge* current = edge_table[i];
|
||||
if (ymin >= current->ymin && ymin <= current->ymax) {
|
||||
|
@ -485,8 +512,30 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill,
|
|||
}
|
||||
qsort(xx, j, sizeof(float), x_cmp);
|
||||
for (i = 1; i < j; i += 2) {
|
||||
(*hline)(im, ROUND_UP(xx[i - 1]), ymin, ROUND_DOWN(xx[i]), ink);
|
||||
int x_end = ROUND_DOWN(xx[i]);
|
||||
if (x_end < x_pos) {
|
||||
// Line would be before the current position
|
||||
continue;
|
||||
}
|
||||
draw_horizontal_lines(im, n, e, ink, &x_pos, ymin, hline);
|
||||
if (x_end < x_pos) {
|
||||
// Line would be before the current position
|
||||
continue;
|
||||
}
|
||||
|
||||
int x_start = ROUND_UP(xx[i-1]);
|
||||
if (x_pos > x_start) {
|
||||
// Line would be partway through x_pos, so increase the starting point
|
||||
x_start = x_pos;
|
||||
if (x_end < x_start) {
|
||||
// Line would now end before it started
|
||||
continue;
|
||||
}
|
||||
}
|
||||
(*hline)(im, x_start, ymin, x_end, ink);
|
||||
x_pos = x_end+1;
|
||||
}
|
||||
draw_horizontal_lines(im, n, e, ink, &x_pos, ymin, hline);
|
||||
}
|
||||
|
||||
free(xx);
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
|
||||
struct _Heap {
|
||||
void **heap;
|
||||
int heapsize;
|
||||
int heapcount;
|
||||
unsigned int heapsize;
|
||||
unsigned int heapcount;
|
||||
HeapCmpFunc cf;
|
||||
};
|
||||
|
||||
|
@ -44,7 +44,7 @@ void ImagingQuantHeapFree(Heap *h) {
|
|||
free(h);
|
||||
}
|
||||
|
||||
static int _heap_grow(Heap *h,int newsize) {
|
||||
static int _heap_grow(Heap *h,unsigned int newsize) {
|
||||
void *newheap;
|
||||
if (!newsize) newsize=h->heapsize<<1;
|
||||
if (newsize<h->heapsize) return 0;
|
||||
|
@ -64,7 +64,7 @@ static int _heap_grow(Heap *h,int newsize) {
|
|||
|
||||
#ifdef DEBUG
|
||||
static int _heap_test(Heap *h) {
|
||||
int k;
|
||||
unsigned int k;
|
||||
for (k=1;k*2<=h->heapcount;k++) {
|
||||
if (h->cf(h,h->heap[k],h->heap[k*2])<0) {
|
||||
printf ("heap is bad\n");
|
||||
|
@ -80,7 +80,7 @@ static int _heap_test(Heap *h) {
|
|||
#endif
|
||||
|
||||
int ImagingQuantHeapRemove(Heap* h,void **r) {
|
||||
int k,l;
|
||||
unsigned int k,l;
|
||||
void *v;
|
||||
|
||||
if (!h->heapcount) {
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef struct _ColorCube{
|
|||
unsigned int rWidth, gWidth, bWidth, aWidth;
|
||||
unsigned int rOffset, gOffset, bOffset, aOffset;
|
||||
|
||||
long size;
|
||||
unsigned long size;
|
||||
ColorBucket buckets;
|
||||
} *ColorCube;
|
||||
|
||||
|
@ -134,10 +134,10 @@ add_color_to_color_cube(const ColorCube cube, const Pixel *p) {
|
|||
bucket->a += p->c.a;
|
||||
}
|
||||
|
||||
static long
|
||||
static unsigned long
|
||||
count_used_color_buckets(const ColorCube cube) {
|
||||
long usedBuckets = 0;
|
||||
long i;
|
||||
unsigned long usedBuckets = 0;
|
||||
unsigned long i;
|
||||
for (i=0; i < cube->size; i++) {
|
||||
if (cube->buckets[i].count > 0) {
|
||||
usedBuckets += 1;
|
||||
|
@ -194,7 +194,7 @@ void add_bucket_values(ColorBucket src, ColorBucket dst) {
|
|||
|
||||
/* expand or shrink a given cube to level */
|
||||
static ColorCube copy_color_cube(const ColorCube cube,
|
||||
int rBits, int gBits, int bBits, int aBits)
|
||||
unsigned int rBits, unsigned int gBits, unsigned int bBits, unsigned int aBits)
|
||||
{
|
||||
unsigned int r, g, b, a;
|
||||
long src_pos, dst_pos;
|
||||
|
@ -302,7 +302,7 @@ void add_lookup_buckets(ColorCube cube, ColorBucket palette, long nColors, long
|
|||
}
|
||||
|
||||
ColorBucket
|
||||
combined_palette(ColorBucket bucketsA, long nBucketsA, ColorBucket bucketsB, long nBucketsB) {
|
||||
combined_palette(ColorBucket bucketsA, unsigned long nBucketsA, ColorBucket bucketsB, unsigned long nBucketsB) {
|
||||
ColorBucket result;
|
||||
if (nBucketsA > LONG_MAX - nBucketsB ||
|
||||
(nBucketsA+nBucketsB) > LONG_MAX / sizeof(struct _ColorBucket)) {
|
||||
|
@ -345,8 +345,8 @@ map_image_pixels(const Pixel *pixelData,
|
|||
}
|
||||
}
|
||||
|
||||
const int CUBE_LEVELS[8] = {4, 4, 4, 0, 2, 2, 2, 0};
|
||||
const int CUBE_LEVELS_ALPHA[8] = {3, 4, 3, 3, 2, 2, 2, 2};
|
||||
const unsigned int CUBE_LEVELS[8] = {4, 4, 4, 0, 2, 2, 2, 0};
|
||||
const unsigned int CUBE_LEVELS_ALPHA[8] = {3, 4, 3, 3, 2, 2, 2, 2};
|
||||
|
||||
int quantize_octree(Pixel *pixelData,
|
||||
uint32_t nPixels,
|
||||
|
@ -365,8 +365,8 @@ int quantize_octree(Pixel *pixelData,
|
|||
ColorBucket paletteBuckets = NULL;
|
||||
uint32_t *qp = NULL;
|
||||
long i;
|
||||
long nCoarseColors, nFineColors, nAlreadySubtracted;
|
||||
const int *cubeBits;
|
||||
unsigned long nCoarseColors, nFineColors, nAlreadySubtracted;
|
||||
const unsigned int *cubeBits;
|
||||
|
||||
if (withAlpha) {
|
||||
cubeBits = CUBE_LEVELS_ALPHA;
|
||||
|
|
Loading…
Reference in New Issue
Block a user