2014-04-11 Marc Glisse <marc.glisse@inria.fr>
[official-gcc.git] / libgo / go / image / png / paeth.go
blob37978aa662d75befa9130f778874e71360eb7928
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package png
7 // paeth implements the Paeth filter function, as per the PNG specification.
8 func paeth(a, b, c uint8) uint8 {
9 // This is an optimized version of the sample code in the PNG spec.
10 // For example, the sample code starts with:
11 // p := int(a) + int(b) - int(c)
12 // pa := abs(p - int(a))
13 // but the optimized form uses fewer arithmetic operations:
14 // pa := int(b) - int(c)
15 // pa = abs(pa)
16 pc := int(c)
17 pa := int(b) - pc
18 pb := int(a) - pc
19 pc = pa + pb
20 if pa < 0 {
21 pa = -pa
23 if pb < 0 {
24 pb = -pb
26 if pc < 0 {
27 pc = -pc
29 if pa <= pb && pa <= pc {
30 return a
31 } else if pb <= pc {
32 return b
34 return c
37 // filterPaeth applies the Paeth filter to the cdat slice.
38 // cdat is the current row's data, pdat is the previous row's data.
39 func filterPaeth(cdat, pdat []byte, bytesPerPixel int) {
40 var a, b, c, pa, pb, pc int
41 for i := 0; i < bytesPerPixel; i++ {
42 a, c = 0, 0
43 for j := i; j < len(cdat); j += bytesPerPixel {
44 b = int(pdat[j])
45 pa = b - c
46 pb = a - c
47 pc = pa + pb
48 if pa < 0 {
49 pa = -pa
51 if pb < 0 {
52 pb = -pb
54 if pc < 0 {
55 pc = -pc
57 if pa <= pb && pa <= pc {
58 // No-op.
59 } else if pb <= pc {
60 a = b
61 } else {
62 a = c
64 a += int(cdat[j])
65 a &= 0xff
66 cdat[j] = uint8(a)
67 c = b