This commit is contained in:
2024-05-03 01:42:45 +02:00
parent f63799bc25
commit b8abea334d
3 changed files with 514 additions and 57 deletions
+16 -5
View File
@@ -7,7 +7,7 @@ import "core:encoding/endian"
import "core:io" import "core:io"
import "core:strings" import "core:strings"
Error :: image.Error //Error :: image.Error
//Image :: image.Image //Image :: image.Image
Options :: image.Options Options :: image.Options
@@ -130,14 +130,14 @@ read_box :: proc(img: ^Image, reader: ^Reader) -> (err: io.Error) {
} }
// if the Box has a size 0 then it's the last Box, parse it and return EOF // if the Box has a size 0 then it's the last Box, parse it and return EOF
if reader.size == 0 { if reader.box.size == 0 {
err = .EOF err = .EOF
} }
fmt.println("box size:", reader.size) fmt.println("box size:", reader.box.size)
fmt.println("type:", reader.type) fmt.println("type:", reader.box.type)
#partial switch reader.type { #partial switch reader.box.type {
case .FTYP: case .FTYP:
read_ftyp(img, reader) read_ftyp(img, reader)
case .META: case .META:
@@ -164,6 +164,8 @@ read_box :: proc(img: ^Image, reader: ^Reader) -> (err: io.Error) {
read_colr(reader) read_colr(reader)
case .IPMA: case .IPMA:
read_ipma(reader) read_ipma(reader)
case .MDAT:
read_mdat(reader)
case: case:
// Skip unknown boxes // Skip unknown boxes
skip_box(reader) skip_box(reader)
@@ -172,6 +174,15 @@ read_box :: proc(img: ^Image, reader: ^Reader) -> (err: io.Error) {
return err return err
} }
@(private)
read_mdat :: proc(reader: ^Reader) {
// TODO:
read_obu(reader)
read_obu(reader)
read_obu(reader)
read_obu(reader)
}
@(private) @(private)
read_ipma :: proc(reader: ^Reader) { read_ipma :: proc(reader: ^Reader) {
vaf, _ := read_bitfield(reader, VersionAndFlags) vaf, _ := read_bitfield(reader, VersionAndFlags)
+72 -37
View File
@@ -3,12 +3,14 @@ package avif
import "core:encoding/endian" import "core:encoding/endian"
import "core:fmt" import "core:fmt"
import "core:io" import "core:io"
import "core:math"
import "core:image"
import "core:strings" import "core:strings"
import "core:unicode/utf8" import "core:unicode/utf8"
BOX_HEADER_SIZE :: 8 // 4 for box size, 4 for box type BOX_HEADER_SIZE :: 8 // 4 for box size, 4 for box type
_BoxError :: enum { BoxError :: enum {
ReadExceedsBox, ReadExceedsBox,
} }
@@ -33,125 +35,151 @@ BoxType :: enum u32 {
CLLI = 'c' << 24 | 'l' << 16 | 'l' << 8 | 'i', // Content Light Level Info CLLI = 'c' << 24 | 'l' << 16 | 'l' << 8 | 'i', // Content Light Level Info
} }
BoxError :: union { Error :: union {
io.Error, io.Error,
_BoxError, BoxError,
OBUError,
image.General_Image_Error,
} }
Box :: struct { Box :: struct {
size: u32, size: u32,
type: BoxType, type: BoxType,
pos: i64,
} }
Reader :: struct { Reader :: struct {
using current_box: Box, box: Box,
s: []byte, // read-only buffer s: []byte, // read-only buffer
i: i64, // current reading index i: i64, // current reading index
box_pos: i64, // Byte index for the Box bits_read_in_byte: u8,
} }
reader_init :: proc(r: ^Reader, s: []byte) { reader_init :: proc(r: ^Reader, s: []byte) {
r.s = s r.s = s
r.i = 0 r.i = 0
r.box_pos = 0 r.box.pos = 0
} }
read_header :: proc(r: ^Reader) -> (err: BoxError) { read_header :: proc(r: ^Reader) -> (err: Error) {
r.box_pos = 0 r.box.pos = 0
r.size = read_u32be(r) or_return r.box.size = read_u32be(r) or_return
type := read_u32be(r) or_return type := read_u32be(r) or_return
r.type = transmute(BoxType)type r.box.type = transmute(BoxType)type
return err return err
} }
read_byte :: proc(r: ^Reader) -> (byte, BoxError) { read_bit :: proc(r: ^Reader) -> (bit: byte, err: Error) {
if r.i >= i64(len(r.s)) { if r.i >= i64(len(r.s)) {
return 0, .EOF return 0, .EOF
} }
if r.box_pos >= i64(r.size) { if r.box.size != 0 && r.box.pos >= i64(r.box.size) {
return 0, .ReadExceedsBox
}
byte := r.s[r.i]
// Get the bit that's after however many bits read starting from the MSB in the byte
bits := 8 - (r.bits_read_in_byte + 1)
b := (r.s[r.i:r.i+1][0] & auto_cast math.pow2_f32(bits)) >> bits
r.bits_read_in_byte += 1
if r.bits_read_in_byte == 8 {
r.i += 1
r.box.pos += 1
r.bits_read_in_byte = 0
}
return b, nil
}
read_byte :: proc(r: ^Reader) -> (byte, Error) {
if r.i >= i64(len(r.s)) {
return 0, .EOF
}
if r.box.size != 0 && r.box.pos >= i64(r.box.size) {
return 0, .ReadExceedsBox return 0, .ReadExceedsBox
} }
b := r.s[r.i] b := r.s[r.i]
r.i += 1 r.i += 1
r.box_pos += 1 r.box.pos += 1
return b, nil return b, nil
} }
read_u16be :: proc(r: ^Reader) -> (u16, BoxError) { read_u16be :: proc(r: ^Reader) -> (u16, Error) {
if r.i >= i64(len(r.s)) { if r.i >= i64(len(r.s)) {
return 0, .EOF return 0, .EOF
} }
if r.box_pos + 2 > i64(r.size) { if r.box.size != 0 && r.box.pos + 2 > i64(r.box.size) {
return 0, .ReadExceedsBox return 0, .ReadExceedsBox
} }
b := endian.unchecked_get_u16be(r.s[r.i:]) b := endian.unchecked_get_u16be(r.s[r.i:])
r.i += 2 r.i += 2
r.box_pos += 2 r.box.pos += 2
return b, nil return b, nil
} }
read_u32be :: proc(r: ^Reader) -> (u32, BoxError) { read_u32be :: proc(r: ^Reader) -> (u32, Error) {
if r.i >= i64(len(r.s)) { if r.i >= i64(len(r.s)) {
return 0, .EOF return 0, .EOF
} }
if r.size != 0 && r.box_pos + 4 > i64(r.size) { if r.box.size != 0 && r.box.pos + 4 > i64(r.box.size) {
return 0, .ReadExceedsBox return 0, .ReadExceedsBox
} }
b := endian.unchecked_get_u32be(r.s[r.i:]) b := endian.unchecked_get_u32be(r.s[r.i:])
r.i += 4 r.i += 4
r.box_pos += 4 r.box.pos += 4
return b, nil return b, nil
} }
read_u64be :: proc(r: ^Reader) -> (u64, BoxError) { read_u64be :: proc(r: ^Reader) -> (u64, Error) {
if r.i >= i64(len(r.s)) { if r.i >= i64(len(r.s)) {
return 0, .EOF return 0, .EOF
} }
if r.size != 0 && r.box_pos + 8 > i64(r.size) { if r.box.size != 0 && r.box.pos + 8 > i64(r.box.size) {
return 0, .ReadExceedsBox return 0, .ReadExceedsBox
} }
b := endian.unchecked_get_u64be(r.s[r.i:]) b := endian.unchecked_get_u64be(r.s[r.i:])
r.i += 8 r.i += 8
r.box_pos += 8 r.box.pos += 8
return b, nil return b, nil
} }
read_slice :: proc(r: ^Reader, s: []byte) -> (n: int, err: BoxError) { read_slice :: proc(r: ^Reader, s: []byte) -> (n: int, err: Error) {
if r.i >= i64(len(r.s)) { if r.i >= i64(len(r.s)) {
return 0, .EOF return 0, .EOF
} }
n = copy(s, r.s[r.i:]) n = copy(s, r.s[r.i:])
if r.box_pos + i64(n) > i64(r.size) { if r.box.pos + i64(n) > i64(r.box.size) {
return 0, .ReadExceedsBox return 0, .ReadExceedsBox
} }
r.i += i64(n) r.i += i64(n)
r.box_pos += i64(n) r.box.pos += i64(n)
return return
} }
read_rune :: proc(r: ^Reader) -> (ch: rune, size: int, err: BoxError) { read_rune :: proc(r: ^Reader) -> (ch: rune, size: int, err: Error) {
if r.i >= i64(len(r.s)) { if r.i >= i64(len(r.s)) {
return 0, 0, .EOF return 0, 0, .EOF
} }
if c := r.s[r.i]; c < utf8.RUNE_SELF { if c := r.s[r.i]; c < utf8.RUNE_SELF {
if r.box_pos >= i64(r.size) { if r.box.pos >= i64(r.box.size) {
return 0, 0, .ReadExceedsBox return 0, 0, .ReadExceedsBox
} }
r.i += 1 r.i += 1
r.box_pos += 1 r.box.pos += 1
return rune(c), 1, nil return rune(c), 1, nil
} }
ch, size = utf8.decode_rune(r.s[r.i:]) ch, size = utf8.decode_rune(r.s[r.i:])
if r.box_pos + i64(size) > i64(r.size) { if r.box.pos + i64(size) > i64(r.box.size) {
return 0, 0, .ReadExceedsBox return 0, 0, .ReadExceedsBox
} }
r.i += i64(size) r.i += i64(size)
r.box_pos += i64(size) r.box.pos += i64(size)
return return
} }
read_string :: proc(r: ^Reader) -> (str: string, err: BoxError) { read_string :: proc(r: ^Reader) -> (str: string, err: Error) {
if r.i >= i64(len(r.s)) { if r.i >= i64(len(r.s)) {
return "", .EOF return "", .EOF
} }
@@ -173,32 +201,39 @@ read_string :: proc(r: ^Reader) -> (str: string, err: BoxError) {
} }
@(private = "file") @(private = "file")
read_bitfield_u32 :: proc(r: ^Reader, $T: typeid) -> (T, BoxError) where size_of(T) == 4 { read_bitfield_u32 :: proc(r: ^Reader, $T: typeid) -> (T, Error) where size_of(T) == 4 {
b, err := read_u32be(r) b, err := read_u32be(r)
return T(b), err return T(b), err
} }
@(private = "file") @(private = "file")
read_bitfield_u16 :: proc(r: ^Reader, $T: typeid) -> (T, BoxError) where size_of(T) == 2 { read_bitfield_u16 :: proc(r: ^Reader, $T: typeid) -> (T, Error) where size_of(T) == 2 {
b, err := read_u16be(r) b, err := read_u16be(r)
return T(b), err return T(b), err
} }
@(private = "file")
read_bitfield_u8 :: proc(r: ^Reader, $T: typeid) -> (T, Error) where size_of(T) == 1 {
b, err := read_byte(r)
return T(b), err
}
read_bitfield :: proc { read_bitfield :: proc {
read_bitfield_u8,
read_bitfield_u16, read_bitfield_u16,
read_bitfield_u32, read_bitfield_u32,
} }
skip_box :: proc(r: ^Reader) { skip_box :: proc(r: ^Reader) {
fmt.printfln("SKIPPED! %v with size %d", r.type, r.size) fmt.printfln("SKIPPED! %v with size %d", r.box.type, r.box.size)
reader_seek(r, auto_cast r.size - BOX_HEADER_SIZE, .Current) reader_seek(r, auto_cast r.box.size - BOX_HEADER_SIZE, .Current)
} }
remaining_box_size :: proc(r: ^Reader) -> i64 { remaining_box_size :: proc(r: ^Reader) -> i64 {
return i64(r.size) - r.box_pos return i64(r.box.size) - r.box.pos
} }
reader_seek :: proc(r: ^Reader, offset: i64, whence: io.Seek_From) -> (i64, BoxError) { reader_seek :: proc(r: ^Reader, offset: i64, whence: io.Seek_From) -> (i64, Error) {
abs: i64 abs: i64
switch whence { switch whence {
case .Start: case .Start:
+426 -15
View File
@@ -1,5 +1,6 @@
package avif package avif
import "core:fmt"
import "core:io" import "core:io"
OBUType :: enum u8 { OBUType :: enum u8 {
@@ -14,17 +15,76 @@ OBUType :: enum u8 {
PADDING = 15, PADDING = 15,
} }
// TODO: write a nice bitstream reader OBUError :: enum {
// ??? Still don't know how I want this to work ReservedOBU,
BitstreamReader :: struct { }
data: []byte,
pos: i64, // Number of bits read from the data slice ColorPrimaries :: enum u8 {
BT_709 = 1,
UNSPECIFIED = 2,
BT_470_M = 4,
BT_470_B_G = 5,
BT_601 = 6,
SMPTE_240 = 7,
GENERIC_FILM = 8,
BT_2020 = 9,
XYZ = 10,
SMPTE_431 = 11,
SMPTE_432 = 12,
EBU_3213 = 22,
}
TransferCharacteristic :: enum u8 {
RESERVED_0 = 0,
BT_709 = 1,
UNSPECIFIED = 2,
RESERVED_3 = 3,
BT_470_M = 4,
BT_470_B_G = 5,
BT_601 = 6,
SMPTE_240 = 7,
LINEAR = 8,
LOG_100 = 9,
LOG_100_SQRT10 = 10,
IEC_61966 = 11,
BT_1361 = 12,
SRGB = 13,
BT_2020_10_BIT = 14,
BT_2020_12_BIT = 15,
SMPTE_2084 = 16,
SMPTE_428 = 17,
HLG = 18,
}
MatrixCoefficient :: enum u8 {
IDENTITY = 0,
BT_709 = 1,
UNSPECIFIED = 2,
RESERVED_3 = 3,
FCC = 4,
BT_470_B_G = 5,
BT_601 = 6,
SMPTE_240 = 7,
SMPTE_YCGCO = 8,
BT_2020_NCL = 9,
BT_2020_CL = 10,
SMPTE_2085 = 11,
CHROMAT_NCL = 12,
CHROMAT_CL = 13,
ICTCP = 14,
}
ChromeSamplePosition :: enum u8 {
UNKNOWN = 0,
VERTICAL = 1,
COLOCATED = 2,
RESERVED = 3,
} }
OBUHeader :: bit_field u8 { OBUHeader :: bit_field u8 {
obu_reserved: u8 | 1, obu_reserved: u8 | 1,
obu_has_size_field: u8 | 1, obu_has_size_field: b8 | 1,
obu_extension_flag: u8 | 1, obu_extension_flag: b8 | 1,
obu_type: OBUType | 4, obu_type: OBUType | 4,
obu_forbidden_bit: u8 | 1, obu_forbidden_bit: u8 | 1,
} }
@@ -35,29 +95,361 @@ OBUExtensionHeader :: bit_field u8 {
temporal_id: u8 | 3, temporal_id: u8 | 3,
} }
read_bit :: proc() -> b8 { read_obu :: proc(r: ^Reader) -> (err: Error) {
// TODO: idfk header := read_bitfield(r, OBUHeader) or_return
// This should read a single bit from the bitstream and advance the bitstream position by 1 size: u64
return false fmt.println(header)
if header.obu_extension_flag {
ext_header := read_bitfield(r, OBUExtensionHeader) or_return
fmt.println(ext_header)
} }
f :: proc(n: int) -> u64 { if header.obu_has_size_field {
size = leb128(r)
} else {
// TODO: is this correct ???
// The spec is NOT clear about wtf sz is, so I assume it's the box size without the header.
// It's also possibly the remaining box size, we'll have to check how other decoders do it.
size = u64(r.box.size - BOX_HEADER_SIZE - 1 - u32(header.obu_extension_flag))
}
// TODO: get bit position
//start_pos := get_position()
//// TODO:
//if header.obu_type != .SEQUENCE_HEADER && header.obu_type != .TEMPORAL_DELIMITER && OperatingPointIdc != 0 && header.obu_extension_flag == 1 {
// in_temporal_layer := (OperatingPointIdc >> temporal_id) & 1
// in_spatial_layer := (OperatingPointIdc >> (spatial_id + 8)) & 1
// if in_temporal_layer == 0 || in_spatial_layer == 0 {
// drop_obu()
// return
// }
//}
fmt.println("OBU size:", size)
if header.obu_type != .SEQUENCE_HEADER &&
header.obu_type != .TEMPORAL_DELIMITER &&
header.obu_type != .FRAME_HEADER &&
header.obu_type != .TILE_GROUP &&
header.obu_type != .METADATA &&
header.obu_type != .FRAME &&
header.obu_type != .REDUNDANT_FRAME_HEADER &&
header.obu_type != .TILE_LIST &&
header.obu_type != .PADDING {
return .ReservedOBU
}
#partial switch header.obu_type {
case .TEMPORAL_DELIMITER:
// do nothing. the temporal OBU has an empty payload
case .SEQUENCE_HEADER:
parse_sequence_header_obu(r)
case .FRAME:
// TODO:
}
// TODO:
//current_pos := get_position()
//payload_bits := current_pos - start_pos
//if size > 0 && header.obu_type != .TILE_GROUP && header.obu_type != .TILE_LIST && header.obu_type != .FRAME {
// trailing_bits(size * 8 - payload_bits)
//}
return nil
}
//timing_info :: proc(r: ^Reader) {
// num_units_in_display_tick = f(r, 32)
// time_scale = f(r, 32)
// equal_picture_interval = f(r, 32)
// if equal_picture_interval == 1 {
// num_ticks_per_picture_minus_1 = uvlc(r)
// }
//}
//
//decoder_model_info :: proc(r: ^Reader) {
// buffer_delay_length_minus_1 = f(r, 5)
// num_units_in_decoding_tick = f(r, 32)
// buffer_removal_time_length_minus_1 = f(r, 5)
// frame_presentation_time_length_minus_1 = f(r, 5)
//}
//
//operating_parameters_info :: proc(r: ^Reader, op: u8) {
// n = buffer_delay_length_minus_1 + 1
// decoder_buffer_delay[op] = f(r, n)
// encoder_buffer_delay[op] = f(r, n)
// low_delay_mode_flag[op] = f(r, 1)
//}
//
//color_config :: proc(r: ^Reader) {
// high_bitdepth = f(r, 1)
//
// if seq_profile == 2 && high_bitdepth == 1 {
// twelve_bit = f(r, 1)
// BitDepth = twelve_bit == 1 ? 12 : 10
// } else if seq_profile <= 2 {
// BitDepth = high_bitdepth == 1 ? 10 : 8
// }
//
// if seq_profile == 1 {
// mono_chrome = 0
// } else {
// mono_chrome = f(r, 1)
// }
//
// num_planes = mono_chrome == 1 ? 1 : 3
// color_description_present_flag = f(r, 1)
//
// if color_description_present_flag == 1 {
// color_primaries = auto_cast f(r, 8)
// transfer_characteristic = auto_cast f(r, 8)
// matrix_coefficients = auto_cast f(r, 8)
// } else {
// color_primaries = .UNSPECIFIED
// transfer_characteristic = .UNSPECIFIED
// matrix_coefficients = .UNSPECIFIED
// }
//
// if mono_chrome == 1 {
// color_range = f(r, 1)
// subsampling_x = 1
// subsampling_y = 1
// chroma_sample_position = .UNKNOWN
// separate_uv_delta_q = 0
// return
// } else if color_primaries == .BT_709 && transfer_characteristic == .SRGB && matrix_coefficients == .IDENTITY {
// color_range = 1
// subsampling_x = 0
// subsampling_y = 0
// } else {
// color_range = f(r, 1)
//
// if seq_profile == 0 {
// subsampling_x = 1
// subsampling_y = 1
// } else if seq_profile == 1 {
// subsampling_x = 0
// subsampling_y = 0
// } else {
// if BitDepth == 12 {
// subsampling_x = f(r, 1)
//
// if subsampling_x == 1 {
// subsampling_y = f(r, 1)
// } else {
// subsampling_y = 0
// }
// } else {
// subsampling_x = 1
// subsampling_y = 0
// }
// }
//
// if subsampling_x == 1 && subsampling_y == 1 {
// chroma_sample_position = auto_cast f(r, 2)
// }
// }
//
// separate_uv_delta_q = f(r, 1)
//}
parse_sequence_header_obu :: proc(r: ^Reader) {
seq_profile := f(r, 3)
still_picture := f(r, 1)
reduced_still_picture_header := f(r, 1)
timing_info_present_flag: u8
decoder_model_info_present_flag: u8
initial_display_delay_present_flag: u8
operating_points_cnt_minus_1: u8
if reduced_still_picture_header == 1 {
// TODO: should these be saved as state ??
timing_info_present_flag = 0
decoder_model_info_present_flag = 0
initial_display_delay_present_flag = 0
operating_points_cnt_minus_1 = 0
//operating_point_idc[ 0 ] = 0
//seq_level_idx[ 0 ]
//seq_tier[ 0 ] = 0
//decoder_model_present_for_this_op[ 0 ] = 0
//initial_display_delay_present_for_this_op[ 0 ] = 0
} else {
//timing_info_present_flag = auto_cast f(r, 1)
//if timing_info_present_flag == 1 {
// timing_info(r)
// decoder_model_info_present_flag = auto_cast f(r, 1)
// if decoder_model_info_present_flag == 1 {
// decoder_model_info(r)
// }
//} else {
// decoder_model_info_present_flag = 0
//}
//initial_display_delay_present_flag = auto_cast f(r, 1)
//operating_points_cnt_minus_1 = auto_cast f(r, 5)
//for i in 0 ..=operating_points_cnt_minus_1 {
// operating_point_idc[i] = f(r, 12)
// seq_level_idx[i] = f(r, 5)
// if seq_level_idx[i] > 7 {
// seq_tier[i] = f(r, 1)
// } else {
// seq_tier[i] = 0
// }
// if decoder_model_info_present_flag == 1 {
// decoder_model_present_for_this_op[i] = f(r, 1)
// if decoder_model_present_for_this_op[i] == 1 {
// operating_parameters_info(r, i)
// }
// } else {
// decoder_model_present_for_this_op[i] = 0
// }
// if initial_display_delay_present_flag == 1 {
// initial_display_delay_present_for_this_op[i] = f(r, 1)
// if initial_display_delay_present_for_this_op[i] == 1 {
// initial_display_delay_minus_1[i] = f(r, 4)
// }
// }
//}
}
fmt.println("seq_profile:", seq_profile)
fmt.println("still_picture:", still_picture)
fmt.println("reduced_still_picture_header:", reduced_still_picture_header)
fmt.println("timing_info_present_flag:", timing_info_present_flag)
fmt.println("decoder_model_info_present_flag:", decoder_model_info_present_flag)
fmt.println("initial_display_delay_present_flag:", initial_display_delay_present_flag)
fmt.println("operating_points_cnt_minus_1:", operating_points_cnt_minus_1)
//operating_point := choose_operating_point()
//operating_point_idc_one := operating_point_idc[operating_point]
frame_width_bits_minus_1 := f(r, 4)
frame_height_bits_minus_1 := f(r, 4)
n := frame_width_bits_minus_1 + 1
max_frame_width_minus_1 := f(r, auto_cast n)
n = frame_height_bits_minus_1 + 1
max_frame_height_minus_1 := f(r, auto_cast n)
frame_id_numbers_present_flag: u8
delta_frame_id_length_minus_2: u8
additional_frame_id_length_minus_1: u8
if reduced_still_picture_header == 1 {
frame_id_numbers_present_flag = 0
} else {
frame_id_numbers_present_flag = auto_cast f(r, 1)
}
if frame_id_numbers_present_flag == 1 {
delta_frame_id_length_minus_2 = auto_cast f(r, 4)
additional_frame_id_length_minus_1 = auto_cast f(r, 3)
}
use_128x128_superblock := f(r, 1)
enable_filter_intra := f(r, 1)
enable_intra_edge_filter := f(r, 1)
fmt.println("frame_width_bits_minus_1:", frame_width_bits_minus_1)
fmt.println("frame_height_bits_minus_1:", frame_height_bits_minus_1)
fmt.println("max_frame_width_minus_1:", max_frame_width_minus_1)
fmt.println("max_frame_height_minus_1:", max_frame_height_minus_1)
fmt.println("frame_id_numbers_present_flag:", frame_id_numbers_present_flag)
fmt.println("delta_frame_id_length_minus_2:", delta_frame_id_length_minus_2)
fmt.println("additional_frame_id_length_minus_1:", additional_frame_id_length_minus_1)
fmt.println("use_128x128_superblock:", use_128x128_superblock)
fmt.println("enable_filter_intra:", enable_filter_intra)
fmt.println("enable_intra_edge_filter:", enable_intra_edge_filter)
//if reduced_still_picture_header == 1 {
// enable_interintra_compound = 0
// enable_masked_compound = 0
// enable_warped_motion = 0
// enable_dual_filter = 0
// enable_order_hint = 0
// enable_jnt_comp = 0
// enable_ref_frame_mvs = 0
// seq_force_screen_content_tools = SELECT_SCREEN_CONTENT_TOOLS
// seq_force_integer_mv = SELECT_INTEGER_MV
// OrderHintBits = 0
//} else {
// enable_interintra_compount = f(r, 1)
// enable_masked_compound = f(r, 1)
// enable_warped_motion = f(r, 1)
// enable_dual_filter = f(r, 1)
// enable_order_hint = f(r, 1)
// if enable_order_hint == 1 {
// enable_jnt_comp = f(r, 1)
// enable_ref_frame_mvs = f(r, 1)
// } else {
// enable_jnt_comp = 0
// enable_ref_frame_mvs = 0
// }
// seq_choose_screen_content_tools = f(r, 1)
// if seq_choose_screen_content_tools == 1 {
// seq_force_screen_content_tools = SELECT_SCREEN_CONTENT_TOOLS
// } else {
// seq_force_screen_content_tools = f(r, 1)
// }
// if seq_force_screen_content_tools > 0 {
// seq_choose_integer_mv = f(r, 1)
// if seq_choose_integer_mv == 1 {
// seq_force_integer_mv = SELECT_INTEGER_MV
// } else {
// seq_force_integer_mv = f(r, 1)
// }
// } else {
// seq_force_integer_mv = SELECT_INTEGER_MV
// }
// if enable_order_hint == 1 {
// order_hint_bits_minus_1 = f(r, 3)
// OrderHintBits = order_hint_bits_minus_1 + 1
// } else {
// OrderHintBits = 0
// }
//}
//enable_superres = f(r, 1)
//enable_cdef = f(r, 1)
//enable_restoration = f(r, 1)
//color_config()
//film_grain_params_present = f(r, 1)
}
f :: proc(r: ^Reader, n: int) -> u64 {
x: u64 = 0 x: u64 = 0
for i in 0 ..< n { for i in 0 ..< n {
x = 2 * x + auto_cast read_bit() // TODO: maybe get rid of or_break and propagate the error??
x = 2 * x + auto_cast read_bit(r) or_break
} }
return x return x
} }
leb128 :: proc() -> u64 { leb128 :: proc(r: ^Reader) -> u64 {
value: u64 = 0 value: u64 = 0
leb128_bytes := 0 leb128_bytes := 0
for i: u64 = 0; i < 8; i += 1 { for i: u64 = 0; i < 8; i += 1 {
leb128_byte := f(8) leb128_byte := f(r, 8)
value |= ((leb128_byte & 0x7f) << (i * 7)) value |= ((leb128_byte & 0x7f) << (i * 7))
leb128_bytes += 1 leb128_bytes += 1
@@ -68,3 +460,22 @@ leb128 :: proc() -> u64 {
return value return value
} }
uvlc :: proc(r: ^Reader) -> u64 {
leading_zeros: u64 = 0
for {
done := f(r, 1)
if done == 1 {
break
}
leading_zeros += 1
}
if leading_zeros >= 32 {
return (1 << 32) - 1
}
value := f(r, auto_cast leading_zeros)
return value + (1 << leading_zeros) - 1
}