github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/image/png/paeth.go (about) 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. 4 5 package png 6 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 22 } 23 if pb < 0 { 24 pb = -pb 25 } 26 if pc < 0 { 27 pc = -pc 28 } 29 if pa <= pb && pa <= pc { 30 return a 31 } else if pb <= pc { 32 return b 33 } 34 return c 35 } 36 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 50 } 51 if pb < 0 { 52 pb = -pb 53 } 54 if pc < 0 { 55 pc = -pc 56 } 57 if pa <= pb && pa <= pc { 58 // No-op. 59 } else if pb <= pc { 60 a = b 61 } else { 62 a = c 63 } 64 a += int(cdat[j]) 65 a &= 0xff 66 cdat[j] = uint8(a) 67 c = b 68 } 69 } 70 }