// Copyright 2019 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.

//go:generate go run gen.go

// Package ccitt implements a CCITT (fax) image decoder.
package ccitt

import (
	"encoding/binary"
	"errors"
	"image"
	"io"
	"math/bits"
)

var (
	errInvalidBounds           = errors.New("ccitt: invalid bounds")
	errInvalidCode             = errors.New("ccitt: invalid code")
	errInvalidMode             = errors.New("ccitt: invalid mode")
	errInvalidOffset           = errors.New("ccitt: invalid offset")
	errMissingEOL              = errors.New("ccitt: missing End-of-Line")
	errRunLengthOverflowsWidth = errors.New("ccitt: run length overflows width")
	errRunLengthTooLong        = errors.New("ccitt: run length too long")
	errUnsupportedMode         = errors.New("ccitt: unsupported mode")
	errUnsupportedSubFormat    = errors.New("ccitt: unsupported sub-format")
	errUnsupportedWidth        = errors.New("ccitt: unsupported width")
)

// Order specifies the bit ordering in a CCITT data stream.
type Order uint32

const (
	// LSB means Least Significant Bits first.
	LSB Order = iota
	// MSB means Most Significant Bits first.
	MSB
)

// SubFormat represents that the CCITT format consists of a number of
// sub-formats. Decoding or encoding a CCITT data stream requires knowing the
// sub-format context. It is not represented in the data stream per se.
type SubFormat uint32

const (
	Group3 SubFormat = iota
	Group4
)

// Options are optional parameters.
type Options struct {
	// Align means that some variable-bit-width codes are byte-aligned.
	Align bool
	// Invert means that black is the 1 bit or 0xFF byte, and white is 0.
	Invert bool
}

// maxWidth is the maximum (inclusive) supported width. This is a limitation of
// this implementation, to guard against integer overflow, and not anything
// inherent to the CCITT format.
const maxWidth = 1 << 20

func invertBytes(b []byte) {
	for i, c := range b {
		b[i] = ^c
	}
}

func reverseBitsWithinBytes(b []byte) {
	for i, c := range b {
		b[i] = bits.Reverse8(c)
	}
}

type bitReader struct {
	r io.Reader

	// readErr is the error returned from the most recent r.Read call. As the
	// io.Reader documentation says, when r.Read returns (n, err), "always
	// process the n > 0 bytes returned before considering the error err".
	readErr error

	// order is whether to process r's bytes LSB first or MSB first.
	order Order

	// The low nBits bits of the bits field hold upcoming bits in LSB order.
	bits  uint64
	nBits uint32

	// bytes[br:bw] holds bytes read from r but not yet loaded into bits.
	br    uint32
	bw    uint32
	bytes [1024]uint8
}

func (b *bitReader) alignToByteBoundary() {
	n := b.nBits & 7
	b.bits >>= n
	b.nBits -= n
}

// nextBitMaxNBits is the maximum possible value of bitReader.nBits after a
// bitReader.nextBit call, provided that bitReader.nBits was not more than this
// value before that call.
//
// Note that the decode function can unread bits, which can temporarily set the
// bitReader.nBits value above nextBitMaxNBits.
const nextBitMaxNBits = 31

func (b *bitReader) nextBit() (uint32, error) {
	for {
		if b.nBits > 0 {
			bit := uint32(b.bits) & 1
			b.bits >>= 1
			b.nBits--
			return bit, nil
		}

		if available := b.bw - b.br; available >= 4 {
			// Read 32 bits, even though b.bits is a uint64, since the decode
			// function may need to unread up to maxCodeLength bits, putting
			// them back in the remaining (64 - 32) bits. TestMaxCodeLength
			// checks that the generated maxCodeLength constant fits.
			//
			// If changing the Uint32 call, also change nextBitMaxNBits.
			b.bits = uint64(binary.LittleEndian.Uint32(b.bytes[b.br:]))
			b.br += 4
			b.nBits = 32
			continue
		} else if available > 0 {
			b.bits = uint64(b.bytes[b.br])
			b.br++
			b.nBits = 8
			continue
		}

		if b.readErr != nil {
			return 0, b.readErr
		}

		n, err := b.r.Read(b.bytes[:])
		b.br = 0
		b.bw = uint32(n)
		b.readErr = err

		if b.order != LSB {
			reverseBitsWithinBytes(b.bytes[:b.bw])
		}
	}
}

func decode(b *bitReader, decodeTable [][2]int16) (uint32, error) {
	nBitsRead, bitsRead, state := uint32(0), uint32(0), int32(1)
	for {
		bit, err := b.nextBit()
		if err != nil {
			return 0, err
		}
		bitsRead |= bit << nBitsRead
		nBitsRead++
		// The "&1" is redundant, but can eliminate a bounds check.
		state = int32(decodeTable[state][bit&1])
		if state < 0 {
			return uint32(^state), nil
		} else if state == 0 {
			// Unread the bits we've read, then return errInvalidCode.
			b.bits = (b.bits << nBitsRead) | uint64(bitsRead)
			b.nBits += nBitsRead
			return 0, errInvalidCode
		}
	}
}

