Skip to content

Commit 66d9f63

Browse files
committed
Add check to determine whether an image is an animated WebP file to avoid unexpected FFmpeg failures
1 parent e8e4d08 commit 66d9f63

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

src/main/java/com/github/stickerifier/stickerify/media/MediaHelper.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public final class MediaHelper {
7373
return null;
7474
}
7575

76-
if (mimeType.startsWith("image/")) {
76+
if (isSupportedImage(inputFile, mimeType)) {
7777
if (isImageCompliant(inputFile, mimeType)) {
7878
LOGGER.atInfo().log("The image doesn't need conversion");
7979
return null;
@@ -288,6 +288,45 @@ private static boolean isAnimationCompliant(@Nullable AnimationDetails animation
288288
&& animation.height() == MAX_SIDE_LENGTH;
289289
}
290290

291+
/**
292+
* Checks if the MIME type corresponds to one of the supported image formats.
293+
*
294+
* @param image the image file to check
295+
* @param mimeType the MIME type to check
296+
* @return {@code true} if the MIME type is supported
297+
*/
298+
private static boolean isSupportedImage(File image, String mimeType) {
299+
if ("image/webp".equals(mimeType) && isAnimatedWebp(image)) {
300+
LOGGER.atInfo().log("The image is an animated WebP");
301+
return false;
302+
}
303+
304+
return mimeType.startsWith("image/");
305+
}
306+
307+
/**
308+
* Detects if a WebP file is animated by checking its file header.
309+
*
310+
* @param file the WebP file to check
311+
* @return {@code true} if the file is an animated WebP
312+
*/
313+
private static boolean isAnimatedWebp(File file) {
314+
try (var fileInputStream = new FileInputStream(file)) {
315+
var header = new byte[256];
316+
int bytesRead = fileInputStream.read(header);
317+
318+
if (bytesRead < 32) {
319+
return false;
320+
}
321+
322+
var headerContent = new String(header, UTF_8);
323+
return headerContent.contains("ANIM");
324+
} catch (IOException e) {
325+
LOGGER.atWarn().setCause(e).log("An error occurred checking if the file is an animated WebP");
326+
return false;
327+
}
328+
}
329+
291330
/**
292331
* Checks if passed-in image is already compliant with Telegram's requisites.
293332
*

src/test/java/com/github/stickerifier/stickerify/media/MediaHelperTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ void resizeAnimatedWebpVideo() {
260260
var webpVideo = loadResource("animated.webp");
261261

262262
var ex = assertThrows(MediaException.class, () -> MediaHelper.convert(webpVideo));
263-
assertThat(ex.getMessage(), equalTo("FFmpeg image conversion failed"));
263+
assertThat(ex.getMessage(), equalTo("The file with image/webp MIME type is not supported"));
264264
}
265265

266266
@Test

0 commit comments

Comments
 (0)