...

Source file src/golang.org/x/image/vp8/filter.go

Documentation: golang.org/x/image/vp8

     1  // Copyright 2014 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 vp8
     6  
     7  // filter2 modifies a 2-pixel wide or 2-pixel high band along an edge.
     8  func filter2(pix []byte, level, index, iStep, jStep int) {
     9  	for n := 16; n > 0; n, index = n-1, index+iStep {
    10  		p1 := int(pix[index-2*jStep])
    11  		p0 := int(pix[index-1*jStep])
    12  		q0 := int(pix[index+0*jStep])
    13  		q1 := int(pix[index+1*jStep])
    14  		if abs(p0-q0)<<1+abs(p1-q1)>>1 > level {
    15  			continue
    16  		}
    17  		a := 3*(q0-p0) + clamp127(p1-q1)
    18  		a1 := clamp15((a + 4) >> 3)
    19  		a2 := clamp15((a + 3) >> 3)
    20  		pix[index-1*jStep] = clamp255(p0 + a2)
    21  		pix[index+0*jStep] = clamp255(q0 - a1)
    22  	}
    23  }
    24  
    25  // filter246 modifies a 2-, 4- or 6-pixel wide or high band along an edge.
    26  func filter246(pix []byte, n, level, ilevel, hlevel, index, iStep, jStep int, fourNotSix bool) {
    27  	for ; n > 0; n, index = n-1, index+iStep {
    28  		p3 := int(pix[index-4*jStep])
    29  		p2 := int(pix[index-3*jStep])
    30  		p1 := int(pix[index-2*jStep])
    31  		p0 := int(pix[index-1*jStep])
    32  		q0 := int(pix[index+0*jStep])
    33  		q1 := int(pix[index+1*jStep])
    34  		q2 := int(pix[index+2*jStep])
    35  		q3 := int(pix[index+3*jStep])
    36  		if abs(p0-q0)<<1+abs(p1-q1)>>1 > level {
    37  			continue
    38  		}
    39  		if abs(p3-p2) > ilevel ||
    40  			abs(p2-p1) > ilevel ||
    41  			abs(p1-p0) > ilevel ||
    42  			abs(q1-q0) > ilevel ||
    43  			abs(q2-q1) > ilevel ||
    44  			abs(q3-q2) > ilevel {
    45  			continue
    46  		}
    47  		if abs(p1-p0) > hlevel || abs(q1-q0) > hlevel {
    48  			// Filter 2 pixels.
    49  			a := 3*(q0-p0) + clamp127(p1-q1)
    50  			a1 := clamp15((a + 4) >> 3)
    51  			a2 := clamp15((a + 3) >> 3)
    52  			pix[index-1*jStep] = clamp255(p0 + a2)
    53  			pix[index+0*jStep] = clamp255(q0 - a1)
    54  		} else if fourNotSix {
    55  			// Filter 4 pixels.
    56  			a := 3 * (q0 - p0)
    57  			a1 := clamp15((a + 4) >> 3)
    58  			a2 := clamp15((a + 3) >> 3)
    59  			a3 := (a1 + 1) >> 1
    60  			pix[index-2*jStep] = clamp255(p1 + a3)
    61  			pix[index-1*jStep] = clamp255(p0 + a2)
    62  			pix[index+0*jStep] = clamp255(q0 - a1)
    63  			pix[index+1*jStep] = clamp255(q1 - a3)
    64  		} else {
    65  			// Filter 6 pixels.
    66  			a := clamp127(3*(q0-p0) + clamp127(p1-q1))
    67  			a1 := (27*a + 63) >> 7
    68  			a2 := (18*a + 63) >> 7
    69  			a3 := (9*a + 63) >> 7
    70  			pix[index-3*jStep] = clamp255(p2 + a3)
    71  			pix[index-2*jStep] = clamp255(p1 + a2)
    72  			pix[index-1*jStep] = clamp255(p0 + a1)
    73  			pix[index+0*jStep] = clamp255(q0 - a1)
    74  			pix[index+1*jStep] = clamp255(q1 - a2)
    75  			pix[index+2*jStep] = clamp255(q2 - a3)
    76  		}
    77  	}
    78  }
    79  
    80  // simpleFilter implements the simple filter, as specified in section 15.2.
    81  func (d *Decoder) simpleFilter() {
    82  	for mby := 0; mby < d.mbh; mby++ {
    83  		for mbx := 0; mbx < d.mbw; mbx++ {
    84  			f := d.perMBFilterParams[d.mbw*mby+mbx]
    85  			if f.level == 0 {
    86  				continue
    87  			}
    88  			l := int(f.level)
    89  			yIndex := (mby*d.img.YStride + mbx) * 16
    90  			if mbx > 0 {
    91  				filter2(d.img.Y, l+4, yIndex, d.img.YStride, 1)
    92  			}
    93  			if f.inner {
    94  				filter2(d.img.Y, l, yIndex+0x4, d.img.YStride, 1)
    95  				filter2(d.img.Y, l, yIndex+0x8, d.img.YStride, 1)
    96  				filter2(d.img.Y, l, yIndex+0xc, d.img.YStride, 1)
    97  			}
    98  			if mby > 0 {
    99  				filter2(d.img.Y, l+4, yIndex, 1, d.img.YStride)
   100  			}
   101  			if f.inner {
   102  				filter2(d.img.Y, l, yIndex+d.img.YStride*0x4, 1, d.img.YStride)
   103  				filter2(d.img.Y, l, yIndex+d.img.YStride*0x8, 1, d.img.YStride)
   104  				filter2(d.img.Y, l, yIndex+d.img.YStride*0xc, 1, d.img.YStride)
   105  			}
   106  		}
   107  	}
   108  }
   109  
   110  // normalFilter implements the normal filter, as specified in section 15.3.
   111  func (d *Decoder) normalFilter() {
   112  	for mby := 0; mby < d.mbh; mby++ {
   113  		for mbx := 0; mbx < d.mbw; mbx++ {
   114  			f := d.perMBFilterParams[d.mbw*mby+mbx]
   115  			if f.level == 0 {
   116  				continue
   117  			}
   118  			l, il, hl := int(f.level), int(f.ilevel), int(f.hlevel)
   119  			yIndex := (mby*d.img.YStride + mbx) * 16
   120  			cIndex := (mby*d.img.CStride + mbx) * 8
   121  			if mbx > 0 {
   122  				filter246(d.img.Y, 16, l+4, il, hl, yIndex, d.img.YStride, 1, false)
   123  				filter246(d.img.Cb, 8, l+4, il, hl, cIndex, d.img.CStride, 1, false)
   124  				filter246(d.img.Cr, 8, l+4, il, hl, cIndex, d.img.CStride, 1, false)
   125  			}
   126  			if f.inner {
   127  				filter246(d.img.Y, 16, l, il, hl, yIndex+0x4, d.img.YStride, 1, true)
   128  				filter246(d.img.Y, 16, l, il, hl, yIndex+0x8, d.img.YStride, 1, true)
   129  				filter246(d.img.Y, 16, l, il, hl, yIndex+0xc, d.img.YStride, 1, true)
   130  				filter246(d.img.Cb, 8, l, il, hl, cIndex+0x4, d.img.CStride, 1, true)
   131  				filter246(d.img.Cr, 8, l, il, hl, cIndex+0x4, d.img.CStride, 1, true)
   132  			}
   133  			if mby > 0 {
   134  				filter246(d.img.Y, 16, l+4, il, hl, yIndex, 1, d.img.YStride, false)
   135  				filter246(d.img.Cb, 8, l+4, il, hl, cIndex, 1, d.img.CStride, false)
   136  				filter246(d.img.Cr, 8, l+4, il, hl, cIndex, 1, d.img.CStride, false)
   137  			}
   138  			if f.inner {
   139  				filter246(d.img.Y, 16, l, il, hl, yIndex+d.img.YStride*0x4, 1, d.img.YStride, true)
   140  				filter246(d.img.Y, 16, l, il, hl, yIndex+d.img.YStride*0x8, 1, d.img.YStride, true)
   141  				filter246(d.img.Y, 16, l, il, hl, yIndex+d.img.YStride*0xc, 1, d.img.YStride, true)
   142  				filter246(d.img.Cb, 8, l, il, hl, cIndex+d.img.CStride*0x4, 1, d.img.CStride, true)
   143  				filter246(d.img.Cr, 8, l, il, hl, cIndex+d.img.CStride*0x4, 1, d.img.CStride, true)
   144  			}
   145  		}
   146  	}
   147  }
   148  
   149  // filterParam holds the loop filter parameters for a macroblock.
   150  type filterParam struct {
   151  	// The first three fields are thresholds used by the loop filter to smooth
   152  	// over the edges and interior of a macroblock. level is used by both the
   153  	// simple and normal filters. The inner level and high edge variance level
   154  	// are only used by the normal filter.
   155  	level, ilevel, hlevel uint8
   156  	// inner is whether the inner loop filter cannot be optimized out as a
   157  	// no-op for this particular macroblock.
   158  	inner bool
   159  }
   160  
   161  // computeFilterParams computes the loop filter parameters, as specified in
   162  // section 15.4.
   163  func (d *Decoder) computeFilterParams() {
   164  	for i := range d.filterParams {
   165  		baseLevel := d.filterHeader.level
   166  		if d.segmentHeader.useSegment {
   167  			baseLevel = d.segmentHeader.filterStrength[i]
   168  			if d.segmentHeader.relativeDelta {
   169  				baseLevel += d.filterHeader.level
   170  			}
   171  		}
   172  
   173  		for j := range d.filterParams[i] {
   174  			p := &d.filterParams[i][j]
   175  			p.inner = j != 0
   176  			level := baseLevel
   177  			if d.filterHeader.useLFDelta {
   178  				// The libwebp C code has a "TODO: only CURRENT is handled for now."
   179  				level += d.filterHeader.refLFDelta[0]
   180  				if j != 0 {
   181  					level += d.filterHeader.modeLFDelta[0]
   182  				}
   183  			}
   184  			if level <= 0 {
   185  				p.level = 0
   186  				continue
   187  			}
   188  			if level > 63 {
   189  				level = 63
   190  			}
   191  			ilevel := level
   192  			if d.filterHeader.sharpness > 0 {
   193  				if d.filterHeader.sharpness > 4 {
   194  					ilevel >>= 2
   195  				} else {
   196  					ilevel >>= 1
   197  				}
   198  				if x := int8(9 - d.filterHeader.sharpness); ilevel > x {
   199  					ilevel = x
   200  				}
   201  			}
   202  			if ilevel < 1 {
   203  				ilevel = 1
   204  			}
   205  			p.ilevel = uint8(ilevel)
   206  			p.level = uint8(2*level + ilevel)
   207  			if d.frameHeader.KeyFrame {
   208  				if level < 15 {
   209  					p.hlevel = 0
   210  				} else if level < 40 {
   211  					p.hlevel = 1
   212  				} else {
   213  					p.hlevel = 2
   214  				}
   215  			} else {
   216  				if level < 15 {
   217  					p.hlevel = 0
   218  				} else if level < 20 {
   219  					p.hlevel = 1
   220  				} else if level < 40 {
   221  					p.hlevel = 2
   222  				} else {
   223  					p.hlevel = 3
   224  				}
   225  			}
   226  		}
   227  	}
   228  }
   229  
   230  // intSize is either 32 or 64.
   231  const intSize = 32 << (^uint(0) >> 63)
   232  
   233  func abs(x int) int {
   234  	// m := -1 if x < 0. m := 0 otherwise.
   235  	m := x >> (intSize - 1)
   236  
   237  	// In two's complement representation, the negative number
   238  	// of any number (except the smallest one) can be computed
   239  	// by flipping all the bits and add 1. This is faster than
   240  	// code with a branch.
   241  	// See Hacker's Delight, section 2-4.
   242  	return (x ^ m) - m
   243  }
   244  
   245  func clamp15(x int) int {
   246  	if x < -16 {
   247  		return -16
   248  	}
   249  	if x > 15 {
   250  		return 15
   251  	}
   252  	return x
   253  }
   254  
   255  func clamp127(x int) int {
   256  	if x < -128 {
   257  		return -128
   258  	}
   259  	if x > 127 {
   260  		return 127
   261  	}
   262  	return x
   263  }
   264  
   265  func clamp255(x int) uint8 {
   266  	if x < 0 {
   267  		return 0
   268  	}
   269  	if x > 255 {
   270  		return 255
   271  	}
   272  	return uint8(x)
   273  }
   274  

View as plain text