1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.formats.png.scanlinefilters;
18
19 import java.io.IOException;
20
21 import org.apache.commons.imaging.ImagingException;
22
23 public class ScanlineFilterPaeth implements ScanlineFilter {
24 private final int bytesPerPixel;
25
26 public ScanlineFilterPaeth(final int bytesPerPixel) {
27 this.bytesPerPixel = bytesPerPixel;
28 }
29
30 private int paethPredictor(final int a, final int b, final int c) {
31
32 final int p = a + b - c;
33 final int pa = Math.abs(p - a);
34 final int pb = Math.abs(p - b);
35 final int pc = Math.abs(p - c);
36
37
38 if (pa <= pb && pa <= pc) {
39 return a;
40 }
41 if (pb <= pc) {
42 return b;
43 }
44 return c;
45 }
46
47 @Override
48 public void unfilter(final byte[] src, final byte[] dst, final byte[] up) throws ImagingException, IOException {
49 for (int i = 0; i < src.length; i++) {
50 int left = 0;
51 final int prevIndex = i - bytesPerPixel;
52 if (prevIndex >= 0) {
53 left = dst[prevIndex];
54 }
55
56 int above = 0;
57 if (up != null) {
58 above = up[i];
59 }
60
61
62 int upperLeft = 0;
63 if (prevIndex >= 0 && up != null) {
64 upperLeft = up[prevIndex];
65 }
66
67
68 final int paethPredictor = paethPredictor(0xff & left, 0xff & above, 0xff & upperLeft);
69
70 dst[i] = (byte) ((src[i] + paethPredictor) % 256);
71
72
73
74
75 }
76 }
77 }