type reader struct {
	br        bitReader
	subFormat SubFormat

	// width is the image width in pixels.
	width int

	// rowsRemaining starts at the image height in pixels, when the reader is
	// driven through the io.Reader interface, and decrements to zero as rows
	// are decoded. When driven through DecodeIntoGray, this field is unused.
	rowsRemaining int

	// curr and prev hold the current and previous rows. Each element is either
	// 0x00 (black) or 0xFF (white).
	//
	// prev may be nil, when processing the first row.
	curr []byte
	prev []byte

	// ri is the read index. curr[:ri] are those bytes of curr that have been
	// passed along via the Read method.
	//
	// When the reader is driven through DecodeIntoGray, instead of through the
	// io.Reader interface, this field is unused.
	ri int

	// wi is the write index. curr[:wi] are those bytes of curr that have
	// already been decoded via the decodeRow method.
	//
	// What this implementation calls wi is roughly equivalent to what the spec
	// calls the a0 index.
	wi int

	// These fields are copied from the *Options (which may be nil).
	align  bool
	invert bool

	// atStartOfRow is whether we have just started the row. Some parts of the
	// spec say to treat this situation as if "wi = -1".
	atStartOfRow bool

	// penColorIsWhite is whether the next run is black or white.
	penColorIsWhite bool

	// seenStartOfImage is whether we've called the startDecode method.
	seenStartOfImage bool

	// readErr is a sticky error for the Read method.
	readErr error
}

func (z *reader) Read(p []byte) (int, error) {
	if z.readErr != nil {
		return 0, z.readErr
	}
	originalP := p

	for len(p) > 0 {
		// Allocate buffers (and decode any start-of-image codes), if
		// processing the first or second row.
		if z.curr == nil {
			if !z.seenStartOfImage {
				if z.readErr = z.startDecode(); z.readErr != nil {
					break
				}
				z.atStartOfRow = true
			}
			z.curr = make([]byte, z.width)
		}

		// Decode the next row, if necessary.
		if z.atStartOfRow {
			if z.rowsRemaining <= 0 {
				if z.readErr = z.finishDecode(); z.readErr != nil {
					break
				}
				z.readErr = io.EOF
				break
			}
			if z.readErr = z.decodeRow(); z.readErr != nil {
				break
			}
			z.rowsRemaining--
		}

		// Pack from z.curr (1 byte per pixel) to p (1 bit per pixel), up to 8
		// elements per iteration.
		i := 0
		for ; i < len(p); i++ {
			numToPack := len(z.curr) - z.ri
			if numToPack <= 0 {
				break
			} else if numToPack > 8 {
				numToPack = 8
			}

			byteValue := byte(0)
			if z.invert {
				// Set the end-of-row padding bits to 1 (if inverted) or 0. If inverted, the 1s
				// are temporary, and will be flipped back to 0s by the invertBytes call below.
				byteValue = 0xFF >> uint(numToPack)
			}

			for j := 0; j < numToPack; j++ {
				byteValue |= (z.curr[z.ri] & 0x80) >> uint(j)
				z.ri++
			}
			p[i] = byteValue
		}
		p = p[i:]

		// Prepare to decode the next row, if necessary.
		if z.ri == len(z.curr) {
			z.ri, z.curr, z.prev = 0, z.prev, z.curr
			z.atStartOfRow = true
		}
	}

	n := len(originalP) - len(p)
	if z.invert {
		invertBytes(originalP[:n])
	}
	return n, z.readErr
}

func (z *reader) penColor() byte {
	if z.penColorIsWhite {
		return 0xFF
	}
	return 0x00
}

func (z *reader) startDecode() error {
	switch z.subFormat {
	case Group3:
		if err := z.decodeEOL(); err != nil {
			return err
		}

	case Group4:
		// No-op.

	default:
		return errUnsupportedSubFormat
	}

	z.seenStartOfImage = true
	return nil
}

func (z *reader) finishDecode() error {
	numberOfEOLs := 0
	switch z.subFormat {
	case Group3:
		// The stream ends with a RTC (Return To Control) of 6 consecutive
		// EOL's, but we should have already just seen an EOL, either in
		// z.startDecode (for a zero-height image) or in z.decodeRow.
		numberOfEOLs = 5

	case Group4:
		// The stream ends with two EOL's, the first of which is possibly
		// byte-aligned.
		numberOfEOLs = 2
		if err := z.decodeEOL(); err == nil {
			numberOfEOLs--
		} else if err == errInvalidCode {
			// Try again, this time starting from a byte boundary.
			z.br.alignToByteBoundary()
		} else {
			return err
		}

	default:
		return errUnsupportedSubFormat
	}

	for ; numberOfEOLs > 0; numberOfEOLs-- {
		if err := z.decodeEOL(); err != nil {
			return err
		}
	}
	return nil
}

