kopia lustrzana https://github.com/Tldraw/Tldraw
add webp animation detection
rodzic
31b4e7ded0
commit
aab7ca3f66
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
Ładowanie…
Reference in New Issue