Yalantis/uCrop · error · CImgInstanceException

min_max(): %s.

Error message

min_max(): %s.

What it means

CImgList<T>::min_max() computes both the minimum and maximum pixel values in one pass. It throws CImgInstanceException "min_max(): %s." when the list is empty or all images within it are empty (ucrop/src/main/jni/CImg.h:65630), because neither extremum can be defined over zero pixels.

Source

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

      }
      return *ptr_max;
    }

    //! Return a reference to the minimum pixel value of the instance list and return the maximum vvalue as well.
    /**
       \param[out] max_val Value of the maximum value found.
    **/
    template<typename t>
    T& min_max(t& max_val) {
      bool is_all_empty = true;
      T *ptr_min = 0;
      cimglist_for(*this,l) if (!_data[l].is_empty()) {
        ptr_min = _data[l]._data;
        is_all_empty = false;
        break;
      }
      if (is_all_empty)
        throw CImgInstanceException(_cimglist_instance
                                    "min_max(): %s.",
                                    _data?"List of empty images":"Empty instance",
                                    cimglist_instance);
      T min_value = *ptr_min, max_value = min_value;
      cimglist_for(*this,l) {
        const CImg<T>& img = _data[l];
        cimg_for(img,ptrs,T) {
          const T val = *ptrs;
          if (val<min_value) { min_value = val; ptr_min = ptrs; }
          if (val>max_value) max_value = val;
        }
      }
      max_val = (t)max_value;
      return *ptr_min;
    }

    //! Return a reference to the minimum pixel value of the instance list and return the maximum vvalue as well \const.
    /**

View on GitHub (pinned to f788b534b4)

Solutions

  1. Pre-check that at least one image in the list is non-empty before calling min_max().
  2. Fix upstream load/crop/resize so images have pixels; verify with !img.is_empty().
  3. Catch CImgInstanceException and handle the no-data case (skip normalization, use defaults).
  4. Restructure the pipeline so the statistics call only runs when the population stage reported success.

Example fix

// before
T mn, mx;
list.min_max(mn, mx);

// after
bool any = false;
for (unsigned int l = 0; l < list.size(); ++l) if (!list[l].is_empty()) { any = true; break; }
if (!any) return;
T mn, mx;
list.min_max(mn, mx);
Defensive patterns

Strategy: validation

Validate before calling

bool any = false; for (unsigned int l = 0; l < list.size(); ++l) if (!list[l].is_empty()) { any = true; break; } if (!any) { /* skip min_max */ }

Type guard

static inline bool hasNonEmptyImage(const CImgList<T>& l) { cimglist_for(l, i) if (!l[i].is_empty()) return true; return false; }

Try / catch

try { list.min_max(mn, mx); } catch (CImgInstanceException& e) { mn = mx = defaultValue; }

Prevention

When it happens

Trigger: Calling min_max() on a CImgList where the scan loop finds no non-empty image — e.g. default-constructed list, assign()-cleared list, or a list of images resized to zero dimensions.

Common situations: Range normalization (mapping values to [min,max]) after a decoding step produced nothing; histogram/contrast tools run on empty batches; buggy crop logic yielding 0x0 images.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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