DrKLO/Telegram · error
%s: can't open %s
Error message
%s: can't open %s
What it means
When the user specifies an ICC profile via the `-icc` option, jpegtran opens it with fopen(icc_filename, READ_BINARY) at jpegtran.c:505. A NULL return means the ICC file path is invalid or inaccessible. Unlike the input JPEG, this error message omits 'for reading' to distinguish it.
Source
Thrown at TMessagesProj/jni/mozjpeg/jpegtran.c:506
usage();
}
#endif /* TWO_FILE_COMMANDLINE */
/* Open the input file. */
if (file_index < argc) {
if ((fp = fopen(argv[file_index], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s for reading\n", progname,
argv[file_index]);
exit(EXIT_FAILURE);
}
} else {
/* default input file is stdin */
fp = read_stdin();
}
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);View on GitHub (pinned to 45ab8f4308)
Solutions
- Verify the ICC file exists and is readable with `access(icc_path, R_OK)` before invoking jpegtran
- Use an absolute path for the ICC profile file
- Extract the ICC profile from the APK assets to internal storage first, then pass that path
Example fix
// before
jpegtran -icc srgb.icc input.jpg -outfile out.jpg
// after
const char *icc = "/data/user/0/app/files/srgb.icc";
if (access(icc, R_OK) != 0) { return -1; }
jpegtran -icc /data/user/0/app/files/srgb.icc input.jpg -outfile out.jpg Defensive patterns
Strategy: validation
Validate before calling
// Validate ICC profile file before invoking jpegtran -icc
int validate_icc_file(const char *path) {
if (access(path, R_OK) != 0) return -1;
struct stat st;
if (stat(path, &st) != 0) return -1;
if (!S_ISREG(st.st_mode)) return -1;
if (st.st_size < 128 || st.st_size > 5*1024*1024) return -1; // ICC profiles are 128B-5MB
return 0;
} Prevention
- Verify the ICC file exists and is readable before passing -icc
- Bundle ICC profiles in app internal storage, not external removable storage
- Use absolute paths for ICC profile files
When it happens
Trigger: Passing `-icc profile.icc` where profile.icc does not exist, is a directory, or has restrictive permissions. Also triggered by a typo in the ICC filename or an expired/cleaned-up temp file path.
Common situations: ICC profile file was downloaded to a cache that was cleared. Path is relative and resolves wrong in JNI context. Profile is bundled as an Android asset but the native code receives a path that doesn't resolve on the filesystem.
Related errors
- %s: can't determine size of %s
- %s: can't read ICC profile from %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/60d2438df05036c2.
Report an issue: GitHub.