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

100.00% Branches 9/9
100.00% Lines 40/40
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
x3
 
x3
x3
x3
x3
x3
 
x41
x41
x41
 
 
x41
x41
x82
x2164
x2164
x2164
x2164
x82
 
x41
x41
x41
x41
x41
x41
x72
x72
 
x41
x41
 
x41
x41
x82
x82
x2164
x2164
x2164
x1119390
x1119390
x2164
x82
 
x41
x41














































import { filterTypes } from "../_common_filter.ts";

export function filter(
  output: Uint8Array<ArrayBuffer>,
  colorType: number,
  pSize: number,
  images: Uint8Array<ArrayBuffer>[][],
): number {
  images = images.filter((x) => x.filter((x) => x.length).length);
  const o = output.length -
    images.reduce((x, y) => x + y.reduce((x, y) => x + y.length, y.length), 0);

  // Shift lines forward in the output buffer to make space for the filter type.
  let offset = o + 1;
  for (let i = 0; i < images.length; ++i) {
    for (let j = 0; j < images[i].length; ++j) {
      output.set(images[i][j], offset);
      images[i][j] = output.subarray(offset, offset + images[i][j].length);
      offset += images[i][j].length + 1;
    }
  }

  let index = 0;
  switch (colorType) {
    case 0:
    case 2:
    case 4:
    case 6:
      index = 4;
      break;
      // default: // 3
  }
  const typeFn = filterTypes[index];

  offset = output.length;
  for (let i = images.length - 1; i >= 0; --i) {
    const lines = images[i];
    for (let y = lines.length - 1; y >= 0; --y) {
      offset -= lines[y].length + 1;
      output[offset] = index;
      for (let x = lines[y].length - 1; x >= 0; --x) {
        lines[y][x] -= typeFn(lines, x, y, pSize);
      }
    }
  }

  return o;
}