// Copyright 2011 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

// Each VP8 frame consists of between 2 and 9 bitstream partitions.
// Each partition is byte-aligned and is independently arithmetic-encoded.
//
// This file implements decoding a partition's bitstream, as specified in
// chapter 7. The implementation follows libwebp's approach instead of the
// specification's reference C implementation. For example, we use a look-up
// table instead of a for loop to recalibrate the encoded range.

var (
	lutShift = [127]uint8{
		7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
		3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
		2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
		2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	}
	lutRangeM1 = [127]uint8{
		127,
		127, 191,
		127, 159, 191, 223,
		127, 143, 159, 175, 191, 207, 223, 239,
		127, 135, 143, 151, 159, 167, 175, 183, 191, 199, 207, 215, 223, 231, 239, 247,
		127, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 183, 187,
		191, 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251,
		127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157,
		159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189,
		191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221,
		223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253,
	}
)

// uniformProb represents a 50% probability that the next bit is 0.
const uniformProb = 128

// partition holds arithmetic-coded bits.
type partition struct {
	// buf is the input bytes.
	buf []byte
	// r is how many of buf's bytes have been consumed.
	r int
	// rangeM1 is range minus 1, where range is in the arithmetic coding sense,
	// not the Go language sense.
	rangeM1 uint32
	// bits and nBits hold those bits shifted out of buf but not yet consumed.
	bits  uint32
	nBits uint8
	// unexpectedEOF tells whether we tried to read past buf.
	unexpectedEOF bool
}

// init initializes the partition.
func ( *partition) ( []byte) {
	.buf = 
	.r = 0
	.rangeM1 = 254
	.bits = 0
	.nBits = 0
	.unexpectedEOF = false
}

// readBit returns the next bit.
func ( *partition) ( uint8) bool {
	if .nBits < 8 {
		if .r >= len(.buf) {
			.unexpectedEOF = true
			return false
		}
		// Expression split for 386 compiler.
		 := uint32(.buf[.r])
		.bits |=  << (8 - .nBits)
		.r++
		.nBits += 8
	}
	 := (.rangeM1*uint32())>>8 + 1
	 := .bits >= <<8
	if  {
		.rangeM1 -= 
		.bits -=  << 8
	} else {
		.rangeM1 =  - 1
	}
	if .rangeM1 < 127 {
		 := lutShift[.rangeM1]
		.rangeM1 = uint32(lutRangeM1[.rangeM1])
		.bits <<= 
		.nBits -= 
	}
	return 
}

// readUint returns the next n-bit unsigned integer.
func ( *partition) (,  uint8) uint32 {
	var  uint32
	for  > 0 {
		--
		if .readBit() {
			 |= 1 << 
		}
	}
	return 
}

// readInt returns the next n-bit signed integer.
func ( *partition) (,  uint8) int32 {
	 := .readUint(, )
	 := .readBit()
	if  {
		return -int32()
	}
	return int32()
}

// readOptionalInt returns the next n-bit signed integer in an encoding
// where the likely result is zero.
func ( *partition) (,  uint8) int32 {
	if !.readBit() {
		return 0
	}
	return .readInt(, )
}