github.com/bluenviron/mediacommon@v1.9.3/pkg/codecs/av1/leb128.go (about)

     1  package av1
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  // LEB128Unmarshal decodes an unsigned integer from the LEB128 format.
     8  // Specification: https://aomediacodec.github.io/av1-spec/#leb128
     9  func LEB128Unmarshal(buf []byte) (uint, int, error) {
    10  	v := uint(0)
    11  	n := 0
    12  
    13  	for i := 0; i < 8; i++ {
    14  		if len(buf) == 0 {
    15  			return 0, 0, fmt.Errorf("not enough bytes")
    16  		}
    17  
    18  		b := buf[0]
    19  
    20  		v |= (uint(b&0b01111111) << (i * 7))
    21  		n++
    22  
    23  		if (b & 0b10000000) == 0 {
    24  			break
    25  		}
    26  
    27  		buf = buf[1:]
    28  	}
    29  
    30  	return v, n, nil
    31  }
    32  
    33  // LEB128MarshalSize returns the marshal size of an unsigned integer in LEB128 format.
    34  // Specification: https://aomediacodec.github.io/av1-spec/#leb128
    35  func LEB128MarshalSize(v uint) int {
    36  	n := 0
    37  
    38  	for {
    39  		v >>= 7
    40  		n++
    41  
    42  		if v <= 0 {
    43  			break
    44  		}
    45  	}
    46  
    47  	return n
    48  }
    49  
    50  // LEB128MarshalTo encodes an unsigned integer with the LEB128 format.
    51  // Specification: https://aomediacodec.github.io/av1-spec/#leb128
    52  func LEB128MarshalTo(v uint, buf []byte) int {
    53  	n := 0
    54  
    55  	for {
    56  		curbyte := byte(v) & 0b01111111
    57  		v >>= 7
    58  
    59  		if v <= 0 {
    60  			buf[n] = curbyte
    61  			n++
    62  			break
    63  		}
    64  
    65  		curbyte |= 0b10000000
    66  		buf[n] = curbyte
    67  		n++
    68  	}
    69  
    70  	return n
    71  }