diff --git a/in-progress/README.md b/in-progress/README.md deleted file mode 100644 index 25ee41ec..00000000 --- a/in-progress/README.md +++ /dev/null @@ -1 +0,0 @@ -The compress folder was moved from src/client/lazy-app. diff --git a/lib/feature-plugin.js b/lib/feature-plugin.js index 058d519d..a976a246 100644 --- a/lib/feature-plugin.js +++ b/lib/feature-plugin.js @@ -22,7 +22,7 @@ const autoGenComment = export default function () { let previousWorkerImports; - let previousEncoderMetas; + let previousJoinedMetas; /** * Generates the worker file & tsconfig for all features @@ -134,7 +134,7 @@ export default function () { const joinedWorkerImports = workerImports.join(); // Avoid regenerating if nothing's changed. - // This also prevents an infinite look in the watcher. + // This also prevents an infinite loop in the watcher. if (joinedWorkerImports === previousWorkerImports) return; previousWorkerImports = joinedWorkerImports; @@ -153,6 +153,14 @@ export default function () { .filter((tsFile) => !tsFile.endsWith('.d.ts')) .map((tsFile) => tsFile.slice(0, -'.ts'.length)); + const processorMetas = ( + await globP('src/features/processors/*/shared/meta.ts', { + absolute: true, + }) + ) + .filter((tsFile) => !tsFile.endsWith('.d.ts')) + .map((tsFile) => tsFile.slice(0, -'.ts'.length)); + const featureMetaBasePath = path.join( process.cwd(), 'src', @@ -161,20 +169,24 @@ export default function () { 'feature-meta', ); - const joinedEncoderMetas = encoderMetas.join(); + const joinedMetas = [...encoderMetas, ...processorMetas].join(); // Avoid regenerating if nothing's changed. - // This also prevents an infinite look in the watcher. - if (joinedEncoderMetas === previousEncoderMetas) return; - previousEncoderMetas = joinedEncoderMetas; + // This also prevents an infinite loop in the watcher. + if (joinedMetas === previousJoinedMetas) return; + previousJoinedMetas = joinedMetas; - const encoderMetaTsNames = encoderMetas.map((tsImport) => [ + const getTsName = (tsImport) => [ path.relative(featureMetaBasePath, tsImport), path.basename(tsImport.slice(0, -'/shared/meta'.length)), - ]); + ]; + + const encoderMetaTsNames = encoderMetas.map(getTsName); + const processorMetaTsNames = processorMetas.map(getTsName); const featureMeta = [ autoGenComment, + // Encoder stuff encoderMetaTsNames.map( ([path, name]) => `import * as ${name}EncoderMeta from '${path}';`, ), @@ -194,6 +206,22 @@ export default function () { `};`, `export type EncoderType = keyof typeof encoderMap`, `export const encoders = [...Object.values(encoderMap)];`, + // Processor stuff + processorMetaTsNames.map( + ([path, name]) => `import * as ${name}ProcessorMeta from '${path}';`, + ), + `interface Enableable { enabled: boolean; }`, + `export interface ProcessorState {`, + processorMetaTsNames.map( + ([_, name]) => ` ${name}: Enableable & ${name}ProcessorMeta.Options;`, + ), + `}`, + `export const defaultProcessorState: ProcessorState = {`, + processorMetaTsNames.map( + ([_, name]) => + ` ${name}: { enabled: false, ...${name}ProcessorMeta.defaultOptions },`, + ), + `}`, ] .flat(Infinity) .join('\n'); diff --git a/in-progress/Compress/custom-els/MultiPanel/index.ts b/src/client/lazy-app/Compress/custom-els/MultiPanel/index.ts similarity index 100% rename from in-progress/Compress/custom-els/MultiPanel/index.ts rename to src/client/lazy-app/Compress/custom-els/MultiPanel/index.ts diff --git a/in-progress/Compress/custom-els/MultiPanel/missing-types.d.ts b/src/client/lazy-app/Compress/custom-els/MultiPanel/missing-types.d.ts similarity index 100% rename from in-progress/Compress/custom-els/MultiPanel/missing-types.d.ts rename to src/client/lazy-app/Compress/custom-els/MultiPanel/missing-types.d.ts diff --git a/in-progress/Compress/custom-els/MultiPanel/styles.css b/src/client/lazy-app/Compress/custom-els/MultiPanel/styles.css similarity index 100% rename from in-progress/Compress/custom-els/MultiPanel/styles.css rename to src/client/lazy-app/Compress/custom-els/MultiPanel/styles.css diff --git a/in-progress/Compress/index.tsx b/src/client/lazy-app/Compress/index.tsx similarity index 100% rename from in-progress/Compress/index.tsx rename to src/client/lazy-app/Compress/index.tsx diff --git a/in-progress/Compress/result-cache.ts b/src/client/lazy-app/Compress/result-cache.ts similarity index 82% rename from in-progress/Compress/result-cache.ts rename to src/client/lazy-app/Compress/result-cache.ts index 839b499d..bfb110dd 100644 --- a/in-progress/Compress/result-cache.ts +++ b/src/client/lazy-app/Compress/result-cache.ts @@ -1,6 +1,5 @@ -import { EncoderState } from '../feature-meta'; -import { shallowEqual } from '../../lib/util'; -import { PreprocessorState } from '../../codecs/preprocessors'; +import { EncoderState, ProcessorState } from '../feature-meta'; +import { shallowEqual } from '../../util'; import * as identity from '../../codecs/identity/encoder-meta'; @@ -11,7 +10,7 @@ interface CacheResult { } interface CacheEntry extends CacheResult { - preprocessorState: PreprocessorState; + processorState: ProcessorState; encoderState: EncoderState; sourceData: ImageData; } @@ -32,7 +31,7 @@ export default class ResultCache { match( sourceData: ImageData, - preprocessorState: PreprocessorState, + processorState: ProcessorState, encoderState: EncoderState, ): CacheResult | undefined { const matchingIndex = this._entries.findIndex((entry) => { @@ -41,11 +40,11 @@ export default class ResultCache { if (entry.encoderState.type !== encoderState.type) return false; // Check that each set of options in the preprocessor are the same - for (const prop in preprocessorState) { + for (const prop in processorState) { if ( !shallowEqual( - (preprocessorState as any)[prop], - (entry.preprocessorState as any)[prop], + (processorState as any)[prop], + (entry.processorState as any)[prop], ) ) return false; diff --git a/in-progress/Compress/style.scss b/src/client/lazy-app/Compress/style.scss similarity index 100% rename from in-progress/Compress/style.scss rename to src/client/lazy-app/Compress/style.scss diff --git a/src/client/lazy-app/util.ts b/src/client/lazy-app/util.ts index dc3180e7..b583f016 100644 --- a/src/client/lazy-app/util.ts +++ b/src/client/lazy-app/util.ts @@ -59,3 +59,13 @@ export async function abortable( }), ]); } + +/** + * Compare two objects, returning a boolean indicating if they have the same properties and strictly + * equal values. + */ +export function shallowEqual(one: any, two: any) { + for (const i in one) if (one[i] !== two[i]) return false; + for (const i in two) if (!(i in one)) return false; + return true; +} diff --git a/src/features/processors/quantize/shared/meta.ts b/src/features/processors/quantize/shared/meta.ts new file mode 100644 index 00000000..410c49a6 --- /dev/null +++ b/src/features/processors/quantize/shared/meta.ts @@ -0,0 +1,23 @@ +/** + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export interface Options { + zx: number; + maxNumColors: number; + dither: number; +} + +export const defaultOptions: Options = { + zx: 0, + maxNumColors: 256, + dither: 1.0, +}; diff --git a/src/features/processors/quantize/shared/missing-types.d.ts b/src/features/processors/quantize/shared/missing-types.d.ts new file mode 100644 index 00000000..c729fd74 --- /dev/null +++ b/src/features/processors/quantize/shared/missing-types.d.ts @@ -0,0 +1,13 @@ +/** + * Copyright 2020 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/// diff --git a/src/features/processors/quantize/shared/tsconfig.json b/src/features/processors/quantize/shared/tsconfig.json new file mode 100644 index 00000000..bea39d16 --- /dev/null +++ b/src/features/processors/quantize/shared/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../../../generic-tsconfig.json", + "compilerOptions": { + "lib": ["webworker", "esnext"] + }, + "references": [{ "path": "../../../" }] +} diff --git a/src/features/processors/quantize/worker/quantize.ts b/src/features/processors/quantize/worker/quantize.ts index 41377a59..9d2db9f6 100644 --- a/src/features/processors/quantize/worker/quantize.ts +++ b/src/features/processors/quantize/worker/quantize.ts @@ -13,18 +13,13 @@ import imagequant, { QuantizerModule } from 'codecs/imagequant/imagequant'; import wasmUrl from 'url:codecs/imagequant/imagequant.wasm'; import { initEmscriptenModule } from 'features/util'; - -export interface QuantizeOptions { - zx: number; - maxNumColors: number; - dither: number; -} +import { Options } from '../shared/meta'; let emscriptenModule: Promise; export default async function process( data: ImageData, - opts: QuantizeOptions, + opts: Options, ): Promise { if (!emscriptenModule) { emscriptenModule = initEmscriptenModule(imagequant, wasmUrl); diff --git a/src/features/processors/quantize/worker/tsconfig.json b/src/features/processors/quantize/worker/tsconfig.json index bea39d16..959fe910 100644 --- a/src/features/processors/quantize/worker/tsconfig.json +++ b/src/features/processors/quantize/worker/tsconfig.json @@ -3,5 +3,5 @@ "compilerOptions": { "lib": ["webworker", "esnext"] }, - "references": [{ "path": "../../../" }] + "references": [{ "path": "../../../" }, { "path": "../shared" }] } diff --git a/src/features/processors/resize/client/index.ts b/src/features/processors/resize/client/index.ts index 523ef508..c8a554c3 100644 --- a/src/features/processors/resize/client/index.ts +++ b/src/features/processors/resize/client/index.ts @@ -3,7 +3,7 @@ import { BuiltinResizeMethod, drawableToImageData, } from 'client/util'; -import { BrowserResizeOptions, VectorResizeOptions } from '../shared'; +import { BrowserResizeOptions, VectorResizeOptions } from '../shared/meta'; import { getContainOffsets } from '../shared/util'; export function browserResize( diff --git a/src/features/processors/resize/shared/index.ts b/src/features/processors/resize/shared/meta.ts similarity index 80% rename from src/features/processors/resize/shared/index.ts rename to src/features/processors/resize/shared/meta.ts index 2a5f6df4..a83a9768 100644 --- a/src/features/processors/resize/shared/index.ts +++ b/src/features/processors/resize/shared/meta.ts @@ -23,7 +23,7 @@ type WorkerResizeMethods = | 'lanczos3' | 'hqx'; -export type ResizeOptions = +export type Options = | BrowserResizeOptions | WorkerResizeOptions | VectorResizeOptions; @@ -47,3 +47,15 @@ export interface WorkerResizeOptions extends ResizeOptionsCommon { export interface VectorResizeOptions extends ResizeOptionsCommon { method: 'vector'; } + +export const defaultOptions: Options = { + // Width and height will always default to the image size. + // This is set elsewhere. + width: 1, + height: 1, + // This will be set to 'vector' if the input is SVG. + method: 'lanczos3', + fitMethod: 'stretch', + premultiply: true, + linearRGB: true, +}; diff --git a/src/features/processors/resize/worker/resize.ts b/src/features/processors/resize/worker/resize.ts index 28fbaa96..72fc8ab8 100644 --- a/src/features/processors/resize/worker/resize.ts +++ b/src/features/processors/resize/worker/resize.ts @@ -1,4 +1,4 @@ -import type { WorkerResizeOptions } from '../shared'; +import type { WorkerResizeOptions } from '../shared/meta'; import { getContainOffsets } from '../shared/util'; import initResizeWasm, { resize as wasmResize } from 'codecs/resize/pkg'; import resizeWasmUrl from 'url:codecs/resize/pkg/squoosh_resize_bg.wasm';