DrKLO/Telegram · error
%s: can't read ICC profile from %s
Error message
%s: can't read ICC profile from %s
What it means
After allocating the ICC buffer, jpegtran reads the profile data with fread(icc_profile, icc_len, 1, icc_file) at jpegtran.c:521. If fread returns less than 1 (fewer than icc_len bytes read), the read failed. This can happen if the file shrank between the size determination and the read, or there is an I/O error.
Source
Thrown at TMessagesProj/jni/mozjpeg/jpegtran.c:522
if (icc_filename != NULL) {
if ((icc_file = fopen(icc_filename, READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, icc_filename);
exit(EXIT_FAILURE);
}
if (fseek(icc_file, 0, SEEK_END) < 0 ||
(icc_len = ftell(icc_file)) < 1 ||
fseek(icc_file, 0, SEEK_SET) < 0) {
fprintf(stderr, "%s: can't determine size of %s\n", progname,
icc_filename);
exit(EXIT_FAILURE);
}
if ((icc_profile = (JOCTET *)malloc(icc_len)) == NULL) {
fprintf(stderr, "%s: can't allocate memory for ICC profile\n", progname);
fclose(icc_file);
exit(EXIT_FAILURE);
}
if (fread(icc_profile, icc_len, 1, icc_file) < 1) {
fprintf(stderr, "%s: can't read ICC profile from %s\n", progname,
icc_filename);
free(icc_profile);
fclose(icc_file);
exit(EXIT_FAILURE);
}
fclose(icc_file);
if (copyoption == JCOPYOPT_ALL)
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)View on GitHub (pinned to 45ab8f4308)
Solutions
- Copy the ICC profile to a stable local temp file and use that path
- Ensure no other process writes to or truncates the ICC file while jpegtran runs
- Verify file integrity (checksum) before passing it
Example fix
// before // icc_path shared, may be truncated by another process // after // copy to exclusive temp file char tmp[256]; snprintf(tmp, sizeof(tmp), "%s/icc_%d.tmp", app_internal_dir, getpid()); copy_file(icc_path, tmp); // pass tmp to jpegtran -icc, delete after
Defensive patterns
Strategy: validation
Validate before calling
// Copy ICC file to a private temp file to prevent concurrent modification
int stage_icc_file(const char *src, char *tmp, size_t tmp_len) {
snprintf(tmp, tmp_len, "/tmp/icc_%d.icc", getpid());
FILE *in = fopen(src, "rb");
if (!in) return -1;
FILE *out = fopen(tmp, "wb");
if (!out) { fclose(in); return -1; }
char buf[4096]; size_t n;
while ((n = fread(buf, 1, sizeof(buf), in)) > 0)
if (fwrite(buf, 1, n, out) != n) { fclose(in); fclose(out); return -1; }
fclose(in); fclose(out);
return 0;
} Prevention
- Copy the ICC profile to a private temp file before passing it to jpegtran
- Ensure no other process writes to or truncates the ICC file during processing
- Verify file integrity with a checksum before use
When it happens
Trigger: The ICC file was truncated or modified between the fseek/ftell and the fread call. A filesystem error during read. The file is on a failing storage device. A race condition where another process truncates the file concurrently.
Common situations: Temp ICC file on Android external storage that gets unmounted. File on network storage with a dropped connection. Concurrent process writes/truncates the ICC file while jpegtran reads it.
Related errors
- %s: can't open %s
- %s: can't determine size of %s
- %s: can't open %s for reading
- %s: can't allocate memory for ICC profile
- %s: can't read from %s
AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14).
Data as JSON: /api/errors/c3d1f9a3830bfd86.
Report an issue: GitHub.