From bdd71e489859eb6c56434ad4b71663b3251b2e7c Mon Sep 17 00:00:00 2001 From: Evan Hahn <69474926+EvanHahn-Signal@users.noreply.github.com> Date: Mon, 28 Sep 2020 13:40:26 -0500 Subject: [PATCH] Support APNGs in Sticker Creator --- .eslintignore | 1 + _locales/en/messages.json | 20 ++- fixtures/2x2.bmp | Bin 0 -> 70 bytes ...imated_PNG_example_bouncing_beach_ball.png | Bin 0 -> 63435 bytes fixtures/apng_with_2_plays.png | Bin 0 -> 646 bytes fixtures/kitten-1-64-64.ico | Bin 0 -> 17470 bytes js/modules/types/message.js | 1 - sticker-creator/app/stages/MetaStage.tsx | 16 +-- sticker-creator/components/StickerGrid.tsx | 12 +- sticker-creator/elements/DropZone.tsx | 10 +- sticker-creator/preload.js | 97 +++++++++++-- sticker-creator/store/ducks/stickers.ts | 38 +++--- sticker-creator/util/preload.ts | 16 +-- sticker-creator/util/useStickerDropzone.ts | 16 +++ ts/models/conversations.ts | 21 ++- .../util/getAnimatedPngDataIfExists_test.ts | 57 ++++++++ ts/test/util/sniffImageMimeType_test.ts | 92 +++++++++++++ ts/types/MIME.ts | 2 + ts/util/getAnimatedPngDataIfExists.ts | 78 +++++++++++ ts/util/sniffImageMimeType.ts | 127 ++++++++++++++++++ 20 files changed, 542 insertions(+), 62 deletions(-) create mode 100644 fixtures/2x2.bmp create mode 100644 fixtures/Animated_PNG_example_bouncing_beach_ball.png create mode 100644 fixtures/apng_with_2_plays.png create mode 100644 fixtures/kitten-1-64-64.ico create mode 100644 sticker-creator/util/useStickerDropzone.ts create mode 100644 ts/test/util/getAnimatedPngDataIfExists_test.ts create mode 100644 ts/test/util/sniffImageMimeType_test.ts create mode 100644 ts/util/getAnimatedPngDataIfExists.ts create mode 100644 ts/util/sniffImageMimeType.ts diff --git a/.eslintignore b/.eslintignore index d19483f72..ccd6fb019 100644 --- a/.eslintignore +++ b/.eslintignore @@ -25,6 +25,7 @@ test/blanket_mocha.js # TypeScript generated files ts/**/*.js sticker-creator/**/*.js +!sticker-creator/preload.js **/*.d.ts webpack.config.ts diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 903689057..60d392366 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -2331,7 +2331,7 @@ "description": "Title for the drop stage of the sticker creator" }, "StickerCreator--DropStage--help": { - "message": "Stickers must be in PNG or WebP format with a transparent background and 512x512 pixels. Recommended margin is 16px.", + "message": "Stickers must be in PNG, APNG, or WebP format with a transparent background and 512x512 pixels. Recommended margin is 16px.", "description": "Help text for the drop stage of the sticker creator" }, "StickerCreator--DropStage--showMargins": { @@ -2460,7 +2460,23 @@ }, "StickerCreator--Toasts--errorProcessing": { "message": "Error processing image", - "description": "Text for the toast when an image cannot be processed was dropped on the sticker creator" + "description": "Text for the toast when an image cannot be processed was dropped on the sticker creator with a generic error" + }, + "StickerCreator--Toasts--APNG--notSquare": { + "message": "Animated PNG stickers must be square", + "description": "Text for the toast when someone tries to upload a non-square APNG" + }, + "StickerCreator--Toasts--mustLoopForever": { + "message": "Animated stickers must loop forever", + "description": "Text for the toast when an image in the sticker creator does not animate forever" + }, + "StickerCreator--Toasts--APNG--dimensionsTooLarge": { + "message": "Animated PNG sticker dimensions are too large", + "description": "Text for the toast when an APNG image in the sticker creator is too large" + }, + "StickerCreator--Toasts--APNG--dimensionsTooSmall": { + "message": "Animated PNG sticker dimensions are too small", + "description": "Text for the toast when an APNG image in the sticker creator is too small" }, "StickerCreator--Toasts--errorUploading": { "message": "Error uploading stickers: $message$", diff --git a/fixtures/2x2.bmp b/fixtures/2x2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e32f57cb6a932df9647cab02ec99c104d48b1202 GIT binary patch literal 70 qcmZ?rbz^`4GX@3*4F(1VCMafPkN`^vfJs#19`CJtytfz_U^D=kg$Q*3 literal 0 HcmV?d00001 diff --git a/fixtures/Animated_PNG_example_bouncing_beach_ball.png b/fixtures/Animated_PNG_example_bouncing_beach_ball.png new file mode 100644 index 0000000000000000000000000000000000000000..1b35084a369ee5d40908a70e01ca47fccb144ce4 GIT binary patch literal 63435 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 WpH@-w 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 { const onDrop = React.useCallback( async ([{ path }]: Array) => { try { - const webp = await convertToWebp(path); - actions.setCover(webp); + const stickerImage = await processStickerImage(path); + actions.setCover(stickerImage); } catch (e) { actions.removeSticker(path); } @@ -31,10 +32,9 @@ export const MetaStage: React.ComponentType = () => { [actions] ); - const { getRootProps, getInputProps, isDragActive } = useDropzone({ - onDrop, - accept: ['image/png', 'image/webp'], - }); + const { getRootProps, getInputProps, isDragActive } = useStickerDropzone( + onDrop + ); const onNext = React.useCallback(() => { setConfirming(true); diff --git a/sticker-creator/components/StickerGrid.tsx b/sticker-creator/components/StickerGrid.tsx index 819288086..0d6b08ee9 100644 --- a/sticker-creator/components/StickerGrid.tsx +++ b/sticker-creator/components/StickerGrid.tsx @@ -9,7 +9,7 @@ import * as styles from './StickerGrid.scss'; import { Props as StickerFrameProps, StickerFrame } from './StickerFrame'; import { stickersDuck } from '../store'; import { DropZone, Props as DropZoneProps } from '../elements/DropZone'; -import { convertToWebp } from '../util/preload'; +import { processStickerImage } from '../util/preload'; const queue = new PQueue({ concurrency: 3, timeout: 1000 * 60 * 2 }); @@ -17,7 +17,7 @@ const SmartStickerFrame = SortableElement( ({ id, showGuide, mode }: StickerFrameProps) => { const data = stickersDuck.useStickerData(id); const actions = stickersDuck.useStickerActions(); - const image = data.webp ? data.webp.src : undefined; + const image = data.imageData ? data.imageData.src : undefined; return ( { queue.add(async () => { try { - const webp = await convertToWebp(path); - actions.addWebp(webp); + const stickerImage = await processStickerImage(path); + actions.addImageData(stickerImage); } catch (e) { window.log.error('Error processing image:', e); actions.removeSticker(path); actions.addToast({ - key: 'StickerCreator--Toasts--errorProcessing', + key: + (e || {}).errorMessageI18nKey || + 'StickerCreator--Toasts--errorProcessing', }); } }); diff --git a/sticker-creator/elements/DropZone.tsx b/sticker-creator/elements/DropZone.tsx index 036e22225..c4b319332 100644 --- a/sticker-creator/elements/DropZone.tsx +++ b/sticker-creator/elements/DropZone.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; -import { useDropzone, FileWithPath } from 'react-dropzone'; +import { FileWithPath } from 'react-dropzone'; import * as styles from './DropZone.scss'; import { useI18n } from '../util/i18n'; +import { useStickerDropzone } from '../util/useStickerDropzone'; export type Props = { readonly inner?: boolean; @@ -32,10 +33,9 @@ export const DropZone: React.ComponentType = props => { [onDrop] ); - const { getRootProps, getInputProps, isDragActive } = useDropzone({ - onDrop: handleDrop, - accept: ['image/png', 'image/webp'], - }); + const { getRootProps, getInputProps, isDragActive } = useStickerDropzone( + handleDrop + ); React.useEffect(() => { if (onDragActive) { diff --git a/sticker-creator/preload.js b/sticker-creator/preload.js index b75067501..a445e41c6 100644 --- a/sticker-creator/preload.js +++ b/sticker-creator/preload.js @@ -12,6 +12,11 @@ const { makeGetter } = require('../preload_utils'); const { dialog } = remote; const { nativeTheme } = remote.require('electron'); +const STICKER_SIZE = 512; +const MIN_STICKER_DIMENSION = 10; +const MAX_STICKER_DIMENSION = STICKER_SIZE; +const MAX_ANIMATED_STICKER_BYTE_LENGTH = 300 * 1024; + window.ROOT_PATH = window.location.href.startsWith('file') ? '../../' : '/'; window.PROTO_ROOT = '../../protos'; window.getEnvironment = () => config.environment; @@ -32,6 +37,9 @@ window.Signal = Signal.setup({}); window.textsecure = require('../ts/textsecure').default; const { initialize: initializeWebAPI } = require('../ts/textsecure/WebAPI'); +const { + getAnimatedPngDataIfExists, +} = require('../ts/util/getAnimatedPngDataIfExists'); const WebAPI = initializeWebAPI({ url: config.serverUrl, @@ -49,25 +57,83 @@ const WebAPI = initializeWebAPI({ version: config.version, }); -window.convertToWebp = async (path, width = 512, height = 512) => { +function processStickerError(message, i18nKey) { + const result = new Error(message); + result.errorMessageI18nKey = i18nKey; + return result; +} + +window.processStickerImage = async path => { const imgBuffer = await pify(readFile)(path); const sharpImg = sharp(imgBuffer); const meta = await sharpImg.metadata(); - const buffer = await sharpImg - .resize({ - width, - height, - fit: 'contain', - background: { r: 0, g: 0, b: 0, alpha: 0 }, - }) - .webp() - .toBuffer(); + const { width, height } = meta; + if (!width || !height) { + throw processStickerError( + 'Sticker height or width were falsy', + 'StickerCreator--Toasts--errorProcessing' + ); + } + + let contentType; + let processedBuffer; + + // [Sharp doesn't support APNG][0], so we do something simpler: validate the file size + // and dimensions without resizing, cropping, or converting. In a perfect world, we'd + // resize and convert any animated image (GIF, animated WebP) to APNG. + // [0]: https://github.com/lovell/sharp/issues/2375 + const animatedPngDataIfExists = getAnimatedPngDataIfExists(imgBuffer); + if (animatedPngDataIfExists) { + if (imgBuffer.byteLength > MAX_ANIMATED_STICKER_BYTE_LENGTH) { + throw processStickerError( + 'Sticker file was too large', + 'StickerCreator--Toasts--tooLarge' + ); + } + if (width !== height) { + throw processStickerError( + 'Sticker must be square', + 'StickerCreator--Toasts--APNG--notSquare' + ); + } + if (width > MAX_STICKER_DIMENSION) { + throw processStickerError( + 'Sticker dimensions are too large', + 'StickerCreator--Toasts--APNG--dimensionsTooLarge' + ); + } + if (width < MIN_STICKER_DIMENSION) { + throw processStickerError( + 'Sticker dimensions are too small', + 'StickerCreator--Toasts--APNG--dimensionsTooSmall' + ); + } + if (animatedPngDataIfExists.numPlays !== Infinity) { + throw processStickerError( + 'Animated stickers must loop forever', + 'StickerCreator--Toasts--mustLoopForever' + ); + } + contentType = 'image/png'; + processedBuffer = imgBuffer; + } else { + contentType = 'image/webp'; + processedBuffer = await sharpImg + .resize({ + width: STICKER_SIZE, + height: STICKER_SIZE, + fit: 'contain', + background: { r: 0, g: 0, b: 0, alpha: 0 }, + }) + .webp() + .toBuffer(); + } return { path, - buffer, - src: `data:image/webp;base64,${buffer.toString('base64')}`, + buffer: processedBuffer, + src: `data:${contentType};base64,${processedBuffer.toString('base64')}`, meta, }; }; @@ -108,7 +174,10 @@ window.encryptAndUpload = async ( password, }); - const uniqueStickers = uniqBy([...stickers, { webp: cover }], 'webp'); + const uniqueStickers = uniqBy( + [...stickers, { imageData: cover }], + 'imageData' + ); const manifestProto = new window.textsecure.protobuf.StickerPack(); manifestProto.title = manifest.title; @@ -133,7 +202,7 @@ window.encryptAndUpload = async ( ); const encryptedStickers = await pMap( uniqueStickers, - ({ webp }) => encrypt(webp.buffer, encryptionKey, iv), + ({ imageData }) => encrypt(imageData.buffer, encryptionKey, iv), { concurrency: 3, timeout: 1000 * 60 * 2, diff --git a/sticker-creator/store/ducks/stickers.ts b/sticker-creator/store/ducks/stickers.ts index b67422631..f7041a6b8 100644 --- a/sticker-creator/store/ducks/stickers.ts +++ b/sticker-creator/store/ducks/stickers.ts @@ -15,18 +15,24 @@ import { bindActionCreators } from 'redux'; import arrayMove from 'array-move'; // eslint-disable-next-line import/no-cycle import { AppState } from '../reducer'; -import { PackMetaData, WebpData, StickerData } from '../../util/preload'; +import { + PackMetaData, + StickerImageData, + StickerData, +} from '../../util/preload'; import { EmojiPickDataType } from '../../../ts/components/emoji/EmojiPicker'; import { convertShortName } from '../../../ts/components/emoji/lib'; export const initializeStickers = createAction>( 'stickers/initializeStickers' ); -export const addWebp = createAction('stickers/addSticker'); +export const addImageData = createAction( + 'stickers/addSticker' +); export const removeSticker = createAction('stickers/removeSticker'); export const moveSticker = createAction('stickers/moveSticker'); -export const setCover = createAction('stickers/setCover'); -export const resetCover = createAction('stickers/resetCover'); +export const setCover = createAction('stickers/setCover'); +export const resetCover = createAction('stickers/resetCover'); export const setEmoji = createAction<{ id: string; emoji: EmojiPickDataType }>( 'stickers/setEmoji' ); @@ -48,7 +54,7 @@ export const maxStickers = 200; export const maxByteSize = 100 * 1024; interface StateStickerData { - readonly webp?: WebpData; + readonly imageData?: StickerImageData; readonly emoji?: EmojiPickDataType; } @@ -59,7 +65,7 @@ interface StateToastData { export type State = { readonly order: Array; - readonly cover?: WebpData; + readonly cover?: StickerImageData; readonly title: string; readonly author: string; readonly packId: string; @@ -71,7 +77,7 @@ export type State = { }; export type Actions = { - addWebp: typeof addWebp; + addImageData: typeof addImageData; initializeStickers: typeof initializeStickers; removeSticker: typeof removeSticker; moveSticker: typeof moveSticker; @@ -100,7 +106,7 @@ const adjustCover = (state: Draft) => { const first = state.order[0]; if (first) { - state.cover = state.data[first].webp; + state.cover = state.data[first].imageData; } else { delete state.cover; } @@ -121,7 +127,7 @@ export const reducer = reduceReducers( }); }), - handleAction(addWebp, (state, { payload }) => { + handleAction(addImageData, (state, { payload }) => { if (isNumber(payload.meta.pages)) { state.toasts.push({ key: 'StickerCreator--Toasts--animated' }); pull(state.order, payload.path); @@ -133,9 +139,9 @@ export const reducer = reduceReducers( } else { const data = state.data[payload.path]; - // If we are adding webp data, proceed to update the state and add/update a toast - if (data && !data.webp) { - data.webp = payload; + // If we are adding image data, proceed to update the state and add/update a toast + if (data && !data.imageData) { + data.imageData = payload; const key = 'StickerCreator--Toasts--imagesAdded'; @@ -223,7 +229,7 @@ export const useTitle = (): string => export const useAuthor = (): string => useSelector(({ stickers }: AppState) => stickers.author); -export const useCover = (): WebpData | undefined => +export const useCover = (): StickerImageData | undefined => useSelector(({ stickers }: AppState) => stickers.cover); export const useStickerOrder = (): Array => @@ -237,7 +243,7 @@ export const useStickersReady = (): boolean => ({ stickers }: AppState) => stickers.order.length >= minStickers && stickers.order.length <= maxStickers && - Object.values(stickers.data).every(({ webp }) => !!webp) + Object.values(stickers.data).every(({ imageData }) => Boolean(imageData)) ); export const useEmojisReady = (): boolean => @@ -288,7 +294,7 @@ export const useSelectOrderedData = (): Array => useSelector(selectOrderedData); const selectOrderedImagePaths = createSelector(selectOrderedData, data => - data.map(({ webp }) => (webp as WebpData).src) + data.map(({ imageData }) => imageData.src) ); export const useOrderedImagePaths = (): Array => @@ -301,7 +307,7 @@ export const useStickerActions = (): Actions => { () => bindActionCreators( { - addWebp, + addImageData, initializeStickers, removeSticker, moveSticker, diff --git a/sticker-creator/util/preload.ts b/sticker-creator/util/preload.ts index ebb5c0479..c52a1a9c1 100644 --- a/sticker-creator/util/preload.ts +++ b/sticker-creator/util/preload.ts @@ -2,32 +2,28 @@ import { Metadata } from 'sharp'; declare global { interface Window { - convertToWebp: ConvertToWebpFn; + processStickerImage: ProcessStickerImageFn; encryptAndUpload: EncryptAndUploadFn; } } -export type WebpData = { +export type StickerImageData = { buffer: Buffer; src: string; path: string; meta: Metadata & { pages?: number }; // Pages is not currently in the sharp metadata type }; -export type ConvertToWebpFn = ( - path: string, - width?: number, - height?: number -) => Promise; +type ProcessStickerImageFn = (path: string) => Promise; -export type StickerData = { webp?: WebpData; emoji?: string }; +export type StickerData = { imageData?: StickerImageData; emoji?: string }; export type PackMetaData = { packId: string; key: string }; export type EncryptAndUploadFn = ( manifest: { title: string; author: string }, stickers: Array, - cover: WebpData, + cover: StickerImageData, onProgress?: () => unknown ) => Promise; -export const { encryptAndUpload, convertToWebp } = window; +export const { encryptAndUpload, processStickerImage } = window; diff --git a/sticker-creator/util/useStickerDropzone.ts b/sticker-creator/util/useStickerDropzone.ts new file mode 100644 index 000000000..d3f849d65 --- /dev/null +++ b/sticker-creator/util/useStickerDropzone.ts @@ -0,0 +1,16 @@ +import { useDropzone, DropzoneOptions } from 'react-dropzone'; + +export const useStickerDropzone = ( + onDrop: DropzoneOptions['onDrop'] +): ReturnType => + useDropzone({ + onDrop, + accept: [ + 'image/png', + 'image/webp', + // Some OSes recognize .apng files with the MIME type but others don't, so we supply + // the extension too. + 'image/apng', + '.apng', + ], + }); diff --git a/ts/models/conversations.ts b/ts/models/conversations.ts index d0f62abca..3c25912c8 100644 --- a/ts/models/conversations.ts +++ b/ts/models/conversations.ts @@ -14,6 +14,8 @@ import { } from '../state/ducks/conversations'; import { ColorType } from '../types/Colors'; import { MessageModel } from './messages'; +import { sniffImageMimeType } from '../util/sniffImageMimeType'; +import { MIMEType, IMAGE_WEBP } from '../types/MIME'; /* eslint-disable more/no-then */ window.Whisper = window.Whisper || {}; @@ -1773,6 +1775,23 @@ export class ConversationModel extends window.Backbone.Model< const { path, width, height } = stickerData; const arrayBuffer = await readStickerData(path); + // We need this content type to be an image so we can display an `` instead of a + // `