pseudocode | type
--------------------------------------------------------------|-----
ExamplePseudoCode( ) { |
value | ur
} |
a++, a-- !a, -a a ^ b a * b, a / b a + b, a - b a << b, a >> b a < b, a <= b, a > b, a >= b a == b, a != b a & b a | b a && b a || b a ? b : c a = b, a += b, a -= b, a *= b
+---+---+---+---+---+---+---+---+ | 0 | 0 | | 0 | 0 | 0 | | 0 | +---+---+---+---+---+---+---+---+ | 0 | 0 | | 0 | 0 | 0 | | 0 | +---+---+---+---+---+---+---+---+ | | | | | | | | | +---+---+---+---+---+---+---+---+ | 0 | 0 | | a | b | c | | c | +---+---+---+---+---+---+---+---+ | 0 | a | | d | e | f | | f | +---+---+---+---+---+---+---+---+ | 0 | d | | g | h | i | | i | +---+---+---+---+---+---+---+---+
+---+---+---+---+ | | | T | | +---+---+---+---+ | |tl | t |tr | +---+---+---+---+ | L | l | X | | +---+---+---+---+
median(l, t, l + t - tl)
median(left16s, top16s, left16s + top16s - diag16s)
left16s = l >= 32768 ? ( l - 65536 ) : l top16s = t >= 32768 ? ( t - 65536 ) : t diag16s = tl >= 32768 ? ( tl - 65536 ) : tl
Q_j[k] = quant_tables[i][j][k&255]
context = Q_0[l - tl] +
Q_1[tl - t] +
Q_2[t - tr] +
Q_3[L - l] +
Q_4[T - t]
Cb = b - g Cr = r - g Y = g + (Cb + Cr) >> 2
g = Y - (Cb + Cr) >> 2 r = Cr + g b = Cb + g
+------------------------+------------------------+ | Pixel(1,1) | Pixel(2,1) | | Y(1,1) Cb(1,1) Cr(1,1) | Y(2,1) Cb(2,1) Cr(2,1) | +------------------------+------------------------+ | Pixel(1,2) | Pixel(2,2) | | Y(1,2) Cb(1,2) Cr(1,2) | Y(2,2) Cb(2,2) Cr(2,2) | +------------------------+------------------------+
Cb = g - b Cr = r - b Y = b + (Cb + Cr) >> 2
b = Y - (Cb + Cr) >> 2 r = Cr + b g = Cb + b
coder_input = ((sample_difference + 2 ^ (bits - 1)) &
(2 ^ bits - 1)) - 2 ^ (bits - 1)
R_0 = 65280
L_0 = 2 ^ 8 * B_0 + B_1
j_0 = 2
r_i = floor( ( R_i * S_(i, C_i) ) / 2 ^ 8 )
b_i = 0 <==>
L_i < R_i - r_i ==>
S_(i+1,C_i) = zero_state_(S_(i, C_i)) AND
l_i = L_i AND
t_i = R_i - r_i
b_i = 1 <==>
L_i >= R_i - r_i ==>
S_(i+1,C_i) = one_state_(S_(i, C_i)) AND
l_i = L_i - R_i + r_i AND
t_i = r_i
C_i != k ==> S_(i + 1, k) = S_(i, k)
t_i < 2 ^ 8 ==> R_(i + 1) = 2 ^ 8 * t_i AND L_(i + 1) = 2 ^ 8 * l_i + B_(j_i) AND j_(i + 1) = j_i + 1 t_i >= 2 ^ 8 ==> R_(i + 1) = t_i AND L_(i + 1) = l_i AND j_(i + 1) = j_i
range = 0xFF00;
end = 0;
low = get_bits(16);
if (low >= range) {
low = range;
end = 1;
}
refill() {
if (range < 256) {
range = range * 256;
low = low * 256;
if (!end) {
c.low += get_bits(8);
if (remaining_bits_in_bitstream( NumBytes ) == 0) {
end = 1;
}
}
}
}
get_rac(state) {
rangeoff = (range * state) / 256;
range -= rangeoff;
if (low < range) {
state = zero_state[state];
refill();
return 0;
} else {
low -= range;
state = one_state[state];
range = rangeoff;
refill();
return 1;
}
}
int get_symbol(RangeCoder *c, uint8_t *state, int is_signed) {
if (get_rac(c, state + 0) {
return 0;
}
int e = 0;
while (get_rac(c, state + 1 + min(e, 9)) { //1..10
e++;
}
int a = 1;
for (int i = e - 1; i >= 0; i--) {
a = a * 2 + get_rac(c, state + 22 + min(i, 9)); // 22..31
}
if (!is_signed) {
return a;
}
if (get_rac(c, state + 11 + min(e, 10))) { //11..21
return -a;
} else {
return a;
}
}
one_state_i =
default_state_transition_i + state_transition_delta_i
zero_state_i = 256 - one_state_(256-i)
0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111,112,113,114,114,115,116,117,118, 119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,133, 134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149, 150,151,152,152,153,154,155,156,157,158,159,160,161,162,163,164, 165,166,167,168,169,170,171,171,172,173,174,175,176,177,178,179, 180,181,182,183,184,185,186,187,188,189,190,190,191,192,194,194, 195,196,197,198,199,200,201,202,202,204,205,206,207,208,209,209, 210,211,212,213,215,215,216,217,218,219,220,220,222,223,224,225, 226,227,227,229,229,230,231,232,234,234,235,236,237,238,239,240, 241,242,243,244,245,246,247,248,248, 0, 0, 0, 0, 0, 0, 0,
0, 10, 10, 10, 10, 16, 16, 16, 28, 16, 16, 29, 42, 49, 20, 49, 59, 25, 26, 26, 27, 31, 33, 33, 33, 34, 34, 37, 67, 38, 39, 39, 40, 40, 41, 79, 43, 44, 45, 45, 48, 48, 64, 50, 51, 52, 88, 52, 53, 74, 55, 57, 58, 58, 74, 60,101, 61, 62, 84, 66, 66, 68, 69, 87, 82, 71, 97, 73, 73, 82, 75,111, 77, 94, 78, 87, 81, 83, 97, 85, 83, 94, 86, 99, 89, 90, 99,111, 92, 93,134, 95, 98,105, 98, 105,110,102,108,102,118,103,106,106,113,109,112,114,112,116,125, 115,116,117,117,126,119,125,121,121,123,145,124,126,131,127,129, 165,130,132,138,133,135,145,136,137,139,146,141,143,142,144,148, 147,155,151,149,151,150,152,157,153,154,156,168,158,162,161,160, 172,163,169,164,166,184,167,170,177,174,171,173,182,176,180,178, 175,189,179,181,186,183,192,185,200,187,191,188,190,197,193,196, 197,194,195,196,198,202,199,201,210,203,207,204,205,206,208,214, 209,211,221,212,213,215,224,216,217,218,219,220,222,228,223,225, 226,224,227,229,240,230,231,232,233,234,235,236,238,239,237,242, 241,243,242,244,245,246,247,248,249,250,251,252,252,253,254,255,
int get_ur_golomb(k) {
for (prefix = 0; prefix < 12; prefix++) {
if (get_bits(1)) {
return get_bits(k) + (prefix << k);
}
}
return get_bits(bits) + 11;
}
int get_sr_golomb(k) {
v = get_ur_golomb(k);
if (v & 1) return - (v >> 1) - 1;
else return (v >> 1);
}
| bits | value |
|---|---|
| 1 | 0 |
| 01 | 1 |
| ... | ... |
| 0000 0000 01 | 9 |
| 0000 0000 001 | 10 |
| 0000 0000 0001 | 11 |
| 0000 0000 0000 | ESC |
| non-ESC | the k least significant bits MSB first |
| ESC | the value - 11, in MSB first order |
| k | bits | value |
|---|---|---|
| 0 | 1 | 0 |
| 0 | 001 | 2 |
| 2 | 1 00 | 0 |
| 2 | 1 10 | 2 |
| 2 | 01 01 | 5 |
| any | 000000000000 10000000 | 139 |
log2_run[41] = {
0, 0, 0, 0, 1, 1, 1, 1,
2, 2, 2, 2, 3, 3, 3, 3,
4, 4, 5, 5, 6, 6, 7, 7,
8, 9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,
24,
};
if (run_count == 0 && run_mode == 1) {
if (get_bits(1)) {
run_count = 1 << log2_run[run_index];
if (x + run_count <= w) {
run_index++;
}
} else {
if (log2_run[run_index]) {
run_count = get_bits(log2_run[run_index]);
} else {
run_count = 0;
}
if (run_index) {
run_index--;
}
run_mode = 2;
}
}
sign_extend(input_number, input_bits) {
negative_bias = 1 << (input_bits - 1);
bits_mask = negative_bias - 1;
output_number = input_number & bits_mask; // Remove negative bit
is_negative = input_number & negative_bias; // Test negative bit
if (is_negative)
output_number -= negative_bias;
return output_number
}
get_vlc_symbol(state) {
i = state->count;
k = 0;
while (i < state->error_sum) {
k++;
i += i;
}
v = get_sr_golomb(k);
if (2 * state->drift < -state->count) {
v = -1 - v;
}
ret = sign_extend(v + state->bias, bits);
state->error_sum += abs(v);
state->drift += v;
if (state->count == 128) {
state->count >>= 1;
state->drift >>= 1;
state->error_sum >>= 1;
}
state->count++;
if (state->drift <= -state->count) {
state->bias = max(state->bias - 1, -128);
state->drift = max(state->drift + state->count,
-state->count + 1);
} else if (state->drift > 0) {
state->bias = min(state->bias + 1, 127);
state->drift = min(state->drift - state->count, 0);
}
return ret;
}
diff = get_vlc_symbol(context_state);
if (diff >= 0) {
diff++;
}
drift = 0;
error_sum = 4;
bias = 0;
count = 1;
| symbol | definition |
|---|---|
| u(n) | Unsigned, big-endian integer symbol using n bits |
| br | Boolean (1-bit) symbol that is range coded with the method described in Section 3.8.1.1 |
| ur | Unsigned scalar symbol that is range coded with the method described in Section 3.8.1.2 |
| sr | Signed scalar symbol that is range coded with the method described in Section 3.8.1.2 |
| sd | Sample Difference symbol that is coded with the method described in Section 3.8 |
pseudocode | type
--------------------------------------------------------------|-----
QuantizationTableSet( i ) { |
scale = 1 |
for (j = 0; j < MAX_CONTEXT_INPUTS; j++) { |
QuantizationTable( i, j, scale ) |
scale *= 2 * len_count[ i ][ j ] - 1 |
} |
context_count[ i ] = ceil( scale / 2 ) |
} |
pseudocode | type
--------------------------------------------------------------|-----
QuantizationTable(i, j, scale) { |
v = 0 |
for (k = 0; k < 128;) { |
len - 1 | ur
for (n = 0; n < len; n++) { |
quant_tables[ i ][ j ][ k ] = scale * v |
k++ |
} |
v++ |
} |
for (k = 1; k < 128; k++) { |
quant_tables[ i ][ j ][ 256 - k ] = \ |
-quant_tables[ i ][ j ][ k ] |
} |
quant_tables[ i ][ j ][ 128 ] = \ |
-quant_tables[ i ][ j ][ 127 ] |
len_count[ i ][ j ] = v |
} |
pseudocode | type
--------------------------------------------------------------|-----
Parameters( ) { |
version | ur
if (version >= 3) { |
micro_version | ur
} |
coder_type | ur
if (coder_type > 1) { |
for (i = 1; i < 256; i++) { |
state_transition_delta[ i ] | sr
} |
} |
colorspace_type | ur
if (version >= 1) { |
bits_per_raw_sample | ur
} |
chroma_planes | br
log2_h_chroma_subsample | ur
log2_v_chroma_subsample | ur
extra_plane | br
if (version >= 3) { |
num_h_slices - 1 | ur
num_v_slices - 1 | ur
quant_table_set_count | ur
} |
for (i = 0; i < quant_table_set_count; i++) { |
QuantizationTableSet( i ) |
} |
if (version >= 3) { |
for (i = 0; i < quant_table_set_count; i++) { |
states_coded | br
if (states_coded) { |
for (j = 0; j < context_count[ i ]; j++) { |
for (k = 0; k < CONTEXT_SIZE; k++) { |
initial_state_delta[ i ][ j ][ k ] | sr
} |
} |
} |
} |
ec | ur
intra | ur
} |
} |
| value | version |
|---|---|
| 0 | FFV1 version 0 |
| 1 | FFV1 version 1 |
| 2 | reserved* |
| 3 | FFV1 version 3 |
| Other | reserved for future use |
| value | micro_version |
|---|---|
| 0...3 | reserved* |
| 4 | first stable variant |
| Other | reserved for future use |
| value | coder used |
|---|---|
| 0 | Golomb Rice |
| 1 | Range coder with default state transition table |
| 2 | Range coder with custom state transition table |
| Other | reserved for future use |
| value | color space encoded | pixel transformation | extra Plane content | interleave method |
|---|---|---|---|---|
| 0 | YCbCr | None | Transparency | Plane then Line |
| 1 | RGB | JPEG 2000 RCT | Transparency | Line then Plane |
| Other | reserved for future use | reserved for future use | reserved for future use | reserved for future use |
| value | presence |
|---|---|
| 0 | chroma Planes are not present |
| 1 | chroma Planes are present |
| value | bits for each Sample |
|---|---|
| 0 | reserved* |
| Other | the actual bits for each Sample |
| value | presence |
|---|---|
| 0 | extra Plane is not present |
| 1 | extra Plane is present |
| value | initial states |
|---|---|
| 0 | initial states are not present and are assumed to be all 128 |
| 1 | initial states are present |
pred = j ? initial_states[ i ][j - 1][ k ] : 128
initial_state[ i ][ j ][ k ] =
( pred + initial_state_delta[ i ][ j ][ k ] ) & 255
| value | error detection/correction type |
|---|---|
| 0 | 32-bit CRC in ConfigurationRecord |
| 1 | 32-bit CRC in Slice and ConfigurationRecord |
| Other | reserved for future use |
| value | relationship |
|---|---|
| 0 | keyframe can be 0 or 1 (non keyframes or keyframes) |
| 1 | keyframe MUST be 1 (keyframes only) |
| Other | reserved for future use |
pseudocode | type
-----------------------------------------------------------|-----
ConfigurationRecord( NumBytes ) { |
ConfigurationRecordIsPresent = 1 |
Parameters( ) |
while (remaining_symbols_in_syntax(NumBytes - 4)) { |
reserved_for_future_use | br/ur/sr
} |
configuration_record_crc_parity | u(32)
} |
pseudocode | type
--------------------------------------------------------------|-----
Frame( NumBytes ) { |
keyframe | br
if (keyframe && !ConfigurationRecordIsPresent { |
Parameters( ) |
} |
while (remaining_bits_in_bitstream( NumBytes )) { |
Slice( ) |
} |
} |
+-----------------------------------------------------------------+ | first Slice header | +-----------------------------------------------------------------+ | first Slice content | +-----------------------------------------------------------------+ | first Slice footer | +-----------------------------------------------------------------+ | --------------------------------------------------------------- | +-----------------------------------------------------------------+ | second Slice header | +-----------------------------------------------------------------+ | second Slice content | +-----------------------------------------------------------------+ | second Slice footer | +-----------------------------------------------------------------+ | --------------------------------------------------------------- | +-----------------------------------------------------------------+ | ... | +-----------------------------------------------------------------+ | --------------------------------------------------------------- | +-----------------------------------------------------------------+ | last Slice header | +-----------------------------------------------------------------+ | last Slice content | +-----------------------------------------------------------------+ | last Slice footer | +-----------------------------------------------------------------+
pseudocode | type
--------------------------------------------------------------|-----
Slice( ) { |
if (version >= 3) { |
SliceHeader( ) |
} |
SliceContent( ) |
if (coder_type == 0) { |
while (!byte_aligned()) { |
padding | u(1)
} |
} |
if (version <= 1) { |
while (remaining_bits_in_bitstream( NumBytes ) != 0) {|
reserved | u(1)
} |
} |
if (version >= 3) { |
SliceFooter( ) |
} |
} |
pseudocode | type
--------------------------------------------------------------|-----
SliceHeader( ) { |
slice_x | ur
slice_y | ur
slice_width - 1 | ur
slice_height - 1 | ur
for (i = 0; i < quant_table_set_index_count; i++) { |
quant_table_set_index[ i ] | ur
} |
picture_structure | ur
sar_num | ur
sar_den | ur
} |
1 + ( ( chroma_planes || version <= 3 ) ? 1 : 0 )
+ ( extra_plane ? 1 : 0 )
| value | picture structure used |
|---|---|
| 0 | unknown |
| 1 | top field first |
| 2 | bottom field first |
| 3 | progressive |
| Other | reserved for future use |
pseudocode | type
--------------------------------------------------------------|-----
SliceContent( ) { |
if (colorspace_type == 0) { |
for (p = 0; p < primary_color_count; p++) { |
for (y = 0; y < plane_pixel_height[ p ]; y++) { |
Line( p, y ) |
} |
} |
} else if (colorspace_type == 1) { |
for (y = 0; y < slice_pixel_height; y++) { |
for (p = 0; p < primary_color_count; p++) { |
Line( p, y ) |
} |
} |
} |
} |
1 + ( chroma_planes ? 2 : 0 ) + ( extra_plane ? 1 : 0 )
chroma_planes == 1 && (p == 1 || p == 2)
? ceil(slice_pixel_height / (1 << log2_v_chroma_subsample))
: slice_pixel_height
floor(
( slice_y + slice_height )
* slice_pixel_height
/ num_v_slices
) - slice_pixel_y.
floor( slice_y * frame_pixel_height / num_v_slices )
pseudocode | type
--------------------------------------------------------------|-----
Line( p, y ) { |
if (colorspace_type == 0) { |
for (x = 0; x < plane_pixel_width[ p ]; x++) { |
sample_difference[ p ][ y ][ x ] | sd
} |
} else if (colorspace_type == 1) { |
for (x = 0; x < slice_pixel_width; x++) { |
sample_difference[ p ][ y ][ x ] | sd
} |
} |
} |
chroma_planes == 1 && (p == 1 || p == 2)
? ceil( slice_pixel_width / (1 << log2_h_chroma_subsample) )
: slice_pixel_width.
floor(
( slice_x + slice_width )
* slice_pixel_width
/ num_h_slices
) - slice_pixel_x
floor( slice_x * frame_pixel_width / num_h_slices )
pseudocode | type
--------------------------------------------------------------|-----
SliceFooter( ) { |
slice_size | u(24)
if (ec) { |
error_status | u(8)
slice_crc_parity | u(32)
} |
} |
| value | error status |
|---|---|
| 0 | no error |
| 1 | Slice contains a correctable error |
| 2 | Slice contains an uncorrectable error |
| Other | reserved for future use |