From b7c223bc0d71d988c1431ec6d6850bab0b945369 Mon Sep 17 00:00:00 2001 From: Surma Date: Mon, 16 Jul 2018 15:18:59 +0100 Subject: [PATCH] Remove baseline image decoders, refactor decodeFile --- src/codecs/browser-jpeg/decoder.ts | 18 ----------------- src/codecs/browser-png/decoder.ts | 18 ----------------- src/codecs/browser-webp/decoder.ts | 4 ++-- src/codecs/decoders.ts | 32 +++++++++++++++++++++++------- src/components/App/index.tsx | 8 ++------ src/lib/util.ts | 8 ++++---- 6 files changed, 33 insertions(+), 55 deletions(-) delete mode 100644 src/codecs/browser-jpeg/decoder.ts delete mode 100644 src/codecs/browser-png/decoder.ts diff --git a/src/codecs/browser-jpeg/decoder.ts b/src/codecs/browser-jpeg/decoder.ts deleted file mode 100644 index 6321d3a1..00000000 --- a/src/codecs/browser-jpeg/decoder.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { canDecodeImage, fileToBitmap } from '../../lib/util'; - -export const name = 'Browser JPEG Decoder'; -export const supportedMimeTypes = ['image/jpeg']; -export async function decode(file: File): Promise { - return fileToBitmap(file); -} - -// tslint:disable-next-line:max-line-length It’s a data URL. Whatcha gonna do? -const jpegFile = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAn/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AJVAA//Z'; - -export function isSupported(): Promise { - return canDecodeImage(jpegFile); -} - -export function canHandleMimeType(mimeType: string): boolean { - return supportedMimeTypes.includes(mimeType); -} diff --git a/src/codecs/browser-png/decoder.ts b/src/codecs/browser-png/decoder.ts deleted file mode 100644 index 47ecd6b8..00000000 --- a/src/codecs/browser-png/decoder.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { canDecodeImage, fileToBitmap } from '../../lib/util'; - -export const name = 'Browser PNG Decoder'; -export const supportedMimeTypes = ['image/png']; -export async function decode(file: File): Promise { - return fileToBitmap(file); -} - -// tslint:disable-next-line:max-line-length It’s a data URL. Whatcha gonna do? -const pngFile = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII='; - -export function isSupported(): Promise { - return canDecodeImage(pngFile); -} - -export function canHandleMimeType(mimeType: string): boolean { - return supportedMimeTypes.includes(mimeType); -} diff --git a/src/codecs/browser-webp/decoder.ts b/src/codecs/browser-webp/decoder.ts index 9a570685..d7be3a37 100644 --- a/src/codecs/browser-webp/decoder.ts +++ b/src/codecs/browser-webp/decoder.ts @@ -1,9 +1,9 @@ -import { canDecodeImage, fileToBitmap } from '../../lib/util'; +import { canDecodeImage, createImageBitmapPolyfill } from '../../lib/util'; export const name = 'Browser WebP Decoder'; export const supportedMimeTypes = ['image/webp']; export async function decode(file: File): Promise { - return fileToBitmap(file); + return createImageBitmapPolyfill(file); } // tslint:disable-next-line:max-line-length It’s a data URL. Whatcha gonna do? diff --git a/src/codecs/decoders.ts b/src/codecs/decoders.ts index b49a2495..e8bee398 100644 --- a/src/codecs/decoders.ts +++ b/src/codecs/decoders.ts @@ -1,9 +1,7 @@ -import * as browserJPEG from './browser-jpeg/decoder'; -import * as browserPNG from './browser-png/decoder'; -import * as browserWebP from './browser-webp/decoder'; import * as wasmWebP from './webp/decoder'; +import * as browserWebP from './browser-webp/decoder'; -import { sniffMimeType } from '../lib/util'; +import { createImageBitmapPolyfill, sniffMimeType } from '../lib/util'; export interface Decoder { name: string; @@ -15,10 +13,8 @@ export interface Decoder { // We load all decoders and filter out the unsupported ones. export const decodersPromise: Promise = Promise.all( [ - browserPNG, - browserJPEG, - wasmWebP, browserWebP, + wasmWebP, ] .map(async (decoder) => { if (await decoder.isSupported()) { @@ -38,3 +34,25 @@ export async function findDecoder(file: File): Promise { } return decoders.find(decoder => decoder.canHandleMimeType(mimeType)); } + +const nativelySupportedMimeTypes = [ + 'image/jpeg', + 'image/png', + 'image/gif', +]; + +export async function decodeFile(file: File): Promise { + const mimeType = await sniffMimeType(file); + if (!mimeType) { + throw new Error('Could not determine mime type'); + } + if (nativelySupportedMimeTypes.includes(mimeType)) { + return createImageBitmapPolyfill(file); + } + const decoder = await findDecoder(file); + if (!decoder) { + throw new Error(`Can’t decode files with mime type ${mimeType}`); + } + console.log(`Going with ${decoder.name}`); + return decoder.decode(file); +} diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 9cfc88a2..d11f83d5 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -26,7 +26,7 @@ import { encoderMap, } from '../../codecs/encoders'; -import { findDecoder } from '../../codecs/decoders'; +import { decodeFile } from '../../codecs/decoders'; interface SourceImage { file: File; @@ -180,11 +180,7 @@ export default class App extends Component { async updateFile(file: File) { this.setState({ loading: true }); try { - const decoder = await findDecoder(file); - if (!decoder) { - throw new Error('Can’t find a decoder for the given file'); - } - const bmp = await decoder.decode(file); + const bmp = await decodeFile(file); // compute the corresponding ImageData once since it only changes when the file changes: const data = await bitmapToImageData(bmp); diff --git a/src/lib/util.ts b/src/lib/util.ts index 1a35eb02..c3a6f5a4 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -105,10 +105,6 @@ export function canDecodeImage(data: string): Promise { }); } -export function fileToBitmap(file: File): Promise { - return createImageBitmap(file); -} - export function blobToArrayBuffer(blob: Blob): Promise { return new Promise((resolve) => { const fileReader = new FileReader(); @@ -143,3 +139,7 @@ export async function sniffMimeType(blob: Blob): Promise { } } } + +export function createImageBitmapPolyfill(blob: Blob): Promise { + return createImageBitmap(blob); +}