mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +03:00 
			
		
		
		
	Merge pull request #5367 from radarhere/quant
This commit is contained in:
		
						commit
						ec74f3b1c0
					
				
							
								
								
									
										
											BIN
										
									
								
								Tests/images/hopper_resized.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/hopper_resized.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 5.1 KiB  | 
| 
						 | 
				
			
			@ -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():
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user