diff --git a/src/features/preprocessors/crop/shared/meta.ts b/src/features/preprocessors/crop/shared/meta.ts
new file mode 100644
index 00000000..fc37d1bf
--- /dev/null
+++ b/src/features/preprocessors/crop/shared/meta.ts
@@ -0,0 +1,25 @@
+/**
+ * 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 {
+ left: number;
+ right: number;
+ top: number;
+ bottom: number;
+}
+
+export const defaultOptions: Options = {
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0,
+};
diff --git a/src/features/preprocessors/crop/shared/missing-types.d.ts b/src/features/preprocessors/crop/shared/missing-types.d.ts
new file mode 100644
index 00000000..c729fd74
--- /dev/null
+++ b/src/features/preprocessors/crop/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/preprocessors/crop/worker/crop.ts b/src/features/preprocessors/crop/worker/crop.ts
new file mode 100644
index 00000000..2d65c466
--- /dev/null
+++ b/src/features/preprocessors/crop/worker/crop.ts
@@ -0,0 +1,63 @@
+/**
+ * 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.
+ */
+import { Options } from '../shared/meta';
+
+export default async function crop(
+ data: ImageData,
+ opts: Options,
+): Promise {
+ const { left, top, right, bottom } = opts;
+ const source = data.data;
+ const { width, height } = data;
+ const cols = width * 4;
+
+ const newWidth = width - left - right;
+ const newHeight = height - top - bottom;
+ const len = newWidth * newHeight * 4;
+ const pixels = new Uint8ClampedArray(len);
+
+ for (let y = 0; y < newHeight; y++) {
+ for (let x = 0; x < newWidth; x++) {
+ let i = y * cols + x * 4;
+ let j = (top + y) * cols + (left + x) * 4;
+ pixels[i] = source[j];
+ pixels[i + 1] = source[j + 1];
+ pixels[i + 2] = source[j + 2];
+ pixels[i + 3] = source[j + 3];
+ }
+ }
+
+ // let sourceX = left;
+ // let sourceY = top;
+ // let x = 0;
+ // let y = 0;
+ // let i = 0;
+ // while (i < len) {
+ // let from = sourceY * cols + sourceX * 4;
+
+ // pixels[i++] = source[from++];
+ // pixels[i++] = source[from++];
+ // pixels[i++] = source[from++];
+ // pixels[i++] = source[from];
+
+ // if (++x === newWidth) {
+ // x = 0;
+ // y++;
+
+ // sourceX = left;
+ // sourceY++;
+ // }
+ // }
+
+ return new ImageData(pixels, newWidth, newHeight);
+}
diff --git a/src/features/preprocessors/crop/worker/missing-types.d.ts b/src/features/preprocessors/crop/worker/missing-types.d.ts
new file mode 100644
index 00000000..c729fd74
--- /dev/null
+++ b/src/features/preprocessors/crop/worker/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/preprocessors/flip/shared/meta.ts b/src/features/preprocessors/flip/shared/meta.ts
new file mode 100644
index 00000000..aa45a540
--- /dev/null
+++ b/src/features/preprocessors/flip/shared/meta.ts
@@ -0,0 +1,21 @@
+/**
+ * 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 {
+ horizontal: boolean;
+ vertical: boolean;
+}
+
+export const defaultOptions: Options = {
+ horizontal: false,
+ vertical: false,
+};
diff --git a/src/features/preprocessors/flip/shared/missing-types.d.ts b/src/features/preprocessors/flip/shared/missing-types.d.ts
new file mode 100644
index 00000000..c729fd74
--- /dev/null
+++ b/src/features/preprocessors/flip/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/preprocessors/flip/worker/flip.ts b/src/features/preprocessors/flip/worker/flip.ts
new file mode 100644
index 00000000..e66cc471
--- /dev/null
+++ b/src/features/preprocessors/flip/worker/flip.ts
@@ -0,0 +1,68 @@
+/**
+ * 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.
+ */
+import { Options } from '../shared/meta';
+
+export default async function flip(
+ data: ImageData,
+ opts: Options,
+): Promise {
+ const { vertical, horizontal } = opts;
+ const source = data.data;
+ const len = source.length;
+ const pixels = new Uint8ClampedArray(len);
+ const { width, height } = data;
+
+ let i = 0;
+ let x = 0;
+ let y = 0;
+ const cols = width * 4;
+ while (i < len) {
+ let from = vertical ? (height - y) * cols + x * 4 : i;
+ if (horizontal) from = from - x * 4 + cols - x * 4; // todo: reduce
+
+ pixels[i++] = source[from++];
+ pixels[i++] = source[from++];
+ pixels[i++] = source[from++];
+ pixels[i++] = source[from];
+
+ if (++x === width) {
+ x = 0;
+ y++;
+ }
+ }
+
+ /*
+ function swap(a: number, b: number) {
+ let tmp = pixels[a];
+ pixels[a] = pixels[b];
+ pixels[b] = tmp;
+ }
+ function swapRgba(a: number, b: number) {
+ swap(a, b);
+ swap(a+1, b+1);
+ swap(a+2, b+2);
+ swap(a+3, b+3);
+ }
+ const COLS = data.width * 4;
+ // for (let y = 0, y2 = (data.height - 1); y < y2; y+=4, y2-=4) {
+ for (let y = 0; y < data.height; y++) {
+ for (let x = 0, x2 = COLS - 4; x < x2; x+=4, x2-=4) {
+ const offsetX = y * COLS;
+ const offsetY = (opts.vertical ? (data.height - y) : y) * COLS;
+ const flippedX = opts.horizontal ? x2 : x;
+ swapRgba(offsetX + x, offsetY + x2);
+ }
+ }
+ */
+ return new ImageData(pixels, data.width, data.height);
+}
diff --git a/src/features/preprocessors/flip/worker/missing-types.d.ts b/src/features/preprocessors/flip/worker/missing-types.d.ts
new file mode 100644
index 00000000..c729fd74
--- /dev/null
+++ b/src/features/preprocessors/flip/worker/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.
+ */
+///