<commit_before>// @flow

import { BOOL } from "constants/controlTypes";
import { cloneCanvas, fillBufferPixel, getBufferIndex } from "utils";

export const optionTypes = {
  invertAlpha: { type: BOOL, default: false }
};

export const defaults = {
  invertAlpha: optionTypes.invertAlpha.default
};

const invert = (
  input: HTMLCanvasElement,
  options: { invertAlpha: boolean } = defaults
): HTMLCanvasElement => {
  const output = cloneCanvas(input, false);
  const inputCtx = input.getContext("2d");
  const outputCtx = output.getContext("2d");

  if (!inputCtx || !outputCtx) return input;

  const buf = inputCtx.getImageData(0, 0, input.width, input.height).data;

  for (let x = 0; x < input.width; x += 1) {
    for (let y = 0; y < input.height; y += 1) {
      const i = getBufferIndex(x, y, input.width);
      const r = 255 - buf[i];
      const g = 255 - buf[i + 1];
      const b = 255 - buf[i + 2];
      const a = options.invertAlpha ? 255 - buf[i + 3] : buf[i + 3];
      fillBufferPixel(buf, i, r, g, b, a);
    }
  }

  outputCtx.putImageData(new ImageData(buf, output.width, output.height), 0, 0);
  return output;
};

export default {
  name: "Invert",
  func: invert,
  options: defaults,
  optionTypes,
  defaults
};
<commit_msg>Make invert colour-aware<commit_after>// @flow

import { BOOL } from "constants/controlTypes";
import { cloneCanvas, fillBufferPixel, getBufferIndex } from "utils";

export const optionTypes = {
  invertR: { type: BOOL, default: true },
  invertG: { type: BOOL, default: true },
  invertB: { type: BOOL, default: true },
  invertA: { type: BOOL, default: false }
};

export const defaults = {
  invertR: optionTypes.invertR.default,
  invertG: optionTypes.invertG.default,
  invertB: optionTypes.invertB.default,
  invertA: optionTypes.invertA.default
};

const invert = (
  input: HTMLCanvasElement,
  options: {
    invertR: boolean,
    invertG: boolean,
    invertB: boolean,
    invertA: boolean
  } = defaults
): HTMLCanvasElement => {
  const output = cloneCanvas(input, false);
  const inputCtx = input.getContext("2d");
  const outputCtx = output.getContext("2d");

  if (!inputCtx || !outputCtx) return input;

  const buf = inputCtx.getImageData(0, 0, input.width, input.height).data;

  for (let x = 0; x < input.width; x += 1) {
    for (let y = 0; y < input.height; y += 1) {
      const i = getBufferIndex(x, y, input.width);
      const r = options.invertR ? 255 - buf[i] : buf[i];
      const g = options.invertG ? 255 - buf[i + 1] : buf[i + 1];
      const b = options.invertB ? 255 - buf[i + 2] : buf[i + 2];
      const a = options.invertA ? 255 - buf[i + 3] : buf[i + 3];
      fillBufferPixel(buf, i, r, g, b, a);
    }
  }

  outputCtx.putImageData(new ImageData(buf, output.width, output.height), 0, 0);
  return output;
};

export default {
  name: "Invert",
  func: invert,
  options: defaults,
  optionTypes,
  defaults
};

{'fraction_non_alphanumeric': 0.14369400413507927, 'fraction_numerical': 0.018607856650585803, 'mean_word_length': 3.371987951807229, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6848810', 'n_tokens_mistral': 1060, 'n_tokens_neox': 1008, 'n_words': 281}