bits

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package bits reads a bit stream MSB-first or LSB-first.

PDF has two kinds of packed data that a byte reader cannot address. Image samples below 8 bits per component are packed several to a byte, so a 1-bit bilevel image stores eight pixels in one byte and a 4-bit one stores two — and a row's last byte is padded, because every row starts on a byte boundary (ISO 32000-2 §8.9.5.1). The bit-stream codecs, CCITT G3/G4 and JBIG2, are built on variable-length prefix codes that straddle byte boundaries by design.

Both orders exist because both occur: image samples and CCITT's default are MSB-first, while CCITT's /BlackIs1-adjacent LSB variant and some JBIG2 contexts are not. Making the order a parameter rather than shipping two readers keeps the callers identical.

This package is stdlib-only and knows nothing about PDF. It sits below filter (docs/DESIGN.md §4) so that the codecs above it share one implementation of the thing they all get wrong independently.

Index

Constants

This section is empty.

Variables

View Source
var ErrEOF = errors.New("bits: end of data")

ErrEOF reports a read past the end of the data.

Distinct from io.EOF because this is not a stream: the caller knows how many bits it expects, and running out means the input is truncated. Returning io.EOF would invite callers to treat it as normal termination, which for a half-read prefix code it is not.

Functions

This section is empty.

Types

type Order

type Order int

Order is the direction bits are consumed within each byte.

const (
	// MSB takes bit 7 of each byte first. This is PDF's image-sample packing and
	// CCITT's usual order.
	MSB Order = iota

	// LSB takes bit 0 of each byte first.
	LSB
)

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader reads bits from a byte slice.

The zero value is not usable; use NewReader. The slice is borrowed, not copied: image data is routinely tens of megabytes and the caller already holds it.

func NewReader

func NewReader(data []byte, order Order) *Reader

NewReader returns a Reader over data.

func (*Reader) Align

func (r *Reader) Align()

Align discards the rest of the current byte.

This is the per-row call an image unpacker makes: a row of samples occupies a whole number of bytes with the remainder padded, so a 5-pixel 1-bit row is one byte and the next row starts at the next. Without it every row after the first would be shifted by the padding, which produces a recognizable but progressively skewed image — a failure that looks like a decoder bug rather than an alignment one.

A no-op when already aligned, so a caller can invoke it per row without checking.

func (*Reader) Bit

func (r *Reader) Bit() (uint32, error)

Bit returns the next bit as 0 or 1.

func (*Reader) Bits

func (r *Reader) Bits(n uint) (uint32, error)

Bits returns the next n bits, the first bit read being the most significant of the result. n must be 0 to 32.

The result is assembled most-significant-first regardless of Order, because Order describes how bits are laid out in the input, not how a multi-bit value is composed. A 4-bit image sample read LSB-first is still the number the producer wrote; reversing it here would make every caller reverse it back.

func (*Reader) Remaining

func (r *Reader) Remaining() int

Remaining returns the number of bits not yet read.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL