Skip to content

Commit 3d9ac17

Browse files
committed
Rework webp animation detection to check on extended details
1 parent 88272f7 commit 3d9ac17

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static com.github.stickerifier.stickerify.media.MediaConstraints.MAX_VIDEO_FILE_SIZE;
1111
import static com.github.stickerifier.stickerify.media.MediaConstraints.MAX_VIDEO_FRAMES;
1212
import static com.github.stickerifier.stickerify.media.MediaConstraints.VP9_CODEC;
13+
import static java.nio.charset.StandardCharsets.ISO_8859_1;
1314
import static java.nio.charset.StandardCharsets.UTF_8;
1415

1516
import com.github.stickerifier.stickerify.exception.CorruptedFileException;
@@ -46,6 +47,11 @@ public final class MediaHelper {
4647
private static final int IMAGE_KEEP_ASPECT_RATIO = -1;
4748
private static final int VIDEO_KEEP_ASPECT_RATIO = -2;
4849

50+
private static final int WEBP_CHUNK_TYPE_OFFSET = 12;
51+
private static final int WEBP_CHUNK_TYPE_LENGTH = 4;
52+
private static final int WEBP_FLAGS_BYTE_OFFSET = 20;
53+
private static final int WEBP_ANIMATION_BIT_MASK = 0x02;
54+
4955
/**
5056
* Based on the type of passed-in file, it converts it into the proper media.
5157
* If no conversion was needed, {@code null} is returned.
@@ -313,15 +319,16 @@ private static boolean isSupportedImage(File image, String mimeType) {
313319
*/
314320
private static boolean isAnimatedWebp(File file) {
315321
try (var fileInputStream = new FileInputStream(file)) {
316-
var header = new byte[256];
317-
int bytesRead = fileInputStream.read(header);
318-
319-
if (bytesRead < 32) {
322+
var header = new byte[WEBP_FLAGS_BYTE_OFFSET + 1];
323+
if (fileInputStream.read(header) < 21) {
320324
return false;
321325
}
322326

323-
var headerContent = new String(header, UTF_8);
324-
return headerContent.contains("ANIM");
327+
var chunkHeader = new String(header, WEBP_CHUNK_TYPE_OFFSET, WEBP_CHUNK_TYPE_LENGTH, ISO_8859_1);
328+
boolean isExtendedFormat = "VP8X".equals(chunkHeader);
329+
boolean hasAnimationFlag = (header[WEBP_FLAGS_BYTE_OFFSET] & WEBP_ANIMATION_BIT_MASK) != 0;
330+
331+
return isExtendedFormat && hasAnimationFlag;
325332
} catch (IOException e) {
326333
LOGGER.atWarn().setCause(e).log("An error occurred checking if the file is an animated WebP");
327334
return false;

0 commit comments

Comments
 (0)