Yalantis/uCrop · error · CImgArgumentException

draw_mandelbrot(): Instance and specified colormap (%u,%u,%u

Error message

draw_mandelbrot(): Instance and specified colormap (%u,%u,%u,%u,%p) have incompatible dimensions.

What it means

draw_mandelbrot() optionally accepts a colormap image; if supplied and non-empty, its spectrum (number of channels) must match the instance image's spectrum, otherwise CImgArgumentException is thrown listing the colormap's dimensions. Internally the colormap is reshaped into a palette of the same channel count as the target image, which is impossible when channel counts differ (e.g. RGB palette on a grayscale image).

Source

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

       \param is_normalized_iteration Tells if iterations are normalized.
       \param is_julia_set Tells if the Mandelbrot or Julia set is rendered.
       \param param_r Real part of the Julia set parameter.
       \param param_i Imaginary part of the Julia set parameter.
       \note Fractal rendering is done by the Escape Time Algorithm.
    **/
    template<typename tc>
    CImg<T>& draw_mandelbrot(const int x0, const int y0, const int x1, const int y1,
                             const CImg<tc>& colormap, const float opacity=1,
                             const double z0r=-2, const double z0i=-2, const double z1r=2, const double z1i=2,
                             const unsigned int iteration_max=255,
                             const bool is_normalized_iteration=false,
                             const bool is_julia_set=false,
                             const double param_r=0, const double param_i=0) {
      if (is_empty()) return *this;
      CImg<tc> palette;
      if (colormap) palette.assign(colormap._data,colormap.size()/colormap._spectrum,1,1,colormap._spectrum,true);
      if (palette && palette._spectrum!=_spectrum)
        throw CImgArgumentException(_cimg_instance
                                    "draw_mandelbrot(): Instance and specified colormap (%u,%u,%u,%u,%p) have "
                                    "incompatible dimensions.",
                                    cimg_instance,
                                    colormap._width,colormap._height,colormap._depth,colormap._spectrum,colormap._data);

      const float nopacity = cimg::abs(opacity), copacity = 1 - std::max(opacity,0.f), ln2 = (float)std::log(2.);
      const int
        _x0 = cimg::cut(x0,0,width() - 1),
        _y0 = cimg::cut(y0,0,height() - 1),
        _x1 = cimg::cut(x1,0,width() - 1),
        _y1 = cimg::cut(y1,0,height() - 1);

      cimg_pragma_openmp(parallel for cimg_openmp_collapse(2)
                         cimg_openmp_if((1 + _x1 - _x0)*(1 + _y1 - _y0)>=(cimg_openmp_sizefactor)*2048))
      for (int q = _y0; q<=_y1; ++q)
        for (int p = _x0; p<=_x1; ++p) {
          unsigned int iteration = 0;
          const double x = z0r + p*(z1r-z0r)/_width, y = z0i + q*(z1i-z0i)/_height;

View on GitHub (pinned to f788b534b4)

Solutions

  1. Match channel counts: convert the palette with colormap.channels(0,2) or the image to color (img.resize(...,3)) so spectra agree.
  2. Construct the palette with the same spectrum as the target: CImg<unsigned char> palette(N,1,1,img.spectrum()).
  3. Check colormap.spectrum()==img.spectrum() (when colormap is non-empty) before calling.
  4. If you don't need a custom palette, omit the colormap argument entirely and use the built-in default.

Example fix

// before
CImg<unsigned char> palette = loadRGBPalette(); // spectrum 3
grayImg.draw_mandelbrot(zoomx,zoomy,...,palette,...);
// after
CImg<unsigned char> palette = loadRGBPalette().channels(0,0); // -> spectrum 1
grayImg.draw_mandelbrot(zoomx,zoomy,...,palette,...);
Defensive patterns

Strategy: validation

Validate before calling

if (colormap && !colormap.is_empty() && colormap.spectrum()!=img.spectrum())
    colormap = colormap.get_resize(colormap.width(),1,1,img.spectrum());
img.draw_mandelbrot(zoomx,zoomy,niter,jx,jy,true,0,0,false,0,0,colormap);

Type guard

bool paletteMatches(const CImg<unsigned char>& img, const CImg<unsigned char>& cmap){
  return cmap.is_empty() || cmap.spectrum()==img.spectrum();
}

Try / catch

try { img.draw_mandelbrot(zx,zy,it,...,colormap,...); }
catch (CImgArgumentException& e) { log_error("draw_mandelbrot palette mismatch: %s", e.what()); }

Prevention

When it happens

Trigger: Calling img.draw_mandelbrot(...,colormap,...) where colormap._spectrum != img._spectrum — e.g. an RGB (3-channel) palette passed to a single-channel image, or a scalar palette passed to an RGB image; also passing an uninitialized-but-nonzero palette image.

Common situations: Reusing a palette from a color image for a grayscale render or vice versa; loading a palette JPEG/PNG with alpha (4 channels) for a 3-channel target; refactoring that changed the working image from color to gray without updating the palette.

Understand the failure class

Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.

Related errors


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