// 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 vp8l implements a decoder for the VP8L lossless image format.
//
// The VP8L specification is at:
// https://developers.google.com/speed/webp/docs/riff_container
package vp8l

import (
	"bufio"
	"errors"
	"image"
	"image/color"
	"io"
)

var (
	errInvalidCodeLengths = errors.New("vp8l: invalid code lengths")
	errInvalidHuffmanTree = errors.New("vp8l: invalid Huffman tree")
)

// colorCacheMultiplier is the multiplier used for the color cache hash
// function, specified in section 4.2.3.
const colorCacheMultiplier = 0x1e35a7bd

// distanceMapTable is the look-up table for distanceMap.
var distanceMapTable = [120]uint8{
	0x18, 0x07, 0x17, 0x19, 0x28, 0x06, 0x27, 0x29, 0x16, 0x1a,
	0x26, 0x2a, 0x38, 0x05, 0x37, 0x39, 0x15, 0x1b, 0x36, 0x3a,
	0x25, 0x2b, 0x48, 0x04, 0x47, 0x49, 0x14, 0x1c, 0x35, 0x3b,
	0x46, 0x4a, 0x24, 0x2c, 0x58, 0x45, 0x4b, 0x34, 0x3c, 0x03,
	0x57, 0x59, 0x13, 0x1d, 0x56, 0x5a, 0x23, 0x2d, 0x44, 0x4c,
	0x55, 0x5b, 0x33, 0x3d, 0x68, 0x02, 0x67, 0x69, 0x12, 0x1e,
	0x66, 0x6a, 0x22, 0x2e, 0x54, 0x5c, 0x43, 0x4d, 0x65, 0x6b,
	0x32, 0x3e, 0x78, 0x01, 0x77, 0x79, 0x53, 0x5d, 0x11, 0x1f,
	0x64, 0x6c, 0x42, 0x4e, 0x76, 0x7a, 0x21, 0x2f, 0x75, 0x7b,
	0x31, 0x3f, 0x63, 0x6d, 0x52, 0x5e, 0x00, 0x74, 0x7c, 0x41,
	0x4f, 0x10, 0x20, 0x62, 0x6e, 0x30, 0x73, 0x7d, 0x51, 0x5f,
	0x40, 0x72, 0x7e, 0x61, 0x6f, 0x50, 0x71, 0x7f, 0x60, 0x70,
}

// distanceMap maps a LZ77 backwards reference distance to a two-dimensional
// pixel offset, specified in section 4.2.2.
func distanceMap(w int32, code uint32) int32 {
	if int32(code) > int32(len(distanceMapTable)) {
		return int32(code) - int32(len(distanceMapTable))
	}
	distCode := int32(distanceMapTable[code-1])
	yOffset := distCode >> 4
	xOffset := 8 - distCode&0xf
	if d := yOffset*w + xOffset; d >= 1 {
		return d
	}
	return 1
}

// decoder holds the bit-stream for a VP8L image.
type decoder struct {
	r     io.ByteReader
	bits  uint32
	nBits uint32
}

// read reads the next n bits from the decoder's bit-stream.
func (d *decoder) read(n uint32) (uint32, error) {
	for d.nBits < n {
		c, err := d.r.ReadByte()
		if err != nil {
			if err == io.EOF {
				err = io.ErrUnexpectedEOF
			}
			return 0, err
		}
		d.bits |= uint32(c) << d.nBits
		d.nBits += 8
	}
	u := d.bits & (1<<n - 1)
	d.bits >>= n
	d.nBits -= n
	return u, nil
}

// decodeTransform decodes the next transform and the width of the image after
// transformation (or equivalently, before inverse transformation), specified
// in section 3.
func (d *decoder) decodeTransform(w int32, h int32) (t transform, newWidth int32, err error) {
	t.oldWidth = w
	t.transformType, err = d.read(2)
	if err != nil {
		return transform{}, 0, err
	}
	switch t.transformType {
	case transformTypePredictor, transformTypeCrossColor:
		t.bits, err = d.read(3)
		if err != nil {
			return transform{}, 0, err
		}
		t.bits += 2
		t.pix, err = d.decodePix(nTiles(w, t.bits), nTiles(h, t.bits), 0, false)
		if err != nil {
			return transform{}, 0, err
		}
	case transformTypeSubtractGreen:
		// No-op.
	case transformTypeColorIndexing:
		nColors, err := d.read(8)
		if err != nil {
			return transform{}, 0, err
		}
		nColors++
		t.bits = 0
		switch {
		case nColors <= 2:
			t.bits = 3
		case nColors <= 4:
			t.bits = 2
		case nColors <= 16:
			t.bits = 1
		}
		w = nTiles(w, t.bits)
		pix, err := d.decodePix(int32(nColors), 1, 4*256, false)
		if err != nil {
			return transform{}, 0, err
		}
		for p := 4; p < len(pix); p += 4 {
			pix[p+0] += pix[p-4]
			pix[p+1] += pix[p-3]
			pix[p+2] += pix[p-2]
			pix[p+3] += pix[p-1]
		}
		// The spec says that "if the index is equal or larger than color_table_size,
		// the argb color value should be set to 0x00000000 (transparent black)."
		// We re-slice up to 256 4-byte pixels.
		t.pix = pix[:4*256]
	}
	return t, w, nil
}

