Merge pull request #5367 from radarhere/quant

This commit is contained in:
Hugo van Kemenade 2021-06-20 21:57:05 +03:00 committed by GitHub
commit ec74f3b1c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 16 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -7,7 +7,12 @@ import pytest
from PIL import Image
from .helper import assert_image_equal, assert_image_similar, hopper
from .helper import (
assert_image_equal,
assert_image_equal_tofile,
assert_image_similar,
hopper,
)
class TestImagingCoreResize:
@ -135,6 +140,17 @@ class TestImagingCoreResize:
with pytest.raises(ValueError):
self.resize(hopper(), (10, 10), 9)
def test_cross_platform(self, tmp_path):
# This test is intended for only check for consistent behaviour across
# platforms. So if a future Pillow change requires that the test file
# be updated, that is okay.
im = hopper().resize((64, 64))
temp_file = str(tmp_path / "temp.gif")
im.save(temp_file)
with Image.open(temp_file) as reloaded:
assert_image_equal_tofile(reloaded, "Tests/images/hopper_resized.gif")
@pytest.fixture
def gradients_image():

View File

@ -753,11 +753,19 @@ annotate_hash_table(BoxNode *n, HashTable *h, uint32_t *box) {
return 1;
}
typedef struct {
uint32_t *distance;
uint32_t index;
} DistanceWithIndex;
static int
_sort_ulong_ptr_keys(const void *a, const void *b) {
uint32_t A = **(uint32_t **)a;
uint32_t B = **(uint32_t **)b;
return (A == B) ? 0 : ((A < B) ? -1 : +1);
_distance_index_cmp(const void *a, const void *b) {
DistanceWithIndex *A = (DistanceWithIndex *)a;
DistanceWithIndex *B = (DistanceWithIndex *)b;
if (*A->distance == *B->distance) {
return A->index < B->index ? -1 : +1;
}
return *A->distance < *B->distance ? -1 : +1;
}
static int
@ -789,10 +797,11 @@ resort_distance_tables(
return 1;
}
static void
static int
build_distance_tables(
uint32_t *avgDist, uint32_t **avgDistSortKey, Pixel *p, uint32_t nEntries) {
uint32_t i, j;
DistanceWithIndex *dwi;
for (i = 0; i < nEntries; i++) {
avgDist[i * nEntries + i] = 0;
@ -804,13 +813,29 @@ build_distance_tables(
avgDistSortKey[i * nEntries + j] = &(avgDist[i * nEntries + j]);
}
}
for (i = 0; i < nEntries; i++) {
qsort(
avgDistSortKey + i * nEntries,
nEntries,
sizeof(uint32_t *),
_sort_ulong_ptr_keys);
dwi = calloc(nEntries, sizeof(DistanceWithIndex));
if (!dwi) {
return 0;
}
for (i = 0; i < nEntries; i++) {
for (j = 0; j < nEntries; j++) {
dwi[j] = (DistanceWithIndex){
&(avgDist[i * nEntries + j]),
j
};
}
qsort(
dwi,
nEntries,
sizeof(DistanceWithIndex),
_distance_index_cmp);
for (j = 0; j < nEntries; j++) {
avgDistSortKey[i * nEntries + j] = dwi[j].distance;
}
}
free(dwi);
return 1;
}
static int
@ -1175,8 +1200,10 @@ k_means(
if (!built) {
compute_palette_from_quantized_pixels(
pixelData, nPixels, paletteData, nPaletteEntries, avg, count, qp);
build_distance_tables(
avgDist, avgDistSortKey, paletteData, nPaletteEntries);
if (!build_distance_tables(
avgDist, avgDistSortKey, paletteData, nPaletteEntries)) {
goto error_3;
}
built = 1;
} else {
recompute_palette_from_averages(paletteData, nPaletteEntries, avg, count);
@ -1372,7 +1399,9 @@ quantize(
goto error_6;
}
build_distance_tables(avgDist, avgDistSortKey, p, nPaletteEntries);
if (!build_distance_tables(avgDist, avgDistSortKey, p, nPaletteEntries)) {
goto error_7;
}
if (!map_image_pixels_from_median_box(
pixelData, nPixels, p, nPaletteEntries, h, avgDist, avgDistSortKey, qp)) {
@ -1577,7 +1606,9 @@ quantize2(
goto error_3;
}
build_distance_tables(avgDist, avgDistSortKey, p, nQuantPixels);
if (!build_distance_tables(avgDist, avgDistSortKey, p, nQuantPixels)) {
goto error_4;
}
if (!map_image_pixels(
pixelData, nPixels, p, nQuantPixels, avgDist, avgDistSortKey, qp)) {