Yalantis/uCrop · error · CImgDisplayException

CImgDisplay::assign(): Invalid %u bits screen mode detected

Error message

CImgDisplay::assign(): Invalid %u bits screen mode detected (only 8, 16, 24 and 32 bits modes are managed).

What it means

After opening the X11 display, CImg reads DefaultDepth() and throws CImgDisplayException if the visual depth is not 8/16/24/32 bits, because its display code only knows how to convert pixels for those depths. Unusual server/visual configurations (e.g. 12-, 15-, or 30-bit depth) are unsupported.

Source

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

      if (s) std::memcpy(tmp_title,np_title,s*sizeof(char));

      // Destroy previous display window if existing.
      if (!is_empty()) assign(false);

      // Open X11 display and retrieve graphical properties.
      cimg::X11_attr &X11_attr = cimg::X11_attr::ref();
      Display* &dpy = X11_attr.display;
      if (!dpy) {
        dpy = XOpenDisplay(0);
        if (!dpy)
          throw CImgDisplayException(_cimgdisplay_instance
                                     "assign(): Failed to open X11 display.",
                                     cimgdisplay_instance);

        X11_attr.nb_bits = DefaultDepth(dpy,DefaultScreen(dpy));
        if (X11_attr.nb_bits!=8 && X11_attr.nb_bits!=16 &&
            X11_attr.nb_bits!=24 && X11_attr.nb_bits!=32)
          throw CImgDisplayException(_cimgdisplay_instance
                                     "assign(): Invalid %u bits screen mode detected "
                                     "(only 8, 16, 24 and 32 bits modes are managed).",
                                     cimgdisplay_instance,
                                     X11_attr.nb_bits);
        XVisualInfo vtemplate;
        vtemplate.visualid = XVisualIDFromVisual(DefaultVisual(dpy,DefaultScreen(dpy)));
        int nb_visuals;
        XVisualInfo *vinfo = XGetVisualInfo(dpy,VisualIDMask,&vtemplate,&nb_visuals);
        if (vinfo && vinfo->red_mask<vinfo->blue_mask) X11_attr.is_blue_first = true;
        X11_attr.byte_order = ImageByteOrder(dpy);
        XFree(vinfo);
      }

      X11_attr.lock();
      if (!X11_attr.events_thread) {
        X11_attr.events_thread = new pthread_t;
        pthread_create(X11_attr.events_thread,0,_events_thread,0);
      }

View on GitHub (pinned to f788b534b4)

Solutions

  1. Reconfigure the X server to a standard 24-bit (or 32-bit) depth in xorg.conf / fbdev settings
  2. Update graphics drivers/firmware so the framebuffer reports a supported depth
  3. Use a different machine/Xvfb instance with depth 24 for display output

Example fix

# before (xorg.conf)
DefaultDepth 15
# after
DefaultDepth 24
Defensive patterns

Strategy: try-catch

Validate before calling

// depth check approximated with xdpyinfo:
// xdpyinfo | grep 'depth of root window'  -> must be 8/16/24/32

Try / catch

try { cimg::CImgDisplay d(img, "win"); } catch (const cimg_library::CImgDisplayException &e) { fprintf(stderr, "Unsupported screen depth: %s\n", e.what()); }

Prevention

When it happens

Trigger: Calling CImgDisplay::assign()/constructor while connected to an X server whose DefaultScreen depth is outside {8,16,24,32} — e.g. 15 or 16-bit framebuffers on embedded devices or legacy X setups.

Common situations: Embedded/ARM boards with unusual framebuffer depths; X servers started with a legacy depth (e.g. Depth 15) in xorg.conf; remote X servers with rare visual configurations.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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