Skip to content

Commit 63c85c1

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

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

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

Lines changed: 14 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,12 @@ 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+
private static final String WEBP_EXTENDED_FILE_FORMAT = "VP8X";
55+
4956
/**
5057
* Based on the type of passed-in file, it converts it into the proper media.
5158
* If no conversion was needed, {@code null} is returned.
@@ -313,15 +320,16 @@ private static boolean isSupportedImage(File image, String mimeType) {
313320
*/
314321
private static boolean isAnimatedWebp(File file) {
315322
try (var fileInputStream = new FileInputStream(file)) {
316-
var header = new byte[256];
317-
int bytesRead = fileInputStream.read(header);
318-
319-
if (bytesRead < 32) {
323+
var header = new byte[WEBP_FLAGS_BYTE_OFFSET + 1];
324+
if (fileInputStream.read(header) < 21) {
320325
return false;
321326
}
322327

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

0 commit comments

Comments
 (0)