All files / internal / apng_png / encode / _to.ts

80.95% Branches 17/21
88.89% Lines 80/90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
x4
x4
x4
x4
 
x24
x41
x41
x41
 
 
 
 
 
 
 
x59
x41
x41
x41
x41
x41
 
x27
x27
x27
x32
x32
x66086
x66086
x66086
x66086
x66086
x66086
x66088
x66088
x66088
x66086
x32
x35
x35
x35
x32
 
 
x24
 
x24
x24
x24
x24
x24
 
x24
x131626
x131646
x131646
x131646
x131646
x131626
x24
 
x4
x4
 
x26
x26
x26
 
x4
x4
 
x10
x10
x131342
x131342
x131342
x10
x10
 
x4
x4
 
x10
x131598
x131598
x131598
x131598
x10
x10
 
x4
x4
x4
 
x13
x13
x65563
x65563
x13
x13











I








I




















I

I























































export function guaranteeInvisiblePixel(
  input: Uint8Array<ArrayBuffer> | Uint8ClampedArray<ArrayBuffer>,
  colors: Map<number, number>,
  forGrayscale: boolean,
): number | undefined {
  if (forGrayscale) {
    for (let y = 0; y < 256; ++y) {
      let colorExists = false;
      for (const [color, _occurances] of colors) {
        if (
          y === (color >>> 24 & 0xFF) &&
          255 === (color & 0xFF)
        ) {
          colorExists = true;
          break;
        }
      }
      if (!colorExists) {
        replaceTransparentPixels(input, y, y, y);
        return y;
      }
    }
  }
  for (let r = 0; r < 256; ++r) {
    for (let g = 0; g < 256; ++g) {
      for (let b = 0; b < 256; ++b) {
        let colorExists = false;
        for (const [color, _occurances] of colors) {
          if (
            r === (color >>> 24 & 0xFF) &&
            g === (color >>> 16 & 0xFF) &&
            b === (color >>> 8 & 0xFF) &&
            255 === (color & 0xFF)
          ) {
            colorExists = true;
            break;
          }
        }
        if (!colorExists) {
          replaceTransparentPixels(input, r, g, b);
          return ((r * 256 + g) * 256 + b) * 256;
        }
      }
    }
  }
}

function replaceTransparentPixels(
  input: Uint8Array<ArrayBuffer> | Uint8ClampedArray<ArrayBuffer>,
  r: number,
  g: number,
  b: number,
): void {
  for (let i = 0; i < input.length; i += 4) {
    if (input[i + 3] === 0) {
      input[i] = r;
      input[i + 1] = g;
      input[i + 2] = b;
    }
  }
}

export function toGrayscale(
  input: Uint8Array<ArrayBuffer> | Uint8ClampedArray<ArrayBuffer>,
): Uint8Array<ArrayBuffer> | Uint8ClampedArray<ArrayBuffer> {
  for (let i = 4; i < input.length; i += 4) input[i / 4] = input[i];
  return input.subarray(0, input.length / 4);
}

export function toGrayscaleAlpha(
  input: Uint8Array<ArrayBuffer> | Uint8ClampedArray<ArrayBuffer>,
): Uint8Array<ArrayBuffer> | Uint8ClampedArray<ArrayBuffer> {
  input[1] = input[3];
  for (let i = 4; i < input.length; i += 4) {
    input[i / 2] = input[i];
    input[i / 2 + 1] = input[i + 3];
  }
  return input.subarray(0, input.length / 2);
}

export function toTruecolor(
  input: Uint8Array<ArrayBuffer> | Uint8ClampedArray<ArrayBuffer>,
): Uint8Array<ArrayBuffer> | Uint8ClampedArray<ArrayBuffer> {
  for (let i = 4; i < input.length; i += 4) {
    input[i / 4 * 3] = input[i];
    input[i / 4 * 3 + 1] = input[i + 1];
    input[i / 4 * 3 + 2] = input[i + 2];
  }
  return input.subarray(0, input.length / 4 * 3);
}

export function toIndex(
  input: Uint8Array<ArrayBuffer> | Uint8ClampedArray<ArrayBuffer>,
  palette: Uint32Array<ArrayBuffer>,
): Uint8Array<ArrayBuffer> | Uint8ClampedArray<ArrayBuffer> {
  const view = new DataView(input.buffer, input.byteOffset, input.byteLength);
  for (let i = 0; i < input.length; i += 4) {
    input[i / 4] = palette.indexOf(view.getUint32(i));
  }
  return input.subarray(0, input.length / 4);
}