aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/image/vp8/filter.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/image/vp8/filter.go')
-rw-r--r--vendor/golang.org/x/image/vp8/filter.go273
1 files changed, 0 insertions, 273 deletions
diff --git a/vendor/golang.org/x/image/vp8/filter.go b/vendor/golang.org/x/image/vp8/filter.go
deleted file mode 100644
index e34a811..0000000
--- a/vendor/golang.org/x/image/vp8/filter.go
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package vp8
-
-// filter2 modifies a 2-pixel wide or 2-pixel high band along an edge.
-func filter2(pix []byte, level, index, iStep, jStep int) {
- for n := 16; n > 0; n, index = n-1, index+iStep {
- p1 := int(pix[index-2*jStep])
- p0 := int(pix[index-1*jStep])
- q0 := int(pix[index+0*jStep])
- q1 := int(pix[index+1*jStep])
- if abs(p0-q0)<<1+abs(p1-q1)>>1 > level {
- continue
- }
- a := 3*(q0-p0) + clamp127(p1-q1)
- a1 := clamp15((a + 4) >> 3)
- a2 := clamp15((a + 3) >> 3)
- pix[index-1*jStep] = clamp255(p0 + a2)
- pix[index+0*jStep] = clamp255(q0 - a1)
- }
-}
-
-// filter246 modifies a 2-, 4- or 6-pixel wide or high band along an edge.
-func filter246(pix []byte, n, level, ilevel, hlevel, index, iStep, jStep int, fourNotSix bool) {
- for ; n > 0; n, index = n-1, index+iStep {
- p3 := int(pix[index-4*jStep])
- p2 := int(pix[index-3*jStep])
- p1 := int(pix[index-2*jStep])
- p0 := int(pix[index-1*jStep])
- q0 := int(pix[index+0*jStep])
- q1 := int(pix[index+1*jStep])
- q2 := int(pix[index+2*jStep])
- q3 := int(pix[index+3*jStep])
- if abs(p0-q0)<<1+abs(p1-q1)>>1 > level {
- continue
- }
- if abs(p3-p2) > ilevel ||
- abs(p2-p1) > ilevel ||
- abs(p1-p0) > ilevel ||
- abs(q1-q0) > ilevel ||
- abs(q2-q1) > ilevel ||
- abs(q3-q2) > ilevel {
- continue
- }
- if abs(p1-p0) > hlevel || abs(q1-q0) > hlevel {
- // Filter 2 pixels.
- a := 3*(q0-p0) + clamp127(p1-q1)
- a1 := clamp15((a + 4) >> 3)
- a2 := clamp15((a + 3) >> 3)
- pix[index-1*jStep] = clamp255(p0 + a2)
- pix[index+0*jStep] = clamp255(q0 - a1)
- } else if fourNotSix {
- // Filter 4 pixels.
- a := 3 * (q0 - p0)
- a1 := clamp15((a + 4) >> 3)
- a2 := clamp15((a + 3) >> 3)
- a3 := (a1 + 1) >> 1
- pix[index-2*jStep] = clamp255(p1 + a3)
- pix[index-1*jStep] = clamp255(p0 + a2)
- pix[index+0*jStep] = clamp255(q0 - a1)
- pix[index+1*jStep] = clamp255(q1 - a3)
- } else {
- // Filter 6 pixels.
- a := clamp127(3*(q0-p0) + clamp127(p1-q1))
- a1 := (27*a + 63) >> 7
- a2 := (18*a + 63) >> 7
- a3 := (9*a + 63) >> 7
- pix[index-3*jStep] = clamp255(p2 + a3)
- pix[index-2*jStep] = clamp255(p1 + a2)
- pix[index-1*jStep] = clamp255(p0 + a1)
- pix[index+0*jStep] = clamp255(q0 - a1)
- pix[index+1*jStep] = clamp255(q1 - a2)
- pix[index+2*jStep] = clamp255(q2 - a3)
- }
- }
-}
-
-// simpleFilter implements the simple filter, as specified in section 15.2.
-func (d *Decoder) simpleFilter() {
- for mby := 0; mby < d.mbh; mby++ {
- for mbx := 0; mbx < d.mbw; mbx++ {
- f := d.perMBFilterParams[d.mbw*mby+mbx]
- if f.level == 0 {
- continue
- }
- l := int(f.level)
- yIndex := (mby*d.img.YStride + mbx) * 16
- if mbx > 0 {
- filter2(d.img.Y, l+4, yIndex, d.img.YStride, 1)
- }
- if f.inner {
- filter2(d.img.Y, l, yIndex+0x4, d.img.YStride, 1)
- filter2(d.img.Y, l, yIndex+0x8, d.img.YStride, 1)
- filter2(d.img.Y, l, yIndex+0xc, d.img.YStride, 1)
- }
- if mby > 0 {
- filter2(d.img.Y, l+4, yIndex, 1, d.img.YStride)
- }
- if f.inner {
- filter2(d.img.Y, l, yIndex+d.img.YStride*0x4, 1, d.img.YStride)
- filter2(d.img.Y, l, yIndex+d.img.YStride*0x8, 1, d.img.YStride)
- filter2(d.img.Y, l, yIndex+d.img.YStride*0xc, 1, d.img.YStride)
- }
- }
- }
-}
-
-// normalFilter implements the normal filter, as specified in section 15.3.
-func (d *Decoder) normalFilter() {
- for mby := 0; mby < d.mbh; mby++ {
- for mbx := 0; mbx < d.mbw; mbx++ {
- f := d.perMBFilterParams[d.mbw*mby+mbx]
- if f.level == 0 {
- continue
- }
- l, il, hl := int(f.level), int(f.ilevel), int(f.hlevel)
- yIndex := (mby*d.img.YStride + mbx) * 16
- cIndex := (mby*d.img.CStride + mbx) * 8
- if mbx > 0 {
- filter246(d.img.Y, 16, l+4, il, hl, yIndex, d.img.YStride, 1, false)
- filter246(d.img.Cb, 8, l+4, il, hl, cIndex, d.img.CStride, 1, false)
- filter246(d.img.Cr, 8, l+4, il, hl, cIndex, d.img.CStride, 1, false)
- }
- if f.inner {
- filter246(d.img.Y, 16, l, il, hl, yIndex+0x4, d.img.YStride, 1, true)
- filter246(d.img.Y, 16, l, il, hl, yIndex+0x8, d.img.YStride, 1, true)
- filter246(d.img.Y, 16, l, il, hl, yIndex+0xc, d.img.YStride, 1, true)
- filter246(d.img.Cb, 8, l, il, hl, cIndex+0x4, d.img.CStride, 1, true)
- filter246(d.img.Cr, 8, l, il, hl, cIndex+0x4, d.img.CStride, 1, true)
- }
- if mby > 0 {
- filter246(d.img.Y, 16, l+4, il, hl, yIndex, 1, d.img.YStride, false)
- filter246(d.img.Cb, 8, l+4, il, hl, cIndex, 1, d.img.CStride, false)
- filter246(d.img.Cr, 8, l+4, il, hl, cIndex, 1, d.img.CStride, false)
- }
- if f.inner {
- filter246(d.img.Y, 16, l, il, hl, yIndex+d.img.YStride*0x4, 1, d.img.YStride, true)
- filter246(d.img.Y, 16, l, il, hl, yIndex+d.img.YStride*0x8, 1, d.img.YStride, true)
- filter246(d.img.Y, 16, l, il, hl, yIndex+d.img.YStride*0xc, 1, d.img.YStride, true)
- filter246(d.img.Cb, 8, l, il, hl, cIndex+d.img.CStride*0x4, 1, d.img.CStride, true)
- filter246(d.img.Cr, 8, l, il, hl, cIndex+d.img.CStride*0x4, 1, d.img.CStride, true)
- }
- }
- }
-}
-
-// filterParam holds the loop filter parameters for a macroblock.
-type filterParam struct {
- // The first three fields are thresholds used by the loop filter to smooth
- // over the edges and interior of a macroblock. level is used by both the
- // simple and normal filters. The inner level and high edge variance level
- // are only used by the normal filter.
- level, ilevel, hlevel uint8
- // inner is whether the inner loop filter cannot be optimized out as a
- // no-op for this particular macroblock.
- inner bool
-}
-
-// computeFilterParams computes the loop filter parameters, as specified in
-// section 15.4.
-func (d *Decoder) computeFilterParams() {
- for i := range d.filterParams {
- baseLevel := d.filterHeader.level
- if d.segmentHeader.useSegment {
- baseLevel = d.segmentHeader.filterStrength[i]
- if d.segmentHeader.relativeDelta {
- baseLevel += d.filterHeader.level
- }
- }
-
- for j := range d.filterParams[i] {
- p := &d.filterParams[i][j]
- p.inner = j != 0
- level := baseLevel
- if d.filterHeader.useLFDelta {
- // The libwebp C code has a "TODO: only CURRENT is handled for now."
- level += d.filterHeader.refLFDelta[0]
- if j != 0 {
- level += d.filterHeader.modeLFDelta[0]
- }
- }
- if level <= 0 {
- p.level = 0
- continue
- }
- if level > 63 {
- level = 63
- }
- ilevel := level
- if d.filterHeader.sharpness > 0 {
- if d.filterHeader.sharpness > 4 {
- ilevel >>= 2
- } else {
- ilevel >>= 1
- }
- if x := int8(9 - d.filterHeader.sharpness); ilevel > x {
- ilevel = x
- }
- }
- if ilevel < 1 {
- ilevel = 1
- }
- p.ilevel = uint8(ilevel)
- p.level = uint8(2*level + ilevel)
- if d.frameHeader.KeyFrame {
- if level < 15 {
- p.hlevel = 0
- } else if level < 40 {
- p.hlevel = 1
- } else {
- p.hlevel = 2
- }
- } else {
- if level < 15 {
- p.hlevel = 0
- } else if level < 20 {
- p.hlevel = 1
- } else if level < 40 {
- p.hlevel = 2
- } else {
- p.hlevel = 3
- }
- }
- }
- }
-}
-
-// intSize is either 32 or 64.
-const intSize = 32 << (^uint(0) >> 63)
-
-func abs(x int) int {
- // m := -1 if x < 0. m := 0 otherwise.
- m := x >> (intSize - 1)
-
- // In two's complement representation, the negative number
- // of any number (except the smallest one) can be computed
- // by flipping all the bits and add 1. This is faster than
- // code with a branch.
- // See Hacker's Delight, section 2-4.
- return (x ^ m) - m
-}
-
-func clamp15(x int) int {
- if x < -16 {
- return -16
- }
- if x > 15 {
- return 15
- }
- return x
-}
-
-func clamp127(x int) int {
- if x < -128 {
- return -128
- }
- if x > 127 {
- return 127
- }
- return x
-}
-
-func clamp255(x int) uint8 {
- if x < 0 {
- return 0
- }
- if x > 255 {
- return 255
- }
- return uint8(x)
-}