// repeatsCodeLength is the minimum code length for repeated codes.
const repeatsCodeLength = 16

// These magic numbers are specified at the end of section 5.2.2.
// The 3-length arrays apply to code lengths >= repeatsCodeLength.
var (
	codeLengthCodeOrder = [19]uint8{
		17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
	}
	repeatBits    = [3]uint8{2, 3, 7}
	repeatOffsets = [3]uint8{3, 3, 11}
)

// decodeCodeLengths decodes a Huffman tree's code lengths which are themselves
// encoded via a Huffman tree, specified in section 5.2.2.
func (d *decoder) decodeCodeLengths(dst []uint32, codeLengthCodeLengths []uint32) error {
	h := hTree{}
	if err := h.build(codeLengthCodeLengths); err != nil {
		return err
	}

	maxSymbol := len(dst)
	useLength, err := d.read(1)
	if err != nil {
		return err
	}
	if useLength != 0 {
		n, err := d.read(3)
		if err != nil {
			return err
		}
		n = 2 + 2*n
		ms, err := d.read(n)
		if err != nil {
			return err
		}
		maxSymbol = int(ms) + 2
		if maxSymbol > len(dst) {
			return errInvalidCodeLengths
		}
	}

	prevCodeLength := uint32(0)
	for symbol := 0; symbol < len(dst); {
		if maxSymbol == 0 {
			break
		}
		maxSymbol--
		codeLength, err := h.next(d)
		if err != nil {
			return err
		}
		if codeLength < repeatsCodeLength {
			dst[symbol] = codeLength
			symbol++
			if codeLength != 0 {
				prevCodeLength = codeLength
			}
			continue
		}

		repeat, err := d.read(uint32(repeatBits[codeLength-repeatsCodeLength]))
		if err != nil {
			return err
		}
		repeat += uint32(repeatOffsets[codeLength-repeatsCodeLength])
		if symbol+int(repeat) > len(dst) {
			return errInvalidCodeLengths
		}
		// A code length of 16 repeats the previous non-zero code.
		// A code length of 17 or 18 repeats zeroes.
		cl := uint32(0)
		if codeLength == 16 {
			cl = prevCodeLength
		}
		for ; repeat > 0; repeat-- {
			dst[symbol] = cl
			symbol++
		}
	}
	return nil
}

// decodeHuffmanTree decodes a Huffman tree into h.
func (d *decoder) decodeHuffmanTree(h *hTree, alphabetSize uint32) error {
	useSimple, err := d.read(1)
	if err != nil {
		return err
	}
	if useSimple != 0 {
		nSymbols, err := d.read(1)
		if err != nil {
			return err
		}
		nSymbols++
		firstSymbolLengthCode, err := d.read(1)
		if err != nil {
			return err
		}
		firstSymbolLengthCode = 7*firstSymbolLengthCode + 1
		var symbols [2]uint32
		symbols[0], err = d.read(firstSymbolLengthCode)
		if err != nil {
			return err
		}
		if nSymbols == 2 {
			symbols[1], err = d.read(8)
			if err != nil {
				return err
			}
		}
		return h.buildSimple(nSymbols, symbols, alphabetSize)
	}

	nCodes, err := d.read(4)
	if err != nil {
		return err
	}
	nCodes += 4
	if int(nCodes) > len(codeLengthCodeOrder) {
		return errInvalidHuffmanTree
	}
	codeLengthCodeLengths := [len(codeLengthCodeOrder)]uint32{}
	for i := uint32(0); i < nCodes; i++ {
		codeLengthCodeLengths[codeLengthCodeOrder[i]], err = d.read(3)
		if err != nil {
			return err
		}
	}
	codeLengths := make([]uint32, alphabetSize)
	if err = d.decodeCodeLengths(codeLengths, codeLengthCodeLengths[:]); err != nil {
		return err
	}
	return h.build(codeLengths)
}

const (
	huffGreen    = 0
	huffRed      = 1
	huffBlue     = 2
	huffAlpha    = 3
	huffDistance = 4
	nHuff        = 5
)

// hGroup is an array of 5 Huffman trees.
type hGroup [nHuff]hTree