func (z *reader) decodeEOL() error {
	// TODO: EOL doesn't have to be in the modeDecodeTable. It could be in its
	// own table, or we could just hard-code it, especially if we might need to
	// cater for optional byte-alignment, or an arbitrary number (potentially
	// more than 8) of 0-valued padding bits.
	if mode, err := decode(&z.br, modeDecodeTable[:]); err != nil {
		return err
	} else if mode != modeEOL {
		return errMissingEOL
	}
	return nil
}

func (z *reader) decodeRow() error {
	z.wi = 0
	z.atStartOfRow = true
	z.penColorIsWhite = true

	if z.align {
		z.br.alignToByteBoundary()
	}

	switch z.subFormat {
	case Group3:
		for ; z.wi < len(z.curr); z.atStartOfRow = false {
			if err := z.decodeRun(); err != nil {
				return err
			}
		}
		return z.decodeEOL()

	case Group4:
		for ; z.wi < len(z.curr); z.atStartOfRow = false {
			mode, err := decode(&z.br, modeDecodeTable[:])
			if err != nil {
				return err
			}
			rm := readerMode{}
			if mode < uint32(len(readerModes)) {
				rm = readerModes[mode]
			}
			if rm.function == nil {
				return errInvalidMode
			}
			if err := rm.function(z, rm.arg); err != nil {
				return err
			}
		}
		return nil
	}

	return errUnsupportedSubFormat
}

func (z *reader) decodeRun() error {
	table := blackDecodeTable[:]
	if z.penColorIsWhite {
		table = whiteDecodeTable[:]
	}

	total := 0
	for {
		n, err := decode(&z.br, table)
		if err != nil {
			return err
		}
		if n > maxWidth {
			panic("unreachable")
		}
		total += int(n)
		if total > maxWidth {
			return errRunLengthTooLong
		}
		// Anything 0x3F or below is a terminal code.
		if n <= 0x3F {
			break
		}
	}

	if total > (len(z.curr) - z.wi) {
		return errRunLengthOverflowsWidth
	}
	dst := z.curr[z.wi : z.wi+total]
	penColor := z.penColor()
	for i := range dst {
		dst[i] = penColor
	}
	z.wi += total
	z.penColorIsWhite = !z.penColorIsWhite

	return nil
}

// The various modes' semantics are based on determining a row of pixels'
// "changing elements": those pixels whose color differs from the one on its
// immediate left.
//
// The row above the first row is implicitly all white. Similarly, the column
// to the left of the first column is implicitly all white.
//
// For example, here's Figure 1 in "ITU-T Recommendation T.6", where the
// current and previous rows contain black (B) and white (w) pixels. The a?
// indexes point into curr, the b? indexes point into prev.
//
//                 b1 b2
//                 v  v
// prev: BBBBBwwwwwBBBwwwww
// curr: BBBwwwwwBBBBBBwwww
//          ^    ^     ^
//          a0   a1    a2
//
// a0 is the "reference element" or current decoder position, roughly
// equivalent to what this implementation calls reader.wi.
//
// a1 is the next changing element to the right of a0, on the "coding line"
// (the current row).
//
// a2 is the next changing element to the right of a1, again on curr.
//
// b1 is the first changing element on the "reference line" (the previous row)
// to the right of a0 and of opposite color to a0.
//
// b2 is the next changing element to the right of b1, again on prev.
//
// The various modes calculate a1 (and a2, for modeH):
//  - modePass calculates that a1 is at or to the right of b2.
//  - modeH    calculates a1 and a2 without considering b1 or b2.
//  - modeV*   calculates a1 to be b1 plus an adjustment (between -3 and +3).

const (
	findB1 = false
	findB2 = true
)

