@@ -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 *
0 commit comments