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  }