# Overview

    library(bitstreamio)

`bitstreamio` is a package for reading bits from a connection or raw vector.

This package has no requirement that reads/write operations be byte aligned.

Reading/writing bits and unaligned bytes is useful for input/output with packed binary file formats e.g. h264-compressed video, mp3 audio etc.

In addition to reading individual bits, this package also provides for:

- Reading/writing unaligned bytes as raw vectors
- Reading/writing unsigned integers (i.e. non-negative integers) at bit depths from 1 to 31
- Read/write signed/unsigned integers with Exponential-Golomb coding

## What’s in the box

- Read write: bits, bytes, unsigned integers, integers coded with exponential golomb (signed and unsigned variants).
  - `bs_write_bit()`, `bs_read_bit()`
  - `bs_write_byte()`, `bs_read_byte()`
  - `bs_write_uint()`, `bs_read_uint()`
  - `bs_write_uint_exp_golomb()`, `bs_read_uint_exp_golomb()`
  - `bs_write_sint_exp_golomb()`, `bs_read_sint_exp_golomb()`
- Bitstream utilities
  - `bs_open()`, `bs_close()`
  - `bs_is_aligned()`, `bs_align()`
  - `bs_advance()`, `bs_peek()`

## Read/Write with a raw vector

    library(bitstreamio)

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Write bits to a raw vector
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    bs <- bs_open(raw(), "w")
    bs_write_bit(bs, c(TRUE , FALSE, FALSE, FALSE))
    bs_write_byte(bs, c(0x01, 0x7f))  # write unaligned byte values
    bs_write_bit(bs, c(FALSE, FALSE, FALSE, TRUE))

    raw_vec <- bs_close(bs)
    raw_vec
    #> [1] 80 17 f1

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Read bits back from raw vector
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    bs <- bs_open(raw_vec, mode = 'r')
    bs_read_bit(bs, 4)
    #> [1]  TRUE FALSE FALSE FALSE
    bs_read_byte(bs, 2) # unaligned byte read
    #> [1] 01 7f
    bs_read_bit(bs, 4)
    #> [1] FALSE FALSE FALSE  TRUE
    bs_close(bs)

## Reading/Write with a connection

    filename <- tempfile()

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Write bits to a file
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    con <- file(filename, "wb")
    bs  <- bs_open(con, mode = 'w')

    bs_write_bit(bs, c(TRUE , FALSE, FALSE, FALSE))
    bs_write_byte(bs, c(1, 127))
    bs_write_bit(bs, c(FALSE, FALSE, FALSE, TRUE))

    bs_close(bs)
    close(con)

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Read the bits back in
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    con <- file(filename, "rb")
    bs  <- bs_open(con, mode = 'r')

    bs_read_bit(bs, 4)
    #> [1]  TRUE FALSE FALSE FALSE
    bs_read_uint(bs, nbits = 8, n = 2)
    #> [1]   1 127
    bs_read_bit(bs, 4)
    #> [1] FALSE FALSE FALSE  TRUE

    bs_close(bs)
    close(con)

## Read/write unsigned integers at varying bit depths

    library(bitstreamio)

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Write bits to a raw vector
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    bs <- bs_open(raw(), "w")
    bs_write_uint(bs,  0:7 , nbits = 3) # write 8 * 3-bit integers
    bs_write_uint(bs, 10:15, nbits = 4) # write 6 * 4-bit integers
    raw_vec <- bs_close(bs)
    raw_vec
    #> [1] 05 39 77 ab cd ef

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Read bits back from raw vector
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    bs <- bs_open(raw_vec, mode = 'r')
    bs_read_uint(bs, nbits = 3, n = 8)
    #> [1] 0 1 2 3 4 5 6 7
    bs_read_uint(bs, nbits = 4, n = 6)
    #> [1] 10 11 12 13 14 15
    bs_close(bs)

## Read/write integers with Exponential-Golomb coding

Exponential-Golomb coding is a way of encoding integers to bit sequences. These bit sequences are often smaller than any standard integer type, and are often used to save space when packing data into a stream when the size of the integer is not known ahead of time.

    # Converstion of unsigned integers to Exponential-Golomb coded bit sequences
    uint_to_exp_golomb_bits(0)
    #> [1] TRUE
    uint_to_exp_golomb_bits(1)
    #> [1] FALSE  TRUE FALSE
    uint_to_exp_golomb_bits(2)
    #> [1] FALSE  TRUE  TRUE
    uint_to_exp_golomb_bits(3)
    #> [1] FALSE FALSE  TRUE FALSE FALSE

    # Converstion of signed integers to Exponential-Golomb coded bit sequences
    sint_to_exp_golomb_bits(0)
    #> [1] TRUE
    sint_to_exp_golomb_bits(-1)
    #> [1] FALSE  TRUE  TRUE
    sint_to_exp_golomb_bits(-2)
    #> [1] FALSE FALSE  TRUE FALSE  TRUE
    sint_to_exp_golomb_bits(3)
    #> [1] FALSE FALSE  TRUE  TRUE FALSE

    library(bitstreamio)

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Write bits to a raw vector
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    bs <- bs_open(raw(), "w")
    bs_write_uint_exp_golomb(bs,  0:9)
    raw_vec <- bs_close(bs)

    # 10 integers encoded into 6 bytes
    raw_vec
    #> [1] a6 42 98 e2 04 8a

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Read bits back from raw vector
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    bs <- bs_open(raw_vec, mode = 'r')
    bs_read_uint_exp_golomb(bs, 10)
    #>  [1] 0 1 2 3 4 5 6 7 8 9
    bs_close(bs)