Yalantis/uCrop · error · CImgArgumentException

quantize(): Invalid quantization request with 0 values.

Error message

quantize(): Invalid quantization request with 0 values.

What it means

CImg<T>::quantize(nb_levels, keep_range) reduces pixel values to nb_levels discrete levels. nb_levels==0 is mathematically meaningless (zero quantization levels), so the method throws this CImgArgumentException immediately. The library throws at the top of the function, before the empty-image early return, so it fires even for empty images.

Source

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

    //! Cut pixel values in specified range \newinstance.
    CImg<T> get_abscut(const T& min_value, const T& max_value, const T& offset) const {
      return (+*this).abscut(min_value,max_value,offset);
    }

    //! Uniformly quantize pixel values.
    /**
       \param nb_levels Number of quantization levels.
       \param keep_range Tells if resulting values keep the same range as the original ones.
       \par Example
       \code
       const CImg<float> img("reference.jpg"), res = img.get_quantize(4);
       (img,res).display();
       \endcode
       \image html ref_quantize.jpg
    **/
    CImg<T>& quantize(const unsigned int nb_levels, const bool keep_range=true) {
      if (!nb_levels)
        throw CImgArgumentException(_cimg_instance
                                    "quantize(): Invalid quantization request with 0 values.",
                                    cimg_instance);

      if (is_empty()) return *this;
      Tfloat m, M = (Tfloat)max_min(m), range = M - m;
      if (range>0) {
        if (keep_range)
          cimg_pragma_openmp(parallel for cimg_openmp_if_size(size(),32768))
          cimg_rofoff(*this,off) {
            const unsigned int val = (unsigned int)((_data[off] - m)*nb_levels/range);
            _data[off] = (T)(m + std::min(val,nb_levels - 1)*range/nb_levels);
          } else
          cimg_pragma_openmp(parallel for cimg_openmp_if_size(size(),32768))
          cimg_rofoff(*this,off) {
            const unsigned int val = (unsigned int)((_data[off] - m)*nb_levels/range);
            _data[off] = (T)std::min(val,nb_levels - 1);
          }
      }

View on GitHub (pinned to f788b534b4)

Solutions

  1. Validate nb_levels >= 1 (typically >= 2 for meaningful output) before calling quantize().
  2. Clamp computed level counts: nb_levels = std::max(2u, computed).
  3. Fix the source of the zero: default missing config to a sane level count like 256.
  4. Check float-to-unsigned truncation; round instead of truncating when deriving levels from a float.

Example fix

// before
unsigned levels = (unsigned)(maxVal / step); // can be 0
img.quantize(levels); // throws when 0
// after
unsigned levels = std::max(2u, (unsigned)std::round(maxVal / step));
img.quantize(levels);
Defensive patterns

Strategy: validation

Validate before calling

bool canQuantize(unsigned int nbLevels) { return nbLevels >= 2; }
if (canQuantize(levels)) img.quantize(levels, keepRange);

Try / catch

try {
  img.quantize(nbLevels);
} catch (const CImgArgumentException& e) {
  std::fprintf(stderr, "quantize needs >=1 level, got %u; using 256\n", nbLevels);
  img.quantize(256);
}

Prevention

When it happens

Trigger: Calling img.quantize(0) or img.get_quantize(0) directly; computing nb_levels from a formula/user input that evaluates to 0 (e.g. (int)(maxValue/step) with step > maxValue, or an unvalidated config field defaulting to 0).

Common situations: Dynamic level count derived from image statistics or a slider that can reach 0; config files where the levels key is missing and parsed as 0; casting a small float level count to unsigned int truncating to 0 (e.g. 0.4 -> 0).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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