// decodeHuffmanGroups decodes the one or more hGroups used to decode the pixel
// data. If one hGroup is used for the entire image, then hPix and hBits will
// be zero. If more than one hGroup is used, then hPix contains the meta-image
// that maps tiles to hGroup index, and hBits contains the log-2 tile size.
func (d *decoder) decodeHuffmanGroups(w int32, h int32, topLevel bool, ccBits uint32) (
	hGroups []hGroup, hPix []byte, hBits uint32, err error) {

	maxHGroupIndex := 0
	if topLevel {
		useMeta, err := d.read(1)
		if err != nil {
			return nil, nil, 0, err
		}
		if useMeta != 0 {
			hBits, err = d.read(3)
			if err != nil {
				return nil, nil, 0, err
			}
			hBits += 2
			hPix, err = d.decodePix(nTiles(w, hBits), nTiles(h, hBits), 0, false)
			if err != nil {
				return nil, nil, 0, err
			}
			for p := 0; p < len(hPix); p += 4 {
				i := int(hPix[p])<<8 | int(hPix[p+1])
				if maxHGroupIndex < i {
					maxHGroupIndex = i
				}
			}
		}
	}
	hGroups = make([]hGroup, maxHGroupIndex+1)
	for i := range hGroups {
		for j, alphabetSize := range alphabetSizes {
			if j == 0 && ccBits > 0 {
				alphabetSize += 1 << ccBits
			}
			if err := d.decodeHuffmanTree(&hGroups[i][j], alphabetSize); err != nil {
				return nil, nil, 0, err
			}
		}
	}
	return hGroups, hPix, hBits, nil
}

const (
	nLiteralCodes  = 256
	nLengthCodes   = 24
	nDistanceCodes = 40
)

var alphabetSizes = [nHuff]uint32{
	nLiteralCodes + nLengthCodes,
	nLiteralCodes,
	nLiteralCodes,
	nLiteralCodes,
	nDistanceCodes,
}

// decodePix decodes pixel data, specified in section 5.2.2.
func (d *decoder) decodePix(w int32, h int32, minCap int32, topLevel bool) ([]byte, error) {
	// Decode the color cache parameters.
	ccBits, ccShift, ccEntries := uint32(0), uint32(0), ([]uint32)(nil)
	useColorCache, err := d.read(1)
	if err != nil {
		return nil, err
	}
	if useColorCache != 0 {
		ccBits, err = d.read(4)
		if err != nil {
			return nil, err
		}
		if ccBits < 1 || 11 < ccBits {
			return nil, errors.New("vp8l: invalid color cache parameters")
		}
		ccShift = 32 - ccBits
		ccEntries = make([]uint32, 1<<ccBits)
	}

	// Decode the Huffman groups.
	hGroups, hPix, hBits, err := d.decodeHuffmanGroups(w, h, topLevel, ccBits)
	if err != nil {
		return nil, err
	}
	hMask, tilesPerRow := int32(0), int32(0)
	if hBits != 0 {
		hMask, tilesPerRow = 1<<hBits-1, nTiles(w, hBits)
	}

	// Decode the pixels.
	if minCap < 4*w*h {
		minCap = 4 * w * h
	}
	pix := make([]byte, 4*w*h, minCap)
	p, cachedP := 0, 0
	x, y := int32(0), int32(0)
	hg, lookupHG := &hGroups[0], hMask != 0
	for p < len(pix) {
		if lookupHG {
			i := 4 * (tilesPerRow*(y>>hBits) + (x >> hBits))
			hg = &hGroups[uint32(hPix[i])<<8|uint32(hPix[i+1])]
		}

		green, err := hg[huffGreen].next(d)
		if err != nil {
			return nil, err
		}
		switch {
		case green < nLiteralCodes:
			// We have a literal pixel.
			red, err := hg[huffRed].next(d)
			if err != nil {
				return nil, err
			}
			blue, err := hg[huffBlue].next(d)
			if err != nil {
				return nil, err
			}
			alpha, err := hg[huffAlpha].next(d)
			if err != nil {
				return nil, err
			}
			pix[p+0] = uint8(red)
			pix[p+1] = uint8(green)
			pix[p+2] = uint8(blue)
			pix[p+3] = uint8(alpha)
			p += 4

			x++
			if x == w {
				x, y = 0, y+1
			}
			lookupHG = hMask != 0 && x&hMask == 0

		case green < nLiteralCodes+nLengthCodes:
			// We have a LZ77 backwards reference.
			length, err := d.lz77Param(green - nLiteralCodes)
			if err != nil {
				return nil, err
			}
			distSym, err := hg[huffDistance].next(d)
			if err != nil {
				return nil, err
			}
			distCode, err := d.lz77Param(distSym)
			if err != nil {
				return nil, err
			}
			dist := distanceMap(w, distCode)
			pEnd := p + 4*int(length)
			q := p - 4*int(dist)
			qEnd := pEnd - 4*int(dist)
			if p < 0 || len(pix) < pEnd || q < 0 || len(pix) < qEnd {
				return nil, errors.New("vp8l: invalid LZ77 parameters")
			}
			for ; p < pEnd; p, q = p+1, q+1 {
				pix[p] = pix[q]
			}

			x += int32(length)
			for x >= w {
				x, y = x-w, y+1
			}
			lookupHG = hMask != 0

		default:
			// We have a color cache lookup. First, insert previous pixels
			// into the cache. Note that VP8L assumes ARGB order, but the
			// Go image.RGBA type is in RGBA order.
			for ; cachedP < p; cachedP += 4 {
				argb := uint32(pix[cachedP+0])<<16 |
					uint32(pix[cachedP+1])<<8 |
					uint32(pix[cachedP+2])<<0 |
					uint32(pix[cachedP+3])<<24
				ccEntries[(argb*colorCacheMultiplier)>>ccShift] = argb
			}
			green -= nLiteralCodes + nLengthCodes
			if int(green) >= len(ccEntries) {
				return nil, errors.New("vp8l: invalid color cache index")
			}
			argb := ccEntries[green]
			pix[p+0] = uint8(argb >> 16)
			pix[p+1] = uint8(argb >> 8)
			pix[p+2] = uint8(argb >> 0)
			pix[p+3] = uint8(argb >> 24)
			p += 4

			x++
			if x == w {
				x, y = 0, y+1
			}
			lookupHG = hMask != 0 && x&hMask == 0
		}
	}
	return pix, nil
}

