stdlibpaeth.go (1811B)
1 // Code generated by gen.go. DO NOT EDIT. 2 3 // Copyright 2012 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package png 8 9 // intSize is either 32 or 64. 10 const intSize = 32 << (^uint(0) >> 63) 11 12 func abs(x int) int { 13 // m := -1 if x < 0. m := 0 otherwise. 14 m := x >> (intSize - 1) 15 16 // In two's complement representation, the negative number 17 // of any number (except the smallest one) can be computed 18 // by flipping all the bits and add 1. This is faster than 19 // code with a branch. 20 // See Hacker's Delight, section 2-4. 21 return (x ^ m) - m 22 } 23 24 // paeth implements the Paeth filter function, as per the PNG specification. 25 func paeth(a, b, c uint8) uint8 { 26 // This is an optimized version of the sample code in the PNG spec. 27 // For example, the sample code starts with: 28 // p := int(a) + int(b) - int(c) 29 // pa := abs(p - int(a)) 30 // but the optimized form uses fewer arithmetic operations: 31 // pa := int(b) - int(c) 32 // pa = abs(pa) 33 pc := int(c) 34 pa := int(b) - pc 35 pb := int(a) - pc 36 pc = abs(pa + pb) 37 pa = abs(pa) 38 pb = abs(pb) 39 if pa <= pb && pa <= pc { 40 return a 41 } else if pb <= pc { 42 return b 43 } 44 return c 45 } 46 47 // filterPaeth applies the Paeth filter to the cdat slice. 48 // cdat is the current row's data, pdat is the previous row's data. 49 func filterPaeth(cdat, pdat []byte, bytesPerPixel int) { 50 var a, b, c, pa, pb, pc int 51 for i := 0; i < bytesPerPixel; i++ { 52 a, c = 0, 0 53 for j := i; j < len(cdat); j += bytesPerPixel { 54 b = int(pdat[j]) 55 pa = b - c 56 pb = a - c 57 pc = abs(pa + pb) 58 pa = abs(pa) 59 pb = abs(pb) 60 if pa <= pb && pa <= pc { 61 // No-op. 62 } else if pb <= pc { 63 a = b 64 } else { 65 a = c 66 } 67 a += int(cdat[j]) 68 a &= 0xff 69 cdat[j] = uint8(a) 70 c = b 71 } 72 } 73 }