Yalantis/uCrop · error · CImgIOException

load_graphicsmagick_external(): Failed to load file '%s' wit

Error message

load_graphicsmagick_external(): Failed to load file '%s' with external command 'gm'.

What it means

After spawning `gm convert <file> <tmpfile>` via popen and reading the resulting PNM/piped output, any exception raised while parsing the piped data is caught, the pipe closed, and a CImgIOException rethrown indicating GraphicsMagick failed to load the file. The failure is really 'gm ran but produced output CImg could not parse' or the gm process errored mid-stream.

Source

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

                      "png"
#else
                      "pnm"
#endif
                      );
        std::FILE *file = popen(command,"r");
        if (file) {
          const unsigned int omode = cimg::exception_mode();
          cimg::exception_mode(0);
          try {
#ifdef cimg_use_png
            load_png(file);
#else
            load_pnm(file);
#endif
          } catch (...) {
            pclose(file);
            cimg::exception_mode(omode);
            throw CImgIOException(_cimg_instance
                                  "load_graphicsmagick_external(): Failed to load file '%s' "
                                  "with external command 'gm'.",
                                  cimg_instance,
                                  filename);
          }
          pclose(file);
          return *this;
        }
      }
#endif
      do {
        cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s.%s",
                      cimg::temporary_path(),
                      cimg_file_separator,
                      cimg::filenamerand(),
#ifdef cimg_use_png
                      "png"
#else

View on GitHub (pinned to f788b534b4)

Solutions

  1. Verify `gm convert input output.png` works from the shell to see gm's real error
  2. Install the missing GraphicsMagick format delegates (e.g. libjpeg, libpng, libwebp dev packages) and rebuild gm
  3. Fall back to load_imagemagick_external() or a native loader for the format
  4. Check file readability/permissions for the user the process runs as

Example fix

// before
img.load_graphicsmagick_external("photo.jpg"); // gm lacks jpeg delegate -> throws
// after
if (cimg::system("gm identify photo.jpg") == 0) {
  img.load_graphicsmagick_external("photo.jpg");
} else {
  img.load_jpeg("photo.jpg"); // built-in fallback
}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure gm can identify the file before using the external loader
if (cimg::system("gm identify \"file.jpg\" > /dev/null 2>&1") != 0) {
  // gm unavailable or missing delegate: use built-in loader
  img.load_jpeg("file.jpg");
} else {
  img.load_graphicsmagick_external("file.jpg");
}

Try / catch

try {
  img.load_graphicsmagick_external(filename);
} catch (CImgIOException& e) {
  cimg::warn("gm pipeline failed, falling back to native loader");
  img.load(filename); // native auto-detect
}

Prevention

When it happens

Trigger: load_graphicsmagick_external() on POSIX when posix_searchpath("gm") found the tool, popen() succeeded, but load_pnp/parsing of the stream threw (empty or malformed output from gm).

Common situations: GraphicsMagick installed but built without delegates (no support for the input format, e.g. missing JPEG/WebP delegate), producing empty output; gm emitting warnings to the stream; permission problems making gm read fail mid-run.

Related errors


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