Yalantis/uCrop · warning

get_serialize(): Unable to compress data unless zlib is enab

Error message

get_serialize(): Unable to compress data unless zlib is enabled, storing them uncompressed.

What it means

CImgList::get_serialize() warns when is_compressed=true was requested but the library was compiled without cimg_use_zlib defined. zlib compression is unavailable, so the data is serialized uncompressed instead of failing. Behavior is still correct, just larger output.

Source

Thrown at ucrop/src/main/jni/CImg.h:68733

      if (!cimg::path_exists(filename))
        throw CImgIOException(_cimglist_instance
                              "save_ffmpeg_external(): Failed to save file '%s' with external command 'ffmpeg'.",
                              cimglist_instance,
                              filename);
      cimglist_for(*this,l) std::remove(filenames[l]);
      return *this;
    }

    //! Serialize a CImgList<T> instance into a raw CImg<unsigned char> buffer.
    /**
       \param is_compressed tells if zlib compression must be used for serialization
       (this requires 'cimg_use_zlib' been enabled).
       \param header_size Reserve empty bytes as a starting header.
    **/
    CImg<ucharT> get_serialize(const bool is_compressed=false, const unsigned int header_size=0) const {
#ifndef cimg_use_zlib
      if (is_compressed)
        cimg::warn(_cimglist_instance
                   "get_serialize(): Unable to compress data unless zlib is enabled, "
                   "storing them uncompressed.",
                   cimglist_instance);
#endif
      CImgList<ucharT> stream;
      if (header_size) CImg<ucharT>(1,header_size,1,1,0).move_to(stream);
      CImg<charT> tmpstr(128);
      const char *const ptype = pixel_type(), *const etype = cimg::endianness()?"big":"little";
      cimg_snprintf(tmpstr,tmpstr._width,"%u %s %s_endian\n",_width,ptype,etype);
      CImg<ucharT>::string(tmpstr,false).move_to(stream);
      cimglist_for(*this,l) {
        const CImg<T>& img = _data[l];
        cimg_snprintf(tmpstr,tmpstr._width,"%u %u %u %u",img._width,img._height,img._depth,img._spectrum);
        CImg<ucharT>::string(tmpstr,false).move_to(stream);
        if (img._data) {
          CImg<T> tmp;
          if (cimg::endianness()) { tmp = img; cimg::invert_endianness(tmp._data,tmp.size()); }
          const CImg<T>& ref = cimg::endianness()?tmp:img;

View on GitHub (pinned to f788b534b4)

Solutions

  1. Define cimg_use_zlib in the build (e.g. LOCAL_CFLAGS / cppFlags += '-Dcimg_use_zlib') and link zlib (-lz), then rebuild.
  2. Pass is_compressed=false and accept uncompressed serialization if zlib is not needed.
  3. Check output size or the warning at runtime and switch to an external compression step (gzip the serialized buffer yourself).

Example fix

// Android.mk before
LOCAL_CFLAGS := -O2
// after
LOCAL_CFLAGS := -O2 -Dcimg_use_zlib
LOCAL_LDLIBS += -lz
Defensive patterns

Strategy: fallback

Validate before calling

#ifdef cimg_use_zlib
  CImg<unsigned char> buf = list.get_serialize(true);
#else
  CImg<unsigned char> buf = list.get_serialize(false);
#endif

Try / catch

CImg<unsigned char> buf;
if (compressed_available()) buf = list.get_serialize(true);
else { warn_user("uncompressed"); buf = list.get_serialize(false); }

Prevention

When it happens

Trigger: Calling get_serialize(true) (or serialize(true)) on a build of CImg.h where the preprocessor macro cimg_use_zlib is not defined, e.g. a plain vendored CImg.h without -Dcimg_use_zlib and linked zlib.

Common situations: Vendoring CImg.h into an Android NDK/jni build (as here) without adding the zlib build flag; upgrading CImg and dropping the compile definition; assuming compression works because zlib exists on the system but was never enabled at compile time.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/39629cbeaaae43be. Report an issue: GitHub.