Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libimagequant for openSUSE:Factory checked in at 2021-12-01 20:46:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libimagequant (Old) and /work/SRC/openSUSE:Factory/.libimagequant.new.31177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libimagequant" Wed Dec 1 20:46:29 2021 rev:9 rq:934865 version:2.17.0 Changes: -------- --- /work/SRC/openSUSE:Factory/libimagequant/libimagequant.changes 2021-06-25 15:01:31.640165438 +0200 +++ /work/SRC/openSUSE:Factory/.libimagequant.new.31177/libimagequant.changes 2021-12-02 02:16:29.522436179 +0100 @@ -1,0 +2,10 @@ +Sat Nov 27 12:55:13 UTC 2021 - Dirk M??ller <dmuel...@suse.com> + +- update to 2.17.0: + * Do not build as unversioned DSO + * use float as in SSE + * Initialize rows using heap to handle large images + * Free rows after remapping + * Disable SSE on arm64 + +------------------------------------------------------------------- Old: ---- libimagequant-2.15.1.tar.gz New: ---- libimagequant-2.17.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libimagequant.spec ++++++ --- /var/tmp/diff_new_pack.4ZHgcq/_old 2021-12-02 02:16:29.922434958 +0100 +++ /var/tmp/diff_new_pack.4ZHgcq/_new 2021-12-02 02:16:29.922434958 +0100 @@ -19,13 +19,13 @@ %define sover 0 %define libname %{name}%{sover} Name: libimagequant -Version: 2.15.1 +Version: 2.17.0 Release: 0 Summary: Palette quantization library License: GPL-3.0-or-later Group: Development/Languages/C and C++ URL: https://pngquant.org/lib/ -Source: https://github.com/ImageOptim/libimagequant/archive/%{version}/%{name}-%{version}.tar.gz +Source0: https://github.com/ImageOptim/libimagequant/archive/refs/tags/%{version}.tar.gz#/%{name}-%{version}.tar.gz BuildRequires: pkgconfig BuildRequires: pkgconfig(lcms2) ++++++ libimagequant-2.15.1.tar.gz -> libimagequant-2.17.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/CMakeLists.txt new/libimagequant-2.17.0/CMakeLists.txt --- old/libimagequant-2.15.1/CMakeLists.txt 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/CMakeLists.txt 2021-11-15 00:57:01.000000000 +0100 @@ -1,8 +1,13 @@ cmake_minimum_required(VERSION 2.6) +file(READ version.txt VERSION) project(imagequant C) -option(BUILD_WITH_SSE "Use SSE" ON) +if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL ARM64) + option(BUILD_WITH_SSE "Use SSE" OFF) +else() + option(BUILD_WITH_SSE "Use SSE" ON) +endif() if(BUILD_WITH_SSE) add_definitions(-DUSE_SSE=1) @@ -39,12 +44,13 @@ pam.c kmeans.c ) +set_target_properties(imagequant PROPERTIES SOVERSION 0 + VERSION 0.0) set(PREFIX ${CMAKE_INSTALL_PREFIX}) -file(READ version.txt VERSION) configure_file(imagequant.pc.in imagequant.pc @ONLY) -install(TARGETS imagequant LIBRARY DESTINATION lib) +install(TARGETS imagequant LIBRARY DESTINATION ${LIB_INSTALL_DIR}) install(FILES libimagequant.h DESTINATION include) -install(FILES ${CMAKE_BINARY_DIR}/libimagequant_a.a DESTINATION lib RENAME libimagequant.a) -install(FILES ${CMAKE_BINARY_DIR}/imagequant.pc DESTINATION lib/pkgconfig) +install(FILES ${CMAKE_BINARY_DIR}/libimagequant_a.a DESTINATION ${LIB_INSTALL_DIR} RENAME libimagequant.a) +install(FILES ${CMAKE_BINARY_DIR}/imagequant.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/Cargo.toml new/libimagequant-2.17.0/Cargo.toml --- old/libimagequant-2.15.1/Cargo.toml 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/Cargo.toml 2021-11-15 00:57:01.000000000 +0100 @@ -1,7 +1,7 @@ # libimagequant is a pure C library. # Rust/Cargo is entirely optional. You can also use ./configure && make [package] -version = "3.0.6+sys2.15.1" +version = "3.1.1+sys2.17.0" authors = ["Kornel Lesin??ski <kor...@pngquant.org>"] build = "rust-sys/build.rs" categories = ["external-ffi-bindings"] @@ -17,15 +17,15 @@ edition = "2018" [build-dependencies] -cc = "1.0.58" +cc = "1.0.71" [dependencies] -rgb = "0.8.25" -bitflags = "1.2.1" +rgb = "0.8.29" +bitflags = "1.3.2" [dependencies.openmp-sys] optional = true -version = "1.2.0-alpha.1" +version = "1.2.0" [features] default = ["sse"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/Makefile new/libimagequant-2.17.0/Makefile --- old/libimagequant-2.15.1/Makefile 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/Makefile 2021-11-15 00:57:01.000000000 +0100 @@ -115,7 +115,7 @@ install -d $(DESTDIR)$(PKGCONFIGDIR) install -d $(DESTDIR)$(INCLUDEDIR) install -m 644 $(STATICLIB) $(DESTDIR)$(LIBDIR)/$(STATICLIB) - install -m 644 $(SHAREDLIBVER) $(DESTDIR)$(LIBDIR)/$(SHAREDLIBVER) + install -m 755 $(SHAREDLIBVER) $(DESTDIR)$(LIBDIR)/$(SHAREDLIBVER) ln -sf $(SHAREDLIBVER) $(DESTDIR)$(LIBDIR)/$(SHAREDLIB) install -m 644 $(PKGCONFIG) $(DESTDIR)$(PKGCONFIGDIR)/$(PKGCONFIG) install -m 644 libimagequant.h $(DESTDIR)$(INCLUDEDIR)/libimagequant.h diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/libimagequant.c new/libimagequant-2.17.0/libimagequant.c --- old/libimagequant-2.15.1/libimagequant.c 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/libimagequant.c 2021-11-15 00:57:01.000000000 +0100 @@ -1768,7 +1768,7 @@ z *= z; // noise is amplified z *= z; // 85 is about 1/3rd of weight (not 0, because noisy pixels still need to be included, just not as precisely). - const unsigned int z_int = 85 + (unsigned int)(z * 171.f); + const unsigned int z_int = 80 + (unsigned int)(z * 176.f); noise[j*cols+i] = MIN(z_int, 255); const int e_int = 255 - (int)(edge * 256.f); edges[j*cols+i] = e_int > 0 ? MIN(e_int, 255) : 0; @@ -1876,7 +1876,7 @@ LIQ_NONNULL static void adjust_histogram_callback(hist_item *item, float diff) { - item->adjusted_weight = (item->perceptual_weight+item->adjusted_weight) * (sqrtf(1.f+diff)); + item->adjusted_weight = (item->perceptual_weight + 2.0 * item->adjusted_weight) * (0.5 + diff); } /** @@ -2100,12 +2100,15 @@ return LIQ_BUFFER_TOO_SMALL; } - LIQ_ARRAY(unsigned char *, rows, input_image->height); + unsigned char **rows = input_image->malloc(input_image->height * sizeof(unsigned char *)); unsigned char *buffer_bytes = buffer; for(unsigned int i=0; i < input_image->height; i++) { rows[i] = &buffer_bytes[input_image->width * i]; } - return liq_write_remapped_image_rows(result, input_image, rows); + + liq_error err = liq_write_remapped_image_rows(result, input_image, rows); + input_image->free(rows); + return err; } LIQ_EXPORT LIQ_NONNULL liq_error liq_write_remapped_image_rows(liq_result *quant, liq_image *input_image, unsigned char **row_pointers) @@ -2156,7 +2159,7 @@ // remapping above was the last chance to do K-Means iteration, hence the final palette is set after remapping set_rounded_palette(&result->int_palette, result->palette, result->gamma, quant->min_posterization_output); - if (!remap_to_palette_floyd(input_image, row_pointers, result, MAX(remapping_error*2.4, 16.f/256.f), generate_dither_map)) { + if (!remap_to_palette_floyd(input_image, row_pointers, result, MAX(remapping_error*2.4, 8.f/256.f), generate_dither_map)) { return LIQ_ABORTED; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/libimagequant.h new/libimagequant-2.17.0/libimagequant.h --- old/libimagequant-2.15.1/libimagequant.h 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/libimagequant.h 2021-11-15 00:57:01.000000000 +0100 @@ -13,8 +13,8 @@ #define LIQ_EXPORT extern #endif -#define LIQ_VERSION 21501 -#define LIQ_VERSION_STRING "2.15.1" +#define LIQ_VERSION 21600 +#define LIQ_VERSION_STRING "2.17.0" #ifndef LIQ_PRIVATE #if defined(__GNUC__) || defined (__llvm__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/mediancut.c new/libimagequant-2.17.0/mediancut.c --- old/libimagequant-2.15.1/mediancut.c 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/mediancut.c 2021-11-15 00:57:01.000000000 +0100 @@ -133,35 +133,37 @@ } } -/** sorts array to make sum of weights lower than halfvar one side, returns edge between <halfvar and >halfvar parts of the set */ -static hist_item *hist_item_sort_halfvar(hist_item base[], unsigned int len, double *const lowervar, const double halfvar) +/** sorts array to make sum of weights lower than halfvar one side, returns index of the edge between <halfvar and >halfvar parts of the set */ +static unsigned int hist_item_sort_halfvar(hist_item base[], unsigned int len, double halfvar) { + unsigned int base_idx = 0; // track base-index do { const unsigned int l = qsort_partition(base, len), r = l+1; // check if sum of left side is smaller than half, // if it is, then it doesn't need to be sorted - unsigned int t = 0; double tmpsum = *lowervar; - while (t <= l && tmpsum < halfvar) tmpsum += base[t++].color_weight; + double tmpsum = 0.; + for(unsigned int t = 0; t <= l && tmpsum < halfvar; ++t) tmpsum += base[t].color_weight; - if (tmpsum < halfvar) { - *lowervar = tmpsum; - } else { + // the split is on the left part + if (tmpsum >= halfvar) { if (l > 0) { - hist_item *res = hist_item_sort_halfvar(base, l, lowervar, halfvar); - if (res) return res; + len = l; + continue; } else { - // End of left recursion. This will be executed in order from the first element. - *lowervar += base[0].color_weight; - if (*lowervar > halfvar) return &base[0]; + // reached the end of left part + return base_idx; } } - + // process the right part + halfvar -= tmpsum; if (len > r) { - base += r; len -= r; // tail-recursive "call" + base += r; + base_idx += r; + len -= r; // tail-recursive "call" } else { - *lowervar += base[r].color_weight; - return (*lowervar > halfvar) ? &base[r] : NULL; + // reached the end of the right part + return base_idx + len; } } while(1); } @@ -370,12 +372,11 @@ */ const double halfvar = prepare_sort(&bv[bi], achv); - double lowervar=0; // hist_item_sort_halfvar sorts and sums lowervar at the same time // returns item to break at ???minus one, which does smell like an off-by-one error. - hist_item *break_p = hist_item_sort_halfvar(&achv[indx], clrs, &lowervar, halfvar); - unsigned int break_at = MIN(clrs-1, break_p - &achv[indx] + 1); + unsigned int break_at = hist_item_sort_halfvar(&achv[indx], clrs, halfvar); + break_at = MIN(clrs-1, break_at + 1); /* ** Split the box. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/pam.c new/libimagequant-2.17.0/pam.c --- old/libimagequant-2.15.1/pam.c 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/pam.c 2021-11-15 00:57:01.000000000 +0100 @@ -33,15 +33,7 @@ // RGBA color is casted to long for easier hasing/comparisons union rgba_as_int px = {pixels[row][col]}; unsigned int hash; - if (!px.rgba.a) { - // "dirty alpha" has different RGBA values that end up being the same fully transparent color - px.l=0; hash=0; - - boost = 2000; - if (importance_map) { - importance_map++; - } - } else { + if (px.rgba.a) { // mask posterizes all 4 channels in one go px.l = (px.l & posterize_mask) | ((px.l & posterize_high_mask) >> (8-ignorebits)); // fancier hashing algorithms didn't improve much @@ -52,13 +44,20 @@ } else { boost = 255; } + } else { + // "dirty alpha" has different RGBA values that end up being the same fully transparent color + px.l=0; hash=0; + + boost = 2000; + if (importance_map) { + importance_map++; + } } if (!pam_add_to_hash(acht, hash, boost, px, row, rows)) { return false; } } - } acht->cols = cols; acht->rows += rows; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/pam.h new/libimagequant-2.17.0/pam.h --- old/libimagequant-2.15.1/pam.h 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/pam.h 2021-11-15 00:57:01.000000000 +0100 @@ -147,12 +147,12 @@ }; } -ALWAYS_INLINE static double colordifference_ch(const double x, const double y, const double alphas); -inline static double colordifference_ch(const double x, const double y, const double alphas) +ALWAYS_INLINE static float colordifference_ch(const float x, const float y, const float alphas); +inline static float colordifference_ch(const float x, const float y, const float alphas) { // maximum of channel blended on white, and blended on black // premultiplied alpha and backgrounds 0/1 shorten the formula - const double black = x-y, white = black+alphas; + const float black = x-y, white = black+alphas; return MAX(black*black, white*white); } @@ -172,7 +172,7 @@ // (px.rgb - px.a) - (py.rgb - py.a) // (px.rgb - py.rgb) + (py.a - px.a) - const double alphas = py.a-px.a; + const float alphas = py.a-px.a; return colordifference_ch(px.r, py.r, alphas) + colordifference_ch(px.g, py.g, alphas) + colordifference_ch(px.b, py.b, alphas); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/rust-api/Cargo.toml new/libimagequant-2.17.0/rust-api/Cargo.toml --- old/libimagequant-2.15.1/rust-api/Cargo.toml 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/rust-api/Cargo.toml 2021-11-15 00:57:01.000000000 +0100 @@ -14,9 +14,10 @@ edition = "2018" [dependencies] -imagequant-sys = { version = "3.0.4-alpha.2", path = "../" } -libc = "0.2.60" -rgb = "0.8.25" +fallible_collections = "0.4.3" +imagequant-sys = { version = "3.1.0", path = "../" } +libc = "0.2.102" +rgb = "0.8.27" [features] default = ["sse"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/rust-api/src/lib.rs new/libimagequant-2.17.0/rust-api/src/lib.rs --- old/libimagequant-2.15.1/rust-api/src/lib.rs 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/rust-api/src/lib.rs 2021-11-15 00:57:01.000000000 +0100 @@ -11,16 +11,25 @@ pub use crate::ffi::liq_error; pub use crate::ffi::liq_error::*; +use fallible_collections::FallibleVec; use imagequant_sys as ffi; use std::fmt; use std::marker::PhantomData; -use std::mem; use std::mem::MaybeUninit; -use std::os::raw::c_int; +use std::mem; +use std::os::raw::{c_int, c_void}; use std::ptr; pub use rgb::RGBA8 as RGBA; +/// Allocates all memory used by the library, like [`libc::malloc`]. +/// +/// Must return properly aligned memory (16-bytes on x86, pointer size on other architectures). +pub type MallocUnsafeFn = unsafe extern "C" fn(size: usize) -> *mut c_void; + +/// Frees all memory used by the library, like [`libc::free`]. +pub type FreeUnsafeFn = unsafe extern "C" fn(*mut c_void); + /// 8-bit RGBA. This is the only color format used by the library. pub type Color = ffi::liq_color; @@ -32,6 +41,8 @@ /// Settings for the conversion process. Start here. pub struct Attributes { handle: *mut ffi::liq_attr, + malloc: MallocUnsafeFn, + free: FreeUnsafeFn, } /// Describes image dimensions for the library. @@ -93,7 +104,13 @@ impl Clone for Attributes { #[inline] fn clone(&self) -> Attributes { - unsafe { Attributes { handle: ffi::liq_attr_copy(&*self.handle) } } + unsafe { + Attributes { + handle: ffi::liq_attr_copy(&*self.handle), + malloc: self.malloc, + free: self.free, + } + } } } @@ -113,7 +130,27 @@ pub fn new() -> Self { let handle = unsafe { ffi::liq_attr_create() }; assert!(!handle.is_null(), "SSE-capable CPU is required for this build."); - Attributes { handle } + Attributes { + handle, + malloc: libc::malloc, + free: libc::free, + } + } + + /// New handle for library configuration, with specified custom allocator for internal use. + /// + /// See also `new_image()` + /// + /// # Safety + /// + /// * `malloc` and `free` must behave according to their corresponding C specification. + /// * `malloc` must return properly aligned memory (16-bytes on x86, pointer-sized on other architectures). + #[inline] + #[must_use] + pub unsafe fn with_allocator(malloc: MallocUnsafeFn, free: FreeUnsafeFn) -> Self { + let handle = ffi::liq_attr_create_with_allocator(malloc, free); + assert!(!handle.is_null(), "SSE-capable CPU is required for this build."); + Attributes { handle, malloc, free } } /// It's better to use `set_quality()` @@ -336,16 +373,16 @@ return Err(LIQ_BUFFER_TOO_SMALL); } let (bitmap, ownership) = if copy { - let copied = libc::malloc(4 * bitmap.len()) as *mut RGBA; + let copied = (attr.malloc)(4 * bitmap.len()) as *mut RGBA; ptr::copy_nonoverlapping(bitmap.as_ptr(), copied, bitmap.len()); (copied as *const _, ffi::liq_ownership::LIQ_OWN_ROWS | ffi::liq_ownership::LIQ_OWN_PIXELS) } else { (bitmap.as_ptr(), ffi::liq_ownership::LIQ_OWN_ROWS) }; - let rows = Self::malloc_image_rows(bitmap, stride, height); + let rows = Self::malloc_image_rows(bitmap, stride, height, attr.malloc); let h = ffi::liq_image_create_rgba_rows(&*attr.handle, rows, width as c_int, height as c_int, gamma); if h.is_null() { - libc::free(rows.cast()); + (attr.free)(rows.cast()); return Err(LIQ_INVALID_POINTER); } let img = Image { @@ -356,7 +393,7 @@ LIQ_OK => Ok(img), err => { drop(img); - libc::free(rows.cast()); + (attr.free)(rows.cast()); Err(err) }, } @@ -364,10 +401,10 @@ /// For arbitrary stride libimagequant requires rows. It's most convenient if they're allocated using libc, /// so they can be owned and freed automatically by the C library. - unsafe fn malloc_image_rows(bitmap: *const RGBA, stride: usize, height: usize) -> *mut *const u8 { + unsafe fn malloc_image_rows(bitmap: *const RGBA, stride: usize, height: usize, malloc: MallocUnsafeFn) -> *mut *const u8 { let mut byte_ptr = bitmap as *const u8; let stride_bytes = stride * 4; - let rows = libc::malloc(mem::size_of::<*const u8>() * height) as *mut *const u8; + let rows = malloc(mem::size_of::<*const u8>() * height) as *mut *const u8; for y in 0..height { *rows.add(y) = byte_ptr; byte_ptr = byte_ptr.add(stride_bytes); @@ -475,7 +512,10 @@ /// It's slighly better if you get palette from the `remapped()` call instead #[must_use] pub fn palette(&mut self) -> Vec<Color> { - self.palette_ref().to_vec() + let pal = self.palette_ref(); + let mut out: Vec<Color> = FallibleVec::try_with_capacity(pal.len()).unwrap(); + out.extend_from_slice(pal); + out } /// Final palette (as a temporary slice) @@ -497,13 +537,13 @@ pub fn remapped(&mut self, image: &mut Image<'_>) -> Result<(Vec<Color>, Vec<u8>), liq_error> { let len = image.width() * image.height(); // Capacity is essential here, as it creates uninitialized buffer - let mut buf = Vec::with_capacity(len); unsafe { - let uninit_slice = std::slice::from_raw_parts_mut(buf.as_ptr() as *mut _, buf.capacity()); + let mut buf: Vec<u8> = FallibleVec::try_with_capacity(len).map_err(|_| liq_error::LIQ_OUT_OF_MEMORY)?; + let uninit_slice = std::slice::from_raw_parts_mut(buf.as_ptr() as *mut MaybeUninit<u8>, buf.capacity()); self.remap_into(image, uninit_slice)?; buf.set_len(uninit_slice.len()); + Ok((self.palette(), buf)) } - Ok((self.palette(), buf)) } /// Remap image into an existing buffer. @@ -664,3 +704,36 @@ assert!(called > 5 && called < 50); assert_eq!(123, res.palette().len()); } + +#[test] +fn custom_allocator_test() { + // SAFETY: This is all in one thread. + static mut ALLOC_COUNTR: usize = 0; + static mut FREE_COUNTR: usize = 0; + + unsafe extern "C" fn test_malloc(size: usize) -> *mut c_void { + ALLOC_COUNTR += 1; + libc::malloc(size) + } + + unsafe extern "C" fn test_free(ptr: *mut c_void) { + FREE_COUNTR += 1; + libc::free(ptr) + } + + let liq = unsafe { Attributes::with_allocator(test_malloc, test_free) }; + assert_eq!(unsafe { ALLOC_COUNTR }, 1); + assert_eq!(unsafe { FREE_COUNTR }, 0); + + let liq2 = liq.clone(); + assert_eq!(liq.malloc, liq2.malloc); + assert_eq!(liq.free, liq2.free); + + drop(liq); + assert_eq!(unsafe { ALLOC_COUNTR }, 2); + assert_eq!(unsafe { FREE_COUNTR }, 1); + + drop(liq2); + assert_eq!(unsafe { ALLOC_COUNTR }, 2); + assert_eq!(unsafe { FREE_COUNTR }, 2); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/rust-sys/libimagequant.rs new/libimagequant-2.17.0/rust-sys/libimagequant.rs --- old/libimagequant-2.15.1/rust-sys/libimagequant.rs 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/rust-sys/libimagequant.rs 2021-11-15 00:57:01.000000000 +0100 @@ -153,6 +153,7 @@ /// The object should be freed using `liq_attr_destroy()` after it's no longer needed. /// Returns `NULL` in the unlikely case that the library cannot run on the current machine (e.g. the library has been compiled for SSE-capable x86 CPU and run on VIA C3 CPU). pub fn liq_attr_create() -> *mut liq_attr; + pub fn liq_attr_create_with_allocator(malloc: unsafe extern "C" fn(usize) -> *mut c_void, free: unsafe extern "C" fn(*mut c_void)) -> *mut liq_attr; pub fn liq_attr_copy(orig: &liq_attr) -> *mut liq_attr; pub fn liq_attr_destroy(attr: &mut liq_attr); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libimagequant-2.15.1/version.txt new/libimagequant-2.17.0/version.txt --- old/libimagequant-2.15.1/version.txt 2021-05-13 11:29:53.000000000 +0200 +++ new/libimagequant-2.17.0/version.txt 2021-11-15 00:57:01.000000000 +0100 @@ -1 +1 @@ -2.15.1 +2.17.0