add webp animation detection

pull/3730/head
Mime Čuvalo 2024-05-10 10:35:48 +01:00
rodzic 31b4e7ded0
commit aab7ca3f66
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: BA84499022AC984D
3 zmienionych plików z 48 dodań i 17 usunięć

Wyświetl plik

@ -3,24 +3,26 @@
* Copyright (c) Philip van Heemstra
*/
export function isApng(buffer: Uint8Array): boolean {
export function isApngAnimated(buffer: ArrayBuffer): boolean {
const view = new Uint8Array(buffer)
if (
!buffer ||
!((typeof Buffer !== 'undefined' && Buffer.isBuffer(buffer)) || buffer instanceof Uint8Array) ||
buffer.length < 16
!view ||
!((typeof Buffer !== 'undefined' && Buffer.isBuffer(view)) || view instanceof Uint8Array) ||
view.length < 16
) {
return false
}
const isPNG =
buffer[0] === 0x89 &&
buffer[1] === 0x50 &&
buffer[2] === 0x4e &&
buffer[3] === 0x47 &&
buffer[4] === 0x0d &&
buffer[5] === 0x0a &&
buffer[6] === 0x1a &&
buffer[7] === 0x0a
view[0] === 0x89 &&
view[1] === 0x50 &&
view[2] === 0x4e &&
view[3] === 0x47 &&
view[4] === 0x0d &&
view[5] === 0x0a &&
view[6] === 0x1a &&
view[7] === 0x0a
if (!isPNG) {
return false
@ -125,10 +127,9 @@ export function isApng(buffer: Uint8Array): boolean {
// APNGs have an animation control chunk ('acTL') preceding the IDATs.
// See: https://en.wikipedia.org/wiki/APNG#File_format
const arr = new Uint8Array(buffer)
const idatIdx = indexOfSubstring(arr, 'IDAT', 12)
const idatIdx = indexOfSubstring(view, 'IDAT', 12)
if (idatIdx >= 12) {
const actlIdx = indexOfSubstring(arr, 'acTL', 8, idatIdx)
const actlIdx = indexOfSubstring(view, 'acTL', 8, idatIdx)
return actlIdx >= 8
}

Wyświetl plik

@ -1,7 +1,8 @@
import { isApng } from './apng'
import { isApngAnimated } from './apng'
import { isAvifAnimated } from './avif'
import { isGifAnimated } from './gif'
import { PngHelpers } from './png'
import { isWebpAnimated } from './webp'
/** @public */
export const DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES = Object.freeze(['image/svg+xml'])
@ -130,8 +131,12 @@ export class MediaHelpers {
return isAvifAnimated(await file.arrayBuffer())
}
if (file.type === 'image/webp') {
return isWebpAnimated(await file.arrayBuffer())
}
if (file.type === 'image/apng') {
return isApng(new Uint8Array(await file.arrayBuffer()))
return isApngAnimated(await file.arrayBuffer())
}
return false

Wyświetl plik

@ -0,0 +1,25 @@
/*!
* MIT License: https://github.com/sindresorhus/is-webp/blob/main/license
* Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
*/
function isWebp(view: Uint8Array) {
if (!view || view.length < 12) {
return false
}
return view[8] === 87 && view[9] === 69 && view[10] === 66 && view[11] === 80
}
export function isWebpAnimated(buffer: ArrayBuffer) {
const view = new Uint8Array(buffer)
if (!isWebp(view)) {
return false
}
if (!view || view.length < 21) {
return false
}
return ((view[20] >> 1) & 1) === 1
}