/* Insert slices into a battle branch; the elements of * prototypes are *not* deallocated by battle_branch_insert_slices_nested(). * The inserted slices are copies of the elements of prototypes). * Each slice is inserted at a position that corresponds to its predefined rank. * @param adapter identifies starting point of insertion (of type STAttackAdapter * or STDefenseAdapter) * @param prototypes contains the prototypes whose copies are inserted * @param nr_prototypes number of elements of array prototypes */ void battle_branch_insert_slices_nested(slice_index adapter, slice_index const prototypes[], unsigned int nr_prototypes) { stip_structure_traversal st; branch_slice_insertion_state_type state = { prototypes, nr_prototypes, slice_rank_order, nr_slice_rank_order_elmts, 0, branch_slice_rank_order_recursive, 0, adapter, 0 }; TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParam("%u",nr_prototypes); TraceFunctionParamListEnd(); assert(SLICE_TYPE(adapter)==STAttackAdapter || SLICE_TYPE(adapter)==STDefenseAdapter); state.base_rank = get_slice_rank(SLICE_TYPE(adapter),&state); assert(state.base_rank!=no_slice_rank); slice_insertion_init_traversal(&st,&state,stip_traversal_context_intro); move_init_slice_insertion_traversal(&st); stip_traverse_structure_children_pipe(adapter,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* (Approximately) depth-first traversl of the stipulation * @param root start of the stipulation (sub)tree * @param st address of data structure holding parameters for the operation */ void stip_traverse_moves(slice_index root, stip_moves_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",root); TraceFunctionParam("%p",st); TraceFunctionParamListEnd(); TraceValue("%u",st->remaining); TraceEOL(); TraceEnumerator(slice_type,SLICE_TYPE(root)); TraceEOL(); assert(SLICE_TYPE(root)<=nr_slice_types); if (st->remaining_watermark[root]<=st->remaining) { stip_moves_visitor const operation = st->map.visitors[SLICE_TYPE(root)]; assert(operation!=0); (*operation)(root,st); st->remaining_watermark[root] = st->remaining+1; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void move_generation_branch_insert_slices_impl(slice_index generating, slice_index const prototypes[], unsigned int nr_prototypes, slice_index base) { stip_structure_traversal st; branch_slice_insertion_state_type state = { prototypes,nr_prototypes, slice_rank_order, nr_slice_rank_order_elmts, 1, branch_slice_rank_order_nonrecursive, 0, generating, 0 }; TraceFunctionEntry(__func__); TraceFunctionParam("%u",generating); TraceFunctionParamListEnd(); state.base_rank = get_slice_rank(SLICE_TYPE(base),&state); assert(state.base_rank!=no_slice_rank); slice_insertion_init_traversal(&st,&state,stip_traversal_context_intro); circe_init_slice_insertion_traversal(&st); stip_traverse_structure(generating,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void help_branch_insert_slices_impl(slice_index si, slice_index const prototypes[], unsigned int nr_prototypes, slice_index base) { stip_structure_traversal st; branch_slice_insertion_state_type state = { prototypes, nr_prototypes, slice_rank_order, nr_slice_rank_order_elmts, 0, branch_slice_rank_order_recursive, 0, si, 0 }; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParam("%u",nr_prototypes); TraceFunctionParamListEnd(); slice_insertion_init_traversal(&st,&state,stip_traversal_context_help); move_init_slice_insertion_traversal(&st); state.base_rank = get_slice_rank(SLICE_TYPE(base),&state); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Like attack_branch_insert_slices, but starting at a proxy slice * @param base used instead of proxy for determining the current position in the * sequence of defense branches */ void attack_branch_insert_slices_behind_proxy(slice_index proxy, slice_index const prototypes[], unsigned int nr_prototypes, slice_index base) { stip_structure_traversal st; branch_slice_insertion_state_type state = { prototypes, nr_prototypes, slice_rank_order, nr_slice_rank_order_elmts, 0, branch_slice_rank_order_recursive, 0, proxy, 0 }; TraceFunctionEntry(__func__); TraceFunctionParam("%u",proxy); TraceFunctionParam("%u",nr_prototypes); TraceFunctionParamListEnd(); assert(SLICE_TYPE(proxy)!=STAttackPlayed); state.base_rank = get_slice_rank(STAttackPlayed,&state); assert(state.base_rank!=no_slice_rank); ++state.base_rank; state.base_rank = get_slice_rank(STDefensePlayed,&state); assert(state.base_rank!=no_slice_rank); ++state.base_rank; slice_insertion_init_traversal(&st,&state,stip_traversal_context_attack); move_init_slice_insertion_traversal(&st); state.base_rank = get_slice_rank(SLICE_TYPE(base),&state); stip_traverse_structure(proxy,&st); deallocate_slice_insertion_prototypes(prototypes,nr_prototypes); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* (Approximately) depth-first traversl of a stipulation sub-tree * @param root root of the sub-tree to traverse * @param st address of structure defining traversal */ void stip_traverse_moves_children(slice_index si, stip_moves_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); TraceEnumerator(slice_type,SLICE_TYPE(si)); TraceEOL(); assert(SLICE_TYPE(si)<=nr_slice_types); { slice_type const type = SLICE_TYPE(si); stip_moves_visitor const operation = moves_children_traversers.visitors[type]; assert(operation!=0); (*operation)(si,st); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_enforcers(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children(si,st); { stip_deep_copies_type copies; stip_structure_traversal st_nested; slice_index const * const threat_start = st->param; slice_index const threat_start_tester = SLICE_TESTER(*threat_start); assert(*threat_start!=no_slice); assert(threat_start_tester!=no_slice); assert(SLICE_TYPE(threat_start_tester)==STThreatStart); { slice_index const prototype = alloc_pipe(STThreatDefeatedTester); attack_branch_insert_slices(threat_start_tester,&prototype,1); } init_deep_copy(&st_nested,st,&copies); stip_structure_traversal_override_single(&st_nested, STThreatDefeatedTester, &move_and_stop_copying); stip_structure_traversal_override_by_contextual(&st_nested, slice_contextual_conditional_pipe, ©_shallow); stip_structure_traversal_override_by_contextual(&st_nested, slice_contextual_testing_pipe, ©_shallow); stip_traverse_structure(threat_start_tester,&st_nested); SLICE_NEXT2(si) = copies[threat_start_tester]; } { /* if the threats are short, max_unsolvable might interfere with enforcing * them */ slice_index const prototype = alloc_reset_unsolvable_slice(); attack_branch_insert_slices(SLICE_NEXT2(si),&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Insert slices into a help branch; the elements of * prototypes are *not* deallocated by help_branch_insert_slices_nested(). * The inserted slices are copies of the elements of prototypes). * Each slice is inserted at a position that corresponds to its predefined rank. * @param adapter identifies starting point of insertion (of type STHelpAdapter) * @param prototypes contains the prototypes whose copies are inserted * @param nr_prototypes number of elements of array prototypes */ void help_branch_insert_slices_nested(slice_index adapter, slice_index const prototypes[], unsigned int nr_prototypes) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParam("%u",nr_prototypes); TraceFunctionParamListEnd(); assert(SLICE_TYPE(adapter)==STHelpAdapter); help_branch_insert_slices_impl(adapter,prototypes,nr_prototypes,adapter); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Insert slices into a goal branch. * The inserted slices are copies of the elements of prototypes). * Each slice is inserted at a position that corresponds to its predefined rank. * @param si identifies starting point of insertion * @param prototypes contains the prototypes whose copies are inserted * @param nr_prototypes number of elements of array prototypes */ static void goal_branch_insert_slices_nested(slice_index si, slice_index const prototypes[], unsigned int nr_prototypes) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParam("%u",nr_prototypes); TraceFunctionParamListEnd(); { slice_type const prototype_type = SLICE_TYPE(prototypes[0]); unsigned int prototype_rank = get_goal_slice_rank(prototype_type); if (prototype_rank==no_goal_slice_type) { if (nr_prototypes>1) goal_branch_insert_slices_nested(si,prototypes+1,nr_prototypes-1); } else do { slice_index const next = SLICE_NEXT1(si); if (SLICE_TYPE(next)==STProxy) si = next; else if (SLICE_TYPE(next)==STOr || SLICE_TYPE(next)==STAnd) { goal_branch_insert_slices_nested(SLICE_NEXT1(next), prototypes,nr_prototypes); goal_branch_insert_slices_nested(SLICE_NEXT2(next), prototypes,nr_prototypes); break; } else { unsigned int const rank_next = get_goal_slice_rank(SLICE_TYPE(next)); if (rank_next==no_goal_slice_type) break; else if (rank_next>prototype_rank) { slice_index const copy = copy_slice(prototypes[0]); pipe_append(si,copy); if (nr_prototypes>1) goal_branch_insert_slices_nested(copy,prototypes+1,nr_prototypes-1); break; } else si = next; } } while (prototype_type!=SLICE_TYPE(si)); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Produce slices representing set play. * @param adapter identifies the adapter slice at the beginning of the branch * @param state address of structure holding state */ void help_branch_make_setplay(slice_index adapter, spin_off_state_type *state) { stip_length_type const length = SLICE_U(adapter).branch.length; stip_length_type min_length = SLICE_U(adapter).branch.min_length; TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); assert(SLICE_TYPE(adapter)==STHelpAdapter); if (min_length==0) min_length = 2; if (length>1) { slice_index const next = SLICE_NEXT1(adapter); slice_index const prototypes[] = { alloc_help_adapter_slice(length-1,min_length-1), alloc_pipe(STEndOfRoot) }; enum { nr_prototypes = sizeof prototypes / sizeof prototypes[0] }; help_branch_insert_slices(next,prototypes,nr_prototypes); { slice_index const set_adapter = branch_find_slice(STHelpAdapter, next, stip_traversal_context_help); assert(set_adapter!=no_slice); help_branch_make_root_slices(set_adapter,state); state->spun_off[adapter] = state->spun_off[set_adapter]; pipe_remove(set_adapter); } } TraceValue("%u\n",state->spun_off[adapter]); TraceFunctionExit(__func__); TraceFunctionParamListEnd(); }
/* Wrap the slices representing the initial moves of the solution with * slices of appropriately equipped slice types * @param adapter identifies the adapter slice at the beginning of the branch * @param state address of structure holding state */ void help_make_root(slice_index adapter, spin_off_state_type *state) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); assert(SLICE_TYPE(adapter)==STHelpAdapter); { slice_index const prototype = alloc_pipe(STEndOfRoot); slice_insertion_insert(adapter,&prototype,1); help_branch_make_root_slices(adapter,state); branch_shorten_slices(adapter,STEndOfRoot,stip_traversal_context_intro); pipe_remove(adapter); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void stip_traverse_moves_conditional_pipe_tester(slice_index conditional_pipe, stip_moves_traversal *st) { stip_traversal_activity_type const save_activity = st->activity; TraceFunctionEntry(__func__); TraceFunctionParam("%u",conditional_pipe); TraceFunctionParam("%p",st); TraceFunctionParamListEnd(); assert(slice_type_get_contextual_type(SLICE_TYPE(conditional_pipe)) ==slice_contextual_conditional_pipe); st->activity = stip_traversal_activity_testing; stip_traverse_moves_branch(SLICE_NEXT2(conditional_pipe),st); st->activity = save_activity; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Instrument a series branch with STConstraintTester slices (as possible in * elabore sstip stipulations) * @param si entry slice of branch to be instrumented * @param constraint identifies branch that constrains the attacker */ void series_branch_insert_goal_constraint(slice_index si, slice_index constraint) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParam("%u",constraint); TraceFunctionParamListEnd(); TraceStipulation(si); TraceStipulation(constraint); assert(SLICE_TYPE(constraint)==STProxy); { slice_index const prototype = alloc_goal_constraint_tester_slice(constraint); slice_insertion_insert(si,&prototype,1); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void stip_traverse_moves_testing_pipe_tester(slice_index testing_pipe, stip_moves_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",testing_pipe); TraceFunctionParamListEnd(); assert(slice_type_get_contextual_type(SLICE_TYPE(testing_pipe)) ==slice_contextual_testing_pipe); if (SLICE_NEXT2(testing_pipe)!=no_slice) { stip_traversal_activity_type const save_activity = st->activity; st->activity = stip_traversal_activity_testing; stip_traverse_moves(SLICE_NEXT2(testing_pipe),st); st->activity = save_activity; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Shorten a help branch by 1 half move * @param identifies entry slice of branch to be shortened */ void help_branch_shorten(slice_index adapter) { slice_index const next = SLICE_NEXT1(adapter); TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); assert(SLICE_TYPE(adapter)==STHelpAdapter); { /* find the new spot for adapter by inserting a copy */ slice_index const prototype = copy_slice(adapter); help_branch_insert_slices(next,&prototype,1); } { /* move adapter to its new spot */ slice_index const copy = branch_find_slice(STHelpAdapter, next, stip_traversal_context_help); assert(copy!=no_slice); pipe_link(SLICE_PREV(adapter),next); pipe_append(copy,adapter); pipe_remove(copy); } /* adjust the length and min_length members */ --SLICE_U(adapter).branch.length; if (SLICE_U(adapter).branch.min_length<=0) increase_min_length(adapter); --SLICE_U(adapter).branch.min_length; branch_shorten_slices(next,STHelpAdapter,stip_traversal_context_help); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Make the postkey play representation of a non-postkey play representation * @param adapter identifies adapter slice into battle branch * @return identifier to adapter slice into postkey representation */ slice_index battle_branch_make_postkeyplay(slice_index adapter) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); TraceStipulation(adapter); assert(SLICE_TYPE(adapter)==STAttackAdapter); { slice_index const notend = branch_find_slice(STNotEndOfBranchGoal, adapter, stip_traversal_context_intro); stip_length_type const length = SLICE_U(adapter).branch.length; stip_length_type const min_length = SLICE_U(adapter).branch.min_length; slice_index const proto = alloc_defense_adapter_slice(length-1, min_length-1); assert(notend!=no_slice); defense_branch_insert_slices(notend,&proto,1); result = branch_find_slice(STDefenseAdapter, notend, stip_traversal_context_defense); assert(result!=no_slice); branch_shorten_slices(adapter,STDefenseAdapter,stip_traversal_context_intro); pipe_remove(adapter); } TraceFunctionExit(__func__); TraceFunctionParam("%u",result); TraceFunctionParamListEnd(); return result; }
/* Produce slices representing set play. * @param adapter identifies the adapter slice at the beginning of the branch * @param state address of structure holding state */ void series_branch_make_setplay(slice_index adapter, spin_off_state_type *state) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); { slice_index const next = SLICE_NEXT1(adapter); slice_index const prototypes[] = { alloc_help_adapter_slice(0,0), alloc_pipe(STEndOfRoot) }; enum { nr_prototypes = sizeof prototypes / sizeof prototypes[0] }; help_branch_insert_slices(next,prototypes,nr_prototypes); { slice_index const set_adapter = branch_find_slice(STHelpAdapter, next, stip_traversal_context_help); assert(set_adapter!=no_slice); if (SLICE_TYPE(SLICE_NEXT1(set_adapter))==STDeadEnd) ; /* set play not applicable */ else help_branch_make_root_slices(set_adapter,state); TraceValue("%u\n",state->spun_off[set_adapter]); state->spun_off[adapter] = state->spun_off[set_adapter]; pipe_remove(set_adapter); } } TraceValue("%u\n",state->spun_off[adapter]); TraceFunctionExit(__func__); TraceFunctionParamListEnd(); }
void parse_slice_header(decoder_context *decoder) { bitstream_reader *reader = &decoder->reader; decoder_context_sps *sps; decoder_context_pps *pps; unsigned pps_id; int i; decoder_reset_SH(decoder); decoder->sh.first_mb_in_slice = bitstream_read_ue(reader); decoder->sh.slice_type = bitstream_read_ue(reader); pps_id = bitstream_read_ue(reader); SYNTAX_IPRINT("first_mb_in_slice = %u\n", decoder->sh.first_mb_in_slice); SYNTAX_IPRINT("slice_type %u = \"%s\"\n", decoder->sh.slice_type, SLICE_TYPE(decoder->sh.slice_type)); SYNTAX_IPRINT("pic_parameter_set_id = %u\n", pps_id); if (pps_id > 255) { SYNTAX_ERR("Slice header is malformed, pps_id overflow\n"); } if (!decoder->pps[pps_id].valid) { SYNTAX_ERR("Cannot parse slice while PPS is invalid\n"); } decoder->active_pps = &decoder->pps[pps_id]; pps = decoder->active_pps; decoder->active_sps = &decoder->sps[pps->seq_parameter_set_id]; sps = decoder->active_sps; decoder->sh.slice_type %= 5; if (sps->separate_colour_plane_flag) { decoder->sh.colour_plane_id = bitstream_read_u(reader, 2); SYNTAX_IPRINT("colour_plane_id = %u\n", decoder->sh.colour_plane_id); } decoder->sh.frame_num = bitstream_read_u(reader, sps->log2_max_frame_num_minus4 + 4); SYNTAX_IPRINT("frame_num = %u\n", decoder->sh.frame_num); if (!sps->frame_mbs_only_flag) { decoder->sh.field_pic_flag = bitstream_read_u(reader, 1); SYNTAX_IPRINT("field_pic_flag = %u\n", decoder->sh.field_pic_flag); if (decoder->sh.field_pic_flag) { decoder->sh.bottom_field_flag = bitstream_read_u(reader, 1); SYNTAX_IPRINT("bottom_field_flag = %u\n", decoder->sh.bottom_field_flag); } } if (IdrPicFlag) { decoder->sh.idr_pic_id = bitstream_read_ue(reader); SYNTAX_IPRINT("idr_pic_id = %u\n", decoder->sh.idr_pic_id); } if (sps->pic_order_cnt_type == 0) { decoder->sh.pic_order_cnt_lsb = bitstream_read_u(reader, sps->log2_max_pic_order_cnt_lsb_minus4 + 4 ); SYNTAX_IPRINT("pic_order_cnt_lsb = %u\n", decoder->sh.pic_order_cnt_lsb); if (pps->bottom_field_pic_order_in_frame_present_flag && !decoder->sh.field_pic_flag) { decoder->sh.delta_pic_order_cnt_bottom = bitstream_read_se(reader); SYNTAX_IPRINT("delta_pic_order_cnt_bottom = %d\n", decoder->sh.delta_pic_order_cnt_bottom); } } if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) { decoder->sh.delta_pic_order_cnt[0] = bitstream_read_se(reader); SYNTAX_IPRINT("delta_pic_order_cnt[0] = %d\n", decoder->sh.delta_pic_order_cnt[0]); if (pps->bottom_field_pic_order_in_frame_present_flag && !decoder->sh.field_pic_flag) { decoder->sh.delta_pic_order_cnt[1] = bitstream_read_se(reader); SYNTAX_IPRINT("delta_pic_order_cnt[1] = %d\n", decoder->sh.delta_pic_order_cnt[1]); } } if (pps->redundant_pic_cnt_present_flag) { decoder->sh.redundant_pic_cnt = bitstream_read_ue(reader); SYNTAX_IPRINT("redundant_pic_cnt = %u\n", decoder->sh.redundant_pic_cnt); } switch (decoder->sh.slice_type) { case B: decoder->sh.direct_spatial_mv_pred_flag = bitstream_read_u(reader, 1); SYNTAX_IPRINT("direct_spatial_mv_pred_flag = %u\n", decoder->sh.direct_spatial_mv_pred_flag); case P: case SP: decoder->sh.num_ref_idx_active_override_flag = bitstream_read_u(reader, 1); SYNTAX_IPRINT("num_ref_idx_active_override_flag = %u\n", decoder->sh.num_ref_idx_active_override_flag); if (!decoder->sh.num_ref_idx_active_override_flag) { break; } decoder->sh.num_ref_idx_l0_active_minus1 = bitstream_read_ue(reader); SYNTAX_IPRINT("num_ref_idx_l0_active_minus1 = %u\n", decoder->sh.num_ref_idx_l0_active_minus1); if (decoder->sh.slice_type != B) { break; } decoder->sh.num_ref_idx_l1_active_minus1 = bitstream_read_ue(reader); SYNTAX_IPRINT("num_ref_idx_l1_active_minus1 = %u\n", decoder->sh.num_ref_idx_l1_active_minus1); break; default: break; } // ref_pic_list_modification( ) { unsigned ref_pic_list_modification_flag_l0; unsigned ref_pic_list_modification_flag_l1; uint32_t modification_of_pic_nums_idc; uint32_t abs_diff_pic_num_minus1; uint32_t long_term_pic_num; int predicted_picture = decoder->sh.frame_num; int remapped_picture; int refIdxL = 0; int l1 = 0; switch (decoder->sh.slice_type) { case P: case B: case SP: ref_pic_list_modification_flag_l0 = bitstream_read_u(reader, 1); SYNTAX_IPRINT("ref_pic_list_modification_flag_l0 = %u\n", ref_pic_list_modification_flag_l0); if (!ref_pic_list_modification_flag_l0) { goto flag_l1; } pics_num: modification_of_pic_nums_idc = bitstream_read_ue(reader); SYNTAX_IPRINT("modification_of_pic_nums_idc = %u\n", modification_of_pic_nums_idc); switch (modification_of_pic_nums_idc) { case 0 ... 1: abs_diff_pic_num_minus1 = bitstream_read_ue(reader); SYNTAX_IPRINT("abs_diff_pic_num_minus1 = %u\n", abs_diff_pic_num_minus1); if (modification_of_pic_nums_idc) { remapped_picture = predicted_picture + abs_diff_pic_num_minus1; SYNTAX_IPRINT("refIdxL%d <- %d\n", l1, remapped_picture); predicted_picture = remapped_picture; } goto pics_num; case 2: long_term_pic_num = bitstream_read_ue(reader); SYNTAX_IPRINT("long_term_pic_num = %u\n", long_term_pic_num); goto pics_num; case 3: if (l1) { break; } flag_l1: switch (decoder->sh.slice_type) { case B: case B_ONLY: ref_pic_list_modification_flag_l1 = bitstream_read_u(reader, 1); SYNTAX_IPRINT("ref_pic_list_modification_flag_l1 = %u\n", ref_pic_list_modification_flag_l1); if (!ref_pic_list_modification_flag_l1) { break; } l1 = 1; goto pics_num; } break; default: SYNTAX_ERR("slice header is malformed\n"); } break; default: break; } } switch (decoder->sh.slice_type) { case P_ONLY: case SP_ONLY: if (!pps->weighted_pred_flag) { break; } goto pred_weight_table; case B: if (!pps->weighted_bipred_idc) { break; } pred_weight_table: { pred_weight **pw; int sz, l = 0; decoder->sh.luma_log2_weight_denom = bitstream_read_ue(reader); SYNTAX_IPRINT("luma_log2_weight_denom = %u\n", decoder->sh.luma_log2_weight_denom); if (ChromaArrayType() != 0) { decoder->sh.chroma_log2_weight_denom = bitstream_read_ue(reader); SYNTAX_IPRINT("chroma_log2_weight_denom = %u\n", decoder->sh.chroma_log2_weight_denom); } table_fill: pw = l ? &decoder->sh.pred_weight_l1 : &decoder->sh.pred_weight_l0; sz = (l ? decoder->sh.num_ref_idx_l1_active_minus1 : decoder->sh.num_ref_idx_l0_active_minus1) + 1; *pw = realloc(*pw, sizeof(pred_weight) * sz); assert(*pw != NULL); for (i = 0; i < sz; i++) { (*pw)[i].luma_weight_l_flag = bitstream_read_u(reader, 1); SYNTAX_IPRINT("luma_weight_l%d_flag[%d] = %u\n", i, l, (*pw)[i].luma_weight_l_flag); if ((*pw)[i].luma_weight_l_flag) { (*pw)[i].luma_weight_l = bitstream_read_se(reader); SYNTAX_IPRINT("luma_weight_l%d[%d] = %u\n", i, l, (*pw)[i].luma_weight_l); } } if (decoder->sh.slice_type != B || l == 1) { break; } l = 1; goto table_fill; } default: break; } if (decoder->nal.ref_idc != 0) { if (IdrPicFlag) { decoder->sh.no_output_of_prior_pics_flag = bitstream_read_u(reader, 1); decoder->sh.long_term_reference_flag = bitstream_read_u(reader, 1); SYNTAX_IPRINT("no_output_of_prior_pics_flag = %u\n", decoder->sh.no_output_of_prior_pics_flag); SYNTAX_IPRINT("long_term_reference_flag = %u\n", decoder->sh.long_term_reference_flag); } else { unsigned adaptive_ref_pic_marking_mode_flag; uint32_t memory_management_control_operation; uint32_t difference_of_pic_nums_minus1; uint32_t long_term_pic_num; uint32_t long_term_frame_idx; uint32_t max_long_term_frame_idx_plus1; adaptive_ref_pic_marking_mode_flag = bitstream_read_u(reader, 1); SYNTAX_IPRINT("adaptive_ref_pic_marking_mode_flag = %u\n", adaptive_ref_pic_marking_mode_flag); if (adaptive_ref_pic_marking_mode_flag) { do { memory_management_control_operation = bitstream_read_ue(reader); SYNTAX_IPRINT("memory_management_control_operation = %u\n", memory_management_control_operation); switch (memory_management_control_operation) { case 1: case 3: difference_of_pic_nums_minus1 = bitstream_read_ue(reader); SYNTAX_IPRINT("difference_of_pic_nums_minus1 = %u\n", difference_of_pic_nums_minus1); if (memory_management_control_operation == 3) { goto long_term_frame_idx__; } break; case 2: long_term_pic_num = bitstream_read_ue(reader); SYNTAX_IPRINT("long_term_pic_num = %u\n", long_term_pic_num); break; long_term_frame_idx__: case 6: long_term_frame_idx = bitstream_read_ue(reader); SYNTAX_IPRINT("long_term_frame_idx = %u\n", long_term_frame_idx); break; case 4: max_long_term_frame_idx_plus1 = bitstream_read_ue(reader); SYNTAX_IPRINT("max_long_term_frame_idx_plus1 = %u\n", max_long_term_frame_idx_plus1); break; case 0: break; default: SYNTAX_ERR("memory_management_control_operation is malformed\n"); break; } } while (memory_management_control_operation != 0); } } } switch (decoder->sh.slice_type) { case I: case SI: break; default: if (!CABAC_MODE) { break; } decoder->sh.cabac_init_idc = bitstream_read_ue(reader); SYNTAX_IPRINT("cabac_init_idc = %u\n", decoder->sh.cabac_init_idc); } decoder->sh.slice_qp_delta = bitstream_read_se(reader); SYNTAX_IPRINT("slice_qp_delta = %d\n", decoder->sh.slice_qp_delta); switch (decoder->sh.slice_type) { case SP: decoder->sh.sp_for_switch_flag = bitstream_read_u(reader, 1); SYNTAX_IPRINT("sp_for_switch_flag = %u\n", decoder->sh.sp_for_switch_flag); case SI: decoder->sh.slice_qs_delta = bitstream_read_se(reader); SYNTAX_IPRINT("slice_qs_delta = %d\n", decoder->sh.slice_qs_delta); break; default: break; } if (pps->deblocking_filter_control_present_flag) { decoder->sh.disable_deblocking_filter_idc = bitstream_read_ue(reader); SYNTAX_IPRINT("disable_deblocking_filter_idc = %u\n", decoder->sh.disable_deblocking_filter_idc); if (decoder->sh.disable_deblocking_filter_idc != 1) { decoder->sh.slice_alpha_c0_offset_div2 = bitstream_read_se(reader); decoder->sh.slice_beta_offset_div2 = bitstream_read_se(reader); SYNTAX_IPRINT("slice_alpha_c0_offset_div2 = %d\n", decoder->sh.slice_alpha_c0_offset_div2); SYNTAX_IPRINT("slice_beta_offset_div2 = %d\n", decoder->sh.slice_beta_offset_div2); } } if (pps->num_slice_groups_minus1 > 0 && pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5) { int bits_nb = 32 - clz(pps->num_slice_groups_minus1 + 1); decoder->sh.slice_group_change_cycle = bitstream_read_u(reader, bits_nb); SYNTAX_IPRINT("slice_group_change_cycle = %u\n", decoder->sh.slice_group_change_cycle); } }
static char *ParsePlay(char *tok, slice_index start, slice_index proxy, play_length_type play_length) { /* seriesmovers with introductory moves */ char *result = 0; char *arrowpos; slice_index const proxy_next = alloc_proxy_slice(); TraceFunctionEntry(__func__); TraceFunctionParam("%s",tok); TraceFunctionParam("%u",start); TraceFunctionParam("%u",proxy); TraceFunctionParamListEnd(); if (token_starts_with("exact-",tok)) { play_length = play_length_exact; tok += 6; } arrowpos = strstr(tok,"->"); if (arrowpos!=0) { char *end; unsigned long const intro_len= strtoul(tok,&end,10); if (intro_len<1 || tok==end || end!=arrowpos) output_plaintext_input_error_message(WrongInt, 0); else { result = ParsePlay(arrowpos+2,start,proxy_next,play_length); if (result!=0 && SLICE_NEXT1(proxy_next)!=no_slice) { /* >=1 move of starting side required */ slice_index const branch = alloc_series_branch(2*intro_len-1,1); help_branch_set_end(branch,proxy_next,1); link_to_branch(proxy,branch); select_output_mode(proxy,output_mode_line); } } } else if (token_starts_with("ser-reci-h",tok)) { /* skip over "ser-reci-h" */ tok = ParseReciEnd(tok+10,start,proxy_next); if (tok!=0 && SLICE_NEXT1(proxy_next)!=no_slice) { stip_length_type length; stip_length_type min_length; result = ParseSeriesLength(tok,&length,&min_length,play_length); if (result!=0) { slice_index const branch = alloc_series_branch(length-1,min_length+1); help_branch_set_end(branch,proxy_next,1); link_to_branch(proxy,branch); solving_impose_starter(proxy_next,Black); select_output_mode(proxy,output_mode_line); } } } else if (token_starts_with("ser-hs",tok)) { tok = ParseGoal(tok+6,start,proxy_next); /* skip over "ser-hs" */ if (tok!=0) { stip_length_type length; stip_length_type min_length; result = ParseSeriesLength(tok,&length,&min_length,play_length); if (result!=0) { slice_index const defense_branch = MakeEndOfSelfPlay(proxy_next); /* in ser-hs, the series is 1 half-move longer than in usual * series play! */ if (length==0) pipe_link(proxy,defense_branch); else { slice_index const series = alloc_series_branch(length,min_length); slice_index const help_proxy = alloc_proxy_slice(); slice_index const help = alloc_help_branch(1,1); link_to_branch(help_proxy,help); help_branch_set_end_forced(help_proxy,defense_branch,1); help_branch_set_end(series,help_proxy,1); link_to_branch(proxy,series); } solving_impose_starter(proxy_next,White); select_output_mode(proxy,output_mode_line); } } } else if (token_starts_with("ser-h",tok)) { result = ParseSeries(tok+5,start,proxy,proxy_next,play_length); /* skip over "ser-h" */ if (result!=0) { slice_index const help = alloc_help_branch(1,1); help_branch_set_end_goal(help,proxy_next,1); help_branch_set_end(proxy,help,1); { slice_index const next = SLICE_NEXT1(proxy_next); assert(next!=no_slice); if (SLICE_TYPE(next)==STGoalReachedTester && SLICE_U(next).goal_handler.goal.type==goal_proofgame) solving_impose_starter(proxy_next,White); else solving_impose_starter(proxy_next,Black); } } } else if (token_starts_with("ser-s",tok)) { result = ParseSeries(tok+5,start,proxy,proxy_next,play_length); /* skip over "ser-s" */ if (result!=0) { help_branch_set_end_forced(proxy,MakeEndOfSelfPlay(proxy_next),1); solving_impose_starter(proxy_next,White); } } else if (token_starts_with("ser-r",tok)) { result = ParseSeries(tok+5,start,proxy,proxy_next,play_length); /* skip over "ser-r" */ if (result!=0) { slice_index const proxy_semi = MakeSemireflexBranch(proxy_next); help_branch_set_end_forced(proxy,proxy_semi,1); series_branch_insert_constraint(proxy,MakeReflexBranch(proxy_semi)); solving_impose_starter(proxy_next,White); } } else if (token_starts_with("ser-",tok)) { result = ParseSeries(tok+4,start,proxy,proxy_next,play_length); /* skip over "ser-" */ if (result!=0) { help_branch_set_end_goal(proxy,proxy_next,1); solving_impose_starter(proxy_next,Black); } } else if (token_starts_with("phser-r",tok)) { boolean const shorten = true; result = ParseHelp(tok+7, /* skip over phser-r */ start, proxy,proxy_next, play_length,shorten); if (result!=0) { slice_index const proxy_semi = MakeSemireflexBranch(proxy_next); help_branch_set_end_forced(proxy,proxy_semi,1); if (help_branch_insert_constraint(proxy,MakeReflexBranch(proxy_semi),0)) { help_branch_insert_check_zigzag(proxy); solving_impose_starter(proxy_next,White); } else result = 0; } } else if (token_starts_with("phser-s",tok)) { boolean const shorten = true; result = ParseHelp(tok+7, /* skip over phser-s */ start, proxy,proxy_next, play_length,shorten); if (result!=0) { help_branch_set_end_forced(proxy,MakeEndOfSelfPlay(proxy_next),1); help_branch_insert_check_zigzag(proxy); solving_impose_starter(proxy_next,White); } } else if (token_starts_with("phser-",tok)) { boolean const shorten = true; result = ParseHelp(tok+6, /* skip over phser- */ start, proxy,proxy_next, play_length,shorten); if (result!=0) { help_branch_set_end_goal(proxy,proxy_next,1); help_branch_insert_check_zigzag(proxy); solving_impose_starter(proxy_next,Black); } } else if (token_starts_with("pser-hs",tok)) { tok = ParseGoal(tok+7,start,proxy_next); /* skip over "ser-hs" */ if (tok!=0) { stip_length_type length; stip_length_type min_length; result = ParseSeriesLength(tok,&length,&min_length,play_length); if (result!=0) { slice_index const series = alloc_help_branch(length,min_length); slice_index const help_proxy = alloc_proxy_slice(); slice_index const help = alloc_help_branch(1,1); slice_index const defense_branch = MakeEndOfSelfPlay(proxy_next); link_to_branch(help_proxy,help); help_branch_set_end_forced(help_proxy,defense_branch,1); help_branch_set_end(series,help_proxy,1); link_to_branch(proxy,series); help_branch_insert_check_zigzag(proxy); solving_impose_starter(proxy_next,White); select_output_mode(proxy,output_mode_line); } } } else if (token_starts_with("pser-h",tok)) { boolean const shorten = true; result = ParseHelp(tok+6, /* skip over pser-h */ start, proxy,proxy_next, play_length,shorten); if (result!=0) { slice_index const to_goal = SLICE_NEXT1(proxy_next); slice_index const nested = alloc_help_branch(1,1); help_branch_set_end_goal(nested,proxy_next,1); help_branch_set_end(proxy,nested,1); help_branch_insert_check_zigzag(proxy); if (SLICE_TYPE(to_goal)==STGoalReachedTester && SLICE_U(to_goal).goal_handler.goal.type==goal_proofgame) solving_impose_starter(proxy_next,White); else solving_impose_starter(proxy_next,Black); } } else if (token_starts_with("pser-r",tok)) { boolean const ends_on_defense = false; result = ParseBattle(tok+6, /* skip over pser-r */ start, proxy,proxy_next, play_length,ends_on_defense); if (result!=0) { slice_index const proxy_semi = MakeSemireflexBranch(proxy_next); battle_branch_insert_end_of_branch_forced(proxy,proxy_semi); battle_branch_insert_attack_constraint(proxy,MakeReflexBranch(proxy_semi)); battle_branch_insert_defense_check_zigzag(proxy); select_output_mode(proxy,output_mode_line); solving_impose_starter(proxy_next,White); } } else if (token_starts_with("pser-s",tok)) { boolean const ends_on_defense = false; result = ParseBattle(tok+6, /* skip over pser-s */ start, proxy,proxy_next, play_length,ends_on_defense); if (result!=0) { battle_branch_insert_direct_end_of_branch(proxy, MakeEndOfSelfPlay(proxy_next)); solving_impose_starter(proxy_next,Black); select_output_mode(proxy,output_mode_line); battle_branch_insert_defense_check_zigzag(proxy); } } else if (token_starts_with("pser-",tok)) { boolean const ends_on_defense = false; result = ParseBattle(tok+5, /* skip over pser- */ start, proxy,proxy_next, play_length,ends_on_defense); if (result!=0) { select_output_mode(proxy,output_mode_line); battle_branch_insert_direct_end_of_branch_goal(proxy,proxy_next); battle_branch_insert_defense_check_zigzag(proxy); } } else if (token_starts_with("reci-h",tok)) { char * const tok2 = ParseReciEnd(tok+6, /* skip over "reci-h" */ start,proxy_next); if (tok2!=0 && SLICE_NEXT1(proxy_next)!=no_slice) { stip_length_type length; stip_length_type min_length; result = ParseHelpLength(tok2,&length,&min_length,play_length); if (length==1) { /* at least 2 half moves requried for a reciprocal stipulation */ output_plaintext_input_error_message(StipNotSupported,0); result = 0; } if (result!=0) { if (length==2) { pipe_link(proxy,SLICE_NEXT1(proxy_next)); dealloc_slice(proxy_next); } else { stip_length_type const min_length2 = (min_length<2 ? min_length : min_length-2); slice_index const branch = alloc_help_branch(length-2,min_length2); help_branch_set_end(branch,proxy_next,1); attach_help_branch(length,proxy,branch); } solving_impose_starter(proxy_next,Black); select_output_mode(proxy,output_mode_line); } } } else if (token_starts_with("dia",tok)) { result = ParseHelpDia(tok,start,proxy,proxy_next,play_length); if (result!=0) solving_impose_starter(proxy,White); } else if (token_starts_with("a=>b",tok)) { result = ParseHelpDia(tok,start,proxy,proxy_next,play_length); if (result!=0) solving_impose_starter(proxy,Black); } else if (token_starts_with("hs",tok)) { boolean const shorten = true; result = ParseHelp(tok+2, /* skip over "hs" */ start, proxy,proxy_next, play_length,shorten); if (result!=0) { help_branch_set_end_forced(proxy,MakeEndOfSelfPlay(proxy_next),1); solving_impose_starter(proxy_next,White); } } else if (token_starts_with("hr",tok)) { boolean const shorten = true; result = ParseHelp(tok+2, /* skip over "hr" */ start, proxy,proxy_next, play_length,shorten); if (result!=0) { slice_index const proxy_semi = MakeSemireflexBranch(proxy_next); help_branch_set_end_forced(proxy,proxy_semi,1); if (help_branch_insert_constraint(proxy,MakeReflexBranch(proxy_semi),0)) solving_impose_starter(proxy_next,White); else result = 0; } } else if (token_starts_with("h",tok)) { boolean const shorten = false; result = ParseHelp(tok+1, /* skip over "h" */ start, proxy,proxy_next, play_length,shorten); if (result!=0) { help_branch_set_end_goal(proxy,proxy_next,1); solving_impose_starter(proxy_next,Black); } } else if (token_starts_with("semi-r",tok)) { boolean const ends_on_defense = false; result = ParseBattle(tok+6, /* skip over "semi-r" */ start, proxy,proxy_next, play_length,ends_on_defense); if (result!=0) { battle_branch_insert_end_of_branch_forced(proxy, MakeSemireflexBranch(proxy_next)); select_output_mode(proxy,output_mode_tree); solving_impose_starter(proxy_next,White); } } else if (token_starts_with("s",tok)) { boolean const ends_on_defense = true; result = ParseBattle(tok+1, /* skip over 's' */ start, proxy,proxy_next, play_length,ends_on_defense); if (result!=0) { select_output_mode(proxy,output_mode_tree); battle_branch_insert_self_end_of_branch_goal(proxy,proxy_next); } } else if (token_starts_with("r",tok)) { boolean const ends_on_defense = false; result = ParseBattle(tok+1, /* skip over 'r' */ start, proxy,proxy_next, play_length,ends_on_defense); if (result!=0) { slice_index const proxy_semi = MakeSemireflexBranch(proxy_next); battle_branch_insert_end_of_branch_forced(proxy,proxy_semi); battle_branch_insert_attack_constraint(proxy,MakeReflexBranch(proxy_semi)); select_output_mode(proxy,output_mode_tree); solving_impose_starter(proxy_next,White); } } else { boolean const ends_on_defense = false; result = ParseBattle(tok,start,proxy,proxy_next,play_length,ends_on_defense); if (result!=0) { select_output_mode(proxy,output_mode_tree); battle_branch_insert_direct_end_of_branch_goal(proxy,proxy_next); } } if (result==0) dealloc_slices(proxy_next); TraceFunctionExit(__func__); TraceFunctionResult("%s",result); TraceFunctionResultEnd(); return result; }