DrKLO/Telegram · error

%s: memory allocation failure

Error message

%s: memory allocation failure

What it means

When JCP_MAX_COMPRESSION is active, jpegtran reads the entire input JPEG into a memory buffer via realloc in a grow-loop at jpegtran.c:546. If realloc returns NULL, the process cannot grow the buffer. This happens with very large JPEG files or under memory pressure. The program exits immediately.

Source

Thrown at TMessagesProj/jni/mozjpeg/jpegtran.c:548

      copyoption = JCOPYOPT_ALL_EXCEPT_ICC;
  }

#ifdef PROGRESS_REPORT
  start_progress_monitor((j_common_ptr)&dstinfo, &progress);
#endif

  /* Specify data source for decompression */
  if (jpeg_c_int_param_supported(&dstinfo, JINT_COMPRESS_PROFILE) &&
      jpeg_c_get_int_param(&dstinfo, JINT_COMPRESS_PROFILE)
        == JCP_MAX_COMPRESSION)
    memsrc = TRUE; /* needed to revert to original */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
  if (memsrc) {
    size_t nbytes;
    do {
      inbuffer = (unsigned char *)realloc(inbuffer, insize + INPUT_BUF_SIZE);
      if (inbuffer == NULL) {
        fprintf(stderr, "%s: memory allocation failure\n", progname);
        exit(EXIT_FAILURE);
      }
      nbytes = JFREAD(fp, &inbuffer[insize], INPUT_BUF_SIZE);
      if (nbytes < INPUT_BUF_SIZE && ferror(fp)) {
        if (file_index < argc)
          fprintf(stderr, "%s: can't read from %s\n", progname,
                  argv[file_index]);
        else
          fprintf(stderr, "%s: can't read from stdin\n", progname);
      }
      insize += (unsigned long)nbytes;
    } while (nbytes == INPUT_BUF_SIZE);
    jpeg_mem_src(&srcinfo, inbuffer, insize);
  } else
#endif
  jpeg_stdio_src(&srcinfo, fp);

  /* Enable saving of extra markers that we want to copy */

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Disable JCP_MAX_COMPRESSION to use stdio source instead of memory source, avoiding the full-file buffer
  2. Reduce the input JPEG dimensions before running jpegtran
  3. Free other memory in the calling process before invoking jpegtran
  4. Use a 64-bit build to increase address space

Example fix

// before
// JCP_MAX_COMPRESSION forces entire file into memory
jpegtran -optimize -progressive large_photo.jpg -outfile out.jpg

// after
// disable max compression to stream via stdio
jpegtran -optimize large_photo.jpg -outfile out.jpg
// or pre-resize the image
jpegtran -scale 1/2 large_photo.jpg -outfile smaller.jpg
Defensive patterns

Strategy: fallback

Validate before calling

// Check available memory / file size before processing with max compression
long validate_memsrc_feasible(const char *input_path) {
    struct stat st;
    if (stat(input_path, &st) != 0) return -1;
    // Need ~2x file size in memory for memsrc mode
    long avail = get_available_memory(); // platform-specific
    if ((unsigned long)st.st_size * 2 > (unsigned long)avail) {
        fprintf(stderr, "Insufficient memory for memsrc; file=%lld avail=%ld\n",
                (long long)st.st_size, avail);
        return -1;
    }
    return st.st_size;
}

Try / catch

// Shell fallback: try max compression, fall back to stdio
jpegtran -optimize input.jpg -outfile out.jpg 2>/dev/null
if [ $? -ne 0 ]; then
    echo "Max compression failed, using stdio mode" >&2
    jpegtran input.jpg -outfile out.jpg
fi

Prevention

When it happens

Trigger: Processing a large JPEG (tens of MB+) with JCP_MAX_COMPRESSION enabled, which forces memsrc mode. Running on a device with limited RAM or a restrictive RLIMIT_AS. Multiple concurrent jpegtran instances competing for memory.

Common situations: Android device with limited heap. Processing a high-resolution photo (e.g. 50MP camera output). A build with JCP_MAX_COMPRESSION as the default profile. 32-bit build hitting address-space limits with a >2GB effective allocation.

Related errors


AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14). Data as JSON: /api/errors/8f45e76573e1e4f8. Report an issue: GitHub.