Fix: skip generating thumbnails for APNG Backported from #5113
| @@ -62,7 +62,7 @@ export function getThumbnailResolution(type) { | ||
| 62 | 62 | * @param {Buffer} buffer The file buffer. |
| 63 | 63 | * @returns {boolean} |
| 64 | 64 | */ |
| 65 | 65 | export function isAnimatedApng(buffer) { |
| 66 | 66 | return buffer.subarray(0, 200).includes('acTL'); |
| 67 | 67 | } |
| 68 | 68 | |
| @@ -8,7 +8,7 @@ import { sync as writeFileAtomicSync } from 'write-file-atomic'; | ||
| 8 | 8 | import { imageSize as sizeOf } from 'image-size'; |
| 9 | 9 | |
| 10 | 10 | import { getConfigValue, invalidateFirefoxCache } from '../util.js'; |
| 11 | 11 | import { getThumbnailResolution, isAnimatedWebP, thumbnailDimensions as dimensions, isAnimatedApng } from './image-metadata.js'; |
| 12 | 12 | import { ResizeStrategy } from '@jimp/plugin-resize'; |
| 13 | 13 | |
| 14 | 14 | export const publicRouter = express.Router(); |
| @@ -159,6 +159,16 @@ export async function generateThumbnail(directories, type, file, forceGenerate = | ||
| 159 | 159 | } |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | + // For PNG files, check if they are actually APNGs. | |
| 163 | + if (fileExtension === '.png' && isKnownAnimated !== false) { | |
| 164 | + const buffer = fs.readFileSync(pathToOriginalFile); | |
| 165 | + const isAnimated = isAnimatedApng(buffer); | |
| 166 | + if (isAnimated) { | |
| 167 | + // The client is expected to handle it. | |
| 168 | + return { path: null, aspectRatio: null, resolution: null }; | |
| 169 | + } | |
| 170 | + } | |
| 171 | + | |
| 162 | 172 | if (SKIPPED_EXTENSIONS.has(fileExtension)) { |
| 163 | 173 | return { path: null, aspectRatio: null, resolution: null }; |
| 164 | 174 | } |