Yalantis/uCrop · error · CImgDisplayException

cimg::SDL3_attr(): %s

Error message

cimg::SDL3_attr(): %s

What it means

CImg's SDL3_attr helper initializes the SDL display subsystem (SDL_Init(SDL_INIT_VIDEO/SDL3 backend)); if SDL init fails it throws CImgDisplayException carrying SDL_GetError(). This is an environment-level failure of the native display backend, not a problem with image data, and typically occurs the first time a CImgDisplay is constructed.

Source

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

      SDL3_attr():nb_cimg_displays(0),display(0),mode(0),mutex_lock_display(0) {
        bool init_failed = true;
        if (SDL_Init(SDL_INIT_VIDEO)) {
          display = SDL_GetPrimaryDisplay();
          if (display) {
            mode = SDL_GetCurrentDisplayMode(display);
            if (mode) {
              mutex_lock_display = SDL_CreateMutex();
              if (mutex_lock_display) init_failed = false;
              main_thread_id = SDL_GetCurrentThreadID();
            }
          }
        }
#if cimg_OS==1
        std::signal(SIGINT,SIG_DFL); // Restore default behavior for CTRL+C
#endif
        if (init_failed)
          throw CImgDisplayException("cimg::SDL3_attr(): %s",SDL_GetError());
        cimg_displays = new CImgDisplay*[512];
      }

      ~SDL3_attr() {
        unlock();
        SDL_DestroyMutex(mutex_lock_display);
        SDL_Quit();
        delete[] cimg_displays;
      }

      SDL3_attr& lock() { // Lock display
        SDL_LockMutex(mutex_lock_display);
        return *this;
      }

      SDL3_attr& unlock() { // Unlock display
        SDL_UnlockMutex(mutex_lock_display);
        return *this;

View on GitHub (pinned to f788b534b4)

Solutions

  1. Run in an environment with a display, or use Xvfb: xvfb-run ./your_binary.
  2. Install the SDL3 development/runtime library that CImg's SDL backend expects.
  3. Avoid code paths that create CImgDisplay in headless builds (guard display usage with cimg::display_info()/compile-time checks or disable display code).
  4. For Android targets, do not initialize CImgDisplay — use CImg's image processing APIs only.
  5. Check SDL_GetError() output embedded in the message for the concrete cause (driver/library/version).
Defensive patterns

Strategy: try-catch

Validate before calling

const bool display_available = (std::getenv("DISPLAY") != nullptr) || (std::getenv("WAYLAND_DISPLAY") != nullptr);
if (!display_available) {
    std::fprintf(stderr, "No display available; skipping CImgDisplay usage\n");
    return; // skip display code path
}

Try / catch

try {
    cimg_library::CImgDisplay disp(img, "preview");
} catch (cimg_library::CImgDisplayException& e) {
    std::fprintf(stderr, "Display init failed: %s\n", e.what());
    // fall back to headless processing: save image to file instead of showing
}

Prevention

When it happens

Trigger: Constructing a CImgDisplay (or any code path initializing the SDL3 display attribute) on a system where SDL_Init fails: no X11/Wayland display, missing SDL3 library, or headless CI/container without a virtual framebuffer.

Common situations: Building/running the uCrop native (JNI) code or its tests on a headless Linux build machine; SDL3 not installed or wrong version so cimg's SDL3 backend fails to load; running on Android where desktop display init is unsupported.

Related errors


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