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

Reply via email to