// findB finds either the b1 or b2 value.
func (z *reader) findB(whichB bool) int {
	// The initial row is a special case. The previous row is implicitly all
	// white, so that there are no changing pixel elements. We return b1 or b2
	// to be at the end of the row.
	if len(z.prev) != len(z.curr) {
		return len(z.curr)
	}

	i := z.wi

	if z.atStartOfRow {
		// a0 is implicitly at -1, on a white pixel. b1 is the first black
		// pixel in the previous row. b2 is the first white pixel after that.
		for ; (i < len(z.prev)) && (z.prev[i] == 0xFF); i++ {
		}
		if whichB == findB2 {
			for ; (i < len(z.prev)) && (z.prev[i] == 0x00); i++ {
			}
		}
		return i
	}

	// As per figure 1 above, assume that the current pen color is white.
	// First, walk past every contiguous black pixel in prev, starting at a0.
	oppositeColor := ^z.penColor()
	for ; (i < len(z.prev)) && (z.prev[i] == oppositeColor); i++ {
	}

	// Then walk past every contiguous white pixel.
	penColor := ^oppositeColor
	for ; (i < len(z.prev)) && (z.prev[i] == penColor); i++ {
	}

	// We're now at a black pixel (or at the end of the row). That's b1.
	if whichB == findB2 {
		// If we're looking for b2, walk past every contiguous black pixel
		// again.
		oppositeColor := ^penColor
		for ; (i < len(z.prev)) && (z.prev[i] == oppositeColor); i++ {
		}
	}

	return i
}

type readerMode struct {
	function func(z *reader, arg int) error
	arg      int
}

var readerModes = [...]readerMode{
	modePass: {function: readerModePass},
	modeH:    {function: readerModeH},
	modeV0:   {function: readerModeV, arg: +0},
	modeVR1:  {function: readerModeV, arg: +1},
	modeVR2:  {function: readerModeV, arg: +2},
	modeVR3:  {function: readerModeV, arg: +3},
	modeVL1:  {function: readerModeV, arg: -1},
	modeVL2:  {function: readerModeV, arg: -2},
	modeVL3:  {function: readerModeV, arg: -3},
	modeExt:  {function: readerModeExt},
}

func readerModePass(z *reader, arg int) error {
	b2 := z.findB(findB2)
	if (b2 < z.wi) || (len(z.curr) < b2) {
		return errInvalidOffset
	}
	dst := z.curr[z.wi:b2]
	penColor := z.penColor()
	for i := range dst {
		dst[i] = penColor
	}
	z.wi = b2
	return nil
}

func readerModeH(z *reader, arg int) error {
	// The first iteration finds a1. The second finds a2.
	for i := 0; i < 2; i++ {
		if err := z.decodeRun(); err != nil {
			return err
		}
	}
	return nil
}

func readerModeV(z *reader, arg int) error {
	a1 := z.findB(findB1) + arg
	if (a1 < z.wi) || (len(z.curr) < a1) {
		return errInvalidOffset
	}
	dst := z.curr[z.wi:a1]
	penColor := z.penColor()
	for i := range dst {
		dst[i] = penColor
	}
	z.wi = a1
	z.penColorIsWhite = !z.penColorIsWhite
	return nil
}

func readerModeExt(z *reader, arg int) error {
	return errUnsupportedMode
}

// DecodeIntoGray decodes the CCITT-formatted data in r into dst.
//
// It returns an error if dst's width and height don't match the implied width
// and height of CCITT-formatted data.
func DecodeIntoGray(dst *image.Gray, r io.Reader, order Order, sf SubFormat, opts *Options) error {
	bounds := dst.Bounds()
	if (bounds.Dx() < 0) || (bounds.Dy() < 0) {
		return errInvalidBounds
	}
	if bounds.Dx() > maxWidth {
		return errUnsupportedWidth
	}

	z := reader{
		br:        bitReader{r: r, order: order},
		subFormat: sf,
		align:     (opts != nil) && opts.Align,
		invert:    (opts != nil) && opts.Invert,
		width:     bounds.Dx(),
	}
	if err := z.startDecode(); err != nil {
		return err
	}

	width := bounds.Dx()
	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		p := (y - bounds.Min.Y) * dst.Stride
		z.curr = dst.Pix[p : p+width]
		if err := z.decodeRow(); err != nil {
			return err
		}
		z.curr, z.prev = nil, z.curr
	}

	if err := z.finishDecode(); err != nil {
		return err
	}

	if z.invert {
		for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
			p := (y - bounds.Min.Y) * dst.Stride
			invertBytes(dst.Pix[p : p+width])
		}
	}

	return nil
}

// NewReader returns an io.Reader that decodes the CCITT-formatted data in r.
// The resultant byte stream is one bit per pixel (MSB first), with 1 meaning
// white and 0 meaning black. Each row in the result is byte-aligned.
func NewReader(r io.Reader, order Order, sf SubFormat, width int, height int, opts *Options) io.Reader {
	readErr := error(nil)
	if (width < 0) || (height < 0) {
		readErr = errInvalidBounds
	} else if width > maxWidth {
		readErr = errUnsupportedWidth
	}

	return &reader{
		br:            bitReader{r: r, order: order},
		subFormat:     sf,
		align:         (opts != nil) && opts.Align,
		invert:        (opts != nil) && opts.Invert,
		width:         width,
		rowsRemaining: height,
		readErr:       readErr,
	}
}