// lz77Param returns the next LZ77 parameter: a length or a distance, specified
// in section 4.2.2.
func (d *decoder) lz77Param(symbol uint32) (uint32, error) {
	if symbol < 4 {
		return symbol + 1, nil
	}
	extraBits := (symbol - 2) >> 1
	offset := (2 + symbol&1) << extraBits
	n, err := d.read(extraBits)
	if err != nil {
		return 0, nil
	}
	return offset + n + 1, nil
}

// decodeHeader decodes the VP8L header from r.
func decodeHeader(r io.Reader) (d *decoder, w int32, h int32, err error) {
	rr, ok := r.(io.ByteReader)
	if !ok {
		rr = bufio.NewReader(r)
	}
	d = &decoder{r: rr}
	magic, err := d.read(8)
	if err != nil {
		return nil, 0, 0, err
	}
	if magic != 0x2f {
		return nil, 0, 0, errors.New("vp8l: invalid header")
	}
	width, err := d.read(14)
	if err != nil {
		return nil, 0, 0, err
	}
	width++
	height, err := d.read(14)
	if err != nil {
		return nil, 0, 0, err
	}
	height++
	_, err = d.read(1) // Read and ignore the hasAlpha hint.
	if err != nil {
		return nil, 0, 0, err
	}
	version, err := d.read(3)
	if err != nil {
		return nil, 0, 0, err
	}
	if version != 0 {
		return nil, 0, 0, errors.New("vp8l: invalid version")
	}
	return d, int32(width), int32(height), nil
}

// DecodeConfig decodes the color model and dimensions of a VP8L image from r.
func DecodeConfig(r io.Reader) (image.Config, error) {
	_, w, h, err := decodeHeader(r)
	if err != nil {
		return image.Config{}, err
	}
	return image.Config{
		ColorModel: color.NRGBAModel,
		Width:      int(w),
		Height:     int(h),
	}, nil
}

// Decode decodes a VP8L image from r.
func Decode(r io.Reader) (image.Image, error) {
	d, w, h, err := decodeHeader(r)
	if err != nil {
		return nil, err
	}
	// Decode the transforms.
	var (
		nTransforms    int
		transforms     [nTransformTypes]transform
		transformsSeen [nTransformTypes]bool
		originalW      = w
	)
	for {
		more, err := d.read(1)
		if err != nil {
			return nil, err
		}
		if more == 0 {
			break
		}
		var t transform
		t, w, err = d.decodeTransform(w, h)
		if err != nil {
			return nil, err
		}
		if transformsSeen[t.transformType] {
			return nil, errors.New("vp8l: repeated transform")
		}
		transformsSeen[t.transformType] = true
		transforms[nTransforms] = t
		nTransforms++
	}
	// Decode the transformed pixels.
	pix, err := d.decodePix(w, h, 0, true)
	if err != nil {
		return nil, err
	}
	// Apply the inverse transformations.
	for i := nTransforms - 1; i >= 0; i-- {
		t := &transforms[i]
		pix = inverseTransforms[t.transformType](t, pix, h)
	}
	return &image.NRGBA{
		Pix:    pix,
		Stride: 4 * int(originalW),
		Rect:   image.Rect(0, 0, int(originalW), int(h)),
	}, nil
}
