diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-10-27 03:23:48 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-10-27 03:23:48 +0000 |
commit | 73b5f8d32198e78366361aa951ef9ce58d1f1d20 (patch) | |
tree | 13dc668296837d6699d8a56dc96bb04dc643fc74 | |
parent | efc30fd95dbc0c5285ab55aab592c8aad8d2c986 (diff) | |
parent | bfa6d88d8fd5dab60aaa1388f9407690dde06c60 (diff) | |
download | libavc-android14-qpr2-release.tar.gz |
Snap for 11012804 from bfa6d88d8fd5dab60aaa1388f9407690dde06c60 to 24Q1-releaseandroid-14.0.0_r33android-14.0.0_r32android-14.0.0_r31android-14.0.0_r30android-14.0.0_r29android14-qpr2-s3-releaseandroid14-qpr2-s2-releaseandroid14-qpr2-s1-releaseandroid14-qpr2-release
Change-Id: I774d8c3bcc04d5c1e1c5bbf182e7c71fa7f63ae6
190 files changed, 21068 insertions, 24056 deletions
diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index b3e7e40..bda845e 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v3 - name: Configure CMake - run: cmake -B ${{github.workspace}}/out -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DENABLE_MVC=1 -DENABLE_SVC=1 + run: cmake -B ${{github.workspace}}/out -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DENABLE_MVC=1 -DENABLE_SVC=1 -DENABLE_TESTS=1 - name: Build run: cmake --build ${{github.workspace}}/out --config ${{env.BUILD_TYPE}} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..912eacc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +third_party @@ -27,10 +27,10 @@ cc_library_headers { cc_library_headers { name: "libmvcdec_headers", export_include_dirs: [ - "decoder", - "decoder/mvc", "common", "common/mvc", + "decoder", + "decoder/mvc", ], min_sdk_version: "29", } @@ -131,8 +131,8 @@ cc_defaults { ], local_include_dirs: [ - "encoder/x86", "common/x86", + "encoder/x86", ], }, @@ -143,8 +143,8 @@ cc_defaults { ], local_include_dirs: [ - "encoder/x86", "common/x86", + "encoder/x86", ], }, }, @@ -182,8 +182,8 @@ cc_defaults { arch: { arm: { local_include_dirs: [ - "decoder/arm", "common/arm", + "decoder/arm", ], cflags: [ "-DARM", @@ -208,8 +208,8 @@ cc_defaults { "-DDEFAULT_ARCH=D_ARCH_ARMV8_GENERIC", ], local_include_dirs: [ - "decoder/arm", "common/armv8", + "decoder/arm", ], }, @@ -227,8 +227,8 @@ cc_defaults { ], local_include_dirs: [ - "decoder/x86", "common/x86", + "decoder/x86", ], }, @@ -240,8 +240,8 @@ cc_defaults { ], local_include_dirs: [ - "decoder/x86", "common/x86", + "decoder/x86", ], }, }, @@ -267,114 +267,114 @@ cc_library_static { srcs: [ "common/ih264_buf_mgr.c", + "common/ih264_chroma_intra_pred_filters.c", + "common/ih264_deblk_edge_filters.c", "common/ih264_disp_mgr.c", + "common/ih264_ihadamard_scaling.c", "common/ih264_inter_pred_filters.c", + "common/ih264_iquant_itrans_recon.c", "common/ih264_luma_intra_pred_filters.c", - "common/ih264_chroma_intra_pred_filters.c", - "common/ih264_padding.c", "common/ih264_mem_fns.c", - "common/ih264_deblk_edge_filters.c", - "common/ih264_iquant_itrans_recon.c", - "common/ih264_ihadamard_scaling.c", + "common/ih264_padding.c", "common/ih264_weighted_pred.c", "common/ithread.c", + "decoder/ih264d_api.c", + "decoder/ih264d_bitstrm.c", "decoder/ih264d_cabac.c", - "decoder/ih264d_parse_mb_header.c", - "decoder/ih264d_parse_cabac.c", - "decoder/ih264d_process_intra_mb.c", - "decoder/ih264d_inter_pred.c", - "decoder/ih264d_parse_bslice.c", - "decoder/ih264d_parse_pslice.c", - "decoder/ih264d_parse_islice.c", "decoder/ih264d_cabac_init_tables.c", - "decoder/ih264d_bitstrm.c", "decoder/ih264d_compute_bs.c", "decoder/ih264d_deblocking.c", - "decoder/ih264d_parse_headers.c", + "decoder/ih264d_dpb_mgr.c", + "decoder/ih264d_format_conv.c", + "decoder/ih264d_function_selector_generic.c", + "decoder/ih264d_inter_pred.c", "decoder/ih264d_mb_utils.c", "decoder/ih264d_mvpred.c", - "decoder/ih264d_utils.c", + "decoder/ih264d_nal.c", + "decoder/ih264d_parse_bslice.c", + "decoder/ih264d_parse_cabac.c", + "decoder/ih264d_parse_cavlc.c", + "decoder/ih264d_parse_headers.c", + "decoder/ih264d_parse_islice.c", + "decoder/ih264d_parse_mb_header.c", + "decoder/ih264d_parse_pslice.c", + "decoder/ih264d_parse_slice.c", "decoder/ih264d_process_bslice.c", + "decoder/ih264d_process_intra_mb.c", "decoder/ih264d_process_pslice.c", - "decoder/ih264d_parse_slice.c", "decoder/ih264d_quant_scaling.c", - "decoder/ih264d_parse_cavlc.c", - "decoder/ih264d_dpb_mgr.c", - "decoder/ih264d_nal.c", "decoder/ih264d_sei.c", "decoder/ih264d_tables.c", - "decoder/ih264d_vui.c", - "decoder/ih264d_format_conv.c", - "decoder/ih264d_thread_parse_decode.c", - "decoder/ih264d_api.c", "decoder/ih264d_thread_compute_bs.c", - "decoder/ih264d_function_selector_generic.c", + "decoder/ih264d_thread_parse_decode.c", + "decoder/ih264d_utils.c", + "decoder/ih264d_vui.c", ], arch: { arm: { srcs: [ - "decoder/arm/ih264d_function_selector.c", "common/arm/ih264_arm_memory_barrier.s", + "decoder/arm/ih264d_function_selector.c", ], neon: { srcs: [ - "decoder/arm/ih264d_function_selector_a9q.c", - "common/arm/ih264_intra_pred_chroma_a9q.s", - "common/arm/ih264_intra_pred_luma_16x16_a9q.s", - "common/arm/ih264_intra_pred_luma_4x4_a9q.s", - "common/arm/ih264_intra_pred_luma_8x8_a9q.s", + "common/arm/ih264_deblk_chroma_a9.s", + "common/arm/ih264_deblk_luma_a9.s", + "common/arm/ih264_default_weighted_pred_a9q.s", + "common/arm/ih264_ihadamard_scaling_a9.s", "common/arm/ih264_inter_pred_chroma_a9q.s", "common/arm/ih264_inter_pred_filters_luma_horz_a9q.s", "common/arm/ih264_inter_pred_filters_luma_vert_a9q.s", "common/arm/ih264_inter_pred_luma_copy_a9q.s", - "common/arm/ih264_inter_pred_luma_horz_qpel_a9q.s", - "common/arm/ih264_inter_pred_luma_vert_qpel_a9q.s", "common/arm/ih264_inter_pred_luma_horz_hpel_vert_hpel_a9q.s", - "common/arm/ih264_inter_pred_luma_horz_qpel_vert_qpel_a9q.s", - "common/arm/ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q.s", "common/arm/ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q.s", - "common/arm/ih264_default_weighted_pred_a9q.s", - "common/arm/ih264_weighted_pred_a9q.s", - "common/arm/ih264_weighted_bi_pred_a9q.s", - "common/arm/ih264_deblk_chroma_a9.s", - "common/arm/ih264_deblk_luma_a9.s", - "common/arm/ih264_padding_neon.s", + "common/arm/ih264_inter_pred_luma_horz_qpel_a9q.s", + "common/arm/ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q.s", + "common/arm/ih264_inter_pred_luma_horz_qpel_vert_qpel_a9q.s", + "common/arm/ih264_inter_pred_luma_vert_qpel_a9q.s", + "common/arm/ih264_intra_pred_chroma_a9q.s", + "common/arm/ih264_intra_pred_luma_16x16_a9q.s", + "common/arm/ih264_intra_pred_luma_4x4_a9q.s", + "common/arm/ih264_intra_pred_luma_8x8_a9q.s", "common/arm/ih264_iquant_itrans_recon_a9.s", "common/arm/ih264_iquant_itrans_recon_dc_a9.s", - "common/arm/ih264_ihadamard_scaling_a9.s", + "common/arm/ih264_padding_neon.s", + "common/arm/ih264_weighted_bi_pred_a9q.s", + "common/arm/ih264_weighted_pred_a9q.s", + "decoder/arm/ih264d_function_selector_a9q.c", ], }, }, arm64: { srcs: [ - "decoder/arm/ih264d_function_selector.c", - "decoder/arm/ih264d_function_selector_av8.c", - "common/armv8/ih264_intra_pred_chroma_av8.s", - "common/armv8/ih264_intra_pred_luma_16x16_av8.s", - "common/armv8/ih264_intra_pred_luma_4x4_av8.s", + "common/armv8/ih264_deblk_chroma_av8.s", + "common/armv8/ih264_deblk_luma_av8.s", + "common/armv8/ih264_default_weighted_pred_av8.s", + "common/armv8/ih264_ihadamard_scaling_av8.s", "common/armv8/ih264_inter_pred_chroma_av8.s", "common/armv8/ih264_inter_pred_filters_luma_horz_av8.s", "common/armv8/ih264_inter_pred_filters_luma_vert_av8.s", "common/armv8/ih264_inter_pred_luma_copy_av8.s", - "common/armv8/ih264_inter_pred_luma_horz_qpel_av8.s", - "common/armv8/ih264_inter_pred_luma_vert_qpel_av8.s", "common/armv8/ih264_inter_pred_luma_horz_hpel_vert_hpel_av8.s", - "common/armv8/ih264_inter_pred_luma_horz_qpel_vert_qpel_av8.s", - "common/armv8/ih264_inter_pred_luma_horz_qpel_vert_hpel_av8.s", "common/armv8/ih264_inter_pred_luma_horz_hpel_vert_qpel_av8.s", - "common/armv8/ih264_default_weighted_pred_av8.s", - "common/armv8/ih264_weighted_pred_av8.s", - "common/armv8/ih264_weighted_bi_pred_av8.s", - "common/armv8/ih264_deblk_chroma_av8.s", - "common/armv8/ih264_deblk_luma_av8.s", - "common/armv8/ih264_padding_neon_av8.s", + "common/armv8/ih264_inter_pred_luma_horz_qpel_av8.s", + "common/armv8/ih264_inter_pred_luma_horz_qpel_vert_hpel_av8.s", + "common/armv8/ih264_inter_pred_luma_horz_qpel_vert_qpel_av8.s", + "common/armv8/ih264_inter_pred_luma_vert_qpel_av8.s", + "common/armv8/ih264_intra_pred_chroma_av8.s", + "common/armv8/ih264_intra_pred_luma_16x16_av8.s", + "common/armv8/ih264_intra_pred_luma_4x4_av8.s", + "common/armv8/ih264_intra_pred_luma_8x8_av8.s", "common/armv8/ih264_iquant_itrans_recon_av8.s", "common/armv8/ih264_iquant_itrans_recon_dc_av8.s", - "common/armv8/ih264_ihadamard_scaling_av8.s", - "common/armv8/ih264_intra_pred_luma_8x8_av8.s", + "common/armv8/ih264_padding_neon_av8.s", + "common/armv8/ih264_weighted_bi_pred_av8.s", + "common/armv8/ih264_weighted_pred_av8.s", + "decoder/arm/ih264d_function_selector.c", + "decoder/arm/ih264d_function_selector_av8.c", ], }, @@ -389,41 +389,41 @@ cc_library_static { x86: { srcs: [ - "decoder/x86/ih264d_function_selector.c", - "decoder/x86/ih264d_function_selector_sse42.c", - "decoder/x86/ih264d_function_selector_ssse3.c", - "common/x86/ih264_inter_pred_filters_ssse3.c", - "common/x86/ih264_deblk_luma_ssse3.c", + "common/x86/ih264_chroma_intra_pred_filters_ssse3.c", "common/x86/ih264_deblk_chroma_ssse3.c", - "common/x86/ih264_padding_ssse3.c", - "common/x86/ih264_mem_fns_ssse3.c", + "common/x86/ih264_deblk_luma_ssse3.c", + "common/x86/ih264_ihadamard_scaling_sse42.c", + "common/x86/ih264_inter_pred_filters_ssse3.c", "common/x86/ih264_iquant_itrans_recon_dc_ssse3.c", + "common/x86/ih264_iquant_itrans_recon_sse42.c", "common/x86/ih264_iquant_itrans_recon_ssse3.c", "common/x86/ih264_luma_intra_pred_filters_ssse3.c", - "common/x86/ih264_chroma_intra_pred_filters_ssse3.c", - "common/x86/ih264_iquant_itrans_recon_sse42.c", + "common/x86/ih264_mem_fns_ssse3.c", + "common/x86/ih264_padding_ssse3.c", "common/x86/ih264_weighted_pred_sse42.c", - "common/x86/ih264_ihadamard_scaling_sse42.c", + "decoder/x86/ih264d_function_selector.c", + "decoder/x86/ih264d_function_selector_sse42.c", + "decoder/x86/ih264d_function_selector_ssse3.c", ], }, x86_64: { srcs: [ - "decoder/x86/ih264d_function_selector.c", - "decoder/x86/ih264d_function_selector_sse42.c", - "decoder/x86/ih264d_function_selector_ssse3.c", - "common/x86/ih264_inter_pred_filters_ssse3.c", - "common/x86/ih264_deblk_luma_ssse3.c", + "common/x86/ih264_chroma_intra_pred_filters_ssse3.c", "common/x86/ih264_deblk_chroma_ssse3.c", - "common/x86/ih264_padding_ssse3.c", - "common/x86/ih264_mem_fns_ssse3.c", + "common/x86/ih264_deblk_luma_ssse3.c", + "common/x86/ih264_ihadamard_scaling_sse42.c", + "common/x86/ih264_inter_pred_filters_ssse3.c", "common/x86/ih264_iquant_itrans_recon_dc_ssse3.c", + "common/x86/ih264_iquant_itrans_recon_sse42.c", "common/x86/ih264_iquant_itrans_recon_ssse3.c", "common/x86/ih264_luma_intra_pred_filters_ssse3.c", - "common/x86/ih264_chroma_intra_pred_filters_ssse3.c", - "common/x86/ih264_iquant_itrans_recon_sse42.c", + "common/x86/ih264_mem_fns_ssse3.c", + "common/x86/ih264_padding_ssse3.c", "common/x86/ih264_weighted_pred_sse42.c", - "common/x86/ih264_ihadamard_scaling_sse42.c", + "decoder/x86/ih264d_function_selector.c", + "decoder/x86/ih264d_function_selector_sse42.c", + "decoder/x86/ih264d_function_selector_ssse3.c", ], }, }, @@ -446,10 +446,10 @@ cc_library_static { ], export_include_dirs: [ - "decoder", - "decoder/mvc", "common", "common/mvc", + "decoder", + "decoder/mvc", ], srcs: [ @@ -473,49 +473,51 @@ cc_library_static { ], srcs: [ //Rate Control - "common/ih264_resi_trans_quant.c", - "common/ih264_iquant_itrans_recon.c", - "common/ih264_ihadamard_scaling.c", - "common/ih264_inter_pred_filters.c", - "common/ih264_luma_intra_pred_filters.c", + "common/ih264_buf_mgr.c", + "common/ih264_cabac_tables.c", + "common/ih264_cavlc_tables.c", "common/ih264_chroma_intra_pred_filters.c", - "common/ih264_padding.c", - "common/ih264_mem_fns.c", + "common/ih264_common_tables.c", "common/ih264_deblk_edge_filters.c", "common/ih264_deblk_tables.c", - "common/ih264_cavlc_tables.c", - "common/ih264_cabac_tables.c", - "common/ih264_common_tables.c", - "common/ih264_trans_data.c", - "common/ih264_buf_mgr.c", "common/ih264_dpb_mgr.c", + "common/ih264_ihadamard_scaling.c", + "common/ih264_inter_pred_filters.c", + "common/ih264_iquant_itrans_recon.c", "common/ih264_list.c", + "common/ih264_luma_intra_pred_filters.c", + "common/ih264_mem_fns.c", + "common/ih264_padding.c", + "common/ih264_resi_trans_quant.c", + "common/ih264_trans_data.c", "common/ithread.c", + "encoder/ih264e_api.c", + "encoder/ih264e_bitstream.c", + "encoder/ih264e_cabac.c", + "encoder/ih264e_cabac_encode.c", + "encoder/ih264e_cabac_init.c", + "encoder/ih264e_cavlc.c", + "encoder/ih264e_core_coding.c", + "encoder/ih264e_deblk.c", + "encoder/ih264e_encode.c", + "encoder/ih264e_encode_header.c", + "encoder/ih264e_fmt_conv.c", + "encoder/ih264e_function_selector_generic.c", "encoder/ih264e_globals.c", - "encoder/ih264e_intra_modes_eval.c", "encoder/ih264e_half_pel.c", + "encoder/ih264e_intra_modes_eval.c", "encoder/ih264e_mc.c", "encoder/ih264e_me.c", - "encoder/ih264e_rc_mem_interface.c", - "encoder/ih264e_time_stamp.c", "encoder/ih264e_modify_frm_rate.c", - "encoder/ih264e_rate_control.c", - "encoder/ih264e_core_coding.c", - "encoder/ih264e_deblk.c", - "encoder/ih264e_api.c", "encoder/ih264e_process.c", - "encoder/ih264e_encode.c", + "encoder/ih264e_rate_control.c", + "encoder/ih264e_rc_mem_interface.c", + "encoder/ih264e_sei.c", + "encoder/ih264e_time_stamp.c", "encoder/ih264e_utils.c", "encoder/ih264e_version.c", - "encoder/ih264e_bitstream.c", - "encoder/ih264e_cavlc.c", - "encoder/ih264e_cabac_init.c", - "encoder/ih264e_cabac.c", - "encoder/ih264e_cabac_encode.c", - "encoder/ih264e_encode_header.c", - "encoder/ih264e_function_selector_generic.c", - "encoder/ih264e_fmt_conv.c", - "encoder/irc_rate_control_api.c", + "encoder/ime.c", + "encoder/ime_distortion_metrics.c", "encoder/irc_bit_allocation.c", "encoder/irc_cbr_buffer_control.c", "encoder/irc_est_sad.c", @@ -523,47 +525,45 @@ cc_library_static { "encoder/irc_frame_info_collector.c", "encoder/irc_mb_model_based.c", "encoder/irc_picture_type.c", + "encoder/irc_rate_control_api.c", "encoder/irc_rd_model.c", "encoder/irc_vbr_storage_vbv.c", "encoder/irc_vbr_str_prms.c", - "encoder/ime.c", - "encoder/ime_distortion_metrics.c", - "encoder/ih264e_sei.c", "encoder/psnr.c", ], arch: { arm: { srcs: [ - "encoder/arm/ih264e_function_selector.c", "common/arm/ih264_arm_memory_barrier.s", + "encoder/arm/ih264e_function_selector.c", ], neon: { srcs: [ - "encoder/arm/ih264e_function_selector_a9q.c", - "common/arm/ih264_resi_trans_quant_a9.s", - "common/arm/ih264_iquant_itrans_recon_a9.s", - "common/arm/ih264_iquant_itrans_recon_dc_a9.s", - "common/arm/ih264_ihadamard_scaling_a9.s", "common/arm/ih264_deblk_chroma_a9.s", "common/arm/ih264_deblk_luma_a9.s", - "common/arm/ih264_intra_pred_chroma_a9q.s", - "common/arm/ih264_intra_pred_luma_16x16_a9q.s", - "common/arm/ih264_intra_pred_luma_4x4_a9q.s", - "common/arm/ih264_intra_pred_luma_8x8_a9q.s", + "common/arm/ih264_ihadamard_scaling_a9.s", "common/arm/ih264_inter_pred_chroma_a9q.s", "common/arm/ih264_inter_pred_filters_luma_horz_a9q.s", "common/arm/ih264_inter_pred_filters_luma_vert_a9q.s", "common/arm/ih264_inter_pred_luma_bilinear_a9q.s", "common/arm/ih264_inter_pred_luma_copy_a9q.s", - "common/arm/ih264_padding_neon.s", + "common/arm/ih264_intra_pred_chroma_a9q.s", + "common/arm/ih264_intra_pred_luma_16x16_a9q.s", + "common/arm/ih264_intra_pred_luma_4x4_a9q.s", + "common/arm/ih264_intra_pred_luma_8x8_a9q.s", + "common/arm/ih264_iquant_itrans_recon_a9.s", + "common/arm/ih264_iquant_itrans_recon_dc_a9.s", "common/arm/ih264_mem_fns_neon.s", + "common/arm/ih264_padding_neon.s", + "common/arm/ih264_resi_trans_quant_a9.s", "encoder/arm/ih264e_evaluate_intra16x16_modes_a9q.s", "encoder/arm/ih264e_evaluate_intra4x4_modes_a9q.s", "encoder/arm/ih264e_evaluate_intra_chroma_modes_a9q.s", - "encoder/arm/ih264e_half_pel.s", "encoder/arm/ih264e_fmt_conv.s", + "encoder/arm/ih264e_function_selector_a9q.c", + "encoder/arm/ih264e_half_pel.s", "encoder/arm/ime_distortion_metrics_a9q.s", ], }, @@ -571,24 +571,24 @@ cc_library_static { arm64: { srcs: [ - "encoder/arm/ih264e_function_selector.c", - "encoder/arm/ih264e_function_selector_av8.c", - "common/armv8/ih264_resi_trans_quant_av8.s", - "common/armv8/ih264_iquant_itrans_recon_av8.s", - "common/armv8/ih264_iquant_itrans_recon_dc_av8.s", + "common/armv8/ih264_deblk_chroma_av8.s", + "common/armv8/ih264_deblk_luma_av8.s", "common/armv8/ih264_ihadamard_scaling_av8.s", + "common/armv8/ih264_inter_pred_chroma_av8.s", + "common/armv8/ih264_inter_pred_filters_luma_horz_av8.s", + "common/armv8/ih264_inter_pred_filters_luma_vert_av8.s", + "common/armv8/ih264_inter_pred_luma_copy_av8.s", "common/armv8/ih264_intra_pred_chroma_av8.s", "common/armv8/ih264_intra_pred_luma_16x16_av8.s", "common/armv8/ih264_intra_pred_luma_4x4_av8.s", "common/armv8/ih264_intra_pred_luma_8x8_av8.s", - "common/armv8/ih264_inter_pred_luma_copy_av8.s", - "common/armv8/ih264_inter_pred_chroma_av8.s", - "common/armv8/ih264_inter_pred_filters_luma_horz_av8.s", - "common/armv8/ih264_inter_pred_filters_luma_vert_av8.s", - "common/armv8/ih264_padding_neon_av8.s", + "common/armv8/ih264_iquant_itrans_recon_av8.s", + "common/armv8/ih264_iquant_itrans_recon_dc_av8.s", "common/armv8/ih264_mem_fns_neon_av8.s", - "common/armv8/ih264_deblk_luma_av8.s", - "common/armv8/ih264_deblk_chroma_av8.s", + "common/armv8/ih264_padding_neon_av8.s", + "common/armv8/ih264_resi_trans_quant_av8.s", + "encoder/arm/ih264e_function_selector.c", + "encoder/arm/ih264e_function_selector_av8.c", "encoder/armv8/ih264e_evaluate_intra16x16_modes_av8.s", "encoder/armv8/ih264e_evaluate_intra_chroma_modes_av8.s", "encoder/armv8/ih264e_half_pel_av8.s", @@ -604,23 +604,23 @@ cc_library_static { x86: { srcs: [ - "encoder/x86/ih264e_function_selector.c", - "encoder/x86/ih264e_function_selector_sse42.c", - "encoder/x86/ih264e_function_selector_ssse3.c", - "common/x86/ih264_iquant_itrans_recon_ssse3.c", - "common/x86/ih264_iquant_itrans_recon_dc_ssse3.c", - "common/x86/ih264_ihadamard_scaling_ssse3.c", - "common/x86/ih264_inter_pred_filters_ssse3.c", - "common/x86/ih264_mem_fns_ssse3.c", - "common/x86/ih264_padding_ssse3.c", - "common/x86/ih264_luma_intra_pred_filters_ssse3.c", "common/x86/ih264_chroma_intra_pred_filters_ssse3.c", "common/x86/ih264_deblk_chroma_ssse3.c", "common/x86/ih264_deblk_luma_ssse3.c", - "common/x86/ih264_iquant_itrans_recon_sse42.c", "common/x86/ih264_ihadamard_scaling_sse42.c", + "common/x86/ih264_ihadamard_scaling_ssse3.c", + "common/x86/ih264_inter_pred_filters_ssse3.c", + "common/x86/ih264_iquant_itrans_recon_dc_ssse3.c", + "common/x86/ih264_iquant_itrans_recon_sse42.c", + "common/x86/ih264_iquant_itrans_recon_ssse3.c", + "common/x86/ih264_luma_intra_pred_filters_ssse3.c", + "common/x86/ih264_mem_fns_ssse3.c", + "common/x86/ih264_padding_ssse3.c", "common/x86/ih264_resi_trans_quant_sse42.c", "common/x86/ih264_weighted_pred_sse42.c", + "encoder/x86/ih264e_function_selector.c", + "encoder/x86/ih264e_function_selector_sse42.c", + "encoder/x86/ih264e_function_selector_ssse3.c", "encoder/x86/ih264e_half_pel_ssse3.c", "encoder/x86/ih264e_intra_modes_eval_ssse3.c", "encoder/x86/ime_distortion_metrics_sse42.c", @@ -629,23 +629,23 @@ cc_library_static { x86_64: { srcs: [ - "encoder/x86/ih264e_function_selector.c", - "encoder/x86/ih264e_function_selector_sse42.c", - "encoder/x86/ih264e_function_selector_ssse3.c", - "common/x86/ih264_iquant_itrans_recon_ssse3.c", - "common/x86/ih264_iquant_itrans_recon_dc_ssse3.c", - "common/x86/ih264_ihadamard_scaling_ssse3.c", - "common/x86/ih264_inter_pred_filters_ssse3.c", - "common/x86/ih264_mem_fns_ssse3.c", - "common/x86/ih264_padding_ssse3.c", - "common/x86/ih264_luma_intra_pred_filters_ssse3.c", "common/x86/ih264_chroma_intra_pred_filters_ssse3.c", "common/x86/ih264_deblk_chroma_ssse3.c", "common/x86/ih264_deblk_luma_ssse3.c", - "common/x86/ih264_iquant_itrans_recon_sse42.c", "common/x86/ih264_ihadamard_scaling_sse42.c", + "common/x86/ih264_ihadamard_scaling_ssse3.c", + "common/x86/ih264_inter_pred_filters_ssse3.c", + "common/x86/ih264_iquant_itrans_recon_dc_ssse3.c", + "common/x86/ih264_iquant_itrans_recon_sse42.c", + "common/x86/ih264_iquant_itrans_recon_ssse3.c", + "common/x86/ih264_luma_intra_pred_filters_ssse3.c", + "common/x86/ih264_mem_fns_ssse3.c", + "common/x86/ih264_padding_ssse3.c", "common/x86/ih264_resi_trans_quant_sse42.c", "common/x86/ih264_weighted_pred_sse42.c", + "encoder/x86/ih264e_function_selector.c", + "encoder/x86/ih264e_function_selector_sse42.c", + "encoder/x86/ih264e_function_selector_ssse3.c", "encoder/x86/ih264e_half_pel_ssse3.c", "encoder/x86/ih264e_intra_modes_eval_ssse3.c", "encoder/x86/ime_distortion_metrics_sse42.c", @@ -724,12 +724,12 @@ cc_library_static { neon: { srcs: [ - "encoder/arm/svc/isvce_function_selector_a9q.c", "common/arm/svc/isvc_intra_sampling_neon.c", "common/arm/svc/isvc_iquant_itrans_recon_neon.c", "common/arm/svc/isvc_mem_fns_neon.c", "common/arm/svc/isvc_resi_trans_quant_neon.c", "encoder/arm/svc/isvce_downscaler_neon.c", + "encoder/arm/svc/isvce_function_selector_a9q.c", "encoder/arm/svc/isvce_rc_utils_neon.c", "encoder/arm/svc/isvce_residual_pred_neon.c", ], @@ -738,18 +738,18 @@ cc_library_static { arm64: { local_include_dirs: [ - "common/arm/svc", "encoder/arm/svc", + "common/arm/svc", ], srcs: [ - "encoder/arm/svc/isvce_function_selector.c", - "encoder/arm/svc/isvce_function_selector_av8.c", "common/arm/svc/isvc_intra_sampling_neon.c", "common/arm/svc/isvc_iquant_itrans_recon_neon.c", "common/arm/svc/isvc_mem_fns_neon.c", "common/arm/svc/isvc_resi_trans_quant_neon.c", "encoder/arm/svc/isvce_downscaler_neon.c", + "encoder/arm/svc/isvce_function_selector.c", + "encoder/arm/svc/isvce_function_selector_av8.c", "encoder/arm/svc/isvce_rc_utils_neon.c", "encoder/arm/svc/isvce_residual_pred_neon.c", ], @@ -767,8 +767,8 @@ cc_library_static { x86: { local_include_dirs: [ - "encoder/x86/svc", "common/x86/svc", + "encoder/x86/svc", ], srcs: [ @@ -791,8 +791,8 @@ cc_library_static { x86_64: { local_include_dirs: [ - "encoder/x86/svc", "common/x86/svc", + "encoder/x86/svc", ], srcs: [ @@ -823,27 +823,25 @@ cc_library_static { ], export_include_dirs: [ - "decoder", - "decoder/svc", "common", "common/svc", + "decoder", + "decoder/svc", ], srcs: [ - "decoder/svc/isvcd_ii_pred.c", - "decoder/svc/isvcd_intra_resamp.c", - "decoder/svc/isvcd_iquant_itrans.c", - "decoder/svc/isvcd_iquant_itrans_residual.c", - "decoder/svc/isvcd_iquant_itrans_residual_recon.c", - "decoder/svc/isvcd_mode_mv_resamp.c", - "decoder/svc/isvcd_pred_residual_recon.c", - "decoder/svc/isvcd_residual_resamp.c", "decoder/svc/isvcd_api.c", "decoder/svc/isvcd_cabac.c", "decoder/svc/isvcd_cabac_init_tables.c", "decoder/svc/isvcd_compute_bs.c", "decoder/svc/isvcd_function_selector_generic.c", + "decoder/svc/isvcd_ii_pred.c", + "decoder/svc/isvcd_intra_resamp.c", + "decoder/svc/isvcd_iquant_itrans.c", + "decoder/svc/isvcd_iquant_itrans_residual.c", + "decoder/svc/isvcd_iquant_itrans_residual_recon.c", "decoder/svc/isvcd_mb_utils.c", + "decoder/svc/isvcd_mode_mv_resamp.c", "decoder/svc/isvcd_nal.c", "decoder/svc/isvcd_nal_parse.c", "decoder/svc/isvcd_parse_cavlc.c", @@ -852,8 +850,10 @@ cc_library_static { "decoder/svc/isvcd_parse_epslice.c", "decoder/svc/isvcd_parse_headers.c", "decoder/svc/isvcd_parse_slice.c", + "decoder/svc/isvcd_pred_residual_recon.c", "decoder/svc/isvcd_process_ebslice.c", "decoder/svc/isvcd_process_epslice.c", + "decoder/svc/isvcd_residual_resamp.c", "decoder/svc/isvcd_thread_compute_bs.c", "decoder/svc/isvcd_thread_parse_decode.c", "decoder/svc/isvcd_utils.c", @@ -929,4 +929,3 @@ cc_library_static { }, } -subdirs = ["test"] diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f04b12..d0c37d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ set(AVC_ROOT "${CMAKE_CURRENT_SOURCE_DIR}") set(AVC_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}") option(ENABLE_MVC "Enables svcenc and svcdec builds" OFF) option(ENABLE_SVC "Enables svcenc and svcdec builds" OFF) +option(ENABLE_TESTS "Enables gtest based unit tests" OFF) if("${AVC_ROOT}" STREQUAL "${AVC_CONFIG_DIR}") message( @@ -48,14 +49,14 @@ if (${ENABLE_SVC}) include("${AVC_ROOT}/decoder/svc/libsvcdec.cmake") endif() -include("${AVC_ROOT}/test/decoder/avcdec.cmake") +include("${AVC_ROOT}/examples/avcdec/avcdec.cmake") if (${ENABLE_MVC}) - include("${AVC_ROOT}/test/mvcdec/mvcdec.cmake") + include("${AVC_ROOT}/examples/mvcdec/mvcdec.cmake") endif() -include("${AVC_ROOT}/test/encoder/avcenc.cmake") +include("${AVC_ROOT}/examples/avcenc/avcenc.cmake") if (${ENABLE_SVC}) - include("${AVC_ROOT}/test/svcenc/svcenc.cmake") - include("${AVC_ROOT}/test/svcdec/svcdec.cmake") + include("${AVC_ROOT}/examples/svcenc/svcenc.cmake") + include("${AVC_ROOT}/examples/svcdec/svcdec.cmake") endif() include("${AVC_ROOT}/fuzzer/avc_dec_fuzzer.cmake") @@ -67,3 +68,7 @@ if (${ENABLE_SVC}) include("${AVC_ROOT}/fuzzer/svc_enc_fuzzer.cmake") include("${AVC_ROOT}/fuzzer/svc_dec_fuzzer.cmake") endif() + +if (${ENABLE_TESTS}) + include("${AVC_ROOT}/tests/AvcEncTest.cmake") +endif() @@ -9,11 +9,11 @@ third_party { type: GIT value: "https://github.com/ittiam-systems/libavc.git" } - version: "v1.2.0" + version: "v1.3.0" license_type: NOTICE last_upgrade_date { year: 2023 - month: 8 - day: 8 + month: 10 + day: 23 } } diff --git a/common/ih264_buf_mgr.c b/common/ih264_buf_mgr.c index 0b5a596..a6c66d0 100644 --- a/common/ih264_buf_mgr.c +++ b/common/ih264_buf_mgr.c @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,53 +27,65 @@ * Contains function definitions for buffer management * * @author -* Srinivas T +* ittiam * * @par List of Functions: -* - ih264_buf_mgr_size() -* - ih264_buf_mgr_lock() -* - ih264_buf_mgr_unlock() -* - ih264_buf_mgr_yield() -* - ih264_buf_mgr_free() -* - ih264_buf_mgr_init() -* - ih264_buf_mgr_add() -* - ih264_buf_mgr_get_next_free() -* - ih264_buf_mgr_check_free() -* - ih264_buf_mgr_set_status() -* - ih264_buf_mgr_get_status() -* - ih264_buf_mgr_get_buf() -* - ih264_buf_mgr_get_bufid() -* - ih264_buf_mgr_get_num_active_buf() +* - ih264_buf_mgr_size +* - ih264_buf_mgr_lock +* - ih264_buf_mgr_unlock +* - ih264_buf_mgr_yield +* - ih264_buf_mgr_free +* - ih264_buf_mgr_init +* - ih264_buf_mgr_add +* - ih264_buf_mgr_get_next_free +* - ih264_buf_mgr_check_free +* - ih264_buf_mgr_release +* - ih264_buf_mgr_set_status +* - ih264_buf_mgr_get_status +* - ih264_buf_mgr_get_buf +* - ih264_buf_mgr_get_bufid +* - ih264_buf_mgr_get_num_active_buf * * @remarks -* None +* none * ******************************************************************************* */ + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ + +/* System Include Files */ #include <stdio.h> #include <stdlib.h> + +/* User Include Files */ #include "ih264_typedefs.h" +#include "ithread.h" #include "ih264_macros.h" -#include "ih264_defs.h" #include "ih264_error.h" +#include "ih264_defs.h" #include "ih264_buf_mgr.h" -#include "ithread.h" + +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ /** ******************************************************************************* * -* @brief Returns size for buf queue context. Does not include buf queue buffer -* requirements +* @brief Returns size for buffer queue context. Does not include the size of the +* actual buffers that are stored here. * -* @par Description -* Returns size for buf queue context. Does not include buf queue buffer -* requirements. Buffer size required to store the bufs should be allocated in -* addition to the value returned here. +* @par Description +* Returns size for buf queue context. Does not include the size of the +* actual buffers that are stored here. * * @returns Size of the buf queue context * -* @remarks +* @remarks none * ******************************************************************************* */ @@ -89,43 +102,40 @@ WORD32 ih264_buf_mgr_size(void) /** ******************************************************************************* * -* @brief -* Locks the buf_mgr context +* @brief Locks the buffer manager context * -* @par Description -* Locks the buf_mgr context by calling ithread_mutex_lock() +* @par Description +* Locks the buffer manager context by calling ithread_mutex_lock() * * @param[in] ps_buf_mgr -* Job Queue context +* Pointer to the buffer manager * * @returns IH264_FAIL if mutex lock fails else IH264_SUCCESS * -* @remarks +* @remarks none * ******************************************************************************* */ IH264_ERROR_T ih264_buf_mgr_lock(buf_mgr_t *ps_buf_mgr) { WORD32 retval; + retval = ithread_mutex_lock(ps_buf_mgr->pv_mutex); if(retval) - { return IH264_FAIL; - } return IH264_SUCCESS; } /** ******************************************************************************* * -* @brief -* Unlocks the buf_mgr context +* @brief Unlocks the buffer manager context * -* @par Description -* Unlocks the buf_mgr context by calling ithread_mutex_unlock() +* @par Description +* Unlocks the buffer manager context by calling ithread_mutex_unlock() * * @param[in] ps_buf_mgr -* Job Queue context +* Pointer to the buffer manager * * @returns IH264_FAIL if mutex unlock fails else IH264_SUCCESS * @@ -133,33 +143,30 @@ IH264_ERROR_T ih264_buf_mgr_lock(buf_mgr_t *ps_buf_mgr) * ******************************************************************************* */ - IH264_ERROR_T ih264_buf_mgr_unlock(buf_mgr_t *ps_buf_mgr) { WORD32 retval; + retval = ithread_mutex_unlock(ps_buf_mgr->pv_mutex); if(retval) - { return IH264_FAIL; - } return IH264_SUCCESS; - } + /** ******************************************************************************* * -* @brief -* Yeilds the thread +* @brief Yields the thread * -* @par Description -* Unlocks the buf_mgr context by calling -* ih264_buf_mgr_unlock(), ithread_yield() and then ih264_buf_mgr_lock() -* buf_mgr is unlocked before to ensure the buf_mgr can be accessed by other threads -* If unlock is not done before calling yield then no other thread can access -* the buf_mgr functions and update buf_mgr. +* @par Description +* Unlocks the buf_mgr context by calling ih264_buf_mgr_unlock(), +* ithread_yield() and then ih264_buf_mgr_lock(). buf_mgr is unlocked before to +* ensure the buf_mgr can be accessed by other threads. If unlock is not done +* before calling yield then no other thread can access the buf_mgr functions +* and update buf_mgr. * * @param[in] ps_buf_mgr -* Job Queue context +* Pointer to the buffer manager * * @returns IH264_FAIL if mutex lock unlock or yield fails else IH264_SUCCESS * @@ -169,89 +176,78 @@ IH264_ERROR_T ih264_buf_mgr_unlock(buf_mgr_t *ps_buf_mgr) */ IH264_ERROR_T ih264_buf_mgr_yield(buf_mgr_t *ps_buf_mgr) { + IH264_ERROR_T ret; - IH264_ERROR_T ret = IH264_SUCCESS; - - IH264_ERROR_T rettmp; - rettmp = ih264_buf_mgr_unlock(ps_buf_mgr); - RETURN_IF((rettmp != IH264_SUCCESS), rettmp); + ret = ih264_buf_mgr_unlock(ps_buf_mgr); + RETURN_IF((ret != IH264_SUCCESS), ret); //ithread_usleep(10); ithread_yield(); - rettmp = ih264_buf_mgr_lock(ps_buf_mgr); - RETURN_IF((rettmp != IH264_SUCCESS), rettmp); - return ret; + ret = ih264_buf_mgr_lock(ps_buf_mgr); + RETURN_IF((ret != IH264_SUCCESS), ret); + return IH264_SUCCESS; } - /** ******************************************************************************* * -* @brief free the buf queue pointers +* @brief frees the buffer manager context * -* @par Description -* Frees the buf_mgr context +* @par Description +* Frees the buffer manager context * -* @param[in] pv_buf -* Memoy for buf queue buffer and buf queue context +* @param[in] ps_buf_mgr +* Pointer to the buffer manager * -* @returns Pointer to buf queue context +* @returns IH264_FAIL if mutex destory fails else IH264_SUCCESS * * @remarks -* Since it will be called only once by master thread this is not thread safe. +* Since it will be called only once by master thread this is not thread safe. * ******************************************************************************* */ IH264_ERROR_T ih264_buf_mgr_free(buf_mgr_t *ps_buf_mgr) { WORD32 ret; - ret = ithread_mutex_destroy(ps_buf_mgr->pv_mutex); + ret = ithread_mutex_destroy(ps_buf_mgr->pv_mutex); if(0 == ret) return IH264_SUCCESS; - else - return IH264_FAIL; + return IH264_FAIL; } + /** ******************************************************************************* * -* @brief -* Buffer manager initialization function. +* @brief Buffer manager context initialization. * * @par Description: -* Initializes the buffer manager structure +* Initializes the buffer manager structure * -* @param[in] ps_buf_mgr +* @param[in] pv_buf * Pointer to the buffer manager * -* @returns +* @returns none * -* @remarks -* None +* @remarks none * ******************************************************************************* */ - - -void *ih264_buf_mgr_init(void *pv_buf) +void* ih264_buf_mgr_init(void *pv_buf) { WORD32 id; - UWORD8 *pu1_buf; - buf_mgr_t *ps_buf_mgr; - pu1_buf = (UWORD8 *)pv_buf; + UWORD8 *pu1_buf = (UWORD8 *)pv_buf; + buf_mgr_t *ps_buf_mgr = (buf_mgr_t *)pu1_buf; - ps_buf_mgr = (buf_mgr_t *)pu1_buf; pu1_buf += sizeof(buf_mgr_t); - ps_buf_mgr->pv_mutex = pu1_buf; - pu1_buf += ithread_get_mutex_lock_size(); + pu1_buf += ithread_get_mutex_lock_size(); ithread_mutex_init(ps_buf_mgr->pv_mutex); ps_buf_mgr->i4_max_buf_cnt = BUF_MGR_MAX_CNT; ps_buf_mgr->i4_active_buf_cnt = 0; - for(id = 0; id < BUF_MGR_MAX_CNT; id++) { ps_buf_mgr->au4_status[id] = 0; @@ -264,19 +260,17 @@ void *ih264_buf_mgr_init(void *pv_buf) /** ******************************************************************************* * -* @brief -* Buffer manager reset function. +* @brief Buffer manager reset function. * * @par Description: -* resets the buffer manager structure +* resets the buffer manager structure * -* @param[in] ps_buf_mgr +* @param[in] pv_buf * Pointer to the buffer manager * -* @returns +* @returns none * -* @remarks -* None +* @remarks none * ******************************************************************************* */ @@ -298,12 +292,11 @@ void ih264_buf_mgr_reset(void *pv_buf_mgr) /** ******************************************************************************* * -* @brief -* Adds and increments the buffer and buffer count. +* @brief Adds and increments the buffer and buffer count. * * @par Description: -* Adds a buffer to the buffer manager if it is not already present and -* increments the active buffer count +* Adds a buffer to the buffer manager if it is not already present and +* increments the active buffer count * * @param[in] ps_buf_mgr * Pointer to the buffer manager @@ -311,10 +304,13 @@ void ih264_buf_mgr_reset(void *pv_buf_mgr) * @param[in] pv_ptr * Pointer to the buffer to be added * +* @param[in] buf_id +* buffer id +* * @returns Returns 0 on success, -1 otherwise * * @remarks -* None +* none * ******************************************************************************* */ @@ -322,8 +318,8 @@ IH264_ERROR_T ih264_buf_mgr_add(buf_mgr_t *ps_buf_mgr, void *pv_ptr, WORD32 buf_id) { - IH264_ERROR_T ret = IH264_SUCCESS; + ret = ih264_buf_mgr_lock(ps_buf_mgr); RETURN_IF((ret != IH264_SUCCESS), ret); @@ -332,17 +328,15 @@ IH264_ERROR_T ih264_buf_mgr_add(buf_mgr_t *ps_buf_mgr, { ret = ih264_buf_mgr_unlock(ps_buf_mgr); RETURN_IF((ret != IH264_SUCCESS), ret); - return IH264_FAIL; } /* Check if the current ID is being used to hold some other buffer */ if((ps_buf_mgr->apv_ptr[buf_id] != NULL) && - (ps_buf_mgr->apv_ptr[buf_id] !=pv_ptr)) + (ps_buf_mgr->apv_ptr[buf_id] != pv_ptr)) { ret = ih264_buf_mgr_unlock(ps_buf_mgr); RETURN_IF((ret != IH264_SUCCESS), ret); - return IH264_FAIL; } ps_buf_mgr->apv_ptr[buf_id] = pv_ptr; @@ -357,12 +351,11 @@ IH264_ERROR_T ih264_buf_mgr_add(buf_mgr_t *ps_buf_mgr, /** ******************************************************************************* * -* @brief -* Gets the next free buffer. +* @brief Gets the next free buffer. * * @par Description: -* Returns the next free buffer available and sets the corresponding status -* to DEC +* Returns the next free buffer available and sets the corresponding status +* to Busy * * @param[in] ps_buf_mgr * Pointer to the buffer manager @@ -373,26 +366,26 @@ IH264_ERROR_T ih264_buf_mgr_add(buf_mgr_t *ps_buf_mgr, * @returns Pointer to the free buffer * * @remarks -* None +* none * ******************************************************************************* */ void* ih264_buf_mgr_get_next_free(buf_mgr_t *ps_buf_mgr, WORD32 *pi4_buf_id) { WORD32 id; - void *pv_ret_ptr; + void *pv_ret_ptr = NULL; IH264_ERROR_T ret = IH264_SUCCESS; + ret = ih264_buf_mgr_lock(ps_buf_mgr); RETURN_IF((ret != IH264_SUCCESS), NULL); - pv_ret_ptr = NULL; for(id = 0; id < ps_buf_mgr->i4_active_buf_cnt; id++) { /* Check if the buffer is non-null and status is zero */ if((ps_buf_mgr->au4_status[id] == 0) && (ps_buf_mgr->apv_ptr[id])) { *pi4_buf_id = id; - /* DEC is set to 1 */ + /* mark buffer as busy before returning */ ps_buf_mgr->au4_status[id] = 1; pv_ret_ptr = ps_buf_mgr->apv_ptr[id]; break; @@ -404,12 +397,10 @@ void* ih264_buf_mgr_get_next_free(buf_mgr_t *ps_buf_mgr, WORD32 *pi4_buf_id) return pv_ret_ptr; } - /** ******************************************************************************* * -* @brief -* Checks the buffer manager for free buffers available. +* @brief Checks the buffer manager for free buffers available. * * @par Description: * Checks if there are any free buffers available @@ -417,22 +408,22 @@ void* ih264_buf_mgr_get_next_free(buf_mgr_t *ps_buf_mgr, WORD32 *pi4_buf_id) * @param[in] ps_buf_mgr * Pointer to the buffer manager * -* @returns Returns 0 if available, -1 otherwise +* @returns Returns IH264_SUCCESS if available, IH264_FAIL otherwise * * @remarks -* None +* none * ******************************************************************************* */ IH264_ERROR_T ih264_buf_mgr_check_free(buf_mgr_t *ps_buf_mgr) { WORD32 id; - IH264_ERROR_T ret = IH264_SUCCESS; + IH264_ERROR_T ret = IH264_FAIL; IH264_ERROR_T rettmp = IH264_SUCCESS; + rettmp = ih264_buf_mgr_lock(ps_buf_mgr); - RETURN_IF((rettmp != IH264_SUCCESS), ret); + RETURN_IF((rettmp != IH264_SUCCESS), rettmp); - ret = IH264_FAIL; for(id = 0; id < ps_buf_mgr->i4_active_buf_cnt; id++) { if((ps_buf_mgr->au4_status[id] == 0) && @@ -443,22 +434,19 @@ IH264_ERROR_T ih264_buf_mgr_check_free(buf_mgr_t *ps_buf_mgr) } } rettmp = ih264_buf_mgr_unlock(ps_buf_mgr); - RETURN_IF((rettmp != IH264_SUCCESS), ret); + RETURN_IF((rettmp != IH264_SUCCESS), rettmp); return ret; - } - /** ******************************************************************************* * -* @brief -* Resets the status bits. +* @brief Release buffer to buffer manager * * @par Description: -* resets the status bits that the mask contains (status corresponding to -* the id) +* Clear the status bit basing on the mask. If the buffer is no longer used by +* the codec then release back to the pool * * @param[in] ps_buf_mgr * Pointer to the buffer manager @@ -469,10 +457,10 @@ IH264_ERROR_T ih264_buf_mgr_check_free(buf_mgr_t *ps_buf_mgr) * @param[in] mask * Contains the bits that are to be reset * -* @returns 0 if success, -1 otherwise +* @returns IH264_SUCCESS if success, IH264_FAIL otherwise * * @remarks -* None +* none * ******************************************************************************* */ @@ -481,10 +469,10 @@ IH264_ERROR_T ih264_buf_mgr_release(buf_mgr_t *ps_buf_mgr, UWORD32 mask) { IH264_ERROR_T ret = IH264_SUCCESS; + ret = ih264_buf_mgr_lock(ps_buf_mgr); RETURN_IF((ret != IH264_SUCCESS), ret); - /* If the given id is pointing to an id which is not yet added */ if(buf_id >= ps_buf_mgr->i4_active_buf_cnt) { @@ -495,31 +483,25 @@ IH264_ERROR_T ih264_buf_mgr_release(buf_mgr_t *ps_buf_mgr, ps_buf_mgr->au4_status[buf_id] &= ~mask; - -/* If both the REF and DISP are zero, DEC is set to zero */ + /* If both the REF and DISP are zero, DEC is set to zero */ if(ps_buf_mgr->au4_status[buf_id] == 1) { ps_buf_mgr->au4_status[buf_id] = 0; } - ret = ih264_buf_mgr_unlock(ps_buf_mgr); RETURN_IF((ret != IH264_SUCCESS), ret); return ret; } - /** ******************************************************************************* * -* @brief -* Sets the status bit. +* @brief Sets the status bit. * * @par Description: -* sets the status bits that the mask contains (status corresponding to the -* id) -* +* sets the status bits that the mask contains (status corresponding to the id) * * @param[in] ps_buf_mgr * Pointer to the buffer manager @@ -527,14 +509,13 @@ IH264_ERROR_T ih264_buf_mgr_release(buf_mgr_t *ps_buf_mgr, * @param[in] buf_id * ID of the buffer whose status needs to be modified * -* * @param[in] mask * Contains the bits that are to be set * -* @returns 0 if success, -1 otherwise +* @returns IH264_SUCCESS if success, IH264_FAIL otherwise * * @remarks -* None +* none * ******************************************************************************* */ @@ -543,6 +524,7 @@ IH264_ERROR_T ih264_buf_mgr_set_status(buf_mgr_t *ps_buf_mgr, UWORD32 mask) { IH264_ERROR_T ret = IH264_SUCCESS; + ret = ih264_buf_mgr_lock(ps_buf_mgr); RETURN_IF((ret != IH264_SUCCESS), ret); @@ -553,7 +535,6 @@ IH264_ERROR_T ih264_buf_mgr_set_status(buf_mgr_t *ps_buf_mgr, return IH264_FAIL; } - if((ps_buf_mgr->au4_status[buf_id] & mask) != 0) { ret = ih264_buf_mgr_unlock(ps_buf_mgr); @@ -568,12 +549,10 @@ IH264_ERROR_T ih264_buf_mgr_set_status(buf_mgr_t *ps_buf_mgr, return ret; } - /** ******************************************************************************* * -* @brief -* Returns the status of the buffer. +* @brief Returns the status of the buffer. * * @par Description: * Returns the status of the buffer corresponding to the id @@ -587,11 +566,11 @@ IH264_ERROR_T ih264_buf_mgr_set_status(buf_mgr_t *ps_buf_mgr, * @returns Status of the buffer corresponding to the id * * @remarks -* None +* none * ******************************************************************************* */ -WORD32 ih264_buf_mgr_get_status( buf_mgr_t *ps_buf_mgr, WORD32 buf_id ) +WORD32 ih264_buf_mgr_get_status(buf_mgr_t *ps_buf_mgr, WORD32 buf_id) { IH264_ERROR_T ret = IH264_SUCCESS; UWORD32 status; @@ -607,15 +586,13 @@ WORD32 ih264_buf_mgr_get_status( buf_mgr_t *ps_buf_mgr, WORD32 buf_id ) return status; } - /** ******************************************************************************* * -* @brief -* Gets the buffer from the buffer manager +* @brief Gets the buffer from the buffer manager * * @par Description: -* Returns the pointer to the buffer corresponding to the id +* Returns the pointer to the buffer corresponding to the id * * @param[in] ps_buf_mgr * Pointer to the buffer manager @@ -626,7 +603,7 @@ WORD32 ih264_buf_mgr_get_status( buf_mgr_t *ps_buf_mgr, WORD32 buf_id ) * @returns Pointer to the buffer required * * @remarks -* None +* none * ******************************************************************************* */ @@ -634,6 +611,7 @@ void* ih264_buf_mgr_get_buf(buf_mgr_t *ps_buf_mgr, WORD32 buf_id) { IH264_ERROR_T ret = IH264_SUCCESS; void *pv_buf; + ret = ih264_buf_mgr_lock(ps_buf_mgr); RETURN_IF((ret != IH264_SUCCESS), NULL); @@ -645,13 +623,11 @@ void* ih264_buf_mgr_get_buf(buf_mgr_t *ps_buf_mgr, WORD32 buf_id) return pv_buf; } - /** ******************************************************************************* * -* @brief -* Gets the buffer id from the buffer manager if the buffer is added to the -* buffer manager +* @brief Gets the buffer id from the buffer manager if the buffer is added to +* the buffer manager * * @par Description: * Returns the buffer id corresponding to the given buffer if it exists @@ -665,7 +641,7 @@ void* ih264_buf_mgr_get_buf(buf_mgr_t *ps_buf_mgr, WORD32 buf_id) * @returns Buffer id if exists, else -1 * * @remarks -* None +* none * ******************************************************************************* */ @@ -674,6 +650,7 @@ WORD32 ih264_buf_mgr_get_bufid(buf_mgr_t *ps_buf_mgr, void *pv_buf) WORD32 id; WORD32 buf_id = -1; IH264_ERROR_T ret = IH264_SUCCESS; + ret = ih264_buf_mgr_lock(ps_buf_mgr); RETURN_IF((ret != IH264_SUCCESS), ret); @@ -691,15 +668,13 @@ WORD32 ih264_buf_mgr_get_bufid(buf_mgr_t *ps_buf_mgr, void *pv_buf) return buf_id; } - /** ******************************************************************************* * -* @brief -* Gets the no.of active buffer +* @brief Gets the no.of active buffer * * @par Description: -* Return the number of active buffers in the buffer manager +* Return the number of active buffers in the buffer manager * * @param[in] ps_buf_mgr * Pointer to the buffer manager @@ -707,19 +682,18 @@ WORD32 ih264_buf_mgr_get_bufid(buf_mgr_t *ps_buf_mgr, void *pv_buf) * @returns number of active buffers * * @remarks -* None +* none * ******************************************************************************* */ UWORD32 ih264_buf_mgr_get_num_active_buf(buf_mgr_t *ps_buf_mgr) { - UWORD32 u4_buf_cnt; + UWORD32 u4_buf_cnt = 0; IH264_ERROR_T ret = IH264_SUCCESS; - u4_buf_cnt = 0; - ret = ih264_buf_mgr_lock(ps_buf_mgr); RETURN_IF((ret != IH264_SUCCESS), ret); + u4_buf_cnt = ps_buf_mgr->i4_active_buf_cnt; ret = ih264_buf_mgr_unlock(ps_buf_mgr); diff --git a/common/ih264_buf_mgr.h b/common/ih264_buf_mgr.h index fe9c53d..435df8c 100644 --- a/common/ih264_buf_mgr.h +++ b/common/ih264_buf_mgr.h @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -25,14 +26,21 @@ * @brief * Function declarations used for buffer management * +* @author +* ittiam +* * @remarks -* None +* none * ******************************************************************************* */ + #ifndef _IH264_BUF_MGR_H_ #define _IH264_BUF_MGR_H_ +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ #define BUF_MGR_MAX_CNT 64 /** Flag for current encoding decoder */ @@ -44,6 +52,9 @@ /** Flag for I/O - Display/output in case of decoder, capture/input in case of encoder */ #define BUF_MGR_IO (1 << 3) +/*****************************************************************************/ +/* Structure Definitions */ +/*****************************************************************************/ typedef struct { /** @@ -61,65 +72,50 @@ typedef struct */ WORD32 i4_active_buf_cnt; - /** - * au4_status[BUF_MGR_MAX_CNT] - */ - UWORD32 au4_status[BUF_MGR_MAX_CNT]; - /* The last three bit of status are: */ - /* Bit 0 - IN USE */ /* Bit 1 - CODEC */ /* Bit 2 - REF */ /* Bit 3 - DISP/IO/RECON */ - void *apv_ptr[BUF_MGR_MAX_CNT]; + UWORD32 au4_status[BUF_MGR_MAX_CNT]; + + /** + * pointer to buffer + */ + void *apv_ptr[BUF_MGR_MAX_CNT]; }buf_mgr_t; -// Returns size of the buffer manager context +/*****************************************************************************/ +/* Function Declarations */ +/*****************************************************************************/ WORD32 ih264_buf_mgr_size(void); -//Free buffer manager IH264_ERROR_T ih264_buf_mgr_free(buf_mgr_t *ps_buf_mgr); -// Reset the buffer manager -void ih264_buf_mgr_reset(void *pv_buf_mgr); - -// Initializes the buffer API structure void *ih264_buf_mgr_init(void *pv_buf); -// Add buffer to buffer manager. 0: success, -1: fail (u4_active_buf_cnt has reached u4_max_buf_cnt) -IH264_ERROR_T ih264_buf_mgr_add(buf_mgr_t *ps_buf_mgr, - void *pv_ptr, +void ih264_buf_mgr_reset(void *pv_buf_mgr); + +IH264_ERROR_T ih264_buf_mgr_add(buf_mgr_t *ps_buf_mgr, void *pv_ptr, WORD32 buf_id); -// this function will set the buffer status to DEC void* ih264_buf_mgr_get_next_free(buf_mgr_t *ps_buf_mgr, WORD32 *pi4_id); -// this function will check if there are any free buffers IH264_ERROR_T ih264_buf_mgr_check_free(buf_mgr_t *ps_buf_mgr); -// mask will have who released it: DISP:REF:DEC -IH264_ERROR_T ih264_buf_mgr_release(buf_mgr_t *ps_buf_mgr, - WORD32 id, +IH264_ERROR_T ih264_buf_mgr_release(buf_mgr_t *ps_buf_mgr, WORD32 id, UWORD32 mask); -// sets the status to one or all of DISP:REF:DEC -IH264_ERROR_T ih264_buf_mgr_set_status(buf_mgr_t *ps_buf_mgr, - WORD32 id, +IH264_ERROR_T ih264_buf_mgr_set_status(buf_mgr_t *ps_buf_mgr, WORD32 id, UWORD32 mask); -// Gets status of the buffer WORD32 ih264_buf_mgr_get_status(buf_mgr_t *ps_buf_mgr, WORD32 id); -// pass the ID - buffer will be returned void* ih264_buf_mgr_get_buf(buf_mgr_t *ps_buf_mgr, WORD32 id); -//Pass buffer to get ID + WORD32 ih264_buf_mgr_get_bufid(buf_mgr_t *ps_buf_mgr, void *pv_buf); -// will return number of active buffers UWORD32 ih264_buf_mgr_get_num_active_buf(buf_mgr_t *ps_buf_mgr); - - #endif /* _IH264_BUF_MGR_H_ */ diff --git a/common/ih264_cabac_tables.c b/common/ih264_cabac_tables.c index 835ea33..f938a63 100644 --- a/common/ih264_cabac_tables.c +++ b/common/ih264_cabac_tables.c @@ -18,7 +18,6 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ - /** ****************************************************************************** * @file @@ -29,11 +28,10 @@ * cabac state transitions * * @author -* Ittiam +* ittiam * -* @par List of Tables -* - gau4_ih264_cabac_table[][] -* - gau1_ih264_cabac_ctxt_init_table[][][] +* @remarks +* none * ****************************************************************************** */ @@ -51,9230 +49,9222 @@ /*****************************************************************************/ /* Extern global definitions */ /*****************************************************************************/ -/*****************************************************************************/ -/* CABAC TABLES */ -/*****************************************************************************/ -/*combined table :guc_RTAB,NextStateLPS,NextStateMPS - input(combined_state): - bits 0-5: state - bits 6:mps - output - bits 0-7:rangeTabLPS - bits 8-14 :combined_next_state_if_mps - bits 15 -21:combined_next_state_if_lps +/** + ****************************************************************************** + * @brief combined table :guc_RTAB, NextStateLPS, NextStateMPS. + * input combined_state bits 0-5: state, bits 6:mps + * output bits 0-7: rangeTabLPS, bits 8-14 : combined_next_state_if_mps, + * bits 15-21 : combined_next_state_if_lps + ****************************************************************************** */ - const UWORD32 gau4_ih264_cabac_table[128][4] = - { - { 2097536, 2097584, 2097616, 2097648 }, +{ + { 2097536, 2097584, 2097616, 2097648 }, - { 640, 679, 709, 739 }, + { 640, 679, 709, 739 }, - { 33664, 33694, 33723, 33752 }, + { 33664, 33694, 33723, 33752 }, - { 66683, 66710, 66738, 66765 }, + { 66683, 66710, 66738, 66765 }, - { 66932, 66958, 66985, 67011 }, + { 66932, 66958, 66985, 67011 }, - { 132719, 132743, 132768, 132793 }, + { 132719, 132743, 132768, 132793 }, - { 132969, 132992, 133016, 133039 }, + { 132969, 132992, 133016, 133039 }, - { 165988, 166010, 166032, 166054 }, + { 165988, 166010, 166032, 166054 }, - { 199007, 199028, 199049, 199070 }, + { 199007, 199028, 199049, 199070 }, - { 232026, 232046, 232066, 232086 }, + { 232026, 232046, 232066, 232086 }, - { 265045, 265064, 265083, 265102 }, + { 265045, 265064, 265083, 265102 }, - { 298065, 298083, 298101, 298119 }, + { 298065, 298083, 298101, 298119 }, - { 298317, 298334, 298351, 298368 }, + { 298317, 298334, 298351, 298368 }, - { 364105, 364121, 364137, 364154 }, + { 364105, 364121, 364137, 364154 }, - { 364357, 364373, 364388, 364404 }, + { 364357, 364373, 364388, 364404 }, - { 397378, 397392, 397407, 397422 }, + { 397378, 397392, 397407, 397422 }, - { 430398, 430412, 430426, 430440 }, + { 430398, 430412, 430426, 430440 }, - { 430651, 430664, 430678, 430691 }, + { 430651, 430664, 430678, 430691 }, - { 496440, 496453, 496465, 496478 }, + { 496440, 496453, 496465, 496478 }, - { 496693, 496705, 496717, 496729 }, + { 496693, 496705, 496717, 496729 }, - { 529715, 529726, 529737, 529749 }, + { 529715, 529726, 529737, 529749 }, - { 529968, 529979, 529989, 530000 }, + { 529968, 529979, 529989, 530000 }, - { 595758, 595768, 595778, 595788 }, + { 595758, 595768, 595778, 595788 }, - { 596011, 596021, 596031, 596040 }, + { 596011, 596021, 596031, 596040 }, - { 629033, 629042, 629051, 629061 }, + { 629033, 629042, 629051, 629061 }, - { 629287, 629296, 629304, 629313 }, + { 629287, 629296, 629304, 629313 }, - { 695077, 695085, 695094, 695102 }, + { 695077, 695085, 695094, 695102 }, - { 695331, 695339, 695347, 695355 }, + { 695331, 695339, 695347, 695355 }, - { 728353, 728361, 728368, 728376 }, + { 728353, 728361, 728368, 728376 }, - { 728608, 728615, 728622, 728629 }, + { 728608, 728615, 728622, 728629 }, - { 761630, 761637, 761643, 761650 }, + { 761630, 761637, 761643, 761650 }, - { 794653, 794659, 794665, 794672 }, + { 794653, 794659, 794665, 794672 }, - { 794907, 794913, 794919, 794925 }, + { 794907, 794913, 794919, 794925 }, - { 827930, 827935, 827941, 827947 }, + { 827930, 827935, 827941, 827947 }, - { 860952, 860958, 860963, 860969 }, + { 860952, 860958, 860963, 860969 }, - { 861207, 861212, 861217, 861223 }, + { 861207, 861212, 861217, 861223 }, - { 894230, 894235, 894240, 894245 }, + { 894230, 894235, 894240, 894245 }, - { 894485, 894490, 894494, 894499 }, + { 894485, 894490, 894494, 894499 }, - { 927508, 927512, 927517, 927521 }, + { 927508, 927512, 927517, 927521 }, - { 960531, 960535, 960539, 960543 }, + { 960531, 960535, 960539, 960543 }, - { 960786, 960790, 960794, 960798 }, + { 960786, 960790, 960794, 960798 }, - { 993809, 993813, 993817, 993820 }, + { 993809, 993813, 993817, 993820 }, - { 994064, 994068, 994071, 994075 }, + { 994064, 994068, 994071, 994075 }, - { 994319, 994323, 994326, 994329 }, + { 994319, 994323, 994326, 994329 }, - { 1027342, 1027346, 1027349, 1027352 }, + { 1027342, 1027346, 1027349, 1027352 }, - { 1060366, 1060369, 1060372, 1060375 }, + { 1060366, 1060369, 1060372, 1060375 }, - { 1060621, 1060624, 1060627, 1060630 }, + { 1060621, 1060624, 1060627, 1060630 }, - { 1093644, 1093647, 1093650, 1093653 }, + { 1093644, 1093647, 1093650, 1093653 }, - { 1093900, 1093902, 1093905, 1093908 }, + { 1093900, 1093902, 1093905, 1093908 }, - { 1094155, 1094158, 1094160, 1094163 }, + { 1094155, 1094158, 1094160, 1094163 }, - { 1127179, 1127181, 1127183, 1127186 }, + { 1127179, 1127181, 1127183, 1127186 }, - { 1127434, 1127436, 1127439, 1127441 }, + { 1127434, 1127436, 1127439, 1127441 }, - { 1160458, 1160460, 1160462, 1160464 }, + { 1160458, 1160460, 1160462, 1160464 }, - { 1160713, 1160715, 1160717, 1160719 }, + { 1160713, 1160715, 1160717, 1160719 }, - { 1160969, 1160971, 1160972, 1160974 }, + { 1160969, 1160971, 1160972, 1160974 }, - { 1193992, 1193994, 1193996, 1193998 }, + { 1193992, 1193994, 1193996, 1193998 }, - { 1194248, 1194249, 1194251, 1194253 }, + { 1194248, 1194249, 1194251, 1194253 }, - { 1194503, 1194505, 1194507, 1194508 }, + { 1194503, 1194505, 1194507, 1194508 }, - { 1227527, 1227529, 1227530, 1227532 }, + { 1227527, 1227529, 1227530, 1227532 }, - { 1227783, 1227784, 1227786, 1227787 }, + { 1227783, 1227784, 1227786, 1227787 }, - { 1228038, 1228040, 1228041, 1228043 }, + { 1228038, 1228040, 1228041, 1228043 }, - { 1261062, 1261063, 1261065, 1261066 }, + { 1261062, 1261063, 1261065, 1261066 }, - { 1261062, 1261063, 1261064, 1261065 }, + { 1261062, 1261063, 1261064, 1261065 }, - { 2080514, 2080514, 2080514, 2080514 }, + { 2080514, 2080514, 2080514, 2080514 }, - { 16768, 16816, 16848, 16880 }, + { 16768, 16816, 16848, 16880 }, - { 2114176, 2114215, 2114245, 2114275 }, + { 2114176, 2114215, 2114245, 2114275 }, - { 2147200, 2147230, 2147259, 2147288 }, + { 2147200, 2147230, 2147259, 2147288 }, - { 2180219, 2180246, 2180274, 2180301 }, + { 2180219, 2180246, 2180274, 2180301 }, - { 2180468, 2180494, 2180521, 2180547 }, + { 2180468, 2180494, 2180521, 2180547 }, - { 2246255, 2246279, 2246304, 2246329 }, + { 2246255, 2246279, 2246304, 2246329 }, - { 2246505, 2246528, 2246552, 2246575 }, + { 2246505, 2246528, 2246552, 2246575 }, - { 2279524, 2279546, 2279568, 2279590 }, + { 2279524, 2279546, 2279568, 2279590 }, - { 2312543, 2312564, 2312585, 2312606 }, + { 2312543, 2312564, 2312585, 2312606 }, - { 2345562, 2345582, 2345602, 2345622 }, + { 2345562, 2345582, 2345602, 2345622 }, - { 2378581, 2378600, 2378619, 2378638 }, + { 2378581, 2378600, 2378619, 2378638 }, - { 2411601, 2411619, 2411637, 2411655 }, + { 2411601, 2411619, 2411637, 2411655 }, - { 2411853, 2411870, 2411887, 2411904 }, + { 2411853, 2411870, 2411887, 2411904 }, - { 2477641, 2477657, 2477673, 2477690 }, + { 2477641, 2477657, 2477673, 2477690 }, - { 2477893, 2477909, 2477924, 2477940 }, + { 2477893, 2477909, 2477924, 2477940 }, - { 2510914, 2510928, 2510943, 2510958 }, + { 2510914, 2510928, 2510943, 2510958 }, - { 2543934, 2543948, 2543962, 2543976 }, + { 2543934, 2543948, 2543962, 2543976 }, - { 2544187, 2544200, 2544214, 2544227 }, + { 2544187, 2544200, 2544214, 2544227 }, - { 2609976, 2609989, 2610001, 2610014 }, + { 2609976, 2609989, 2610001, 2610014 }, - { 2610229, 2610241, 2610253, 2610265 }, + { 2610229, 2610241, 2610253, 2610265 }, - { 2643251, 2643262, 2643273, 2643285 }, + { 2643251, 2643262, 2643273, 2643285 }, - { 2643504, 2643515, 2643525, 2643536 }, + { 2643504, 2643515, 2643525, 2643536 }, - { 2709294, 2709304, 2709314, 2709324 }, + { 2709294, 2709304, 2709314, 2709324 }, - { 2709547, 2709557, 2709567, 2709576 }, + { 2709547, 2709557, 2709567, 2709576 }, - { 2742569, 2742578, 2742587, 2742597 }, + { 2742569, 2742578, 2742587, 2742597 }, - { 2742823, 2742832, 2742840, 2742849 }, + { 2742823, 2742832, 2742840, 2742849 }, - { 2808613, 2808621, 2808630, 2808638 }, + { 2808613, 2808621, 2808630, 2808638 }, - { 2808867, 2808875, 2808883, 2808891 }, + { 2808867, 2808875, 2808883, 2808891 }, - { 2841889, 2841897, 2841904, 2841912 }, + { 2841889, 2841897, 2841904, 2841912 }, - { 2842144, 2842151, 2842158, 2842165 }, + { 2842144, 2842151, 2842158, 2842165 }, - { 2875166, 2875173, 2875179, 2875186 }, + { 2875166, 2875173, 2875179, 2875186 }, - { 2908189, 2908195, 2908201, 2908208 }, + { 2908189, 2908195, 2908201, 2908208 }, - { 2908443, 2908449, 2908455, 2908461 }, + { 2908443, 2908449, 2908455, 2908461 }, - { 2941466, 2941471, 2941477, 2941483 }, + { 2941466, 2941471, 2941477, 2941483 }, - { 2974488, 2974494, 2974499, 2974505 }, + { 2974488, 2974494, 2974499, 2974505 }, - { 2974743, 2974748, 2974753, 2974759 }, + { 2974743, 2974748, 2974753, 2974759 }, - { 3007766, 3007771, 3007776, 3007781 }, + { 3007766, 3007771, 3007776, 3007781 }, - { 3008021, 3008026, 3008030, 3008035 }, + { 3008021, 3008026, 3008030, 3008035 }, - { 3041044, 3041048, 3041053, 3041057 }, + { 3041044, 3041048, 3041053, 3041057 }, - { 3074067, 3074071, 3074075, 3074079 }, + { 3074067, 3074071, 3074075, 3074079 }, - { 3074322, 3074326, 3074330, 3074334 }, + { 3074322, 3074326, 3074330, 3074334 }, - { 3107345, 3107349, 3107353, 3107356 }, + { 3107345, 3107349, 3107353, 3107356 }, - { 3107600, 3107604, 3107607, 3107611 }, + { 3107600, 3107604, 3107607, 3107611 }, - { 3107855, 3107859, 3107862, 3107865 }, + { 3107855, 3107859, 3107862, 3107865 }, - { 3140878, 3140882, 3140885, 3140888 }, + { 3140878, 3140882, 3140885, 3140888 }, - { 3173902, 3173905, 3173908, 3173911 }, + { 3173902, 3173905, 3173908, 3173911 }, - { 3174157, 3174160, 3174163, 3174166 }, + { 3174157, 3174160, 3174163, 3174166 }, - { 3207180, 3207183, 3207186, 3207189 }, + { 3207180, 3207183, 3207186, 3207189 }, - { 3207436, 3207438, 3207441, 3207444 }, + { 3207436, 3207438, 3207441, 3207444 }, - { 3207691, 3207694, 3207696, 3207699 }, + { 3207691, 3207694, 3207696, 3207699 }, - { 3240715, 3240717, 3240719, 3240722 }, + { 3240715, 3240717, 3240719, 3240722 }, - { 3240970, 3240972, 3240975, 3240977 }, + { 3240970, 3240972, 3240975, 3240977 }, - { 3273994, 3273996, 3273998, 3274000 }, + { 3273994, 3273996, 3273998, 3274000 }, - { 3274249, 3274251, 3274253, 3274255 }, + { 3274249, 3274251, 3274253, 3274255 }, - { 3274505, 3274507, 3274508, 3274510 }, + { 3274505, 3274507, 3274508, 3274510 }, - { 3307528, 3307530, 3307532, 3307534 }, + { 3307528, 3307530, 3307532, 3307534 }, - { 3307784, 3307785, 3307787, 3307789 }, + { 3307784, 3307785, 3307787, 3307789 }, - { 3308039, 3308041, 3308043, 3308044 }, + { 3308039, 3308041, 3308043, 3308044 }, - { 3341063, 3341065, 3341066, 3341068 }, + { 3341063, 3341065, 3341066, 3341068 }, - { 3341319, 3341320, 3341322, 3341323 }, + { 3341319, 3341320, 3341322, 3341323 }, - { 3341574, 3341576, 3341577, 3341579 }, + { 3341574, 3341576, 3341577, 3341579 }, - { 3374598, 3374599, 3374601, 3374602 }, + { 3374598, 3374599, 3374601, 3374602 }, - { 3374598, 3374599, 3374600, 3374601 }, + { 3374598, 3374599, 3374600, 3374601 }, - { 4194050, 4194050, 4194050, 4194050 }, + { 4194050, 4194050, 4194050, 4194050 }, + +}; - }; -/*****************************************************************************/ -/* Global Variable Initialization */ -/*****************************************************************************/ const UWORD8 gau1_ih264_cabac_ctxt_init_table[NUM_CAB_INIT_IDC_PLUS_ONE][QP_RANGE][NUM_CABAC_CTXTS] = +{ + + { - { - - { - - { - - 62, - 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 30, 61, 62, - 54, 14, 118, 6, 78, 65, 1, 14, 73, 13, 64, 20, 62, - 67, 90, 104, 126, 104, 67, 78, 65, 1, 86, 95, 2, - 18, 69, 81, 96, 8, 67, 86, 88, 5, 76, 94, 9, 69, - 81, 88, 67, 74, 74, 80, 72, 5, 22, 0, 0, 0, 83, - 86, 97, 72, 22, 1, 18, 78, 96, 126, 98, 101, 67, - 82, 94, 83, 110, 91, 102, 93, 126, 92, 89, 96, - 108, 17, 65, 6, 93, 74, 92, 87, 126, 9, 3, 4, 69, - 15, 68, 69, 88, 85, 78, 75, 77, 9, 13, 68, 13, 21, - 81, 0, 70, 67, 6, 76, 28, 64, 2, 28, 38, 39, 34, - 27, 93, 73, 73, 17, 14, 100, 10, 10, 10, 2, 7, 7, - 0, 3, 1, 6, 69, 6, 24, 12, 68, 64, 2, 0, 13, 24, - 19, 11, 15, 3, 4, 4, 30, 19, 20, 78, 3, 69, 35, - 23, 19, 14, 17, 19, 12, 16, 24, 1, 17, 9, 9, 5, 0, - 12, 6, 10, 11, 8, 18, 27, 10, 82, 8, 78, 17, 32, - 84, 56, 62, 60, 59, 62, 62, 57, 57, 54, 44, 36, - 33, 43, 29, 70, 67, 4, 67, 33, 31, 28, 34, 32, 25, - 20, 22, 0, 4, 64, 94, 89, 108, 76, 19, 18, 11, 64, - 4, 70, 75, 82, 102, 77, 39, 21, 15, 8, 4, 71, 83, - 87, 119, 5, 34, 27, 25, 20, 8, 5, 64, 74, 90, 70, - 34, 32, 21, 4, 5, 72, 81, 97, 5, 58, 49, 45, 36, - 23, 5, 70, 79, 85, 62, 106, 106, 87, 114, 110, 98, - 110, 106, 103, 107, 108, 112, 96, 95, 91, 93, 94, - 86, 67, 80, 85, 70, 3, 5, 2, 13, 13, 14, 9, 22, - 17, 12, 14, 11, 22, 16, 8, 22, 19, 13, 10, 14, 0, - 64, 69, 4, 70, 19, 32, 20, 10, 29, 25, 11, 23, 31, - 19, 25, 13, 6, 20, 52, 49, 52, 52, 54, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 34, 62, 62, 62, 62, 62, - 62, 54, 37, 36, 6, 82, 75, 97, 125, 62, 62, 62, - 57, 55, 53, 41, 44, 31, 32, 22, 19, 16, 65, 71, 3, - 0, 65, 39, 43, 40, 31, 40, 39, 23, 31, 34, 21, 6, - 10, 2, 86, 23, 12, 4, 79, 71, 69, 70, 66, 68, 73, - 69, 70, 67, 1, 70, 66, 65, 0, 62, 62, 62, 62, 62, - 60, 54, 36, 4, 66, 28, 21, 18, 15, 7, 3, 1, 66, - 76, 85, 81, 77, 81, 80, 73, 74, 83, 71, 67, 2, 66, - 66, 4, 4, 62, 62, 62, 62, 61, 57, 46, 29, 1 }, - - { - - 62, - 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 29, 60, - 62, 54, 14, 115, 6, 77, 64, 1, 14, 72, 12, 65, - 20, 62, 68, 91, 104, 124, 102, 67, 77, 64, 1, - 85, 93, 3, 18, 68, 80, 95, 8, 67, 85, 88, 5, 75, - 93, 9, 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, - 0, 0, 82, 86, 97, 71, 22, 1, 18, 77, 95, 124, - 96, 99, 65, 80, 92, 82, 108, 89, 100, 92, 125, - 91, 88, 95, 107, 18, 64, 7, 92, 73, 91, 86, 124, - 9, 3, 4, 69, 16, 68, 68, 87, 84, 77, 74, 76, 9, - 13, 67, 13, 21, 80, 0, 69, 67, 6, 75, 28, 64, 2, - 28, 37, 39, 34, 27, 92, 72, 72, 17, 14, 99, 10, - 10, 10, 3, 7, 7, 1, 4, 2, 6, 68, 6, 24, 12, 68, - 64, 2, 0, 13, 23, 19, 11, 15, 4, 5, 4, 29, 19, - 20, 77, 3, 69, 35, 23, 19, 14, 17, 19, 12, 16, - 24, 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 18, 27, - 10, 81, 8, 77, 17, 31, 83, 55, 62, 59, 58, 61, - 62, 56, 56, 52, 43, 35, 32, 41, 28, 71, 67, 4, - 67, 32, 30, 27, 33, 31, 24, 19, 21, 0, 4, 64, - 93, 88, 107, 75, 20, 18, 11, 0, 5, 69, 74, 81, - 100, 76, 39, 21, 15, 8, 5, 70, 82, 86, 117, 5, - 35, 28, 25, 20, 9, 5, 64, 73, 89, 70, 35, 32, - 21, 4, 6, 71, 80, 96, 5, 58, 49, 45, 36, 23, 5, - 69, 78, 84, 62, 105, 105, 86, 112, 108, 97, 108, - 104, 101, 105, 106, 110, 95, 94, 90, 92, 92, 85, - 67, 79, 84, 69, 3, 5, 2, 13, 13, 13, 8, 22, 17, - 13, 14, 11, 22, 16, 8, 22, 19, 13, 10, 14, 0, - 64, 68, 5, 70, 19, 32, 20, 10, 29, 25, 12, 23, - 30, 19, 25, 13, 6, 19, 52, 49, 52, 51, 53, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 33, 62, 62, 62, - 62, 62, 62, 53, 36, 35, 6, 81, 74, 95, 122, 62, - 62, 62, 56, 53, 52, 40, 42, 30, 31, 21, 18, 15, - 66, 71, 3, 0, 66, 38, 42, 39, 30, 39, 38, 22, - 30, 33, 20, 5, 9, 1, 86, 23, 12, 4, 78, 70, 68, - 69, 65, 67, 71, 68, 69, 66, 3, 68, 65, 0, 2, 62, - 62, 62, 62, 62, 58, 51, 34, 2, 65, 29, 22, 19, - 16, 8, 4, 2, 65, 75, 84, 80, 76, 80, 78, 71, 73, - 82, 70, 66, 3, 65, 65, 4, 4, 62, 62, 62, 62, 58, - 54, 43, 26, 64 }, - - { - - 62, - 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 28, 59, - 61, 54, 14, 113, 6, 76, 0, 1, 13, 72, 11, 66, - 19, 60, 70, 92, 105, 121, 101, 67, 76, 0, 1, 85, - 92, 3, 17, 68, 80, 94, 8, 67, 85, 88, 5, 75, 92, - 9, 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, 0, - 0, 81, 86, 97, 71, 21, 1, 18, 77, 95, 122, 94, - 97, 64, 78, 91, 81, 107, 88, 99, 91, 123, 91, - 88, 95, 106, 18, 64, 7, 91, 73, 90, 86, 123, 9, - 3, 4, 69, 16, 68, 68, 87, 84, 77, 74, 76, 9, 13, - 67, 13, 21, 80, 0, 69, 67, 6, 75, 27, 64, 2, 27, - 36, 38, 33, 26, 91, 72, 72, 16, 13, 99, 9, 10, - 10, 3, 7, 7, 2, 4, 2, 6, 68, 6, 23, 12, 69, 64, - 2, 64, 13, 22, 19, 11, 14, 4, 5, 4, 28, 19, 19, - 77, 3, 70, 34, 23, 19, 14, 17, 19, 12, 16, 24, - 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 17, 26, 9, - 81, 8, 77, 16, 30, 83, 53, 62, 57, 56, 59, 60, - 54, 54, 50, 41, 33, 30, 39, 26, 72, 67, 4, 68, - 31, 29, 26, 32, 29, 23, 18, 20, 64, 3, 65, 93, - 88, 106, 75, 20, 18, 11, 0, 5, 69, 74, 81, 99, - 75, 39, 21, 15, 8, 5, 70, 81, 85, 115, 5, 35, - 28, 25, 20, 9, 5, 64, 73, 88, 70, 35, 32, 21, 4, - 6, 71, 80, 95, 5, 57, 48, 44, 35, 23, 5, 69, 78, - 84, 62, 104, 104, 85, 111, 107, 96, 107, 103, - 100, 104, 105, 108, 94, 93, 90, 91, 91, 85, 68, - 79, 83, 69, 3, 4, 2, 12, 12, 12, 7, 21, 17, 13, - 14, 10, 21, 16, 8, 21, 18, 13, 10, 13, 0, 64, - 68, 5, 70, 18, 31, 19, 10, 28, 24, 12, 22, 29, - 19, 25, 12, 5, 17, 51, 48, 51, 50, 52, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 32, 62, 62, 62, 62, - 62, 62, 51, 35, 34, 6, 80, 74, 94, 120, 60, 60, - 62, 54, 51, 50, 38, 40, 29, 29, 20, 16, 14, 67, - 72, 2, 0, 67, 37, 41, 37, 28, 37, 36, 21, 28, - 31, 19, 4, 8, 0, 87, 22, 11, 3, 78, 70, 68, 68, - 65, 66, 70, 67, 68, 65, 4, 67, 64, 1, 3, 62, 62, - 62, 62, 60, 55, 48, 31, 0, 65, 29, 22, 19, 16, - 9, 4, 2, 65, 75, 84, 80, 75, 80, 77, 70, 73, 81, - 69, 65, 3, 65, 64, 4, 4, 62, 62, 62, 60, 55, 50, - 39, 23, 67 }, - - { - - 62, - 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 26, 57, - 60, 54, 14, 111, 6, 75, 1, 1, 12, 72, 10, 67, - 19, 58, 71, 93, 105, 118, 100, 67, 75, 1, 1, 84, - 91, 4, 17, 68, 79, 93, 7, 68, 85, 88, 5, 75, 92, - 9, 69, 80, 88, 65, 73, 73, 79, 70, 5, 22, 0, 0, - 0, 81, 86, 97, 70, 20, 1, 18, 77, 95, 120, 92, - 96, 1, 76, 90, 80, 105, 87, 98, 90, 121, 90, 88, - 94, 105, 18, 64, 7, 91, 73, 90, 85, 121, 9, 2, - 3, 70, 16, 68, 68, 86, 84, 76, 74, 75, 9, 13, - 67, 13, 20, 80, 0, 69, 67, 6, 75, 26, 64, 2, 26, - 35, 37, 32, 25, 91, 71, 72, 15, 13, 98, 9, 10, - 10, 3, 7, 7, 3, 4, 2, 6, 67, 6, 22, 12, 70, 64, - 2, 64, 12, 21, 19, 11, 13, 4, 5, 4, 26, 19, 18, - 77, 3, 70, 33, 23, 19, 14, 17, 19, 12, 16, 24, - 1, 16, 9, 9, 5, 0, 11, 5, 9, 10, 7, 16, 25, 9, - 81, 7, 77, 15, 28, 83, 52, 62, 55, 54, 57, 58, - 52, 52, 48, 39, 32, 29, 37, 24, 73, 67, 4, 68, - 30, 28, 25, 30, 28, 21, 17, 19, 65, 3, 65, 93, - 88, 106, 74, 20, 18, 11, 0, 5, 69, 74, 80, 98, - 75, 39, 21, 15, 8, 6, 69, 80, 84, 113, 5, 35, - 28, 25, 20, 10, 5, 64, 73, 88, 70, 35, 32, 20, - 4, 6, 71, 80, 94, 5, 57, 48, 43, 34, 23, 5, 69, - 77, 83, 62, 103, 103, 85, 110, 106, 95, 105, - 102, 99, 103, 103, 107, 94, 92, 90, 91, 89, 85, - 68, 79, 83, 69, 2, 4, 2, 11, 11, 11, 6, 21, 16, - 13, 13, 10, 21, 15, 8, 20, 18, 12, 10, 12, 0, - 65, 68, 5, 71, 18, 31, 18, 10, 27, 24, 12, 21, - 28, 18, 24, 11, 5, 16, 50, 47, 51, 49, 51, 61, - 62, 62, 62, 62, 62, 62, 62, 62, 31, 62, 62, 62, - 62, 62, 62, 49, 34, 33, 6, 79, 74, 93, 118, 58, - 58, 62, 52, 49, 48, 37, 38, 27, 28, 19, 15, 12, - 68, 73, 2, 64, 68, 36, 39, 36, 26, 35, 34, 19, - 27, 29, 17, 3, 6, 65, 88, 21, 10, 2, 78, 69, 68, - 68, 64, 66, 69, 66, 67, 64, 5, 66, 0, 3, 4, 62, - 62, 62, 62, 58, 52, 45, 28, 65, 64, 30, 23, 20, - 16, 10, 5, 2, 64, 74, 84, 79, 75, 79, 76, 69, - 73, 81, 69, 65, 3, 64, 0, 4, 4, 62, 62, 62, 57, - 52, 46, 35, 19, 69 }, - - { - - 62, - 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 25, 56, - 58, 54, 14, 108, 5, 74, 1, 1, 11, 72, 9, 68, 18, - 56, 73, 94, 106, 115, 99, 67, 74, 1, 1, 84, 90, - 4, 16, 68, 79, 93, 7, 68, 84, 88, 5, 75, 91, 8, - 70, 80, 88, 65, 72, 73, 78, 70, 5, 22, 0, 0, 0, - 80, 87, 97, 70, 19, 1, 18, 77, 95, 119, 91, 94, - 2, 75, 89, 79, 104, 85, 97, 89, 119, 90, 87, 94, - 104, 18, 64, 7, 90, 73, 89, 85, 120, 8, 2, 3, - 70, 16, 68, 68, 86, 84, 76, 74, 75, 9, 12, 67, - 13, 20, 80, 0, 69, 67, 6, 75, 26, 65, 2, 26, 34, - 36, 31, 24, 90, 71, 72, 14, 12, 98, 8, 10, 9, 3, - 7, 7, 4, 5, 2, 5, 67, 5, 21, 11, 71, 64, 2, 65, - 12, 20, 18, 10, 13, 5, 5, 4, 25, 18, 17, 77, 3, - 71, 33, 23, 19, 14, 17, 19, 12, 16, 23, 1, 16, - 9, 9, 5, 64, 11, 5, 9, 10, 7, 16, 24, 8, 81, 7, - 77, 14, 27, 83, 50, 62, 53, 52, 55, 56, 50, 50, - 46, 37, 30, 27, 34, 22, 74, 67, 3, 69, 29, 27, - 24, 29, 26, 20, 16, 17, 65, 2, 66, 93, 88, 105, - 74, 20, 18, 11, 0, 5, 69, 74, 80, 97, 74, 39, - 21, 15, 8, 6, 69, 80, 84, 111, 5, 35, 28, 25, - 20, 10, 5, 64, 73, 87, 70, 35, 31, 20, 4, 6, 71, - 80, 94, 5, 56, 47, 42, 33, 23, 5, 69, 77, 83, - 62, 102, 102, 84, 108, 105, 94, 104, 100, 98, - 101, 102, 105, 93, 92, 89, 90, 88, 84, 69, 79, - 82, 69, 2, 3, 1, 10, 10, 10, 5, 20, 16, 13, 13, - 9, 20, 15, 8, 19, 17, 12, 9, 11, 64, 65, 68, 5, - 71, 17, 30, 17, 10, 26, 23, 12, 20, 27, 18, 24, - 10, 4, 14, 49, 47, 50, 48, 49, 60, 62, 62, 62, - 62, 62, 62, 62, 62, 29, 62, 62, 62, 62, 62, 62, - 47, 33, 31, 6, 78, 73, 92, 116, 57, 56, 60, 51, - 47, 46, 35, 36, 26, 26, 17, 13, 11, 69, 74, 1, - 64, 69, 34, 38, 34, 25, 33, 32, 18, 25, 27, 16, - 2, 5, 66, 88, 20, 10, 1, 78, 69, 67, 67, 64, 65, - 68, 66, 66, 0, 6, 65, 1, 4, 5, 62, 62, 62, 61, - 55, 49, 42, 25, 68, 64, 30, 23, 20, 17, 10, 5, - 3, 64, 74, 83, 79, 74, 79, 75, 68, 73, 80, 68, - 64, 3, 64, 1, 4, 4, 62, 62, 61, 54, 49, 42, 31, - 16, 72 }, - - { - - 62, - 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 23, 54, - 57, 54, 14, 106, 5, 73, 2, 1, 11, 71, 8, 69, 18, - 54, 75, 95, 106, 112, 97, 67, 73, 2, 1, 84, 89, - 4, 16, 68, 79, 92, 7, 69, 84, 88, 5, 75, 90, 8, - 70, 80, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0, - 80, 87, 97, 69, 18, 1, 18, 76, 95, 117, 89, 93, - 4, 73, 87, 78, 103, 84, 96, 88, 117, 89, 87, 93, - 103, 18, 64, 7, 90, 73, 89, 84, 118, 8, 2, 3, - 70, 16, 68, 67, 85, 84, 76, 74, 74, 9, 12, 67, - 13, 20, 79, 0, 68, 67, 6, 75, 25, 65, 2, 25, 33, - 36, 30, 23, 89, 70, 72, 13, 12, 97, 8, 10, 9, 3, - 7, 7, 5, 5, 2, 5, 67, 5, 20, 11, 72, 64, 2, 65, - 11, 19, 18, 10, 12, 5, 5, 4, 24, 18, 16, 77, 3, - 71, 32, 23, 19, 14, 17, 19, 12, 16, 23, 1, 16, - 9, 9, 5, 64, 11, 5, 8, 10, 7, 15, 23, 8, 81, 6, - 77, 13, 26, 83, 49, 61, 52, 51, 53, 54, 48, 48, - 44, 35, 28, 25, 32, 21, 75, 67, 3, 69, 28, 26, - 23, 28, 25, 18, 15, 16, 66, 2, 66, 93, 88, 105, - 74, 20, 18, 11, 0, 5, 68, 73, 79, 96, 74, 39, - 21, 15, 8, 6, 68, 79, 83, 109, 5, 35, 28, 25, - 20, 10, 5, 64, 73, 86, 70, 36, 31, 19, 4, 6, 71, - 80, 93, 5, 56, 46, 41, 32, 23, 5, 69, 77, 82, - 62, 101, 101, 83, 107, 104, 93, 103, 99, 97, - 100, 100, 103, 92, 91, 89, 90, 87, 84, 69, 78, - 81, 69, 1, 3, 1, 10, 9, 9, 4, 19, 15, 13, 12, 9, - 20, 15, 8, 18, 16, 12, 9, 10, 64, 65, 68, 5, 71, - 16, 30, 17, 10, 25, 22, 12, 19, 26, 17, 23, 9, - 3, 12, 48, 46, 50, 47, 48, 58, 62, 62, 62, 62, - 62, 62, 62, 62, 28, 62, 62, 62, 62, 62, 61, 45, - 32, 30, 6, 77, 73, 91, 114, 55, 55, 58, 49, 45, - 44, 34, 34, 25, 24, 16, 11, 9, 70, 75, 1, 64, - 70, 33, 36, 32, 23, 32, 31, 16, 24, 26, 14, 1, - 4, 67, 89, 20, 9, 0, 77, 68, 67, 67, 0, 64, 67, - 65, 65, 1, 8, 64, 2, 5, 7, 62, 62, 62, 58, 53, - 46, 39, 22, 70, 64, 31, 24, 21, 17, 11, 5, 3, 0, - 73, 83, 79, 73, 78, 74, 67, 72, 79, 68, 64, 3, - 0, 2, 4, 4, 62, 62, 58, 51, 46, 39, 27, 12, 75 }, - - { - - 62, - 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 22, 53, - 56, 54, 14, 104, 5, 73, 3, 1, 10, 71, 7, 70, 17, - 53, 76, 96, 107, 109, 96, 67, 73, 3, 1, 83, 88, - 5, 15, 67, 78, 91, 6, 69, 84, 88, 5, 74, 90, 8, - 70, 79, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0, - 79, 87, 97, 69, 18, 0, 18, 76, 94, 115, 87, 91, - 5, 71, 86, 77, 101, 83, 95, 88, 116, 89, 87, 93, - 103, 19, 64, 7, 89, 72, 88, 84, 117, 8, 1, 2, - 71, 16, 68, 67, 85, 84, 75, 74, 74, 9, 12, 66, - 13, 19, 79, 0, 68, 67, 6, 75, 24, 65, 2, 24, 32, - 35, 30, 23, 89, 70, 72, 13, 11, 97, 7, 10, 9, 3, - 7, 7, 5, 5, 2, 5, 66, 5, 19, 11, 72, 65, 2, 66, - 11, 18, 18, 10, 11, 5, 5, 4, 22, 18, 15, 77, 3, - 72, 31, 23, 18, 14, 17, 19, 12, 16, 23, 1, 15, - 9, 8, 5, 64, 10, 4, 8, 9, 6, 14, 22, 7, 81, 6, - 76, 12, 24, 83, 47, 59, 50, 49, 51, 52, 46, 46, - 42, 33, 27, 24, 30, 19, 76, 67, 3, 70, 27, 25, - 22, 26, 23, 17, 14, 15, 67, 1, 67, 93, 88, 104, - 73, 20, 18, 11, 1, 5, 68, 73, 79, 95, 73, 38, - 21, 15, 8, 7, 68, 78, 82, 107, 5, 36, 28, 25, - 20, 11, 5, 64, 72, 86, 70, 36, 31, 19, 4, 6, 70, - 79, 92, 5, 55, 46, 40, 32, 23, 5, 68, 76, 82, - 62, 101, 100, 83, 106, 103, 92, 101, 98, 96, 99, - 99, 102, 92, 90, 89, 89, 85, 84, 70, 78, 81, 69, - 1, 2, 1, 9, 8, 8, 3, 19, 15, 13, 12, 8, 19, 14, - 8, 18, 16, 11, 9, 10, 64, 66, 68, 5, 72, 16, 29, - 16, 9, 24, 22, 13, 19, 25, 17, 23, 9, 3, 11, 47, - 45, 49, 46, 47, 57, 62, 62, 62, 62, 62, 62, 62, - 61, 27, 62, 62, 62, 62, 62, 59, 43, 31, 29, 6, - 76, 73, 89, 111, 53, 53, 56, 47, 43, 42, 32, 32, - 23, 23, 15, 10, 8, 71, 76, 0, 65, 71, 32, 35, - 31, 21, 30, 29, 15, 22, 24, 13, 64, 2, 69, 90, - 19, 8, 64, 77, 68, 67, 66, 0, 64, 65, 64, 64, 2, - 9, 1, 3, 7, 8, 62, 62, 60, 56, 50, 44, 36, 20, - 72, 0, 31, 24, 21, 17, 12, 6, 3, 0, 73, 83, 78, - 73, 78, 73, 66, 72, 79, 67, 0, 3, 0, 3, 4, 4, - 62, 62, 56, 48, 42, 35, 24, 9, 77 }, - - { - - 62, - 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 20, 51, - 54, 54, 14, 101, 4, 72, 3, 1, 9, 71, 6, 71, 17, - 51, 78, 97, 107, 106, 95, 67, 72, 3, 1, 83, 87, - 5, 15, 67, 78, 91, 6, 70, 83, 88, 5, 74, 89, 7, - 70, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0, - 79, 87, 97, 68, 17, 0, 18, 76, 94, 114, 85, 90, - 7, 69, 85, 76, 100, 81, 94, 87, 114, 88, 86, 92, - 102, 19, 64, 7, 89, 72, 88, 83, 115, 7, 1, 2, - 71, 16, 68, 67, 84, 84, 75, 74, 73, 9, 11, 66, - 13, 19, 79, 0, 68, 67, 6, 75, 24, 65, 2, 24, 31, - 34, 29, 22, 88, 69, 72, 12, 11, 96, 7, 10, 8, 3, - 7, 7, 6, 6, 2, 5, 66, 5, 18, 11, 73, 65, 2, 66, - 10, 17, 17, 10, 11, 6, 5, 4, 21, 17, 14, 77, 3, - 72, 31, 23, 18, 14, 17, 19, 12, 16, 23, 1, 15, - 9, 8, 5, 64, 10, 4, 7, 9, 6, 14, 21, 7, 81, 5, - 76, 11, 23, 83, 46, 57, 48, 47, 49, 50, 44, 44, - 40, 31, 25, 22, 27, 17, 77, 67, 2, 70, 26, 24, - 21, 25, 22, 15, 13, 14, 67, 1, 67, 93, 88, 104, - 73, 20, 18, 11, 1, 5, 68, 73, 78, 94, 73, 38, - 21, 15, 8, 7, 67, 77, 82, 105, 5, 36, 28, 25, - 20, 11, 5, 64, 72, 85, 70, 36, 30, 18, 4, 6, 70, - 79, 92, 5, 55, 45, 39, 31, 23, 5, 68, 76, 81, - 62, 100, 99, 82, 104, 102, 91, 100, 96, 95, 97, - 97, 100, 91, 89, 88, 89, 84, 83, 70, 78, 80, 69, - 0, 2, 0, 8, 7, 7, 2, 18, 14, 13, 11, 8, 19, 14, - 8, 17, 15, 11, 8, 9, 64, 66, 68, 5, 72, 15, 29, - 15, 9, 23, 21, 13, 18, 24, 16, 22, 8, 2, 9, 46, - 45, 49, 45, 45, 55, 62, 62, 62, 62, 62, 62, 62, - 59, 25, 62, 62, 62, 62, 62, 56, 41, 30, 28, 6, - 75, 72, 88, 109, 52, 51, 54, 46, 41, 40, 31, 30, - 22, 21, 13, 8, 6, 72, 77, 0, 65, 72, 30, 33, 29, - 20, 28, 27, 13, 21, 22, 11, 65, 1, 70, 90, 18, - 8, 65, 77, 67, 66, 66, 1, 0, 64, 0, 0, 3, 10, 2, - 4, 8, 9, 62, 61, 58, 53, 48, 41, 33, 17, 74, 0, - 32, 25, 22, 18, 13, 6, 4, 1, 72, 82, 78, 72, 77, - 72, 65, 72, 78, 67, 0, 3, 1, 4, 4, 4, 62, 62, - 53, 45, 39, 31, 20, 5, 80 }, - - { - - 62, - 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 19, 50, - 53, 54, 14, 99, 4, 71, 4, 1, 8, 71, 5, 73, 16, - 49, 80, 98, 108, 104, 94, 67, 71, 4, 1, 83, 86, - 5, 14, 67, 78, 90, 5, 70, 83, 89, 5, 74, 89, 7, - 71, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0, - 78, 88, 97, 68, 16, 0, 18, 76, 94, 112, 84, 88, - 8, 68, 84, 75, 99, 80, 93, 86, 112, 88, 86, 92, - 101, 19, 64, 7, 88, 72, 87, 83, 114, 7, 0, 1, - 72, 16, 68, 67, 84, 84, 75, 74, 73, 8, 11, 66, - 13, 18, 79, 0, 68, 67, 5, 75, 23, 66, 2, 23, 29, - 33, 28, 21, 88, 69, 72, 11, 10, 96, 6, 9, 8, 3, - 7, 7, 7, 6, 2, 4, 66, 4, 17, 10, 74, 65, 2, 67, - 10, 16, 17, 9, 10, 6, 5, 4, 19, 17, 13, 77, 3, - 73, 30, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, - 9, 8, 4, 65, 9, 3, 7, 8, 5, 13, 20, 6, 81, 5, - 76, 10, 21, 83, 44, 55, 46, 45, 47, 47, 42, 42, - 38, 29, 23, 20, 25, 15, 78, 67, 2, 71, 25, 22, - 19, 23, 20, 14, 11, 12, 68, 0, 68, 93, 88, 103, - 73, 20, 18, 11, 1, 5, 68, 73, 78, 93, 72, 38, - 21, 15, 8, 7, 67, 77, 81, 104, 5, 36, 28, 25, - 19, 11, 5, 64, 72, 85, 70, 36, 30, 18, 4, 6, 70, - 79, 91, 5, 54, 44, 38, 30, 22, 5, 68, 76, 81, - 62, 99, 98, 82, 103, 101, 91, 99, 95, 94, 96, - 96, 99, 91, 89, 88, 88, 83, 83, 71, 78, 80, 69, - 0, 1, 0, 7, 6, 5, 1, 17, 14, 13, 11, 7, 18, 13, - 7, 16, 14, 10, 8, 8, 65, 67, 68, 5, 73, 14, 28, - 14, 9, 22, 20, 13, 17, 23, 16, 22, 7, 1, 7, 45, - 44, 48, 43, 44, 54, 62, 62, 62, 62, 62, 62, 62, - 56, 24, 62, 62, 62, 62, 61, 54, 39, 28, 26, 6, - 75, 72, 87, 107, 50, 49, 52, 44, 38, 38, 29, 28, - 20, 19, 12, 6, 5, 73, 78, 64, 66, 73, 29, 32, - 27, 18, 26, 25, 12, 19, 20, 10, 66, 64, 72, 91, - 17, 7, 66, 77, 67, 66, 65, 1, 0, 0, 0, 1, 4, 11, - 3, 5, 9, 10, 61, 59, 56, 51, 45, 38, 30, 14, 77, - 0, 32, 25, 22, 18, 13, 6, 4, 1, 72, 82, 78, 72, - 77, 71, 64, 72, 78, 66, 1, 3, 1, 4, 4, 3, 62, - 61, 51, 42, 36, 27, 16, 2, 83 }, - - { - - 62, - 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 18, 49, - 52, 54, 14, 97, 4, 70, 5, 1, 8, 70, 4, 74, 15, - 47, 81, 99, 109, 101, 92, 67, 70, 5, 1, 82, 85, - 6, 13, 67, 77, 89, 5, 70, 83, 89, 5, 74, 88, 7, - 71, 79, 88, 0, 71, 71, 77, 68, 5, 22, 0, 0, 0, - 77, 88, 97, 68, 15, 0, 18, 75, 94, 110, 82, 86, - 9, 66, 82, 74, 97, 79, 91, 85, 110, 88, 86, 92, - 100, 19, 64, 7, 87, 72, 86, 82, 113, 7, 0, 1, - 72, 16, 68, 66, 83, 83, 74, 74, 73, 8, 11, 66, - 13, 18, 78, 0, 67, 67, 5, 74, 22, 66, 2, 22, 28, - 33, 27, 20, 87, 69, 71, 10, 9, 96, 5, 9, 8, 4, - 7, 7, 8, 6, 2, 4, 65, 4, 17, 10, 75, 65, 2, 68, - 10, 15, 17, 9, 9, 6, 5, 4, 18, 17, 13, 77, 3, - 74, 29, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, - 9, 8, 4, 65, 9, 3, 7, 8, 5, 12, 20, 6, 81, 5, - 76, 9, 20, 83, 42, 54, 45, 44, 45, 45, 41, 41, - 36, 27, 22, 19, 23, 14, 79, 67, 2, 72, 24, 21, - 18, 22, 19, 13, 10, 11, 69, 64, 69, 93, 87, 102, - 72, 21, 18, 11, 1, 6, 67, 72, 77, 92, 71, 38, - 21, 15, 8, 8, 67, 76, 80, 102, 5, 36, 28, 25, - 19, 12, 5, 64, 72, 84, 70, 37, 30, 18, 4, 7, 70, - 79, 90, 5, 54, 44, 38, 29, 22, 5, 68, 75, 80, - 62, 98, 97, 81, 102, 99, 90, 97, 94, 92, 95, 95, - 97, 90, 88, 88, 87, 81, 83, 72, 77, 79, 69, 0, - 0, 0, 7, 5, 4, 0, 17, 14, 13, 11, 7, 17, 13, 7, - 15, 14, 10, 8, 7, 65, 67, 67, 6, 73, 14, 27, 14, - 9, 22, 20, 13, 16, 22, 16, 22, 6, 1, 6, 45, 43, - 47, 42, 43, 53, 60, 60, 62, 62, 62, 62, 62, 54, - 23, 62, 62, 62, 62, 58, 52, 38, 27, 25, 6, 74, - 72, 86, 105, 48, 48, 50, 42, 36, 37, 28, 26, 19, - 18, 11, 5, 4, 74, 78, 64, 66, 74, 28, 31, 26, - 16, 25, 24, 11, 18, 19, 9, 67, 65, 73, 92, 17, - 6, 66, 76, 67, 66, 64, 2, 1, 1, 1, 2, 5, 13, 4, - 6, 11, 12, 60, 58, 54, 49, 42, 35, 27, 11, 79, - 1, 32, 25, 23, 18, 14, 7, 4, 2, 71, 82, 77, 71, - 77, 70, 1, 71, 77, 65, 2, 3, 2, 5, 4, 3, 62, 59, - 49, 40, 33, 24, 12, 64, 85 }, - - { - - 62, - 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 16, 47, - 50, 54, 14, 94, 3, 69, 5, 1, 7, 70, 3, 75, 15, - 45, 83, 100, 109, 98, 91, 67, 69, 5, 1, 82, 84, - 6, 13, 67, 77, 89, 5, 71, 82, 89, 5, 74, 87, 6, - 71, 79, 88, 1, 70, 71, 76, 67, 5, 22, 0, 0, 0, - 77, 88, 97, 67, 14, 0, 18, 75, 94, 109, 80, 85, - 11, 64, 81, 73, 96, 77, 90, 84, 108, 87, 85, 91, - 99, 19, 64, 7, 87, 72, 86, 82, 111, 6, 0, 1, 72, - 16, 68, 66, 83, 83, 74, 74, 72, 8, 10, 66, 13, - 18, 78, 0, 67, 67, 5, 74, 22, 66, 2, 22, 27, 32, - 26, 19, 86, 68, 71, 9, 9, 95, 5, 9, 7, 4, 7, 7, - 9, 7, 2, 4, 65, 4, 16, 10, 76, 65, 2, 68, 9, 14, - 16, 9, 9, 7, 5, 4, 17, 16, 12, 77, 3, 74, 29, - 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, 9, 8, 4, - 65, 9, 3, 6, 8, 5, 12, 19, 5, 81, 4, 76, 8, 19, - 83, 41, 52, 43, 42, 43, 43, 39, 39, 34, 25, 20, - 17, 20, 12, 80, 67, 1, 72, 23, 20, 17, 21, 17, - 11, 9, 10, 69, 64, 69, 93, 87, 102, 72, 21, 18, - 11, 1, 6, 67, 72, 77, 91, 71, 38, 21, 15, 8, 8, - 66, 75, 80, 100, 5, 36, 28, 25, 19, 12, 5, 64, - 72, 83, 70, 37, 29, 17, 4, 7, 70, 79, 90, 5, 53, - 43, 37, 28, 22, 5, 68, 75, 80, 62, 97, 96, 80, - 100, 98, 89, 96, 92, 91, 93, 93, 95, 89, 87, 87, - 87, 80, 82, 72, 77, 78, 69, 64, 0, 64, 6, 4, 3, - 64, 16, 13, 13, 10, 6, 17, 13, 7, 14, 13, 10, 7, - 6, 65, 67, 67, 6, 73, 13, 27, 13, 9, 21, 19, 13, - 15, 21, 15, 21, 5, 0, 4, 44, 43, 47, 41, 41, 51, - 58, 58, 62, 62, 62, 62, 62, 52, 21, 59, 62, 59, - 62, 56, 49, 36, 26, 24, 6, 73, 71, 85, 103, 47, - 46, 48, 41, 34, 35, 26, 24, 18, 16, 9, 3, 2, 75, - 79, 65, 66, 75, 26, 29, 24, 15, 23, 22, 9, 16, - 17, 7, 68, 66, 74, 92, 16, 6, 67, 76, 66, 65, - 64, 2, 2, 2, 2, 3, 6, 14, 5, 7, 12, 13, 60, 56, - 52, 46, 40, 32, 24, 8, 81, 1, 33, 26, 23, 19, - 15, 7, 5, 2, 71, 81, 77, 70, 76, 69, 2, 71, 76, - 65, 2, 3, 2, 6, 4, 3, 62, 57, 46, 37, 30, 20, 8, - 68, 88 }, - - { - - 62, - 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 15, 46, - 49, 54, 14, 92, 3, 69, 6, 1, 6, 70, 2, 76, 14, - 44, 84, 101, 110, 95, 90, 67, 69, 6, 1, 81, 83, - 7, 12, 66, 76, 88, 4, 71, 82, 89, 5, 73, 87, 6, - 71, 78, 88, 1, 70, 71, 76, 67, 5, 22, 0, 0, 0, - 76, 88, 97, 67, 14, 64, 18, 75, 93, 107, 78, 83, - 12, 1, 80, 72, 94, 76, 89, 84, 107, 87, 85, 91, - 99, 20, 64, 7, 86, 71, 85, 81, 110, 6, 64, 0, - 73, 16, 68, 66, 82, 83, 73, 74, 72, 8, 10, 65, - 13, 17, 78, 0, 67, 67, 5, 74, 21, 66, 2, 21, 26, - 31, 26, 19, 86, 68, 71, 9, 8, 95, 4, 9, 7, 4, 7, - 7, 9, 7, 2, 4, 64, 4, 15, 10, 76, 66, 2, 69, 9, - 13, 16, 9, 8, 7, 5, 4, 15, 16, 11, 77, 3, 75, - 28, 22, 17, 14, 17, 18, 11, 16, 22, 0, 13, 9, 7, - 4, 65, 8, 2, 6, 7, 4, 11, 18, 5, 81, 4, 75, 7, - 17, 83, 39, 50, 41, 40, 41, 41, 37, 37, 32, 23, - 19, 16, 18, 10, 81, 67, 1, 73, 22, 19, 16, 19, - 16, 10, 8, 9, 70, 65, 70, 93, 87, 101, 71, 21, - 18, 11, 2, 6, 67, 72, 76, 90, 70, 37, 21, 15, 8, - 9, 66, 74, 79, 98, 5, 37, 28, 25, 19, 13, 5, 64, - 71, 83, 70, 37, 29, 17, 4, 7, 69, 78, 89, 5, 53, - 43, 36, 28, 22, 5, 67, 74, 79, 62, 97, 95, 80, - 99, 97, 88, 94, 91, 90, 92, 92, 94, 89, 86, 87, - 86, 78, 82, 73, 77, 78, 69, 64, 64, 64, 5, 3, 2, - 65, 16, 13, 13, 10, 6, 16, 12, 7, 14, 13, 9, 7, - 6, 65, 68, 67, 6, 74, 13, 26, 12, 8, 20, 19, 14, - 15, 20, 15, 21, 5, 0, 3, 43, 42, 46, 40, 40, 50, - 56, 56, 61, 60, 62, 62, 60, 49, 20, 57, 62, 56, - 62, 53, 47, 34, 25, 23, 6, 72, 71, 83, 100, 45, - 44, 46, 39, 32, 33, 25, 22, 16, 15, 8, 2, 1, 76, - 80, 65, 67, 76, 25, 28, 23, 13, 21, 20, 8, 15, - 15, 6, 70, 68, 76, 93, 15, 5, 68, 76, 66, 65, 0, - 3, 2, 4, 3, 4, 7, 15, 7, 8, 14, 14, 59, 55, 50, - 44, 37, 30, 21, 6, 83, 2, 33, 26, 24, 19, 16, 8, - 5, 3, 70, 81, 76, 70, 76, 68, 3, 71, 76, 64, 3, - 3, 3, 7, 4, 3, 62, 55, 44, 34, 26, 16, 5, 71, 90 }, - - { - - 62, - 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 13, 44, - 48, 54, 14, 90, 3, 68, 7, 1, 5, 70, 1, 77, 14, - 42, 86, 102, 110, 92, 89, 67, 68, 7, 1, 81, 82, - 7, 12, 66, 76, 87, 4, 72, 82, 89, 5, 73, 86, 6, - 72, 78, 88, 2, 70, 71, 76, 66, 5, 22, 0, 0, 0, - 76, 89, 97, 66, 13, 64, 18, 75, 93, 105, 77, 82, - 14, 2, 79, 71, 93, 75, 88, 83, 105, 86, 85, 90, - 98, 20, 64, 7, 86, 71, 85, 81, 108, 6, 64, 0, - 73, 16, 68, 66, 82, 83, 73, 74, 71, 8, 10, 65, - 13, 17, 78, 0, 67, 67, 5, 74, 20, 67, 2, 20, 25, - 30, 25, 18, 85, 67, 71, 8, 8, 94, 4, 9, 7, 4, 7, - 7, 10, 7, 2, 3, 64, 3, 14, 9, 77, 66, 2, 69, 8, - 12, 16, 8, 7, 7, 5, 4, 14, 16, 10, 77, 3, 75, - 27, 22, 17, 14, 17, 18, 11, 16, 21, 0, 13, 9, 7, - 4, 66, 8, 2, 5, 7, 4, 10, 17, 4, 81, 3, 75, 6, - 16, 83, 38, 48, 39, 38, 39, 39, 35, 35, 30, 21, - 17, 14, 16, 8, 82, 67, 1, 73, 21, 18, 15, 18, - 14, 8, 7, 7, 71, 65, 70, 93, 87, 101, 71, 21, - 18, 11, 2, 6, 67, 72, 76, 89, 70, 37, 21, 15, 8, - 9, 65, 74, 78, 96, 5, 37, 28, 25, 19, 13, 5, 64, - 71, 82, 70, 37, 29, 16, 4, 7, 69, 78, 88, 5, 52, - 42, 35, 27, 22, 5, 67, 74, 79, 62, 96, 94, 79, - 98, 96, 87, 93, 90, 89, 91, 90, 92, 88, 86, 87, - 86, 77, 82, 73, 77, 77, 69, 65, 64, 64, 4, 2, 1, - 66, 15, 12, 13, 9, 5, 16, 12, 7, 13, 12, 9, 7, - 5, 66, 68, 67, 6, 74, 12, 26, 11, 8, 19, 18, 14, - 14, 19, 14, 20, 4, 64, 1, 42, 41, 46, 39, 39, - 48, 54, 54, 59, 57, 62, 62, 57, 47, 19, 54, 62, - 53, 58, 50, 44, 32, 24, 21, 6, 71, 71, 82, 98, - 43, 42, 44, 37, 30, 31, 23, 20, 15, 13, 7, 0, - 64, 77, 81, 66, 67, 77, 24, 26, 21, 11, 19, 18, - 6, 13, 13, 4, 71, 69, 77, 94, 14, 4, 69, 76, 65, - 65, 0, 3, 3, 5, 3, 5, 8, 16, 8, 9, 15, 15, 59, - 53, 48, 41, 35, 27, 18, 3, 86, 2, 34, 27, 24, - 19, 16, 8, 5, 3, 70, 81, 76, 69, 75, 67, 4, 71, - 75, 64, 3, 3, 3, 8, 4, 3, 61, 53, 41, 31, 23, - 12, 1, 75, 93 }, - - { - - 62, - 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 12, 43, - 46, 54, 14, 87, 2, 67, 7, 1, 5, 69, 0, 78, 13, - 40, 88, 103, 111, 89, 87, 67, 67, 7, 1, 81, 81, - 7, 11, 66, 76, 87, 4, 72, 81, 89, 5, 73, 85, 5, - 72, 78, 88, 2, 69, 70, 75, 66, 5, 22, 0, 0, 0, - 75, 89, 97, 66, 12, 64, 18, 74, 93, 104, 75, 80, - 15, 4, 77, 70, 92, 73, 87, 82, 103, 86, 84, 90, - 97, 20, 64, 7, 85, 71, 84, 80, 107, 5, 64, 0, - 73, 16, 68, 65, 81, 83, 73, 74, 71, 8, 9, 65, - 13, 17, 77, 0, 66, 67, 5, 74, 20, 67, 2, 20, 24, - 30, 24, 17, 84, 67, 71, 7, 7, 94, 3, 9, 6, 4, 7, - 7, 11, 8, 2, 3, 64, 3, 13, 9, 78, 66, 2, 70, 8, - 11, 15, 8, 7, 8, 5, 4, 13, 15, 9, 77, 3, 76, 27, - 22, 17, 14, 17, 18, 11, 16, 21, 0, 13, 9, 7, 4, - 66, 8, 2, 5, 7, 4, 10, 16, 4, 81, 3, 75, 5, 15, - 83, 36, 46, 38, 37, 37, 37, 33, 33, 28, 19, 15, - 12, 13, 7, 83, 67, 0, 74, 20, 17, 14, 17, 13, 7, - 6, 6, 71, 66, 71, 93, 87, 100, 71, 21, 18, 11, - 2, 6, 66, 71, 75, 88, 69, 37, 21, 15, 8, 9, 65, - 73, 78, 94, 5, 37, 28, 25, 19, 13, 5, 64, 71, - 81, 70, 38, 28, 16, 4, 7, 69, 78, 88, 5, 52, 41, - 34, 26, 22, 5, 67, 74, 78, 62, 95, 93, 78, 96, - 95, 86, 92, 88, 88, 89, 89, 90, 87, 85, 86, 85, - 76, 81, 74, 76, 76, 69, 65, 65, 65, 4, 1, 0, 67, - 14, 12, 13, 9, 5, 15, 12, 7, 12, 11, 9, 6, 4, - 66, 68, 67, 6, 74, 11, 25, 11, 8, 18, 17, 14, - 13, 18, 14, 20, 3, 65, 64, 41, 41, 45, 38, 37, - 47, 52, 52, 57, 55, 62, 61, 54, 45, 17, 51, 62, - 50, 54, 48, 42, 30, 23, 20, 6, 70, 70, 81, 96, - 42, 41, 42, 36, 28, 29, 22, 18, 14, 11, 5, 65, - 65, 78, 82, 66, 67, 78, 22, 25, 19, 10, 18, 17, - 5, 12, 12, 3, 72, 70, 78, 94, 14, 4, 70, 75, 65, - 64, 1, 4, 4, 6, 4, 6, 9, 18, 9, 10, 16, 17, 58, - 51, 46, 39, 32, 24, 15, 0, 88, 2, 34, 27, 25, - 20, 17, 8, 6, 4, 69, 80, 76, 68, 75, 66, 5, 70, - 74, 0, 4, 3, 4, 9, 4, 3, 59, 51, 39, 28, 20, 9, - 66, 78, 96 }, - - { - - 61, - 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 10, 41, - 45, 54, 14, 85, 2, 66, 8, 1, 4, 69, 64, 79, 13, - 38, 89, 104, 111, 86, 86, 67, 66, 8, 1, 80, 80, - 8, 11, 66, 75, 86, 3, 73, 81, 89, 5, 73, 85, 5, - 72, 78, 88, 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, - 75, 89, 97, 65, 11, 64, 18, 74, 93, 102, 73, 79, - 17, 6, 76, 69, 90, 72, 86, 81, 101, 85, 84, 89, - 96, 20, 64, 7, 85, 71, 84, 80, 105, 5, 65, 64, - 74, 16, 68, 65, 81, 83, 72, 74, 70, 8, 9, 65, - 13, 16, 77, 0, 66, 67, 5, 74, 19, 67, 2, 19, 23, - 29, 23, 16, 84, 66, 71, 6, 7, 93, 3, 9, 6, 4, 7, - 7, 12, 8, 2, 3, 0, 3, 12, 9, 79, 66, 2, 70, 7, - 10, 15, 8, 6, 8, 5, 4, 11, 15, 8, 77, 3, 76, 26, - 22, 17, 14, 17, 18, 11, 16, 21, 0, 12, 9, 7, 4, - 66, 7, 1, 4, 6, 3, 9, 15, 3, 81, 2, 75, 4, 13, - 83, 35, 44, 36, 35, 35, 35, 31, 31, 26, 17, 14, - 11, 11, 5, 84, 67, 0, 74, 19, 16, 13, 15, 11, 5, - 5, 5, 72, 66, 71, 93, 87, 100, 70, 21, 18, 11, - 2, 6, 66, 71, 75, 87, 69, 37, 21, 15, 8, 10, 64, - 72, 77, 92, 5, 37, 28, 25, 19, 14, 5, 64, 71, - 81, 70, 38, 28, 15, 4, 7, 69, 78, 87, 5, 51, 41, - 33, 25, 22, 5, 67, 73, 78, 62, 94, 92, 78, 95, - 94, 85, 90, 87, 87, 88, 87, 89, 87, 84, 86, 85, - 74, 81, 74, 76, 76, 69, 66, 65, 65, 3, 0, 64, - 68, 14, 11, 13, 8, 4, 15, 11, 7, 11, 11, 8, 6, - 3, 66, 69, 67, 6, 75, 11, 25, 10, 8, 17, 17, 14, - 12, 17, 13, 19, 2, 65, 65, 40, 40, 45, 37, 36, - 45, 50, 50, 55, 52, 60, 59, 51, 42, 16, 48, 62, - 47, 50, 45, 39, 28, 22, 19, 6, 69, 70, 80, 94, - 40, 39, 40, 34, 26, 27, 20, 16, 12, 10, 4, 66, - 67, 79, 83, 67, 68, 79, 21, 23, 18, 8, 16, 15, - 3, 10, 10, 1, 73, 72, 80, 95, 13, 3, 71, 75, 64, - 64, 1, 4, 4, 7, 5, 7, 10, 19, 10, 11, 18, 18, - 58, 50, 44, 36, 30, 21, 12, 66, 90, 3, 35, 28, - 25, 20, 18, 9, 6, 4, 69, 80, 75, 68, 74, 65, 6, - 70, 74, 0, 4, 3, 4, 10, 4, 3, 58, 49, 36, 25, - 17, 5, 70, 82, 98 }, - - { - - 60, - 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 9, 40, 44, - 54, 14, 83, 2, 65, 9, 1, 3, 69, 65, 80, 12, 36, - 91, 105, 112, 83, 85, 67, 65, 9, 1, 80, 79, 8, - 10, 66, 75, 85, 3, 73, 81, 89, 5, 73, 84, 5, 72, - 78, 88, 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, 74, - 89, 97, 65, 10, 64, 18, 74, 93, 100, 71, 77, 18, - 8, 75, 68, 89, 71, 85, 80, 99, 85, 84, 89, 95, - 20, 64, 7, 84, 71, 83, 79, 104, 5, 65, 64, 74, - 16, 68, 65, 80, 83, 72, 74, 70, 8, 9, 65, 13, - 16, 77, 0, 66, 67, 5, 74, 18, 67, 2, 18, 22, 28, - 22, 15, 83, 66, 71, 5, 6, 93, 2, 9, 6, 4, 7, 7, - 13, 8, 2, 3, 0, 3, 11, 9, 80, 66, 2, 71, 7, 9, - 15, 8, 5, 8, 5, 4, 10, 15, 7, 77, 3, 77, 25, 22, - 17, 14, 17, 18, 11, 16, 21, 0, 12, 9, 7, 4, 66, - 7, 1, 4, 6, 3, 8, 14, 3, 81, 2, 75, 3, 12, 83, - 33, 42, 34, 33, 33, 33, 29, 29, 24, 15, 12, 9, - 9, 3, 85, 67, 0, 75, 18, 15, 12, 14, 10, 4, 4, - 4, 73, 67, 72, 93, 87, 99, 70, 21, 18, 11, 2, 6, - 66, 71, 74, 86, 68, 37, 21, 15, 8, 10, 64, 71, - 76, 90, 5, 37, 28, 25, 19, 14, 5, 64, 71, 80, - 70, 38, 28, 15, 4, 7, 69, 78, 86, 5, 51, 40, 32, - 24, 22, 5, 67, 73, 77, 62, 93, 91, 77, 94, 93, - 84, 89, 86, 86, 87, 86, 87, 86, 83, 86, 84, 73, - 81, 75, 76, 75, 69, 66, 66, 65, 2, 64, 65, 69, - 13, 11, 13, 8, 4, 14, 11, 7, 10, 10, 8, 6, 2, - 66, 69, 67, 6, 75, 10, 24, 9, 8, 16, 16, 14, 11, - 16, 13, 19, 1, 66, 67, 39, 39, 44, 36, 35, 44, - 48, 48, 53, 50, 57, 56, 48, 40, 15, 45, 59, 44, - 46, 42, 37, 26, 21, 18, 6, 68, 70, 79, 92, 38, - 37, 38, 32, 24, 25, 19, 14, 11, 8, 3, 68, 68, - 80, 84, 67, 68, 80, 20, 22, 16, 6, 14, 13, 2, 9, - 8, 0, 74, 73, 81, 96, 12, 2, 72, 75, 64, 64, 2, - 5, 5, 8, 6, 8, 11, 20, 11, 12, 19, 19, 57, 48, - 42, 34, 27, 18, 9, 69, 92, 3, 35, 28, 26, 20, - 19, 9, 6, 5, 68, 80, 75, 67, 74, 64, 7, 70, 73, - 1, 5, 3, 5, 11, 4, 3, 57, 47, 34, 22, 14, 1, 74, - 85, 101 }, - - { - - 58, - 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 7, 38, 42, - 53, 14, 81, 1, 65, 9, 0, 2, 69, 67, 82, 11, 34, - 93, 106, 113, 81, 84, 68, 65, 9, 0, 80, 78, 8, - 9, 66, 75, 85, 2, 74, 81, 90, 5, 73, 84, 4, 73, - 78, 88, 3, 69, 70, 75, 65, 4, 22, 0, 0, 0, 74, - 90, 97, 65, 9, 65, 18, 74, 93, 99, 70, 76, 19, - 9, 74, 67, 88, 70, 84, 80, 98, 85, 84, 89, 95, - 20, 64, 7, 84, 71, 83, 79, 103, 4, 66, 65, 75, - 16, 68, 65, 80, 83, 72, 74, 70, 7, 8, 65, 12, - 15, 77, 64, 66, 67, 4, 74, 17, 68, 1, 17, 20, - 27, 21, 14, 83, 66, 71, 4, 5, 93, 1, 8, 5, 4, 7, - 7, 13, 8, 2, 2, 0, 2, 10, 8, 81, 67, 1, 72, 6, - 8, 14, 7, 4, 8, 5, 4, 8, 14, 6, 77, 3, 78, 24, - 21, 16, 14, 17, 17, 10, 16, 20, 64, 11, 9, 6, 3, - 67, 6, 0, 3, 5, 2, 7, 13, 2, 81, 1, 75, 2, 10, - 83, 31, 40, 32, 31, 31, 30, 27, 27, 22, 13, 10, - 7, 6, 1, 87, 68, 64, 76, 17, 13, 10, 12, 8, 2, - 2, 2, 74, 68, 73, 93, 87, 99, 70, 21, 18, 11, 2, - 6, 66, 71, 74, 85, 68, 36, 21, 15, 8, 10, 64, - 71, 76, 89, 4, 37, 28, 24, 18, 14, 5, 64, 71, - 80, 70, 38, 27, 14, 3, 7, 69, 78, 86, 5, 50, 39, - 31, 23, 21, 5, 67, 73, 77, 62, 93, 90, 77, 93, - 92, 84, 88, 85, 85, 86, 85, 86, 86, 83, 86, 84, - 72, 81, 76, 76, 75, 69, 67, 67, 66, 1, 65, 67, - 71, 12, 10, 13, 7, 3, 13, 10, 6, 9, 9, 7, 5, 1, - 67, 70, 67, 6, 76, 9, 23, 8, 7, 15, 15, 14, 10, - 14, 12, 18, 0, 67, 69, 38, 38, 43, 34, 33, 42, - 46, 46, 50, 47, 54, 53, 45, 37, 13, 42, 55, 41, - 41, 39, 34, 24, 19, 16, 6, 68, 70, 78, 90, 36, - 35, 36, 30, 21, 23, 17, 11, 9, 6, 1, 70, 70, 81, - 85, 68, 69, 82, 18, 20, 14, 4, 12, 11, 0, 7, 6, - 65, 76, 75, 83, 97, 11, 1, 73, 75, 64, 64, 2, 5, - 5, 9, 6, 9, 11, 21, 12, 13, 20, 20, 56, 46, 39, - 31, 24, 15, 5, 72, 95, 3, 35, 28, 26, 20, 19, 9, - 6, 5, 68, 80, 75, 67, 74, 0, 8, 70, 73, 1, 5, 3, - 5, 11, 4, 2, 55, 44, 31, 19, 10, 66, 78, 89, 104 }, - - { - - 57, - 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 6, 37, 41, - 53, 14, 78, 1, 64, 10, 0, 2, 68, 68, 83, 11, 33, - 94, 107, 113, 78, 82, 68, 64, 10, 0, 79, 76, 9, - 9, 65, 74, 84, 2, 74, 80, 90, 5, 72, 83, 4, 73, - 77, 88, 4, 68, 69, 74, 64, 4, 22, 0, 0, 0, 73, - 90, 97, 64, 9, 65, 18, 73, 92, 97, 68, 74, 21, - 11, 72, 66, 86, 68, 82, 79, 96, 84, 83, 88, 94, - 21, 0, 8, 83, 70, 82, 78, 101, 4, 66, 65, 75, - 17, 68, 64, 79, 82, 71, 73, 69, 7, 8, 64, 12, - 15, 76, 64, 65, 67, 4, 73, 17, 68, 1, 17, 19, - 27, 21, 14, 82, 65, 70, 4, 5, 92, 1, 8, 5, 5, 7, - 7, 14, 9, 3, 2, 1, 2, 10, 8, 81, 67, 1, 72, 6, - 7, 14, 7, 4, 9, 6, 4, 7, 14, 6, 76, 3, 78, 24, - 21, 16, 14, 17, 17, 10, 16, 20, 64, 11, 9, 6, 3, - 67, 6, 0, 3, 5, 2, 7, 13, 2, 80, 1, 74, 2, 9, - 82, 30, 39, 31, 30, 29, 28, 26, 26, 20, 12, 9, - 6, 4, 0, 88, 68, 64, 76, 16, 12, 9, 11, 7, 1, 1, - 1, 74, 68, 73, 92, 86, 98, 69, 22, 18, 11, 3, 7, - 65, 70, 73, 83, 67, 36, 21, 15, 8, 11, 0, 70, - 75, 87, 4, 38, 29, 24, 18, 15, 5, 64, 70, 79, - 70, 39, 27, 14, 3, 8, 68, 77, 85, 5, 50, 39, 31, - 23, 21, 5, 66, 72, 76, 62, 92, 89, 76, 91, 90, - 83, 86, 83, 83, 84, 83, 84, 85, 82, 85, 83, 70, - 80, 76, 75, 74, 68, 67, 67, 66, 1, 65, 68, 72, - 12, 10, 14, 7, 3, 13, 10, 6, 9, 9, 7, 5, 1, 67, - 70, 66, 7, 76, 9, 23, 8, 7, 15, 15, 15, 10, 13, - 12, 18, 0, 67, 70, 38, 38, 43, 33, 32, 41, 44, - 44, 48, 45, 52, 51, 43, 35, 12, 40, 52, 38, 37, - 37, 32, 23, 18, 15, 6, 67, 69, 76, 87, 35, 34, - 35, 29, 19, 22, 16, 9, 8, 5, 0, 71, 71, 82, 85, - 68, 69, 83, 17, 19, 13, 3, 11, 10, 64, 6, 5, 66, - 77, 76, 84, 97, 11, 1, 73, 74, 0, 0, 3, 6, 6, - 11, 7, 10, 12, 23, 14, 14, 22, 22, 56, 45, 37, - 29, 22, 13, 2, 74, 97, 4, 36, 29, 27, 21, 20, - 10, 7, 6, 67, 79, 74, 66, 73, 2, 10, 69, 72, 2, - 6, 4, 6, 12, 4, 2, 54, 42, 29, 17, 7, 69, 81, - 92, 106 }, - - { - - 56, - 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 5, 36, 40, - 53, 14, 76, 1, 0, 11, 0, 1, 68, 69, 84, 10, 31, - 96, 108, 114, 75, 81, 68, 0, 11, 0, 79, 75, 9, - 8, 65, 74, 83, 2, 74, 80, 90, 5, 72, 82, 4, 73, - 77, 88, 4, 68, 69, 74, 64, 4, 22, 0, 0, 0, 72, - 90, 97, 64, 8, 65, 18, 73, 92, 95, 66, 72, 22, - 13, 71, 65, 85, 67, 81, 78, 94, 84, 83, 88, 93, - 21, 0, 8, 82, 70, 81, 78, 100, 4, 66, 65, 75, - 17, 68, 64, 79, 82, 71, 73, 69, 7, 8, 64, 12, - 15, 76, 64, 65, 67, 4, 73, 16, 68, 1, 16, 18, - 26, 20, 13, 81, 65, 70, 3, 4, 92, 0, 8, 5, 5, 7, - 7, 15, 9, 3, 2, 1, 2, 9, 8, 82, 67, 1, 73, 6, 6, - 14, 7, 3, 9, 6, 4, 6, 14, 5, 76, 3, 79, 23, 21, - 16, 14, 17, 17, 10, 16, 20, 64, 11, 9, 6, 3, 67, - 6, 0, 3, 5, 2, 6, 12, 1, 80, 1, 74, 1, 8, 82, - 28, 37, 29, 28, 27, 26, 24, 24, 18, 10, 7, 4, 2, - 65, 89, 68, 64, 77, 15, 11, 8, 10, 5, 0, 0, 0, - 75, 69, 74, 92, 86, 97, 69, 22, 18, 11, 3, 7, - 65, 70, 73, 82, 66, 36, 21, 15, 8, 11, 0, 69, - 74, 85, 4, 38, 29, 24, 18, 15, 5, 64, 70, 78, - 70, 39, 27, 14, 3, 8, 68, 77, 84, 5, 49, 38, 30, - 22, 21, 5, 66, 72, 76, 62, 91, 88, 75, 90, 89, - 82, 85, 82, 82, 83, 82, 82, 84, 81, 85, 82, 69, - 80, 77, 75, 73, 68, 67, 68, 66, 0, 66, 69, 73, - 11, 10, 14, 7, 2, 12, 10, 6, 8, 8, 7, 5, 0, 67, - 70, 66, 7, 76, 8, 22, 7, 7, 14, 14, 15, 9, 12, - 12, 18, 64, 68, 72, 37, 37, 42, 32, 31, 40, 42, - 42, 46, 43, 49, 48, 40, 33, 11, 37, 49, 35, 33, - 34, 30, 21, 17, 14, 6, 66, 69, 75, 85, 33, 32, - 33, 27, 17, 20, 14, 7, 7, 3, 64, 73, 72, 83, 86, - 69, 69, 84, 16, 18, 11, 1, 9, 8, 65, 4, 3, 67, - 78, 77, 85, 98, 10, 0, 74, 74, 0, 0, 4, 6, 7, - 12, 8, 11, 13, 24, 15, 15, 23, 23, 55, 43, 35, - 27, 19, 10, 64, 77, 99, 4, 36, 29, 27, 21, 21, - 10, 7, 6, 67, 79, 74, 65, 73, 3, 11, 69, 71, 3, - 7, 4, 6, 13, 4, 2, 53, 40, 27, 14, 4, 73, 85, - 95, 109 }, - - { - - 55, - 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 3, 34, 39, - 53, 14, 74, 1, 1, 12, 0, 0, 68, 70, 85, 10, 29, - 97, 109, 114, 72, 80, 68, 1, 12, 0, 78, 74, 10, - 8, 65, 73, 82, 1, 75, 80, 90, 5, 72, 82, 4, 73, - 77, 88, 5, 68, 69, 74, 0, 4, 22, 0, 0, 0, 72, - 90, 97, 0, 7, 65, 18, 73, 92, 93, 64, 71, 24, - 15, 70, 64, 83, 66, 80, 77, 92, 83, 83, 87, 92, - 21, 0, 8, 82, 70, 81, 77, 98, 4, 67, 66, 76, 17, - 68, 64, 78, 82, 70, 73, 68, 7, 8, 64, 12, 14, - 76, 64, 65, 67, 4, 73, 15, 68, 1, 15, 17, 25, - 19, 12, 81, 64, 70, 2, 4, 91, 0, 8, 5, 5, 7, 7, - 16, 9, 3, 2, 2, 2, 8, 8, 83, 67, 1, 73, 5, 5, - 14, 7, 2, 9, 6, 4, 4, 14, 4, 76, 3, 79, 22, 21, - 16, 14, 17, 17, 10, 16, 20, 64, 10, 9, 6, 3, 67, - 5, 64, 2, 4, 1, 5, 11, 1, 80, 0, 74, 0, 6, 82, - 27, 35, 27, 26, 25, 24, 22, 22, 16, 8, 6, 3, 0, - 67, 90, 68, 64, 77, 14, 10, 7, 8, 4, 65, 64, 64, - 76, 69, 74, 92, 86, 97, 68, 22, 18, 11, 3, 7, - 65, 70, 72, 81, 66, 36, 21, 15, 8, 12, 1, 68, - 73, 83, 4, 38, 29, 24, 18, 16, 5, 64, 70, 78, - 70, 39, 27, 13, 3, 8, 68, 77, 83, 5, 49, 38, 29, - 21, 21, 5, 66, 71, 75, 62, 90, 87, 75, 89, 88, - 81, 83, 81, 81, 82, 80, 81, 84, 80, 85, 82, 67, - 80, 77, 75, 73, 68, 68, 68, 66, 64, 67, 70, 74, - 11, 9, 14, 6, 2, 12, 9, 6, 7, 8, 6, 5, 64, 67, - 71, 66, 7, 77, 8, 22, 6, 7, 13, 14, 15, 8, 11, - 11, 17, 65, 68, 73, 36, 36, 42, 31, 30, 38, 40, - 40, 44, 40, 47, 46, 37, 30, 10, 34, 46, 32, 29, - 31, 27, 19, 16, 13, 6, 65, 69, 74, 83, 31, 30, - 31, 25, 15, 18, 13, 5, 5, 2, 65, 74, 74, 84, 87, - 69, 70, 85, 15, 16, 10, 64, 7, 6, 67, 3, 1, 69, - 79, 79, 87, 99, 9, 64, 75, 74, 1, 0, 4, 7, 7, - 13, 9, 12, 14, 25, 16, 16, 25, 24, 55, 42, 33, - 24, 17, 7, 67, 80, 101, 5, 37, 30, 28, 21, 22, - 11, 7, 7, 66, 79, 73, 65, 72, 4, 12, 69, 71, 3, - 7, 4, 7, 14, 4, 2, 52, 38, 24, 11, 1, 77, 89, - 99, 111 }, - - { - - 53, - 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 2, 33, 37, - 53, 14, 71, 0, 2, 12, 0, 64, 68, 71, 86, 9, 27, - 99, 110, 115, 69, 79, 68, 2, 12, 0, 78, 73, 10, - 7, 65, 73, 82, 1, 75, 79, 90, 5, 72, 81, 3, 74, - 77, 88, 5, 67, 69, 73, 0, 4, 22, 0, 0, 0, 71, - 91, 97, 0, 6, 65, 18, 73, 92, 92, 0, 69, 25, 16, - 69, 0, 82, 64, 79, 76, 90, 83, 82, 87, 91, 21, - 0, 8, 81, 70, 80, 77, 97, 3, 67, 66, 76, 17, 68, - 64, 78, 82, 70, 73, 68, 7, 7, 64, 12, 14, 76, - 64, 65, 67, 4, 73, 15, 69, 1, 15, 16, 24, 18, - 11, 80, 64, 70, 1, 3, 91, 64, 8, 4, 5, 7, 7, 17, - 10, 3, 1, 2, 1, 7, 7, 84, 67, 1, 74, 5, 4, 13, - 6, 2, 10, 6, 4, 3, 13, 3, 76, 3, 80, 22, 21, 16, - 14, 17, 17, 10, 16, 19, 64, 10, 9, 6, 3, 68, 5, - 64, 2, 4, 1, 5, 10, 0, 80, 0, 74, 64, 5, 82, 25, - 33, 25, 24, 23, 22, 20, 20, 14, 6, 4, 1, 66, 69, - 91, 68, 65, 78, 13, 9, 6, 7, 2, 66, 65, 66, 76, - 70, 75, 92, 86, 96, 68, 22, 18, 11, 3, 7, 65, - 70, 72, 80, 65, 36, 21, 15, 8, 12, 1, 68, 73, - 81, 4, 38, 29, 24, 18, 16, 5, 64, 70, 77, 70, - 39, 26, 13, 3, 8, 68, 77, 83, 5, 48, 37, 28, 20, - 21, 5, 66, 71, 75, 62, 89, 86, 74, 87, 87, 80, - 82, 79, 80, 80, 79, 79, 83, 80, 84, 81, 66, 79, - 78, 75, 72, 68, 68, 69, 67, 65, 68, 71, 75, 10, - 9, 14, 6, 1, 11, 9, 6, 6, 7, 6, 4, 65, 68, 71, - 66, 7, 77, 7, 21, 5, 7, 12, 13, 15, 7, 10, 11, - 17, 66, 69, 75, 35, 36, 41, 30, 28, 37, 38, 38, - 42, 38, 44, 43, 34, 28, 8, 31, 42, 29, 25, 29, - 25, 17, 15, 11, 6, 64, 68, 73, 81, 30, 28, 29, - 24, 13, 16, 11, 3, 4, 0, 67, 76, 75, 85, 88, 70, - 70, 86, 13, 15, 8, 65, 5, 4, 68, 1, 64, 70, 80, - 80, 88, 99, 8, 64, 76, 74, 1, 1, 5, 7, 8, 14, 9, - 13, 15, 26, 17, 17, 26, 25, 54, 40, 31, 22, 14, - 4, 70, 83, 104, 5, 37, 30, 28, 22, 22, 11, 8, 7, - 66, 78, 73, 64, 72, 5, 13, 69, 70, 4, 8, 4, 7, - 15, 4, 2, 50, 36, 22, 8, 65, 81, 93, 102, 114 }, - - { - - 52, - 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 0, 31, 36, - 53, 14, 69, 0, 3, 13, 0, 64, 67, 72, 87, 9, 25, - 101, 111, 115, 66, 77, 68, 3, 13, 0, 78, 72, 10, - 7, 65, 73, 81, 1, 76, 79, 90, 5, 72, 80, 3, 74, - 77, 88, 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 71, - 91, 97, 1, 5, 65, 18, 72, 92, 90, 2, 68, 27, 18, - 67, 1, 81, 0, 78, 75, 88, 82, 82, 86, 90, 21, 0, - 8, 81, 70, 80, 76, 95, 3, 67, 66, 76, 17, 68, 0, - 77, 82, 70, 73, 67, 7, 7, 64, 12, 14, 75, 64, - 64, 67, 4, 73, 14, 69, 1, 14, 15, 24, 17, 10, - 79, 0, 70, 0, 3, 90, 64, 8, 4, 5, 7, 7, 18, 10, - 3, 1, 2, 1, 6, 7, 85, 67, 1, 74, 4, 3, 13, 6, 1, - 10, 6, 4, 2, 13, 2, 76, 3, 80, 21, 21, 16, 14, - 17, 17, 10, 16, 19, 64, 10, 9, 6, 3, 68, 5, 64, - 1, 4, 1, 4, 9, 0, 80, 64, 74, 65, 4, 82, 24, 31, - 24, 23, 21, 20, 18, 18, 12, 4, 2, 64, 68, 70, - 92, 68, 65, 78, 12, 8, 5, 6, 1, 68, 66, 67, 77, - 70, 75, 92, 86, 96, 68, 22, 18, 11, 3, 7, 64, - 69, 71, 79, 65, 36, 21, 15, 8, 12, 2, 67, 72, - 79, 4, 38, 29, 24, 18, 16, 5, 64, 70, 76, 70, - 40, 26, 12, 3, 8, 68, 77, 82, 5, 48, 36, 27, 19, - 21, 5, 66, 71, 74, 62, 88, 85, 73, 86, 86, 79, - 81, 78, 79, 79, 77, 77, 82, 79, 84, 81, 65, 79, - 78, 74, 71, 68, 69, 69, 67, 65, 69, 72, 76, 9, - 8, 14, 5, 1, 11, 9, 6, 5, 6, 6, 4, 66, 68, 71, - 66, 7, 77, 6, 21, 5, 7, 11, 12, 15, 6, 9, 10, - 16, 67, 70, 77, 34, 35, 41, 29, 27, 35, 36, 36, - 40, 35, 41, 41, 31, 26, 7, 28, 39, 26, 21, 26, - 22, 15, 14, 10, 6, 0, 68, 72, 79, 28, 27, 27, - 22, 11, 14, 10, 1, 3, 65, 68, 78, 77, 86, 89, - 70, 70, 87, 12, 13, 6, 67, 4, 3, 70, 0, 65, 72, - 81, 81, 89, 100, 8, 65, 77, 73, 2, 1, 5, 8, 9, - 15, 10, 14, 16, 28, 18, 18, 27, 27, 54, 38, 29, - 19, 12, 1, 73, 86, 106, 5, 38, 31, 29, 22, 23, - 11, 8, 8, 65, 78, 73, 0, 71, 6, 14, 68, 69, 4, - 8, 4, 8, 16, 4, 2, 49, 34, 19, 5, 68, 84, 97, - 106, 117 }, - - { - - 51, - 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 64, 30, 35, - 53, 14, 67, 0, 3, 14, 0, 65, 67, 73, 88, 8, 24, - 102, 112, 116, 0, 76, 68, 3, 14, 0, 77, 71, 11, - 6, 64, 72, 80, 0, 76, 79, 90, 5, 71, 80, 3, 74, - 76, 88, 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 70, - 91, 97, 1, 5, 66, 18, 72, 91, 88, 4, 66, 28, 20, - 66, 2, 79, 1, 77, 75, 87, 82, 82, 86, 90, 22, 0, - 8, 80, 69, 79, 76, 94, 3, 68, 67, 77, 17, 68, 0, - 77, 82, 69, 73, 67, 7, 7, 0, 12, 13, 75, 64, 64, - 67, 4, 73, 13, 69, 1, 13, 14, 23, 17, 10, 79, 0, - 70, 0, 2, 90, 65, 8, 4, 5, 7, 7, 18, 10, 3, 1, - 3, 1, 5, 7, 85, 68, 1, 75, 4, 2, 13, 6, 0, 10, - 6, 4, 0, 13, 1, 76, 3, 81, 20, 21, 15, 14, 17, - 17, 10, 16, 19, 64, 9, 9, 5, 3, 68, 4, 65, 1, 3, - 0, 3, 8, 64, 80, 64, 73, 66, 2, 82, 22, 29, 22, - 21, 19, 18, 16, 16, 10, 2, 1, 65, 70, 72, 93, - 68, 65, 79, 11, 7, 4, 4, 64, 69, 67, 68, 78, 71, - 76, 92, 86, 95, 67, 22, 18, 11, 4, 7, 64, 69, - 71, 78, 64, 35, 21, 15, 8, 13, 2, 66, 71, 77, 4, - 39, 29, 24, 18, 17, 5, 64, 69, 76, 70, 40, 26, - 12, 3, 8, 67, 76, 81, 5, 47, 36, 26, 19, 21, 5, - 65, 70, 74, 62, 88, 84, 73, 85, 85, 78, 79, 77, - 78, 78, 76, 76, 82, 78, 84, 80, 0, 79, 79, 74, - 71, 68, 69, 70, 67, 66, 70, 73, 77, 9, 8, 14, 5, - 0, 10, 8, 6, 5, 6, 5, 4, 66, 68, 72, 66, 7, 78, - 6, 20, 4, 6, 10, 12, 16, 6, 8, 10, 16, 67, 70, - 78, 33, 34, 40, 28, 26, 34, 34, 34, 38, 33, 39, - 38, 28, 23, 6, 26, 36, 23, 17, 23, 20, 13, 13, - 9, 6, 1, 68, 70, 76, 26, 25, 25, 20, 9, 12, 8, - 64, 1, 66, 69, 79, 78, 87, 90, 71, 71, 88, 11, - 12, 5, 69, 2, 1, 71, 65, 67, 73, 83, 83, 91, - 101, 7, 66, 78, 73, 2, 1, 6, 8, 9, 17, 11, 15, - 17, 29, 20, 19, 29, 28, 53, 37, 27, 17, 9, 64, - 76, 88, 108, 6, 38, 31, 29, 22, 24, 12, 8, 8, - 65, 78, 72, 0, 71, 7, 15, 68, 69, 5, 9, 4, 8, - 17, 4, 2, 48, 32, 17, 2, 72, 88, 100, 109, 119 }, - - { - - 50, - 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 66, 28, 33, - 53, 14, 64, 64, 4, 14, 0, 66, 67, 74, 89, 8, 22, - 104, 113, 116, 3, 75, 68, 4, 14, 0, 77, 70, 11, - 6, 64, 72, 80, 0, 77, 78, 90, 5, 71, 79, 2, 74, - 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 70, - 91, 97, 2, 4, 66, 18, 72, 91, 87, 6, 65, 30, 22, - 65, 3, 78, 3, 76, 74, 85, 81, 81, 85, 89, 22, 0, - 8, 80, 69, 79, 75, 92, 2, 68, 67, 77, 17, 68, 0, - 76, 82, 69, 73, 66, 7, 6, 0, 12, 13, 75, 64, 64, - 67, 4, 73, 13, 69, 1, 13, 13, 22, 16, 9, 78, 1, - 70, 64, 2, 89, 65, 8, 3, 5, 7, 7, 19, 11, 3, 1, - 3, 1, 4, 7, 86, 68, 1, 75, 3, 1, 12, 6, 0, 11, - 6, 4, 64, 12, 0, 76, 3, 81, 20, 21, 15, 14, 17, - 17, 10, 16, 19, 64, 9, 9, 5, 3, 68, 4, 65, 0, 3, - 0, 3, 7, 64, 80, 65, 73, 67, 1, 82, 21, 27, 20, - 19, 17, 16, 14, 14, 8, 0, 64, 67, 73, 74, 94, - 68, 66, 79, 10, 6, 3, 3, 65, 71, 68, 69, 78, 71, - 76, 92, 86, 95, 67, 22, 18, 11, 4, 7, 64, 69, - 70, 77, 64, 35, 21, 15, 8, 13, 3, 65, 71, 75, 4, - 39, 29, 24, 18, 17, 5, 64, 69, 75, 70, 40, 25, - 11, 3, 8, 67, 76, 81, 5, 47, 35, 25, 18, 21, 5, - 65, 70, 73, 62, 87, 83, 72, 83, 84, 77, 78, 75, - 77, 76, 74, 74, 81, 77, 83, 80, 1, 78, 79, 74, - 70, 68, 70, 70, 68, 67, 71, 74, 78, 8, 7, 14, 4, - 0, 10, 8, 6, 4, 5, 5, 3, 67, 68, 72, 66, 7, 78, - 5, 20, 3, 6, 9, 11, 16, 5, 7, 9, 15, 68, 71, 80, - 32, 34, 40, 27, 24, 32, 32, 32, 36, 30, 36, 36, - 25, 21, 4, 23, 32, 20, 13, 21, 17, 11, 12, 8, 6, - 2, 67, 69, 74, 25, 23, 23, 19, 7, 10, 7, 66, 0, - 68, 71, 81, 80, 88, 91, 71, 71, 89, 9, 10, 3, - 70, 0, 64, 73, 66, 69, 75, 84, 84, 92, 101, 6, - 66, 79, 73, 3, 2, 6, 9, 10, 18, 12, 16, 18, 30, - 21, 20, 30, 29, 53, 35, 25, 14, 7, 67, 79, 91, - 110, 6, 39, 32, 30, 23, 25, 12, 9, 9, 64, 77, - 72, 1, 70, 8, 16, 68, 68, 5, 9, 4, 9, 18, 4, 2, - 46, 30, 14, 64, 75, 92, 104, 113, 122 }, - - { - - 48, - 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 67, 27, 32, - 53, 14, 1, 64, 5, 15, 0, 67, 67, 75, 91, 7, 20, - 106, 114, 117, 5, 74, 68, 5, 15, 0, 77, 69, 11, - 5, 64, 72, 79, 64, 77, 78, 91, 5, 71, 79, 2, 75, - 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 69, - 92, 97, 2, 3, 66, 18, 72, 91, 85, 7, 0, 31, 23, - 64, 4, 77, 4, 75, 73, 83, 81, 81, 85, 88, 22, 0, - 8, 79, 69, 78, 75, 91, 2, 69, 68, 78, 17, 68, 0, - 76, 82, 69, 73, 66, 6, 6, 0, 12, 12, 75, 64, 64, - 67, 3, 73, 12, 70, 1, 12, 11, 21, 15, 8, 78, 1, - 70, 65, 1, 89, 66, 7, 3, 5, 7, 7, 20, 11, 3, 0, - 3, 0, 3, 6, 87, 68, 1, 76, 3, 0, 12, 5, 64, 11, - 6, 4, 66, 12, 64, 76, 3, 82, 19, 20, 15, 14, 17, - 16, 9, 16, 18, 65, 8, 9, 5, 2, 69, 3, 66, 0, 2, - 64, 2, 6, 65, 80, 65, 73, 68, 64, 82, 19, 25, - 18, 17, 15, 13, 12, 12, 6, 65, 66, 69, 75, 76, - 95, 68, 66, 80, 9, 4, 1, 1, 67, 72, 70, 71, 79, - 72, 77, 92, 86, 94, 67, 22, 18, 11, 4, 7, 64, - 69, 70, 76, 0, 35, 21, 15, 8, 13, 3, 65, 70, 74, - 4, 39, 29, 24, 17, 17, 5, 64, 69, 75, 70, 40, - 25, 11, 3, 8, 67, 76, 80, 5, 46, 34, 24, 17, 20, - 5, 65, 70, 73, 62, 86, 82, 72, 82, 83, 77, 77, - 74, 76, 75, 73, 73, 81, 77, 83, 79, 2, 78, 80, - 74, 70, 68, 70, 71, 68, 68, 72, 76, 79, 7, 7, - 14, 4, 64, 9, 7, 5, 3, 4, 4, 3, 68, 69, 73, 66, - 7, 79, 4, 19, 2, 6, 8, 10, 16, 4, 6, 9, 15, 69, - 72, 82, 31, 33, 39, 25, 23, 31, 30, 30, 33, 28, - 33, 33, 22, 18, 3, 20, 29, 17, 9, 18, 15, 9, 10, - 6, 6, 2, 67, 68, 72, 23, 21, 21, 17, 4, 8, 5, - 68, 65, 70, 72, 83, 81, 89, 92, 72, 72, 90, 8, - 9, 1, 72, 65, 66, 74, 68, 71, 76, 85, 86, 94, - 102, 5, 67, 80, 73, 3, 2, 7, 9, 10, 19, 12, 17, - 19, 31, 22, 21, 31, 30, 52, 33, 23, 12, 4, 70, - 82, 94, 113, 6, 39, 32, 30, 23, 25, 12, 9, 9, - 64, 77, 72, 1, 70, 9, 17, 68, 68, 6, 10, 4, 9, - 18, 4, 1, 45, 28, 12, 67, 78, 96, 108, 116, 125 }, - - { - - 47, - 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 68, 26, 31, - 53, 14, 3, 64, 6, 16, 0, 67, 66, 76, 92, 6, 18, - 107, 115, 118, 8, 72, 68, 6, 16, 0, 76, 68, 12, - 4, 64, 71, 78, 64, 77, 78, 91, 5, 71, 78, 2, 75, - 76, 88, 7, 66, 67, 72, 2, 4, 22, 0, 0, 0, 68, - 92, 97, 2, 2, 66, 18, 71, 91, 83, 9, 2, 32, 25, - 1, 5, 75, 5, 73, 72, 81, 81, 81, 85, 87, 22, 0, - 8, 78, 69, 77, 74, 90, 2, 69, 68, 78, 17, 68, 1, - 75, 81, 68, 73, 66, 6, 6, 0, 12, 12, 74, 64, 0, - 67, 3, 72, 11, 70, 1, 11, 10, 21, 14, 7, 77, 1, - 69, 66, 0, 89, 67, 7, 3, 6, 7, 7, 21, 11, 3, 0, - 4, 0, 3, 6, 88, 68, 1, 77, 3, 64, 12, 5, 65, 11, - 6, 4, 67, 12, 64, 76, 3, 83, 18, 20, 15, 14, 17, - 16, 9, 16, 18, 65, 8, 9, 5, 2, 69, 3, 66, 0, 2, - 64, 1, 6, 65, 80, 65, 73, 69, 65, 82, 17, 24, - 17, 16, 13, 11, 11, 11, 4, 67, 67, 70, 77, 77, - 96, 68, 66, 81, 8, 3, 0, 0, 68, 73, 71, 72, 80, - 73, 78, 92, 85, 93, 66, 23, 18, 11, 4, 8, 0, 68, - 69, 75, 1, 35, 21, 15, 8, 14, 3, 64, 69, 72, 4, - 39, 29, 24, 17, 18, 5, 64, 69, 74, 70, 41, 25, - 11, 3, 9, 67, 76, 79, 5, 46, 34, 24, 16, 20, 5, - 65, 69, 72, 62, 85, 81, 71, 81, 81, 76, 75, 73, - 74, 74, 72, 71, 80, 76, 83, 78, 4, 78, 81, 73, - 69, 68, 70, 72, 68, 68, 73, 77, 80, 7, 7, 14, 4, - 64, 8, 7, 5, 2, 4, 4, 3, 69, 69, 73, 65, 8, 79, - 4, 18, 2, 6, 8, 10, 16, 3, 5, 9, 15, 70, 72, 83, - 31, 32, 38, 24, 22, 30, 28, 28, 31, 26, 31, 30, - 20, 16, 2, 17, 26, 14, 5, 15, 13, 8, 9, 5, 6, 3, - 67, 67, 70, 21, 20, 19, 15, 2, 7, 4, 70, 66, 71, - 73, 84, 82, 90, 92, 72, 72, 91, 7, 8, 0, 74, 66, - 67, 75, 69, 72, 77, 86, 87, 95, 103, 5, 68, 80, - 72, 3, 2, 8, 10, 11, 20, 13, 18, 20, 33, 23, 22, - 33, 32, 51, 32, 21, 10, 1, 73, 85, 97, 115, 7, - 39, 32, 31, 23, 26, 13, 9, 10, 0, 77, 71, 2, 70, - 10, 19, 67, 67, 7, 11, 4, 10, 19, 4, 1, 44, 26, - 10, 69, 81, 99, 112, 119, 126 }, - - { - - 46, - 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 70, 24, 29, - 53, 14, 6, 65, 7, 16, 0, 68, 66, 77, 93, 6, 16, - 109, 116, 118, 11, 71, 68, 7, 16, 0, 76, 67, 12, - 4, 64, 71, 78, 64, 78, 77, 91, 5, 71, 77, 1, 75, - 76, 88, 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 68, - 92, 97, 3, 1, 66, 18, 71, 91, 82, 11, 3, 34, 27, - 2, 6, 74, 7, 72, 71, 79, 80, 80, 84, 86, 22, 0, - 8, 78, 69, 77, 74, 88, 1, 69, 68, 78, 17, 68, 1, - 75, 81, 68, 73, 65, 6, 5, 0, 12, 12, 74, 64, 0, - 67, 3, 72, 11, 70, 1, 11, 9, 20, 13, 6, 76, 2, - 69, 67, 0, 88, 67, 7, 2, 6, 7, 7, 22, 12, 3, 0, - 4, 0, 2, 6, 89, 68, 1, 77, 2, 65, 11, 5, 65, 12, - 6, 4, 68, 11, 65, 76, 3, 83, 18, 20, 15, 14, 17, - 16, 9, 16, 18, 65, 8, 9, 5, 2, 69, 3, 66, 64, 2, - 64, 1, 5, 66, 80, 66, 73, 70, 66, 82, 16, 22, - 15, 14, 11, 9, 9, 9, 2, 69, 69, 72, 80, 79, 97, - 68, 67, 81, 7, 2, 64, 64, 70, 75, 72, 73, 80, - 73, 78, 92, 85, 93, 66, 23, 18, 11, 4, 8, 0, 68, - 69, 74, 1, 35, 21, 15, 8, 14, 4, 0, 69, 70, 4, - 39, 29, 24, 17, 18, 5, 64, 69, 73, 70, 41, 24, - 10, 3, 9, 67, 76, 79, 5, 45, 33, 23, 15, 20, 5, - 65, 69, 72, 62, 84, 80, 70, 79, 80, 75, 74, 71, - 73, 72, 70, 69, 79, 75, 82, 78, 5, 77, 81, 73, - 68, 68, 71, 72, 69, 69, 74, 78, 81, 6, 6, 14, 3, - 65, 8, 7, 5, 1, 3, 4, 2, 70, 69, 73, 65, 8, 79, - 3, 18, 1, 6, 7, 9, 16, 2, 4, 8, 14, 71, 73, 85, - 30, 32, 38, 23, 20, 28, 26, 26, 29, 23, 28, 28, - 17, 14, 0, 14, 22, 11, 1, 13, 10, 6, 8, 4, 6, 4, - 66, 66, 68, 20, 18, 17, 14, 0, 5, 2, 72, 67, 73, - 75, 86, 84, 91, 93, 73, 72, 92, 5, 6, 65, 75, - 68, 69, 77, 71, 74, 79, 87, 88, 96, 103, 4, 68, - 81, 72, 4, 3, 8, 10, 12, 21, 14, 19, 21, 34, 24, - 23, 34, 33, 51, 30, 19, 7, 64, 76, 88, 100, 117, - 7, 40, 33, 31, 24, 27, 13, 10, 10, 0, 76, 71, 3, - 69, 11, 20, 67, 66, 7, 11, 4, 10, 20, 4, 1, 42, - 24, 7, 72, 84, 103, 116, 123, 126 }, - - { - - 45, - 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 71, 23, 28, - 53, 14, 8, 65, 7, 17, 0, 69, 66, 78, 94, 5, 15, - 110, 117, 119, 14, 70, 68, 7, 17, 0, 75, 66, 13, - 3, 0, 70, 77, 65, 78, 77, 91, 5, 70, 77, 1, 75, - 75, 88, 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 67, - 92, 97, 3, 1, 67, 18, 71, 90, 80, 13, 5, 35, 29, - 3, 7, 72, 8, 71, 71, 78, 80, 80, 84, 86, 23, 0, - 8, 77, 68, 76, 73, 87, 1, 70, 69, 79, 17, 68, 1, - 74, 81, 67, 73, 65, 6, 5, 1, 12, 11, 74, 64, 0, - 67, 3, 72, 10, 70, 1, 10, 8, 19, 13, 6, 76, 2, - 69, 67, 64, 88, 68, 7, 2, 6, 7, 7, 22, 12, 3, 0, - 5, 0, 1, 6, 89, 69, 1, 78, 2, 66, 11, 5, 66, 12, - 6, 4, 70, 11, 66, 76, 3, 84, 17, 20, 14, 14, 17, - 16, 9, 16, 18, 65, 7, 9, 4, 2, 69, 2, 67, 64, 1, - 65, 0, 4, 66, 80, 66, 72, 71, 68, 82, 14, 20, - 13, 12, 9, 7, 7, 7, 0, 71, 70, 73, 82, 81, 98, - 68, 67, 82, 6, 1, 65, 66, 71, 76, 73, 74, 81, - 74, 79, 92, 85, 92, 65, 23, 18, 11, 5, 8, 0, 68, - 68, 73, 2, 34, 21, 15, 8, 15, 4, 1, 68, 68, 4, - 40, 29, 24, 17, 19, 5, 64, 68, 73, 70, 41, 24, - 10, 3, 9, 66, 75, 78, 5, 45, 33, 22, 15, 20, 5, - 64, 68, 71, 62, 84, 79, 70, 78, 79, 74, 72, 70, - 72, 71, 69, 68, 79, 74, 82, 77, 7, 77, 82, 73, - 68, 68, 71, 73, 69, 70, 75, 79, 82, 6, 6, 14, 3, - 65, 7, 6, 5, 1, 3, 3, 2, 70, 69, 74, 65, 8, 80, - 3, 17, 0, 5, 6, 9, 17, 2, 3, 8, 14, 71, 73, 86, - 29, 31, 37, 22, 19, 27, 24, 24, 27, 21, 26, 25, - 14, 11, 64, 12, 19, 8, 66, 10, 8, 4, 7, 3, 6, 5, - 66, 64, 65, 18, 16, 15, 12, 65, 3, 1, 74, 69, - 74, 76, 87, 85, 92, 94, 73, 73, 93, 4, 5, 66, - 77, 70, 71, 78, 72, 76, 80, 89, 90, 98, 104, 3, - 69, 82, 72, 4, 3, 9, 11, 12, 23, 15, 20, 22, 35, - 26, 24, 36, 34, 50, 29, 17, 5, 67, 78, 91, 102, - 119, 8, 40, 33, 32, 24, 28, 14, 10, 11, 1, 76, - 70, 3, 69, 12, 21, 67, 66, 8, 12, 4, 11, 21, 4, - 1, 41, 22, 5, 75, 88, 107, 119, 126, 126 }, - - { - - 43, - 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 73, 21, 27, - 53, 14, 10, 65, 8, 18, 0, 70, 66, 79, 95, 5, 13, - 112, 118, 119, 17, 69, 68, 8, 18, 0, 75, 65, 13, - 3, 0, 70, 76, 65, 79, 77, 91, 5, 70, 76, 1, 76, - 75, 88, 9, 65, 67, 71, 4, 4, 22, 0, 0, 0, 67, - 93, 97, 4, 0, 67, 18, 71, 90, 78, 14, 6, 37, 30, - 4, 8, 71, 9, 70, 70, 76, 79, 80, 83, 85, 23, 0, - 8, 77, 68, 76, 73, 85, 1, 70, 69, 79, 17, 68, 1, - 74, 81, 67, 73, 64, 6, 5, 1, 12, 11, 74, 64, 0, - 67, 3, 72, 9, 71, 1, 9, 7, 18, 12, 5, 75, 3, 69, - 68, 64, 87, 68, 7, 2, 6, 7, 7, 23, 12, 3, 64, 5, - 64, 0, 5, 90, 69, 1, 78, 1, 67, 11, 4, 67, 12, - 6, 4, 71, 11, 67, 76, 3, 84, 16, 20, 14, 14, 17, - 16, 9, 16, 17, 65, 7, 9, 4, 2, 70, 2, 67, 65, 1, - 65, 64, 3, 67, 80, 67, 72, 72, 69, 82, 13, 18, - 11, 10, 7, 5, 5, 5, 65, 73, 72, 75, 84, 83, 99, - 68, 67, 82, 5, 0, 66, 67, 73, 78, 74, 76, 82, - 74, 79, 92, 85, 92, 65, 23, 18, 11, 5, 8, 0, 68, - 68, 72, 2, 34, 21, 15, 8, 15, 5, 1, 67, 66, 4, - 40, 29, 24, 17, 19, 5, 64, 68, 72, 70, 41, 24, - 9, 3, 9, 66, 75, 77, 5, 44, 32, 21, 14, 20, 5, - 64, 68, 71, 62, 83, 78, 69, 77, 78, 73, 71, 69, - 71, 70, 67, 66, 78, 74, 82, 77, 8, 77, 82, 73, - 67, 68, 72, 73, 69, 71, 76, 80, 83, 5, 5, 14, 2, - 66, 7, 6, 5, 0, 2, 3, 2, 71, 70, 74, 65, 8, 80, - 2, 17, 64, 5, 5, 8, 17, 1, 2, 7, 13, 72, 74, 88, - 28, 30, 37, 21, 18, 25, 22, 22, 25, 18, 23, 23, - 11, 9, 65, 9, 16, 5, 70, 7, 5, 2, 6, 1, 6, 6, - 66, 0, 0, 16, 14, 13, 10, 67, 1, 64, 76, 70, 76, - 77, 89, 87, 93, 95, 74, 73, 94, 3, 3, 68, 79, - 72, 73, 80, 74, 78, 82, 90, 91, 99, 105, 2, 70, - 83, 72, 5, 3, 9, 11, 13, 24, 15, 21, 23, 36, 27, - 25, 37, 35, 50, 27, 15, 2, 69, 81, 94, 105, 122, - 8, 41, 34, 32, 24, 28, 14, 10, 11, 1, 76, 70, 4, - 68, 13, 22, 67, 65, 8, 12, 4, 11, 22, 4, 1, 40, - 20, 2, 78, 91, 111, 123, 126, 126 }, - - { - - 42, - 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 74, 20, 25, - 53, 14, 13, 66, 9, 18, 0, 70, 65, 80, 96, 4, 11, - 114, 119, 120, 20, 67, 68, 9, 18, 0, 75, 64, 13, - 2, 0, 70, 76, 65, 79, 76, 91, 5, 70, 75, 0, 76, - 75, 88, 9, 64, 66, 70, 4, 4, 22, 0, 0, 0, 66, - 93, 97, 4, 64, 67, 18, 70, 90, 77, 16, 8, 38, - 32, 6, 9, 70, 11, 69, 69, 74, 79, 79, 83, 84, - 23, 0, 8, 76, 68, 75, 72, 84, 0, 70, 69, 79, 17, - 68, 2, 73, 81, 67, 73, 64, 6, 4, 1, 12, 11, 73, - 64, 1, 67, 3, 72, 9, 71, 1, 9, 6, 18, 11, 4, 74, - 3, 69, 69, 65, 87, 69, 7, 1, 6, 7, 7, 24, 13, 3, - 64, 5, 64, 64, 5, 91, 69, 1, 79, 1, 68, 10, 4, - 67, 13, 6, 4, 72, 10, 68, 76, 3, 85, 16, 20, 14, - 14, 17, 16, 9, 16, 17, 65, 7, 9, 4, 2, 70, 2, - 67, 65, 1, 65, 64, 2, 67, 80, 67, 72, 73, 70, - 82, 11, 16, 10, 9, 5, 3, 3, 3, 67, 75, 74, 77, - 87, 84, 100, 68, 68, 83, 4, 64, 67, 68, 74, 79, - 75, 77, 82, 75, 80, 92, 85, 91, 65, 23, 18, 11, - 5, 8, 1, 67, 67, 71, 3, 34, 21, 15, 8, 15, 5, 2, - 67, 64, 4, 40, 29, 24, 17, 19, 5, 64, 68, 71, - 70, 42, 23, 9, 3, 9, 66, 75, 77, 5, 44, 31, 20, - 13, 20, 5, 64, 68, 70, 62, 82, 77, 68, 75, 77, - 72, 70, 67, 70, 68, 66, 64, 77, 73, 81, 76, 9, - 76, 83, 72, 66, 68, 72, 74, 70, 71, 77, 81, 84, - 4, 5, 14, 2, 66, 6, 6, 5, 64, 1, 3, 1, 72, 70, - 74, 65, 8, 80, 1, 16, 64, 5, 4, 7, 17, 0, 1, 7, - 13, 73, 75, 90, 27, 30, 36, 20, 16, 24, 20, 20, - 23, 16, 20, 20, 8, 7, 67, 6, 12, 2, 74, 5, 3, 0, - 5, 0, 6, 7, 65, 1, 2, 15, 13, 11, 9, 69, 64, 65, - 78, 71, 78, 79, 91, 88, 94, 96, 74, 73, 95, 1, - 2, 70, 80, 73, 74, 81, 75, 79, 83, 91, 92, 100, - 105, 2, 70, 84, 71, 5, 4, 10, 12, 14, 25, 16, - 22, 24, 38, 28, 26, 38, 37, 49, 25, 13, 0, 72, - 84, 97, 108, 124, 8, 41, 34, 33, 25, 29, 14, 11, - 12, 2, 75, 70, 5, 68, 14, 23, 66, 64, 9, 13, 4, - 12, 23, 4, 1, 38, 18, 0, 81, 94, 114, 126, 126, - 126 }, - - { - - 41, - 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 76, 18, 24, - 53, 14, 15, 66, 10, 19, 0, 71, 65, 81, 97, 4, 9, - 115, 120, 120, 23, 66, 68, 10, 19, 0, 74, 0, 14, - 2, 0, 69, 75, 66, 80, 76, 91, 5, 70, 75, 0, 76, - 75, 88, 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 66, - 93, 97, 5, 65, 67, 18, 70, 90, 75, 18, 9, 40, - 34, 7, 10, 68, 12, 68, 68, 72, 78, 79, 82, 83, - 23, 0, 8, 76, 68, 75, 72, 82, 0, 71, 70, 80, 17, - 68, 2, 73, 81, 66, 73, 0, 6, 4, 1, 12, 10, 73, - 64, 1, 67, 3, 72, 8, 71, 1, 8, 5, 17, 10, 3, 74, - 4, 69, 70, 65, 86, 69, 7, 1, 6, 7, 7, 25, 13, 3, - 64, 6, 64, 65, 5, 92, 69, 1, 79, 0, 69, 10, 4, - 68, 13, 6, 4, 74, 10, 69, 76, 3, 85, 15, 20, 14, - 14, 17, 16, 9, 16, 17, 65, 6, 9, 4, 2, 70, 1, - 68, 66, 0, 66, 65, 1, 68, 80, 68, 72, 74, 72, - 82, 10, 14, 8, 7, 3, 1, 1, 1, 69, 77, 75, 78, - 89, 86, 101, 68, 68, 83, 3, 65, 68, 70, 76, 81, - 76, 78, 83, 75, 80, 92, 85, 91, 64, 23, 18, 11, - 5, 8, 1, 67, 67, 70, 3, 34, 21, 15, 8, 16, 6, 3, - 66, 1, 4, 40, 29, 24, 17, 20, 5, 64, 68, 71, 70, - 42, 23, 8, 3, 9, 66, 75, 76, 5, 43, 31, 19, 12, - 20, 5, 64, 67, 70, 62, 81, 76, 68, 74, 76, 71, - 68, 66, 69, 67, 64, 0, 77, 72, 81, 76, 11, 76, - 83, 72, 66, 68, 73, 74, 70, 72, 78, 82, 85, 4, - 4, 14, 1, 67, 6, 5, 5, 65, 1, 2, 1, 73, 70, 75, - 65, 8, 81, 1, 16, 65, 5, 3, 7, 17, 64, 0, 6, 12, - 74, 75, 91, 26, 29, 36, 19, 15, 22, 18, 18, 21, - 13, 18, 18, 5, 4, 68, 3, 9, 64, 78, 2, 0, 65, 4, - 64, 6, 8, 65, 2, 4, 13, 11, 9, 7, 71, 66, 67, - 80, 73, 79, 80, 92, 90, 95, 97, 75, 74, 96, 0, - 0, 71, 82, 75, 76, 83, 77, 81, 85, 92, 94, 102, - 106, 1, 71, 85, 71, 6, 4, 10, 12, 14, 26, 17, - 23, 25, 39, 29, 27, 40, 38, 49, 24, 11, 66, 74, - 87, 100, 111, 126, 9, 42, 35, 33, 25, 30, 15, - 11, 12, 2, 75, 69, 5, 67, 15, 24, 66, 64, 9, 13, - 4, 12, 24, 4, 1, 37, 16, 66, 84, 97, 118, 126, - 126, 126 }, - - { - - 40, - 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 77, 17, 23, - 53, 14, 17, 66, 11, 20, 0, 72, 65, 82, 98, 3, 7, - 117, 121, 121, 26, 65, 68, 11, 20, 0, 74, 1, 14, - 1, 0, 69, 74, 66, 80, 76, 91, 5, 70, 74, 0, 76, - 75, 88, 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 65, - 93, 97, 5, 66, 67, 18, 70, 90, 73, 20, 11, 41, - 36, 8, 11, 67, 13, 67, 67, 70, 78, 79, 82, 82, - 23, 0, 8, 75, 68, 74, 71, 81, 0, 71, 70, 80, 17, - 68, 2, 72, 81, 66, 73, 0, 6, 4, 1, 12, 10, 73, - 64, 1, 67, 3, 72, 7, 71, 1, 7, 4, 16, 9, 2, 73, - 4, 69, 71, 66, 86, 70, 7, 1, 6, 7, 7, 26, 13, 3, - 64, 6, 64, 66, 5, 93, 69, 1, 80, 0, 70, 10, 4, - 69, 13, 6, 4, 75, 10, 70, 76, 3, 86, 14, 20, 14, - 14, 17, 16, 9, 16, 17, 65, 6, 9, 4, 2, 70, 1, - 68, 66, 0, 66, 66, 0, 68, 80, 68, 72, 75, 73, - 82, 8, 12, 6, 5, 1, 64, 64, 64, 71, 79, 77, 80, - 91, 88, 102, 68, 68, 84, 2, 66, 69, 71, 77, 82, - 77, 79, 84, 76, 81, 92, 85, 90, 64, 23, 18, 11, - 5, 8, 1, 67, 66, 69, 4, 34, 21, 15, 8, 16, 6, 4, - 65, 3, 4, 40, 29, 24, 17, 20, 5, 64, 68, 70, 70, - 42, 23, 8, 3, 9, 66, 75, 75, 5, 43, 30, 18, 11, - 20, 5, 64, 67, 69, 62, 80, 75, 67, 73, 75, 70, - 67, 65, 68, 66, 0, 2, 76, 71, 81, 75, 12, 76, - 84, 72, 65, 68, 73, 75, 70, 73, 79, 83, 86, 3, - 4, 14, 1, 67, 5, 5, 5, 66, 0, 2, 1, 74, 70, 75, - 65, 8, 81, 0, 15, 66, 5, 2, 6, 17, 65, 64, 6, - 12, 75, 76, 93, 25, 28, 35, 18, 14, 21, 16, 16, - 19, 11, 15, 15, 2, 2, 69, 0, 6, 67, 82, 64, 65, - 67, 3, 65, 6, 9, 65, 3, 6, 11, 9, 7, 5, 73, 68, - 68, 82, 74, 81, 81, 94, 91, 96, 98, 75, 74, 97, - 64, 64, 73, 84, 77, 78, 84, 78, 83, 86, 93, 95, - 103, 107, 0, 72, 86, 71, 6, 4, 11, 13, 15, 27, - 18, 24, 26, 40, 30, 28, 41, 39, 48, 22, 9, 68, - 77, 90, 103, 114, 126, 9, 42, 35, 34, 25, 31, - 15, 11, 13, 3, 75, 69, 6, 67, 16, 25, 66, 0, 10, - 14, 4, 13, 25, 4, 1, 36, 14, 68, 87, 100, 122, - 126, 126, 126 }, - - { - - 38, - 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 79, 15, 21, - 52, 14, 19, 67, 11, 20, 64, 73, 65, 84, 100, 2, - 5, 119, 122, 122, 28, 64, 69, 11, 20, 64, 74, 2, - 14, 0, 0, 69, 74, 67, 81, 76, 92, 5, 70, 74, 64, - 77, 75, 88, 10, 64, 66, 70, 5, 3, 22, 0, 0, 0, - 65, 94, 97, 5, 67, 68, 18, 70, 90, 72, 21, 12, - 42, 37, 9, 12, 66, 14, 66, 67, 69, 78, 79, 82, - 82, 23, 0, 8, 75, 68, 74, 71, 80, 64, 72, 71, - 81, 17, 68, 2, 72, 81, 66, 73, 0, 5, 3, 1, 11, - 9, 73, 65, 1, 67, 2, 72, 6, 72, 0, 6, 2, 15, 8, - 1, 73, 4, 69, 72, 67, 86, 71, 6, 0, 6, 7, 7, 26, - 13, 3, 65, 6, 65, 67, 4, 94, 70, 0, 81, 64, 71, - 9, 3, 70, 13, 6, 4, 77, 9, 71, 76, 3, 87, 13, - 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1, - 71, 0, 69, 67, 64, 67, 67, 64, 69, 80, 69, 72, - 76, 75, 82, 6, 10, 4, 3, 64, 67, 66, 66, 73, 81, - 79, 82, 94, 90, 104, 69, 69, 85, 1, 68, 71, 73, - 79, 84, 79, 81, 85, 77, 82, 92, 85, 90, 64, 23, - 18, 11, 5, 8, 1, 67, 66, 68, 4, 33, 21, 15, 8, - 16, 6, 4, 65, 4, 3, 40, 29, 23, 16, 20, 5, 64, - 68, 70, 70, 42, 22, 7, 2, 9, 66, 75, 75, 5, 42, - 29, 17, 10, 19, 5, 64, 67, 69, 62, 80, 74, 67, - 72, 74, 70, 66, 64, 67, 65, 1, 3, 76, 71, 81, - 75, 13, 76, 85, 72, 65, 68, 74, 76, 71, 74, 80, - 85, 88, 2, 3, 14, 0, 68, 4, 4, 4, 67, 64, 1, 0, - 75, 71, 76, 65, 8, 82, 64, 14, 67, 4, 1, 5, 17, - 66, 66, 5, 11, 76, 77, 95, 24, 27, 34, 16, 12, - 19, 14, 14, 16, 8, 12, 12, 64, 64, 71, 66, 2, - 70, 87, 67, 68, 69, 1, 67, 6, 9, 65, 4, 8, 9, 7, - 5, 3, 76, 70, 70, 85, 76, 83, 83, 96, 93, 97, - 99, 76, 75, 99, 66, 66, 75, 86, 79, 80, 86, 80, - 85, 88, 95, 97, 105, 108, 64, 73, 87, 71, 6, 4, - 11, 13, 15, 28, 18, 25, 26, 41, 31, 29, 42, 40, - 47, 20, 6, 71, 80, 93, 107, 117, 126, 9, 42, 35, - 34, 25, 31, 15, 11, 13, 3, 75, 69, 6, 67, 17, - 26, 66, 0, 10, 14, 4, 13, 25, 4, 0, 34, 11, 71, - 90, 104, 126, 126, 126, 126 }, - - { - - 37, - 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 80, 14, 20, - 52, 14, 22, 67, 12, 21, 64, 73, 64, 85, 101, 2, - 4, 120, 123, 122, 31, 1, 69, 12, 21, 64, 73, 4, - 15, 0, 1, 68, 73, 67, 81, 75, 92, 5, 69, 73, 64, - 77, 74, 88, 11, 0, 65, 69, 6, 3, 22, 0, 0, 0, - 64, 94, 97, 6, 67, 68, 18, 69, 89, 70, 23, 14, - 44, 39, 11, 13, 64, 16, 64, 66, 67, 77, 78, 81, - 81, 24, 1, 9, 74, 67, 73, 70, 78, 64, 72, 71, - 81, 18, 68, 3, 71, 80, 65, 72, 1, 5, 3, 2, 11, - 9, 72, 65, 2, 67, 2, 71, 6, 72, 0, 6, 1, 15, 8, - 1, 72, 5, 68, 72, 67, 85, 71, 6, 0, 7, 7, 7, 27, - 14, 4, 65, 7, 65, 67, 4, 94, 70, 0, 81, 64, 72, - 9, 3, 70, 14, 7, 4, 78, 9, 71, 75, 3, 87, 13, - 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1, - 71, 0, 69, 67, 64, 67, 67, 64, 69, 79, 69, 71, - 76, 76, 81, 5, 9, 3, 2, 66, 69, 67, 67, 75, 82, - 80, 83, 96, 91, 105, 69, 69, 85, 0, 69, 72, 74, - 80, 85, 80, 82, 85, 77, 82, 91, 84, 89, 0, 24, - 18, 11, 6, 9, 2, 66, 65, 66, 5, 33, 21, 15, 8, - 17, 7, 5, 64, 6, 3, 41, 30, 23, 16, 21, 5, 64, - 67, 69, 70, 43, 22, 7, 2, 10, 65, 74, 74, 5, 42, - 29, 17, 10, 19, 5, 0, 66, 68, 62, 79, 73, 66, - 70, 72, 69, 64, 1, 65, 0, 3, 5, 75, 70, 80, 74, - 15, 75, 85, 71, 64, 67, 74, 76, 71, 74, 80, 86, - 89, 2, 3, 15, 0, 68, 4, 4, 4, 67, 64, 1, 0, 75, - 71, 76, 64, 9, 82, 64, 14, 67, 4, 1, 5, 18, 66, - 67, 5, 11, 76, 77, 96, 24, 27, 34, 15, 11, 18, - 12, 12, 14, 6, 10, 10, 66, 66, 72, 68, 64, 73, - 91, 69, 70, 70, 0, 68, 6, 10, 64, 6, 11, 8, 6, - 4, 2, 78, 71, 71, 87, 77, 84, 84, 97, 94, 98, - 99, 76, 75, 100, 67, 67, 76, 87, 80, 81, 87, 81, - 86, 89, 96, 98, 106, 108, 64, 73, 87, 70, 7, 5, - 12, 14, 16, 30, 19, 26, 27, 43, 33, 30, 44, 42, - 47, 19, 4, 73, 82, 95, 110, 119, 126, 10, 43, - 36, 35, 26, 32, 16, 12, 14, 4, 74, 68, 7, 66, - 19, 28, 65, 1, 11, 15, 5, 14, 26, 4, 0, 33, 9, - 73, 92, 107, 126, 126, 126, 126 }, - - { - - 36, - 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 81, 13, 19, - 52, 14, 24, 67, 13, 22, 64, 74, 64, 86, 102, 1, - 2, 122, 124, 123, 34, 2, 69, 13, 22, 64, 73, 5, - 15, 64, 1, 68, 72, 67, 81, 75, 92, 5, 69, 72, - 64, 77, 74, 88, 11, 0, 65, 69, 6, 3, 22, 0, 0, - 0, 0, 94, 97, 6, 68, 68, 18, 69, 89, 68, 25, 16, - 45, 41, 12, 14, 0, 17, 0, 65, 65, 77, 78, 81, - 80, 24, 1, 9, 73, 67, 72, 70, 77, 64, 72, 71, - 81, 18, 68, 3, 71, 80, 65, 72, 1, 5, 3, 2, 11, - 9, 72, 65, 2, 67, 2, 71, 5, 72, 0, 5, 0, 14, 7, - 0, 71, 5, 68, 73, 68, 85, 72, 6, 0, 7, 7, 7, 28, - 14, 4, 65, 7, 65, 68, 4, 95, 70, 0, 82, 64, 73, - 9, 3, 71, 14, 7, 4, 79, 9, 72, 75, 3, 88, 12, - 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1, - 71, 0, 69, 67, 64, 67, 68, 65, 70, 79, 69, 71, - 77, 77, 81, 3, 7, 1, 0, 68, 71, 69, 69, 77, 84, - 82, 85, 98, 93, 106, 69, 69, 86, 64, 70, 73, 75, - 82, 86, 81, 83, 86, 78, 83, 91, 84, 88, 0, 24, - 18, 11, 6, 9, 2, 66, 65, 65, 6, 33, 21, 15, 8, - 17, 7, 6, 0, 8, 3, 41, 30, 23, 16, 21, 5, 64, - 67, 68, 70, 43, 22, 7, 2, 10, 65, 74, 73, 5, 41, - 28, 16, 9, 19, 5, 0, 66, 68, 62, 78, 72, 65, 69, - 71, 68, 0, 2, 64, 1, 4, 7, 74, 69, 80, 73, 16, - 75, 86, 71, 0, 67, 74, 77, 71, 75, 81, 87, 90, - 1, 3, 15, 0, 69, 3, 4, 4, 68, 65, 1, 0, 76, 71, - 76, 64, 9, 82, 65, 13, 68, 4, 0, 4, 18, 67, 68, - 5, 11, 77, 78, 98, 23, 26, 33, 14, 10, 17, 10, - 10, 12, 4, 7, 7, 69, 68, 73, 71, 67, 76, 95, 72, - 72, 72, 64, 69, 6, 11, 64, 7, 13, 6, 4, 2, 0, - 80, 73, 73, 89, 78, 86, 85, 99, 95, 99, 100, 77, - 75, 101, 68, 68, 78, 89, 82, 83, 88, 83, 88, 90, - 97, 99, 107, 109, 65, 74, 88, 70, 7, 5, 13, 14, - 17, 31, 20, 27, 28, 44, 34, 31, 45, 43, 46, 17, - 2, 75, 85, 98, 113, 122, 126, 10, 43, 36, 35, - 26, 33, 16, 12, 14, 4, 74, 68, 8, 66, 20, 29, - 65, 2, 12, 16, 5, 14, 27, 4, 0, 32, 7, 75, 95, - 110, 126, 126, 126, 126 }, - - { - - 35, - 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 83, 11, - 18, 52, 14, 26, 67, 14, 23, 64, 75, 64, 87, 103, - 1, 0, 123, 125, 123, 37, 3, 69, 14, 23, 64, 72, - 6, 16, 64, 1, 67, 71, 68, 82, 75, 92, 5, 69, 72, - 64, 77, 74, 88, 12, 0, 65, 69, 7, 3, 22, 0, 0, - 0, 0, 94, 97, 7, 69, 68, 18, 69, 89, 66, 27, 17, - 47, 43, 13, 15, 2, 18, 1, 64, 0, 76, 78, 80, 79, - 24, 1, 9, 73, 67, 72, 69, 75, 64, 73, 72, 82, - 18, 68, 3, 70, 80, 64, 72, 2, 5, 3, 2, 11, 8, - 72, 65, 2, 67, 2, 71, 4, 72, 0, 4, 64, 13, 6, - 64, 71, 6, 68, 74, 68, 84, 72, 6, 0, 7, 7, 7, - 29, 14, 4, 65, 8, 65, 69, 4, 96, 70, 0, 82, 65, - 74, 9, 3, 72, 14, 7, 4, 81, 9, 73, 75, 3, 88, - 11, 19, 13, 14, 17, 15, 8, 16, 16, 66, 4, 9, 3, - 1, 71, 64, 70, 68, 65, 68, 69, 66, 70, 79, 70, - 71, 78, 79, 81, 2, 5, 64, 65, 70, 73, 71, 71, - 79, 86, 83, 86, 100, 95, 107, 69, 69, 86, 65, - 71, 74, 77, 83, 88, 82, 84, 87, 78, 83, 91, 84, - 88, 1, 24, 18, 11, 6, 9, 2, 66, 64, 64, 6, 33, - 21, 15, 8, 18, 8, 7, 1, 10, 3, 41, 30, 23, 16, - 22, 5, 64, 67, 68, 70, 43, 22, 6, 2, 10, 65, 74, - 72, 5, 41, 28, 15, 8, 19, 5, 0, 65, 67, 62, 77, - 71, 65, 68, 70, 67, 2, 3, 0, 2, 6, 8, 74, 68, - 80, 73, 18, 75, 86, 71, 0, 67, 75, 77, 71, 76, - 82, 88, 91, 1, 2, 15, 64, 69, 3, 3, 4, 69, 65, - 0, 0, 77, 71, 77, 64, 9, 83, 65, 13, 69, 4, 64, - 4, 18, 68, 69, 4, 10, 78, 78, 99, 22, 25, 33, - 13, 9, 15, 8, 8, 10, 1, 5, 5, 72, 71, 74, 74, - 70, 79, 99, 75, 75, 74, 65, 70, 6, 12, 64, 8, - 15, 4, 2, 0, 65, 82, 75, 74, 91, 80, 87, 86, - 100, 97, 100, 101, 77, 76, 102, 69, 70, 79, 91, - 84, 85, 90, 84, 90, 92, 98, 101, 109, 110, 66, - 75, 89, 70, 8, 5, 13, 15, 17, 32, 21, 28, 29, - 45, 35, 32, 47, 44, 46, 16, 0, 78, 87, 101, 116, - 125, 126, 11, 44, 37, 36, 26, 34, 17, 12, 15, 5, - 74, 67, 8, 65, 21, 30, 65, 2, 12, 16, 5, 15, 28, - 4, 0, 31, 5, 78, 98, 113, 126, 126, 126, 126 }, - - { - - 33, - 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 84, 10, - 16, 52, 14, 29, 68, 15, 23, 64, 76, 64, 88, 104, - 0, 65, 125, 126, 124, 40, 4, 69, 15, 23, 64, 72, - 7, 16, 65, 1, 67, 71, 68, 82, 74, 92, 5, 69, 71, - 65, 78, 74, 88, 12, 1, 65, 68, 7, 3, 22, 0, 0, - 0, 1, 95, 97, 7, 70, 68, 18, 69, 89, 65, 28, 19, - 48, 44, 14, 16, 3, 20, 2, 0, 2, 76, 77, 80, 78, - 24, 1, 9, 72, 67, 71, 69, 74, 65, 73, 72, 82, - 18, 68, 3, 70, 80, 64, 72, 2, 5, 2, 2, 11, 8, - 72, 65, 2, 67, 2, 71, 4, 73, 0, 4, 65, 12, 5, - 65, 70, 6, 68, 75, 69, 84, 73, 6, 64, 7, 7, 7, - 30, 15, 4, 66, 8, 66, 70, 3, 97, 70, 0, 83, 65, - 75, 8, 2, 72, 15, 7, 4, 82, 8, 74, 75, 3, 89, - 11, 19, 13, 14, 17, 15, 8, 16, 15, 66, 4, 9, 3, - 1, 72, 64, 70, 68, 65, 68, 69, 67, 71, 79, 70, - 71, 79, 80, 81, 0, 3, 66, 67, 72, 75, 73, 73, - 81, 88, 85, 88, 103, 97, 108, 69, 70, 87, 66, - 72, 75, 78, 85, 89, 83, 86, 87, 79, 84, 91, 84, - 87, 1, 24, 18, 11, 6, 9, 2, 66, 64, 0, 7, 33, - 21, 15, 8, 18, 8, 7, 1, 12, 3, 41, 30, 23, 16, - 22, 5, 64, 67, 67, 70, 43, 21, 6, 2, 10, 65, 74, - 72, 5, 40, 27, 14, 7, 19, 5, 0, 65, 67, 62, 76, - 70, 64, 66, 69, 66, 3, 5, 1, 4, 7, 10, 73, 68, - 79, 72, 19, 74, 87, 71, 1, 67, 75, 78, 72, 77, - 83, 89, 92, 0, 2, 15, 64, 70, 2, 3, 4, 70, 66, - 0, 64, 78, 72, 77, 64, 9, 83, 66, 12, 70, 4, 65, - 3, 18, 69, 70, 4, 10, 79, 79, 101, 21, 25, 32, - 12, 7, 14, 6, 6, 8, 64, 2, 2, 75, 73, 76, 77, - 74, 82, 103, 77, 77, 76, 66, 72, 6, 13, 0, 9, - 17, 3, 0, 65, 66, 84, 77, 76, 93, 81, 89, 88, - 102, 98, 101, 102, 78, 76, 103, 71, 71, 81, 92, - 86, 87, 91, 86, 92, 93, 99, 102, 110, 110, 67, - 75, 90, 70, 8, 6, 14, 15, 18, 33, 21, 29, 30, - 46, 36, 33, 48, 45, 45, 14, 65, 80, 90, 104, - 119, 126, 126, 11, 44, 37, 36, 27, 34, 17, 13, - 15, 5, 73, 67, 9, 65, 22, 31, 65, 3, 13, 17, 5, - 15, 29, 4, 0, 29, 3, 80, 101, 116, 126, 126, - 126, 126 }, - - { - - 32, - 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 86, 8, 15, - 52, 14, 31, 68, 16, 24, 64, 76, 0, 89, 105, 0, - 67, 126, 126, 124, 43, 6, 69, 16, 24, 64, 72, 8, - 16, 65, 1, 67, 70, 68, 83, 74, 92, 5, 69, 70, - 65, 78, 74, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, - 0, 1, 95, 97, 8, 71, 68, 18, 68, 89, 0, 30, 20, - 50, 46, 16, 17, 4, 21, 3, 1, 4, 75, 77, 79, 77, - 24, 1, 9, 72, 67, 71, 68, 72, 65, 73, 72, 82, - 18, 68, 4, 69, 80, 64, 72, 3, 5, 2, 2, 11, 8, - 71, 65, 3, 67, 2, 71, 3, 73, 0, 3, 66, 12, 4, - 66, 69, 7, 68, 76, 69, 83, 73, 6, 64, 7, 7, 7, - 31, 15, 4, 66, 8, 66, 71, 3, 98, 70, 0, 83, 66, - 76, 8, 2, 73, 15, 7, 4, 83, 8, 75, 75, 3, 89, - 10, 19, 13, 14, 17, 15, 8, 16, 15, 66, 4, 9, 3, - 1, 72, 64, 70, 69, 65, 68, 70, 68, 71, 79, 71, - 71, 80, 81, 81, 64, 1, 67, 68, 74, 77, 75, 75, - 83, 90, 87, 90, 105, 98, 109, 69, 70, 87, 67, - 73, 76, 79, 86, 91, 84, 87, 88, 79, 84, 91, 84, - 87, 1, 24, 18, 11, 6, 9, 3, 65, 0, 1, 7, 33, 21, - 15, 8, 18, 9, 8, 2, 14, 3, 41, 30, 23, 16, 22, - 5, 64, 67, 66, 70, 44, 21, 5, 2, 10, 65, 74, 71, - 5, 40, 26, 13, 6, 19, 5, 0, 65, 66, 62, 75, 69, - 0, 65, 68, 65, 4, 6, 2, 5, 9, 12, 72, 67, 79, - 72, 20, 74, 87, 70, 2, 67, 76, 78, 72, 77, 84, - 90, 93, 64, 1, 15, 65, 70, 2, 3, 4, 71, 67, 0, - 64, 79, 72, 77, 64, 9, 83, 67, 12, 70, 4, 66, 2, - 18, 70, 71, 3, 9, 80, 80, 103, 20, 24, 32, 11, - 6, 12, 4, 4, 6, 67, 64, 0, 78, 75, 77, 80, 77, - 85, 107, 80, 80, 78, 67, 73, 6, 14, 0, 10, 19, - 1, 64, 67, 68, 86, 79, 77, 95, 82, 91, 89, 104, - 100, 102, 103, 78, 76, 104, 72, 73, 83, 94, 87, - 88, 93, 87, 93, 95, 100, 103, 111, 111, 67, 76, - 91, 69, 9, 6, 14, 16, 19, 34, 22, 30, 31, 48, - 37, 34, 49, 47, 45, 12, 67, 83, 92, 107, 122, - 126, 126, 11, 45, 38, 37, 27, 35, 17, 13, 16, 6, - 73, 67, 10, 64, 23, 32, 64, 4, 13, 17, 5, 16, - 30, 4, 0, 28, 1, 83, 104, 119, 126, 126, 126, - 126 }, - - { - - 31, - 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 87, 7, 14, - 52, 14, 33, 68, 16, 25, 64, 77, 0, 90, 106, 64, - 68, 126, 126, 125, 46, 7, 69, 16, 25, 64, 71, 9, - 17, 66, 2, 66, 69, 69, 83, 74, 92, 5, 68, 70, - 65, 78, 73, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, - 0, 2, 95, 97, 8, 71, 69, 18, 68, 88, 2, 32, 22, - 51, 48, 17, 18, 6, 22, 4, 1, 5, 75, 77, 79, 77, - 25, 1, 9, 71, 66, 70, 68, 71, 65, 74, 73, 83, - 18, 68, 4, 69, 80, 0, 72, 3, 5, 2, 3, 11, 7, 71, - 65, 3, 67, 2, 71, 2, 73, 0, 2, 67, 11, 4, 66, - 69, 7, 68, 76, 70, 83, 74, 6, 64, 7, 7, 7, 31, - 15, 4, 66, 9, 66, 72, 3, 98, 71, 0, 84, 66, 77, - 8, 2, 74, 15, 7, 4, 85, 8, 76, 75, 3, 90, 9, 19, - 12, 14, 17, 15, 8, 16, 15, 66, 3, 9, 2, 1, 72, - 65, 71, 69, 66, 69, 71, 69, 72, 79, 71, 70, 81, - 83, 81, 66, 64, 69, 70, 76, 79, 77, 77, 85, 92, - 88, 91, 107, 100, 110, 69, 70, 88, 68, 74, 77, - 81, 88, 92, 85, 88, 89, 80, 85, 91, 84, 86, 2, - 24, 18, 11, 7, 9, 3, 65, 0, 2, 8, 32, 21, 15, 8, - 19, 9, 9, 3, 16, 3, 42, 30, 23, 16, 23, 5, 64, - 66, 66, 70, 44, 21, 5, 2, 10, 64, 73, 70, 5, 39, - 26, 12, 6, 19, 5, 1, 64, 66, 62, 75, 68, 0, 64, - 67, 64, 6, 7, 3, 6, 10, 13, 72, 66, 79, 71, 22, - 74, 88, 70, 2, 67, 76, 79, 72, 78, 85, 91, 94, - 64, 1, 15, 65, 71, 1, 2, 4, 71, 67, 64, 64, 79, - 72, 78, 64, 9, 84, 67, 11, 71, 3, 67, 2, 19, 70, - 72, 3, 9, 80, 80, 104, 19, 23, 31, 10, 5, 11, 2, - 2, 4, 69, 66, 66, 81, 78, 78, 82, 80, 88, 111, - 83, 82, 80, 68, 74, 6, 15, 0, 12, 22, 64, 66, - 69, 70, 88, 81, 79, 97, 84, 92, 90, 105, 101, - 103, 104, 79, 77, 105, 73, 74, 84, 96, 89, 90, - 94, 89, 95, 96, 102, 105, 113, 112, 68, 77, 92, - 69, 9, 6, 15, 16, 19, 36, 23, 31, 32, 49, 39, - 35, 51, 48, 44, 11, 69, 85, 95, 109, 125, 126, - 126, 12, 45, 38, 37, 27, 36, 18, 13, 16, 6, 73, - 66, 10, 64, 24, 33, 64, 4, 14, 18, 5, 16, 31, 4, - 0, 27, 64, 85, 107, 123, 126, 126, 126, 126 }, - - { - - 30, - 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 89, 5, 12, - 52, 14, 36, 69, 17, 25, 64, 78, 0, 91, 107, 64, - 70, 126, 126, 125, 49, 8, 69, 17, 25, 64, 71, - 10, 17, 66, 2, 66, 69, 69, 84, 73, 92, 5, 68, - 69, 66, 78, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, - 0, 0, 2, 95, 97, 9, 72, 69, 18, 68, 88, 3, 34, - 23, 53, 50, 18, 19, 7, 24, 5, 2, 7, 74, 76, 78, - 76, 25, 1, 9, 71, 66, 70, 67, 69, 66, 74, 73, - 83, 18, 68, 4, 68, 80, 0, 72, 4, 5, 1, 3, 11, 7, - 71, 65, 3, 67, 2, 71, 2, 73, 0, 2, 68, 10, 3, - 67, 68, 8, 68, 77, 70, 82, 74, 6, 65, 7, 7, 7, - 32, 16, 4, 66, 9, 66, 73, 3, 99, 71, 0, 84, 67, - 78, 7, 2, 74, 16, 7, 4, 86, 7, 77, 75, 3, 90, 9, - 19, 12, 14, 17, 15, 8, 16, 15, 66, 3, 9, 2, 1, - 72, 65, 71, 70, 66, 69, 71, 70, 72, 79, 72, 70, - 82, 84, 81, 67, 66, 71, 72, 78, 81, 79, 79, 87, - 94, 90, 93, 110, 102, 111, 69, 71, 88, 69, 75, - 78, 82, 89, 94, 86, 89, 89, 80, 85, 91, 84, 86, - 2, 24, 18, 11, 7, 9, 3, 65, 1, 3, 8, 32, 21, 15, - 8, 19, 10, 10, 3, 18, 3, 42, 30, 23, 16, 23, 5, - 64, 66, 65, 70, 44, 20, 4, 2, 10, 64, 73, 70, 5, - 39, 25, 11, 5, 19, 5, 1, 64, 65, 62, 74, 67, 1, - 1, 66, 0, 7, 9, 4, 8, 12, 15, 71, 65, 78, 71, - 23, 73, 88, 70, 3, 67, 77, 79, 73, 79, 86, 92, - 95, 65, 0, 15, 66, 71, 1, 2, 4, 72, 68, 64, 65, - 80, 72, 78, 64, 9, 84, 68, 11, 72, 3, 68, 1, 19, - 71, 73, 2, 8, 81, 81, 106, 18, 23, 31, 9, 3, 9, - 0, 0, 2, 72, 69, 68, 84, 80, 80, 85, 84, 91, - 115, 85, 85, 82, 69, 75, 6, 16, 1, 13, 24, 65, - 68, 71, 71, 90, 83, 80, 99, 85, 94, 92, 107, - 103, 104, 105, 79, 77, 106, 75, 76, 86, 97, 91, - 92, 96, 90, 97, 98, 103, 106, 114, 112, 69, 77, - 93, 69, 10, 7, 15, 17, 20, 37, 24, 32, 33, 50, - 40, 36, 52, 49, 44, 9, 71, 88, 97, 112, 126, - 126, 126, 12, 46, 39, 38, 28, 37, 18, 14, 17, 7, - 72, 66, 11, 0, 25, 34, 64, 5, 14, 18, 5, 17, 32, - 4, 0, 25, 66, 88, 110, 126, 126, 126, 126, 126 }, - - { - - 28, - 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 90, 4, 11, - 52, 14, 38, 69, 18, 26, 64, 79, 0, 92, 109, 65, - 72, 126, 126, 126, 51, 9, 69, 18, 26, 64, 71, - 11, 17, 67, 2, 66, 68, 70, 84, 73, 93, 5, 68, - 69, 66, 79, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, - 0, 0, 3, 96, 97, 9, 73, 69, 18, 68, 88, 5, 35, - 25, 54, 51, 19, 20, 8, 25, 6, 3, 9, 74, 76, 78, - 75, 25, 1, 9, 70, 66, 69, 67, 68, 66, 75, 74, - 84, 18, 68, 4, 68, 80, 0, 72, 4, 4, 1, 3, 11, 6, - 71, 65, 3, 67, 1, 71, 1, 74, 0, 1, 70, 9, 2, 68, - 68, 8, 68, 78, 71, 82, 75, 5, 65, 7, 7, 7, 33, - 16, 4, 67, 9, 67, 74, 2, 100, 71, 0, 85, 67, 79, - 7, 1, 75, 16, 7, 4, 88, 7, 78, 75, 3, 91, 8, 18, - 12, 14, 17, 14, 7, 16, 14, 67, 2, 9, 2, 0, 73, - 66, 72, 70, 67, 70, 72, 71, 73, 79, 72, 70, 83, - 86, 81, 69, 68, 73, 74, 80, 84, 81, 81, 89, 96, - 92, 95, 112, 104, 112, 69, 71, 89, 70, 77, 80, - 84, 91, 95, 88, 91, 90, 81, 86, 91, 84, 85, 2, - 24, 18, 11, 7, 9, 3, 65, 1, 4, 9, 32, 21, 15, 8, - 19, 10, 10, 4, 19, 3, 42, 30, 23, 15, 23, 5, 64, - 66, 65, 70, 44, 20, 4, 2, 10, 64, 73, 69, 5, 38, - 24, 10, 4, 18, 5, 1, 64, 65, 62, 73, 66, 1, 2, - 65, 0, 8, 10, 5, 9, 13, 16, 71, 65, 78, 70, 24, - 73, 89, 70, 3, 67, 77, 80, 73, 80, 87, 94, 96, - 66, 0, 15, 66, 72, 0, 1, 3, 73, 69, 65, 65, 81, - 73, 79, 64, 9, 85, 69, 10, 73, 3, 69, 0, 19, 72, - 74, 2, 8, 82, 82, 108, 17, 22, 30, 7, 2, 8, 65, - 65, 64, 74, 72, 71, 87, 83, 81, 88, 87, 94, 119, - 88, 87, 84, 71, 77, 6, 16, 1, 14, 26, 67, 70, - 73, 73, 93, 85, 82, 101, 87, 96, 93, 109, 104, - 105, 106, 80, 78, 107, 76, 77, 88, 99, 93, 94, - 97, 92, 99, 99, 104, 108, 116, 113, 70, 78, 94, - 69, 10, 7, 16, 17, 20, 38, 24, 33, 34, 51, 41, - 37, 53, 50, 43, 7, 73, 90, 100, 115, 126, 126, - 126, 12, 46, 39, 38, 28, 37, 18, 14, 17, 7, 72, - 66, 11, 0, 26, 35, 64, 5, 15, 19, 5, 17, 32, 4, - 64, 24, 68, 90, 113, 126, 126, 126, 126, 126 }, - - { - - 27, - 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 91, 3, 10, - 52, 14, 40, 69, 19, 27, 64, 79, 1, 93, 110, 66, - 74, 126, 126, 126, 54, 11, 69, 19, 27, 64, 70, - 12, 18, 68, 2, 65, 67, 70, 84, 73, 93, 5, 68, - 68, 66, 79, 73, 88, 14, 2, 0, 67, 9, 3, 22, 0, - 0, 0, 4, 96, 97, 9, 74, 69, 18, 67, 88, 7, 37, - 27, 55, 53, 21, 21, 10, 26, 8, 4, 11, 74, 76, - 78, 74, 25, 1, 9, 69, 66, 68, 66, 67, 66, 75, - 74, 84, 18, 68, 5, 67, 79, 1, 72, 4, 4, 1, 3, - 11, 6, 70, 65, 4, 67, 1, 70, 0, 74, 0, 0, 71, 9, - 1, 69, 67, 8, 67, 79, 72, 82, 76, 5, 65, 8, 7, - 7, 34, 16, 4, 67, 10, 67, 74, 2, 101, 71, 0, 86, - 67, 80, 7, 1, 76, 16, 7, 4, 89, 7, 78, 75, 3, - 92, 7, 18, 12, 14, 17, 14, 7, 16, 14, 67, 2, 9, - 2, 0, 73, 66, 72, 70, 67, 70, 73, 71, 73, 79, - 72, 70, 84, 87, 81, 71, 69, 74, 75, 82, 86, 82, - 82, 91, 98, 93, 96, 114, 105, 113, 69, 71, 90, - 71, 78, 81, 85, 92, 96, 89, 92, 91, 82, 87, 91, - 83, 84, 3, 25, 18, 11, 7, 10, 4, 64, 2, 5, 10, - 32, 21, 15, 8, 20, 10, 11, 5, 21, 3, 42, 30, 23, - 15, 24, 5, 64, 66, 64, 70, 45, 20, 4, 2, 11, 64, - 73, 68, 5, 38, 24, 10, 3, 18, 5, 1, 0, 64, 62, - 72, 65, 2, 3, 0, 1, 10, 11, 7, 10, 14, 18, 70, - 64, 78, 69, 26, 73, 90, 69, 4, 67, 77, 81, 73, - 80, 88, 95, 97, 66, 0, 15, 66, 72, 64, 1, 3, 74, - 69, 65, 65, 82, 73, 79, 0, 10, 85, 69, 9, 73, 3, - 69, 0, 19, 73, 75, 2, 8, 83, 82, 109, 17, 21, - 29, 6, 1, 7, 67, 67, 66, 76, 74, 74, 89, 85, 82, - 91, 90, 97, 123, 91, 89, 85, 72, 78, 6, 17, 1, - 15, 28, 69, 71, 75, 75, 95, 86, 83, 103, 88, 97, - 94, 110, 105, 106, 106, 80, 78, 108, 77, 78, 89, - 101, 94, 95, 98, 93, 100, 100, 105, 109, 117, - 114, 70, 79, 94, 68, 10, 7, 17, 18, 21, 39, 25, - 34, 35, 53, 42, 38, 55, 52, 42, 6, 75, 92, 103, - 118, 126, 126, 126, 13, 46, 39, 39, 28, 38, 19, - 14, 18, 8, 72, 65, 12, 0, 27, 37, 0, 6, 16, 20, - 5, 18, 33, 4, 64, 23, 70, 92, 115, 126, 126, - 126, 126, 126 }, - - { - - 26, - 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 93, 1, 8, - 52, 14, 43, 70, 20, 27, 64, 80, 1, 94, 111, 66, - 76, 126, 126, 126, 57, 12, 69, 20, 27, 64, 70, - 13, 18, 68, 2, 65, 67, 70, 85, 72, 93, 5, 68, - 67, 67, 79, 73, 88, 15, 3, 0, 66, 10, 3, 22, 0, - 0, 0, 4, 96, 97, 10, 75, 69, 18, 67, 88, 8, 39, - 28, 57, 55, 22, 22, 11, 28, 9, 5, 13, 73, 75, - 77, 73, 25, 1, 9, 69, 66, 68, 66, 65, 67, 75, - 74, 84, 18, 68, 5, 67, 79, 1, 72, 5, 4, 0, 3, - 11, 6, 70, 65, 4, 67, 1, 70, 0, 74, 0, 0, 72, 8, - 0, 70, 66, 9, 67, 80, 72, 81, 76, 5, 66, 8, 7, - 7, 35, 17, 4, 67, 10, 67, 75, 2, 102, 71, 0, 86, - 68, 81, 6, 1, 76, 17, 7, 4, 90, 6, 79, 75, 3, - 92, 7, 18, 12, 14, 17, 14, 7, 16, 14, 67, 2, 9, - 2, 0, 73, 66, 72, 71, 67, 70, 73, 72, 74, 79, - 73, 70, 85, 88, 81, 72, 71, 76, 77, 84, 88, 84, - 84, 93, 100, 95, 98, 117, 107, 114, 69, 72, 90, - 72, 79, 82, 86, 94, 98, 90, 93, 91, 82, 87, 91, - 83, 84, 3, 25, 18, 11, 7, 10, 4, 64, 2, 6, 10, - 32, 21, 15, 8, 20, 11, 12, 5, 23, 3, 42, 30, 23, - 15, 24, 5, 64, 66, 0, 70, 45, 19, 3, 2, 11, 64, - 73, 68, 5, 37, 23, 9, 2, 18, 5, 1, 0, 64, 62, - 71, 64, 3, 5, 1, 2, 11, 13, 8, 12, 16, 20, 69, - 0, 77, 69, 27, 72, 90, 69, 5, 67, 78, 81, 74, - 81, 89, 96, 98, 67, 64, 15, 67, 73, 64, 1, 3, - 75, 70, 65, 66, 83, 73, 79, 0, 10, 85, 70, 9, - 74, 3, 70, 64, 19, 74, 76, 1, 7, 84, 83, 111, - 16, 21, 29, 5, 64, 5, 69, 69, 68, 79, 77, 76, - 92, 87, 84, 94, 94, 100, 126, 93, 92, 87, 73, - 79, 6, 18, 2, 16, 30, 70, 73, 77, 76, 97, 88, - 85, 105, 89, 99, 96, 112, 107, 107, 107, 81, 78, - 109, 79, 80, 91, 102, 96, 97, 100, 95, 102, 102, - 106, 110, 118, 114, 71, 79, 95, 68, 11, 8, 17, - 18, 22, 40, 26, 35, 36, 54, 43, 39, 56, 53, 42, - 4, 77, 95, 105, 121, 126, 126, 126, 13, 47, 40, - 39, 29, 39, 19, 15, 18, 8, 71, 65, 13, 1, 28, - 38, 0, 7, 16, 20, 5, 18, 34, 4, 64, 21, 72, 95, - 118, 126, 126, 126, 126, 126 }, - - { - - 25, - 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 94, 0, 7, - 52, 14, 45, 70, 20, 28, 64, 81, 1, 95, 112, 67, - 77, 126, 126, 126, 60, 13, 69, 20, 28, 64, 69, - 14, 19, 69, 3, 64, 66, 71, 85, 72, 93, 5, 67, - 67, 67, 79, 72, 88, 15, 3, 0, 66, 10, 3, 22, 0, - 0, 0, 5, 96, 97, 10, 75, 70, 18, 67, 87, 10, 41, - 30, 58, 57, 23, 23, 13, 29, 10, 5, 14, 73, 75, - 77, 73, 26, 1, 9, 68, 65, 67, 65, 64, 67, 76, - 75, 85, 18, 68, 5, 66, 79, 2, 72, 5, 4, 0, 4, - 11, 5, 70, 65, 4, 67, 1, 70, 64, 74, 0, 64, 73, - 7, 0, 70, 66, 9, 67, 80, 73, 81, 77, 5, 66, 8, - 7, 7, 35, 17, 4, 67, 11, 67, 76, 2, 102, 72, 0, - 87, 68, 82, 6, 1, 77, 17, 7, 4, 92, 6, 80, 75, - 3, 93, 6, 18, 11, 14, 17, 14, 7, 16, 14, 67, 1, - 9, 1, 0, 73, 67, 73, 71, 68, 71, 74, 73, 74, 79, - 73, 69, 86, 90, 81, 74, 73, 78, 79, 86, 90, 86, - 86, 95, 102, 96, 99, 119, 109, 115, 69, 72, 91, - 73, 80, 83, 88, 95, 99, 91, 94, 92, 83, 88, 91, - 83, 83, 4, 25, 18, 11, 8, 10, 4, 64, 3, 7, 11, - 31, 21, 15, 8, 21, 11, 13, 6, 25, 3, 43, 30, 23, - 15, 25, 5, 64, 65, 0, 70, 45, 19, 3, 2, 11, 0, - 72, 67, 5, 37, 23, 8, 2, 18, 5, 2, 1, 0, 62, 71, - 0, 3, 6, 2, 3, 13, 14, 9, 13, 17, 21, 69, 1, 77, - 68, 29, 72, 91, 69, 5, 67, 78, 82, 74, 82, 90, - 97, 99, 67, 64, 15, 67, 73, 65, 0, 3, 75, 70, - 66, 66, 83, 73, 80, 0, 10, 86, 70, 8, 75, 2, 71, - 64, 20, 74, 77, 1, 7, 84, 83, 112, 15, 20, 28, - 4, 65, 4, 71, 71, 70, 81, 79, 79, 95, 90, 85, - 96, 97, 103, 126, 96, 94, 89, 74, 80, 6, 19, 2, - 18, 33, 72, 75, 79, 78, 99, 90, 86, 107, 91, - 100, 97, 113, 108, 108, 108, 81, 79, 110, 80, - 81, 92, 104, 98, 99, 101, 96, 104, 103, 108, - 112, 120, 115, 72, 80, 96, 68, 11, 8, 18, 19, - 22, 42, 27, 36, 37, 55, 45, 40, 58, 54, 41, 3, - 79, 97, 108, 123, 126, 126, 126, 14, 47, 40, 40, - 29, 40, 20, 15, 19, 9, 71, 64, 13, 1, 29, 39, 0, - 7, 17, 21, 5, 19, 35, 4, 64, 20, 74, 97, 121, - 126, 126, 126, 126, 126 }, - - { - - 23, - 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 96, 65, 6, - 52, 14, 47, 70, 21, 29, 64, 82, 1, 96, 113, 67, - 79, 126, 126, 126, 62, 14, 69, 21, 29, 64, 69, - 15, 19, 69, 3, 64, 65, 71, 86, 72, 93, 5, 67, - 66, 67, 80, 72, 88, 16, 3, 0, 66, 11, 3, 22, 0, - 0, 0, 5, 97, 97, 11, 76, 70, 18, 67, 87, 12, 42, - 31, 60, 58, 24, 24, 14, 30, 11, 6, 16, 72, 75, - 76, 72, 26, 1, 9, 68, 65, 67, 65, 1, 67, 76, 75, - 85, 18, 68, 5, 66, 79, 2, 72, 6, 4, 0, 4, 11, 5, - 70, 65, 4, 67, 1, 70, 65, 75, 0, 65, 74, 6, 64, - 71, 65, 10, 67, 81, 73, 80, 77, 5, 66, 8, 7, 7, - 36, 17, 4, 68, 11, 68, 77, 1, 103, 72, 0, 87, - 69, 83, 6, 0, 78, 17, 7, 4, 93, 6, 81, 75, 3, - 93, 5, 18, 11, 14, 17, 14, 7, 16, 13, 67, 1, 9, - 1, 0, 74, 67, 73, 72, 68, 71, 75, 74, 75, 79, - 74, 69, 87, 91, 81, 75, 75, 80, 81, 88, 92, 88, - 88, 97, 104, 98, 101, 121, 111, 116, 69, 72, 91, - 74, 81, 84, 89, 97, 101, 92, 96, 93, 83, 88, 91, - 83, 83, 4, 25, 18, 11, 8, 10, 4, 64, 3, 8, 11, - 31, 21, 15, 8, 21, 12, 13, 7, 27, 3, 43, 30, 23, - 15, 25, 5, 64, 65, 1, 70, 45, 19, 2, 2, 11, 0, - 72, 66, 5, 36, 22, 7, 1, 18, 5, 2, 1, 0, 62, 70, - 1, 4, 7, 3, 4, 14, 15, 10, 14, 19, 23, 68, 1, - 77, 68, 30, 72, 91, 69, 6, 67, 79, 82, 74, 83, - 91, 98, 100, 68, 65, 15, 68, 74, 65, 0, 3, 76, - 71, 66, 66, 84, 74, 80, 0, 10, 86, 71, 8, 76, 2, - 72, 65, 20, 75, 78, 0, 6, 85, 84, 114, 14, 19, - 28, 3, 66, 2, 73, 73, 72, 84, 82, 81, 98, 92, - 86, 99, 100, 106, 126, 99, 97, 91, 75, 82, 6, - 20, 2, 19, 35, 74, 77, 81, 80, 101, 92, 88, 109, - 92, 102, 98, 115, 110, 109, 109, 82, 79, 111, - 81, 83, 94, 106, 100, 101, 103, 98, 106, 105, - 109, 113, 121, 116, 73, 81, 97, 68, 12, 8, 18, - 19, 23, 43, 27, 37, 38, 56, 46, 41, 59, 55, 41, - 1, 81, 100, 110, 126, 126, 126, 126, 14, 48, 41, - 40, 29, 40, 20, 15, 19, 9, 71, 64, 14, 2, 30, - 40, 0, 8, 17, 21, 5, 19, 36, 4, 64, 19, 76, 100, - 124, 126, 126, 126, 126, 126 }, - - { - - 22, - 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 66, 4, - 52, 14, 50, 71, 22, 29, 64, 82, 2, 97, 114, 68, - 81, 126, 126, 126, 62, 16, 69, 22, 29, 64, 69, - 16, 19, 70, 3, 64, 65, 71, 86, 71, 93, 5, 67, - 65, 68, 80, 72, 88, 16, 4, 1, 65, 11, 3, 22, 0, - 0, 0, 6, 97, 97, 11, 77, 70, 18, 66, 87, 13, 44, - 33, 61, 60, 26, 25, 15, 32, 12, 7, 18, 72, 74, - 76, 71, 26, 1, 9, 67, 65, 66, 64, 2, 68, 76, 75, - 85, 18, 68, 6, 65, 79, 2, 72, 6, 4, 64, 4, 11, - 5, 69, 65, 5, 67, 1, 70, 65, 75, 0, 65, 75, 6, - 65, 72, 64, 10, 67, 82, 74, 80, 78, 5, 67, 8, 7, - 7, 37, 18, 4, 68, 11, 68, 78, 1, 104, 72, 0, 88, - 69, 84, 5, 0, 78, 18, 7, 4, 94, 5, 82, 75, 3, - 94, 5, 18, 11, 14, 17, 14, 7, 16, 13, 67, 1, 9, - 1, 0, 74, 67, 73, 72, 68, 71, 75, 75, 75, 79, - 74, 69, 88, 92, 81, 77, 77, 81, 82, 90, 94, 90, - 90, 99, 106, 100, 103, 124, 112, 117, 69, 73, - 92, 75, 82, 85, 90, 98, 102, 93, 97, 93, 84, 89, - 91, 83, 82, 4, 25, 18, 11, 8, 10, 5, 0, 4, 9, - 12, 31, 21, 15, 8, 21, 12, 14, 7, 29, 3, 43, 30, - 23, 15, 25, 5, 64, 65, 2, 70, 46, 18, 2, 2, 11, - 0, 72, 66, 5, 36, 21, 6, 0, 18, 5, 2, 1, 1, 62, - 69, 2, 5, 9, 4, 5, 15, 17, 11, 16, 20, 25, 67, - 2, 76, 67, 31, 71, 92, 68, 7, 67, 79, 83, 75, - 83, 92, 99, 101, 69, 65, 15, 68, 74, 66, 0, 3, - 77, 72, 66, 67, 85, 74, 80, 0, 10, 86, 72, 7, - 76, 2, 73, 66, 20, 76, 79, 0, 6, 86, 85, 116, - 13, 19, 27, 2, 68, 1, 75, 75, 74, 86, 85, 84, - 101, 94, 88, 102, 104, 109, 126, 101, 99, 93, - 76, 83, 6, 21, 3, 20, 37, 75, 78, 83, 81, 103, - 94, 89, 111, 93, 104, 100, 117, 111, 110, 110, - 82, 79, 112, 83, 84, 96, 107, 101, 102, 104, 99, - 107, 106, 110, 114, 122, 116, 73, 81, 98, 67, - 12, 9, 19, 20, 24, 44, 28, 38, 39, 58, 47, 42, - 60, 57, 40, 64, 83, 102, 113, 126, 126, 126, - 126, 14, 48, 41, 41, 30, 41, 20, 16, 20, 10, 70, - 64, 15, 2, 31, 41, 1, 9, 18, 22, 5, 20, 37, 4, - 64, 17, 78, 102, 126, 126, 126, 126, 126, 126 }, - - { - - 21, - 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 68, 3, - 52, 14, 52, 71, 23, 30, 64, 83, 2, 98, 115, 68, - 83, 126, 126, 126, 62, 17, 69, 23, 30, 64, 68, - 17, 20, 70, 3, 0, 64, 72, 87, 71, 93, 5, 67, 65, - 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, 0, - 0, 6, 97, 97, 12, 78, 70, 18, 66, 87, 15, 46, - 34, 62, 62, 27, 26, 17, 33, 13, 8, 20, 71, 74, - 75, 70, 26, 1, 9, 67, 65, 66, 64, 4, 68, 77, 76, - 86, 18, 68, 6, 65, 79, 3, 72, 7, 4, 64, 4, 11, - 4, 69, 65, 5, 67, 1, 70, 66, 75, 0, 66, 76, 5, - 66, 73, 64, 11, 67, 83, 74, 79, 78, 5, 67, 8, 7, - 7, 38, 18, 4, 68, 12, 68, 79, 1, 105, 72, 0, 88, - 70, 85, 5, 0, 79, 18, 7, 4, 96, 5, 83, 75, 3, - 94, 4, 18, 11, 14, 17, 14, 7, 16, 13, 67, 0, 9, - 1, 0, 74, 68, 74, 73, 69, 72, 76, 76, 76, 79, - 75, 69, 89, 94, 81, 78, 79, 83, 84, 92, 96, 92, - 92, 101, 108, 101, 104, 126, 114, 118, 69, 73, - 92, 76, 83, 86, 92, 100, 104, 94, 98, 94, 84, - 89, 91, 83, 82, 5, 25, 18, 11, 8, 10, 5, 0, 4, - 10, 12, 31, 21, 15, 8, 22, 13, 15, 8, 31, 3, 43, - 30, 23, 15, 26, 5, 64, 65, 2, 70, 46, 18, 1, 2, - 11, 0, 72, 65, 5, 35, 21, 5, 64, 18, 5, 2, 2, 1, - 62, 68, 3, 5, 10, 5, 6, 17, 18, 12, 17, 22, 26, - 67, 3, 76, 67, 33, 71, 92, 68, 7, 67, 80, 83, - 75, 84, 93, 100, 102, 69, 66, 15, 69, 75, 66, - 64, 3, 78, 72, 67, 67, 86, 74, 81, 0, 10, 87, - 72, 7, 77, 2, 74, 66, 20, 77, 80, 64, 5, 87, 85, - 117, 12, 18, 27, 1, 69, 64, 77, 77, 76, 89, 87, - 86, 104, 97, 89, 105, 107, 112, 126, 104, 102, - 95, 77, 84, 6, 22, 3, 21, 39, 77, 80, 85, 83, - 105, 96, 91, 113, 95, 105, 101, 118, 113, 111, - 111, 83, 80, 113, 84, 86, 97, 109, 103, 104, - 106, 101, 109, 108, 111, 116, 124, 117, 74, 82, - 99, 67, 13, 9, 19, 20, 24, 45, 29, 39, 40, 59, - 48, 43, 62, 58, 40, 65, 85, 105, 115, 126, 126, - 126, 126, 15, 49, 42, 41, 30, 42, 21, 16, 20, - 10, 70, 0, 15, 3, 32, 42, 1, 9, 18, 22, 5, 20, - 38, 4, 64, 16, 80, 105, 126, 126, 126, 126, 126, - 126 }, - - { - - 20, - 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 100, 69, - 2, 52, 14, 54, 71, 24, 31, 64, 84, 2, 99, 116, - 69, 85, 126, 126, 126, 62, 18, 69, 24, 31, 64, - 68, 18, 20, 71, 3, 0, 0, 72, 87, 71, 93, 5, 67, - 64, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, - 0, 0, 7, 97, 97, 12, 79, 70, 18, 66, 87, 17, 48, - 36, 62, 62, 28, 27, 18, 34, 14, 9, 22, 71, 74, - 75, 69, 26, 1, 9, 66, 65, 65, 0, 5, 68, 77, 76, - 86, 18, 68, 6, 64, 79, 3, 72, 7, 4, 64, 4, 11, - 4, 69, 65, 5, 67, 1, 70, 67, 75, 0, 67, 77, 4, - 67, 74, 0, 11, 67, 84, 75, 79, 79, 5, 67, 8, 7, - 7, 39, 18, 4, 68, 12, 68, 80, 1, 106, 72, 0, 89, - 70, 86, 5, 0, 80, 18, 7, 4, 97, 5, 84, 75, 3, - 95, 3, 18, 11, 14, 17, 14, 7, 16, 13, 67, 0, 9, - 1, 0, 74, 68, 74, 73, 69, 72, 77, 77, 76, 79, - 75, 69, 90, 95, 81, 80, 81, 85, 86, 94, 98, 94, - 94, 103, 110, 103, 106, 126, 116, 119, 69, 73, - 93, 77, 84, 87, 93, 101, 105, 95, 99, 95, 85, - 90, 91, 83, 81, 5, 25, 18, 11, 8, 10, 5, 0, 5, - 11, 13, 31, 21, 15, 8, 22, 13, 16, 9, 33, 3, 43, - 30, 23, 15, 26, 5, 64, 65, 3, 70, 46, 18, 1, 2, - 11, 0, 72, 64, 5, 35, 20, 4, 65, 18, 5, 2, 2, 2, - 62, 67, 4, 6, 11, 6, 7, 18, 19, 13, 18, 23, 28, - 66, 4, 76, 66, 34, 71, 93, 68, 8, 67, 80, 84, - 75, 85, 94, 101, 103, 70, 66, 15, 69, 75, 67, - 64, 3, 79, 73, 67, 67, 87, 74, 81, 0, 10, 87, - 73, 6, 78, 2, 75, 67, 20, 78, 81, 64, 5, 88, 86, - 119, 11, 17, 26, 0, 70, 65, 79, 79, 78, 91, 90, - 89, 107, 99, 90, 108, 110, 115, 126, 107, 104, - 97, 78, 85, 6, 23, 3, 22, 41, 79, 82, 87, 85, - 107, 98, 92, 115, 96, 107, 102, 120, 114, 112, - 112, 83, 80, 114, 85, 87, 99, 111, 105, 106, - 107, 102, 111, 109, 112, 117, 125, 118, 75, 83, - 100, 67, 13, 9, 20, 21, 25, 46, 30, 40, 41, 60, - 49, 44, 62, 59, 39, 67, 87, 107, 118, 126, 126, - 126, 126, 15, 49, 42, 42, 30, 43, 21, 16, 21, - 11, 70, 0, 16, 3, 33, 43, 1, 10, 19, 23, 5, 21, - 39, 4, 64, 15, 82, 107, 126, 126, 126, 126, 126, - 126 }, - - { - - 18, - 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 102, 71, - 0, 51, 14, 56, 72, 24, 31, 65, 85, 2, 101, 118, - 70, 87, 126, 126, 126, 62, 19, 70, 24, 31, 65, - 68, 19, 20, 72, 3, 0, 0, 73, 88, 71, 94, 5, 67, - 64, 69, 81, 72, 88, 17, 4, 1, 65, 12, 2, 22, 0, - 0, 0, 7, 98, 97, 12, 80, 71, 18, 66, 87, 18, 49, - 37, 62, 62, 29, 28, 19, 35, 15, 9, 23, 71, 74, - 75, 69, 26, 1, 9, 66, 65, 65, 0, 6, 69, 78, 77, - 87, 18, 68, 6, 64, 79, 3, 72, 7, 3, 65, 4, 10, - 3, 69, 66, 5, 67, 0, 70, 68, 76, 64, 68, 79, 3, - 68, 75, 0, 11, 67, 85, 76, 79, 80, 4, 68, 8, 7, - 7, 39, 18, 4, 69, 12, 69, 81, 0, 107, 73, 64, - 90, 71, 87, 4, 64, 81, 18, 7, 4, 99, 4, 85, 75, - 3, 96, 2, 17, 10, 14, 17, 13, 6, 16, 12, 68, 64, - 9, 0, 64, 75, 69, 75, 74, 70, 73, 78, 78, 77, - 79, 76, 69, 91, 97, 81, 82, 83, 87, 88, 96, 101, - 96, 96, 105, 112, 105, 108, 126, 118, 121, 70, - 74, 94, 78, 86, 89, 95, 103, 107, 97, 101, 96, - 86, 91, 91, 83, 81, 5, 25, 18, 11, 8, 10, 5, 0, - 5, 12, 13, 30, 21, 15, 8, 22, 13, 16, 9, 34, 2, - 43, 30, 22, 14, 26, 5, 64, 65, 3, 70, 46, 17, 0, - 1, 11, 0, 72, 64, 5, 34, 19, 3, 66, 17, 5, 2, 2, - 2, 62, 67, 5, 6, 12, 7, 7, 19, 20, 14, 19, 24, - 29, 66, 4, 76, 66, 35, 71, 94, 68, 8, 67, 81, - 85, 76, 86, 95, 103, 105, 71, 67, 15, 70, 76, - 68, 65, 2, 80, 74, 68, 68, 88, 75, 82, 0, 10, - 88, 74, 5, 79, 1, 76, 68, 20, 79, 83, 65, 4, 89, - 87, 121, 10, 16, 25, 65, 72, 67, 81, 81, 81, 94, - 93, 92, 110, 102, 92, 111, 114, 118, 126, 110, - 107, 99, 80, 87, 6, 23, 3, 23, 43, 81, 84, 89, - 87, 110, 100, 94, 118, 98, 109, 104, 122, 116, - 113, 113, 84, 81, 116, 87, 89, 101, 113, 107, - 108, 109, 104, 113, 111, 114, 119, 126, 119, 76, - 84, 101, 67, 13, 9, 20, 21, 25, 47, 30, 41, 41, - 61, 50, 45, 62, 60, 38, 69, 90, 110, 121, 126, - 126, 126, 126, 15, 49, 42, 42, 30, 43, 21, 16, - 21, 11, 70, 0, 16, 3, 34, 44, 1, 10, 19, 23, 5, - 21, 39, 4, 65, 13, 85, 110, 126, 126, 126, 126, - 126, 126 }, - - { - - 17, - 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 103, 72, - 64, 51, 14, 59, 72, 25, 32, 65, 85, 3, 102, 119, - 70, 88, 126, 126, 126, 62, 21, 70, 25, 32, 65, - 67, 21, 21, 72, 4, 1, 1, 73, 88, 70, 94, 5, 66, - 0, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, - 0, 0, 8, 98, 97, 13, 80, 71, 18, 65, 86, 20, 51, - 39, 62, 62, 31, 29, 21, 37, 17, 10, 25, 70, 73, - 74, 68, 27, 2, 10, 65, 64, 64, 1, 8, 69, 78, 77, - 87, 19, 68, 7, 0, 78, 4, 71, 8, 3, 65, 5, 10, 3, - 68, 66, 6, 67, 0, 69, 68, 76, 64, 68, 80, 3, 68, - 75, 1, 12, 66, 85, 76, 78, 80, 4, 68, 9, 7, 7, - 40, 19, 5, 69, 13, 69, 81, 0, 107, 73, 64, 90, - 71, 88, 4, 64, 81, 19, 8, 4, 100, 4, 85, 74, 3, - 96, 2, 17, 10, 14, 17, 13, 6, 16, 12, 68, 64, 9, - 0, 64, 75, 69, 75, 74, 70, 73, 78, 78, 77, 78, - 76, 68, 91, 98, 80, 83, 84, 88, 89, 98, 103, 97, - 97, 107, 113, 106, 109, 126, 119, 122, 70, 74, - 94, 79, 87, 90, 96, 104, 108, 98, 102, 96, 86, - 91, 90, 82, 80, 6, 26, 18, 11, 9, 11, 6, 1, 6, - 14, 14, 30, 21, 15, 8, 23, 14, 17, 10, 36, 2, - 44, 31, 22, 14, 27, 5, 64, 64, 4, 70, 47, 17, 0, - 1, 12, 1, 71, 0, 5, 34, 19, 3, 66, 17, 5, 3, 3, - 3, 62, 66, 6, 7, 14, 9, 8, 21, 22, 16, 21, 26, - 31, 65, 5, 75, 65, 37, 70, 94, 67, 9, 66, 81, - 85, 76, 86, 95, 104, 106, 71, 67, 16, 70, 76, - 68, 65, 2, 80, 74, 68, 68, 88, 75, 82, 1, 11, - 88, 74, 5, 79, 1, 76, 68, 21, 79, 84, 65, 4, 89, - 87, 122, 10, 16, 25, 66, 73, 68, 83, 83, 83, 96, - 95, 94, 112, 104, 93, 113, 117, 121, 126, 112, - 109, 100, 81, 88, 6, 24, 4, 25, 46, 82, 85, 90, - 88, 112, 101, 95, 120, 99, 110, 105, 123, 117, - 114, 113, 84, 81, 117, 88, 90, 102, 114, 108, - 109, 110, 105, 114, 112, 115, 120, 126, 119, 76, - 84, 101, 66, 14, 10, 21, 22, 26, 49, 31, 42, 42, - 62, 52, 46, 62, 62, 38, 70, 92, 112, 123, 126, - 126, 126, 126, 16, 50, 43, 43, 31, 44, 22, 17, - 22, 12, 69, 1, 17, 4, 36, 46, 2, 11, 20, 24, 6, - 22, 40, 4, 65, 12, 87, 112, 126, 126, 126, 126, - 126, 126 }, - - { - - 16, - 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 104, 73, - 65, 51, 14, 61, 72, 26, 33, 65, 86, 3, 103, 120, - 71, 90, 126, 126, 126, 62, 22, 70, 26, 33, 65, - 67, 22, 21, 73, 4, 1, 2, 73, 88, 70, 94, 5, 66, - 1, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, - 0, 0, 9, 98, 97, 13, 81, 71, 18, 65, 86, 22, 53, - 41, 62, 62, 32, 30, 22, 38, 18, 11, 27, 70, 73, - 74, 67, 27, 2, 10, 64, 64, 0, 1, 9, 69, 78, 77, - 87, 19, 68, 7, 0, 78, 4, 71, 8, 3, 65, 5, 10, 3, - 68, 66, 6, 67, 0, 69, 69, 76, 64, 69, 81, 2, 69, - 76, 2, 12, 66, 86, 77, 78, 81, 4, 68, 9, 7, 7, - 41, 19, 5, 69, 13, 69, 82, 0, 108, 73, 64, 91, - 71, 89, 4, 64, 82, 19, 8, 4, 101, 4, 86, 74, 3, - 97, 1, 17, 10, 14, 17, 13, 6, 16, 12, 68, 64, 9, - 0, 64, 75, 69, 75, 74, 70, 73, 79, 79, 78, 78, - 76, 68, 92, 99, 80, 85, 86, 90, 91, 100, 105, - 99, 99, 109, 115, 108, 111, 126, 121, 123, 70, - 74, 95, 80, 88, 91, 97, 106, 109, 99, 103, 97, - 87, 92, 90, 82, 79, 6, 26, 18, 11, 9, 11, 6, 1, - 6, 15, 15, 30, 21, 15, 8, 23, 14, 18, 11, 38, 2, - 44, 31, 22, 14, 27, 5, 64, 64, 5, 70, 47, 17, 0, - 1, 12, 1, 71, 1, 5, 33, 18, 2, 67, 17, 5, 3, 3, - 3, 62, 65, 7, 8, 15, 10, 9, 22, 23, 17, 22, 27, - 33, 64, 6, 75, 64, 38, 70, 95, 67, 10, 66, 81, - 86, 76, 87, 96, 105, 107, 72, 67, 16, 70, 77, - 69, 65, 2, 81, 75, 68, 68, 89, 75, 82, 1, 11, - 88, 75, 4, 80, 1, 77, 69, 21, 80, 85, 65, 4, 90, - 88, 124, 9, 15, 24, 67, 74, 69, 85, 85, 85, 98, - 98, 97, 115, 106, 94, 116, 120, 124, 126, 115, - 111, 102, 82, 89, 6, 25, 4, 26, 48, 84, 87, 92, - 90, 114, 103, 97, 122, 100, 112, 106, 125, 118, - 115, 114, 85, 81, 118, 89, 91, 104, 116, 110, - 111, 111, 107, 116, 113, 116, 121, 126, 120, 77, - 85, 102, 66, 14, 10, 22, 22, 27, 50, 32, 43, 43, - 62, 53, 47, 62, 62, 37, 72, 94, 114, 126, 126, - 126, 126, 126, 16, 50, 43, 43, 31, 45, 22, 17, - 22, 12, 69, 1, 18, 4, 37, 47, 2, 12, 21, 25, 6, - 22, 41, 4, 65, 11, 89, 114, 126, 126, 126, 126, - 126, 126 }, - - { - - 15, - 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 106, 75, - 66, 51, 14, 62, 72, 27, 34, 65, 87, 3, 104, 121, - 71, 92, 126, 126, 126, 62, 23, 70, 27, 34, 65, - 66, 23, 22, 73, 4, 2, 3, 74, 89, 70, 94, 5, 66, - 1, 69, 81, 71, 88, 19, 5, 2, 64, 14, 2, 22, 0, - 0, 0, 9, 98, 97, 14, 82, 71, 18, 65, 86, 24, 55, - 42, 62, 62, 33, 31, 24, 39, 19, 12, 29, 69, 73, - 73, 66, 27, 2, 10, 64, 64, 0, 2, 11, 69, 79, 78, - 88, 19, 68, 7, 1, 78, 5, 71, 9, 3, 65, 5, 10, 2, - 68, 66, 6, 67, 0, 69, 70, 76, 64, 70, 82, 1, 70, - 77, 2, 13, 66, 87, 77, 77, 81, 4, 68, 9, 7, 7, - 42, 19, 5, 69, 14, 69, 83, 0, 109, 73, 64, 91, - 72, 90, 4, 64, 83, 19, 8, 4, 103, 4, 87, 74, 3, - 97, 0, 17, 10, 14, 17, 13, 6, 16, 12, 68, 65, 9, - 0, 64, 75, 70, 76, 75, 71, 74, 80, 80, 78, 78, - 77, 68, 93, 101, 80, 86, 88, 92, 93, 102, 107, - 101, 101, 111, 117, 109, 112, 126, 123, 124, 70, - 74, 95, 81, 89, 92, 99, 107, 111, 100, 104, 98, - 87, 92, 90, 82, 79, 7, 26, 18, 11, 9, 11, 6, 1, - 7, 16, 15, 30, 21, 15, 8, 24, 15, 19, 12, 40, 2, - 44, 31, 22, 14, 28, 5, 64, 64, 5, 70, 47, 17, - 64, 1, 12, 1, 71, 2, 5, 33, 18, 1, 68, 17, 5, 3, - 4, 4, 62, 64, 8, 8, 16, 11, 10, 24, 24, 18, 23, - 29, 34, 64, 7, 75, 64, 40, 70, 95, 67, 10, 66, - 82, 86, 76, 88, 97, 106, 108, 72, 68, 16, 71, - 77, 69, 66, 2, 82, 75, 69, 68, 90, 75, 83, 1, - 11, 89, 75, 4, 81, 1, 78, 69, 21, 81, 86, 66, 3, - 91, 88, 125, 8, 14, 24, 68, 75, 71, 87, 87, 87, - 101, 100, 99, 118, 109, 95, 119, 123, 126, 126, - 118, 114, 104, 83, 90, 6, 26, 4, 27, 50, 86, 89, - 94, 92, 116, 105, 98, 124, 102, 113, 107, 126, - 120, 116, 115, 85, 82, 119, 90, 93, 105, 118, - 112, 113, 113, 108, 118, 115, 117, 123, 126, - 121, 78, 86, 103, 66, 15, 10, 22, 23, 27, 51, - 33, 44, 44, 62, 54, 48, 62, 62, 37, 73, 96, 117, - 126, 126, 126, 126, 126, 17, 51, 44, 44, 31, 46, - 23, 17, 23, 13, 69, 2, 18, 5, 38, 48, 2, 12, 21, - 25, 6, 23, 42, 4, 65, 10, 91, 117, 126, 126, - 126, 126, 126, 126 }, - - }, - - { - - { - - 62, - 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 38, 62, - 62, 54, 22, 118, 65, 71, 79, 11, 13, 70, 9, 29, - 41, 62, 61, 27, 69, 126, 101, 76, 71, 79, 11, - 69, 90, 11, 20, 69, 82, 96, 4, 75, 87, 100, 7, - 74, 85, 4, 81, 86, 95, 66, 77, 70, 86, 72, 2, - 22, 0, 0, 0, 83, 86, 97, 72, 22, 1, 48, 12, 80, - 126, 91, 96, 81, 98, 102, 97, 119, 99, 110, 102, - 126, 80, 89, 94, 92, 24, 65, 84, 126, 73, 104, - 91, 126, 8, 7, 8, 2, 10, 68, 74, 88, 103, 91, - 89, 92, 76, 87, 110, 105, 78, 112, 99, 126, 126, - 126, 126, 66, 78, 71, 72, 4, 8, 70, 75, 89, 119, - 75, 43, 41, 126, 9, 2, 5, 3, 2, 67, 84, 74, 65, - 11, 6, 2, 69, 70, 8, 71, 5, 2, 22, 38, 31, 20, - 16, 19, 12, 17, 25, 66, 25, 21, 29, 89, 18, 35, - 32, 62, 62, 48, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 53, 62, 62, 62, 62, 62, 62, 62, 56, 62, - 62, 62, 27, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 53, 45, 38, 22, 75, 72, 77, 28, 32, 28, - 33, 18, 21, 18, 37, 9, 66, 7, 73, 67, 116, 112, - 71, 2, 10, 66, 77, 80, 84, 87, 126, 101, 24, 10, - 2, 75, 77, 91, 107, 111, 122, 76, 19, 11, 6, 5, - 72, 69, 69, 74, 86, 66, 29, 31, 32, 11, 8, 67, - 73, 89, 11, 59, 55, 55, 44, 26, 2, 73, 70, 78, - 62, 126, 124, 110, 126, 124, 105, 121, 117, 102, - 117, 116, 122, 95, 100, 95, 111, 114, 89, 80, - 82, 85, 81, 72, 64, 67, 7, 69, 69, 69, 69, 67, - 77, 64, 2, 67, 64, 6, 65, 66, 1, 12, 66, 71, 75, - 70, 72, 3, 26, 16, 28, 26, 22, 22, 15, 22, 22, - 4, 13, 23, 66, 13, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 54, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 49, 37, 26, 8, 65, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 43, 33, - 19, 15, 14, 18, 41, 41, 42, 43, 35, 39, 29, 21, - 24, 13, 70, 9, 71, 83, 31, 14, 9, 85, 81, 77, - 81, 80, 73, 74, 83, 71, 67, 2, 66, 66, 4, 4, 62, - 62, 62, 62, 62, 60, 53, 36, 6, 71, 39, 27, 21, - 11, 6, 0, 65, 67, 82, 81, 76, 72, 78, 72, 68, - 70, 76, 66, 1, 6, 2, 3, 9, 5, 62, 62, 62, 62, - 62, 60, 53, 36, 6 }, - - { - - 62, - 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 37, - 61, 62, 55, 22, 116, 65, 70, 78, 11, 13, 69, - 9, 28, 40, 61, 58, 25, 70, 124, 100, 75, 70, - 78, 11, 69, 89, 11, 20, 68, 81, 95, 4, 75, 86, - 99, 7, 73, 84, 4, 80, 85, 94, 65, 76, 70, 85, - 71, 2, 22, 0, 0, 0, 82, 86, 97, 71, 22, 1, 48, - 12, 80, 124, 89, 94, 79, 95, 100, 95, 117, 97, - 108, 100, 124, 80, 88, 93, 91, 24, 65, 83, - 124, 72, 103, 90, 125, 8, 7, 8, 2, 11, 68, 73, - 87, 102, 90, 88, 91, 75, 86, 108, 103, 77, - 110, 97, 122, 122, 123, 124, 65, 77, 70, 71, - 4, 9, 69, 74, 88, 116, 74, 41, 40, 124, 9, 3, - 5, 4, 3, 66, 82, 73, 64, 11, 6, 2, 68, 69, 7, - 70, 5, 2, 22, 37, 31, 20, 16, 19, 12, 17, 24, - 65, 25, 21, 29, 89, 18, 35, 32, 62, 62, 47, - 62, 62, 62, 61, 62, 62, 62, 62, 62, 62, 52, - 62, 62, 62, 62, 62, 62, 62, 54, 62, 60, 62, - 26, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 61, 52, 44, 37, 21, 75, 72, 77, 28, 31, 27, - 32, 17, 20, 17, 36, 8, 66, 6, 73, 67, 115, - 110, 70, 3, 10, 65, 76, 79, 83, 86, 124, 99, - 25, 11, 3, 74, 76, 89, 105, 109, 120, 75, 20, - 12, 7, 6, 71, 68, 68, 73, 85, 66, 30, 31, 32, - 11, 9, 66, 73, 88, 11, 59, 55, 54, 43, 26, 3, - 72, 69, 77, 62, 124, 122, 108, 124, 122, 103, - 119, 115, 100, 115, 114, 119, 94, 99, 94, 109, - 112, 88, 79, 81, 84, 80, 71, 64, 67, 7, 69, - 69, 69, 68, 66, 76, 0, 2, 66, 0, 6, 64, 65, 1, - 12, 65, 70, 74, 69, 71, 3, 25, 16, 27, 26, 22, - 22, 15, 22, 22, 4, 13, 22, 66, 12, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 52, 62, 62, 62, 62, 62, 62, 62, 61, 62, 48, - 36, 25, 8, 65, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 42, 32, 18, 15, 14, 17, 40, - 40, 41, 41, 34, 38, 28, 20, 23, 12, 70, 8, 71, - 83, 30, 13, 8, 84, 80, 76, 80, 78, 71, 73, 82, - 70, 66, 3, 65, 65, 4, 4, 62, 62, 62, 62, 60, - 56, 49, 32, 4, 70, 39, 28, 22, 12, 7, 1, 64, - 66, 81, 80, 75, 71, 77, 71, 67, 69, 75, 65, 2, - 6, 3, 4, 9, 5, 62, 62, 62, 62, 60, 56, 49, 32, - 4 }, - - { - - 62, - 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 36, - 59, 61, 55, 22, 114, 65, 70, 77, 11, 12, 69, - 8, 26, 39, 58, 54, 22, 72, 121, 99, 75, 70, - 77, 11, 69, 88, 11, 19, 68, 81, 94, 4, 75, 86, - 99, 7, 73, 84, 4, 80, 85, 94, 65, 76, 70, 85, - 71, 2, 22, 0, 0, 0, 81, 86, 97, 71, 21, 1, 47, - 12, 80, 122, 88, 93, 77, 93, 99, 94, 115, 96, - 107, 99, 122, 80, 88, 93, 91, 24, 65, 82, 122, - 72, 102, 89, 123, 8, 7, 8, 1, 11, 68, 73, 86, - 101, 89, 87, 90, 75, 85, 107, 102, 76, 109, - 96, 117, 118, 120, 121, 65, 77, 70, 71, 4, 9, - 69, 74, 88, 114, 74, 39, 38, 121, 9, 3, 5, 4, - 3, 66, 80, 72, 64, 11, 6, 2, 67, 68, 6, 70, 5, - 2, 21, 36, 30, 20, 15, 19, 12, 17, 23, 65, 24, - 20, 28, 89, 18, 34, 31, 62, 62, 46, 60, 62, - 62, 59, 62, 62, 62, 62, 62, 62, 50, 62, 62, - 62, 62, 62, 62, 62, 52, 62, 58, 62, 24, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 50, - 42, 35, 19, 75, 72, 78, 27, 30, 26, 31, 16, - 19, 16, 34, 7, 66, 5, 74, 68, 114, 109, 69, 3, - 10, 65, 75, 78, 82, 85, 122, 98, 25, 11, 3, - 73, 75, 88, 103, 107, 118, 74, 21, 13, 8, 7, - 70, 68, 68, 73, 84, 66, 31, 31, 31, 11, 9, 66, - 73, 88, 11, 59, 54, 53, 42, 26, 3, 72, 69, 77, - 62, 123, 121, 107, 122, 120, 102, 117, 113, - 99, 113, 112, 117, 93, 98, 94, 108, 110, 88, - 79, 81, 83, 80, 71, 64, 67, 6, 69, 69, 69, 68, - 66, 75, 0, 2, 66, 0, 6, 64, 65, 1, 11, 65, 70, - 74, 69, 70, 2, 24, 16, 26, 25, 21, 21, 15, 21, - 21, 4, 13, 21, 66, 11, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 50, 62, 62, - 62, 62, 62, 62, 62, 59, 59, 46, 34, 24, 7, 66, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 40, 30, 16, 14, 13, 15, 39, 39, 39, 39, - 32, 36, 26, 19, 21, 11, 71, 7, 72, 84, 28, 12, - 7, 84, 80, 75, 80, 77, 70, 73, 81, 69, 65, 3, - 65, 64, 4, 4, 62, 62, 62, 62, 57, 52, 45, 28, - 1, 70, 39, 28, 22, 12, 8, 1, 64, 66, 81, 80, - 75, 71, 77, 70, 66, 69, 75, 65, 2, 6, 3, 5, 9, - 5, 62, 62, 62, 62, 57, 52, 45, 28, 1 }, - - { - - 62, - 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 34, 57, - 60, 55, 22, 112, 65, 69, 76, 11, 12, 69, 8, - 25, 38, 56, 51, 20, 73, 118, 98, 75, 69, 76, - 11, 70, 87, 11, 19, 68, 81, 94, 4, 75, 86, 99, - 7, 73, 83, 4, 80, 84, 94, 65, 76, 70, 85, 71, - 2, 22, 0, 0, 0, 81, 86, 97, 70, 20, 1, 46, 11, - 80, 119, 87, 92, 76, 91, 97, 92, 113, 94, 106, - 98, 120, 80, 88, 92, 91, 24, 65, 81, 120, 72, - 101, 89, 121, 8, 6, 7, 1, 11, 68, 72, 86, 100, - 88, 87, 89, 74, 84, 105, 100, 76, 108, 95, - 112, 113, 117, 118, 65, 77, 70, 70, 4, 9, 68, - 73, 87, 112, 74, 37, 36, 118, 9, 3, 5, 4, 3, - 65, 79, 71, 64, 11, 6, 2, 67, 67, 5, 70, 5, 1, - 21, 35, 30, 20, 15, 19, 12, 17, 22, 65, 23, - 19, 28, 89, 18, 34, 31, 62, 62, 45, 58, 62, - 62, 57, 62, 62, 62, 62, 62, 61, 48, 62, 62, - 62, 62, 62, 62, 60, 50, 62, 56, 62, 22, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 48, - 40, 34, 17, 75, 72, 78, 26, 29, 25, 30, 15, - 18, 15, 32, 6, 67, 4, 75, 68, 114, 107, 68, 4, - 10, 65, 74, 78, 82, 85, 120, 97, 25, 11, 4, - 72, 74, 87, 102, 106, 116, 73, 21, 13, 8, 7, - 69, 67, 68, 73, 84, 66, 31, 31, 30, 11, 9, 66, - 73, 87, 11, 58, 54, 52, 41, 26, 3, 72, 69, 77, - 62, 122, 119, 106, 121, 119, 101, 115, 111, - 98, 112, 110, 115, 93, 97, 93, 107, 108, 87, - 79, 81, 83, 79, 71, 64, 67, 6, 69, 69, 70, 67, - 65, 74, 0, 2, 65, 0, 6, 64, 65, 1, 11, 65, 70, - 74, 69, 70, 1, 23, 16, 25, 24, 20, 21, 15, 20, - 20, 4, 13, 20, 66, 10, 62, 62, 61, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 48, 62, 62, - 62, 62, 62, 62, 62, 57, 57, 44, 32, 22, 6, 67, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, - 60, 38, 28, 15, 13, 12, 14, 37, 37, 37, 37, - 31, 34, 24, 18, 20, 10, 72, 6, 73, 85, 27, 11, - 6, 84, 79, 75, 79, 76, 69, 73, 81, 69, 65, 3, - 64, 0, 4, 4, 62, 62, 62, 59, 54, 48, 41, 24, - 65, 70, 39, 28, 22, 12, 8, 2, 64, 66, 80, 80, - 75, 70, 76, 69, 65, 69, 74, 65, 2, 6, 3, 5, 9, - 5, 62, 62, 62, 59, 54, 48, 41, 24, 65 }, - - { - - 62, - 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 33, 55, - 59, 55, 21, 110, 65, 69, 75, 10, 11, 69, 7, - 23, 37, 53, 47, 17, 75, 115, 97, 75, 69, 75, - 10, 70, 86, 11, 18, 68, 80, 93, 4, 75, 86, 99, - 7, 73, 83, 4, 80, 84, 93, 65, 76, 70, 85, 70, - 2, 22, 0, 0, 0, 80, 87, 97, 70, 19, 1, 45, 11, - 80, 117, 86, 91, 74, 89, 96, 91, 112, 93, 104, - 97, 118, 80, 87, 92, 91, 24, 65, 80, 118, 72, - 101, 88, 119, 8, 6, 7, 0, 11, 68, 72, 85, 99, - 87, 86, 88, 74, 84, 104, 99, 75, 107, 94, 107, - 109, 114, 115, 65, 76, 70, 70, 4, 9, 68, 73, - 87, 110, 74, 35, 34, 116, 9, 4, 5, 4, 3, 65, - 77, 70, 0, 10, 6, 2, 66, 67, 4, 70, 5, 1, 20, - 34, 29, 19, 14, 19, 12, 17, 21, 65, 22, 18, - 27, 89, 17, 33, 30, 62, 62, 44, 56, 62, 62, - 55, 62, 62, 62, 62, 62, 59, 46, 59, 62, 62, - 62, 62, 62, 57, 48, 62, 54, 62, 21, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 60, 55, 46, 38, - 32, 15, 75, 72, 79, 25, 28, 24, 28, 14, 16, - 14, 31, 5, 67, 3, 75, 69, 113, 106, 67, 4, 10, - 64, 74, 77, 81, 84, 118, 95, 25, 12, 4, 72, - 73, 86, 100, 104, 115, 73, 22, 14, 9, 8, 68, - 67, 68, 72, 83, 66, 32, 31, 30, 10, 9, 66, 73, - 87, 11, 58, 53, 51, 40, 26, 3, 71, 69, 77, 62, - 120, 118, 105, 119, 117, 100, 114, 110, 97, - 110, 109, 113, 92, 96, 93, 106, 107, 87, 79, - 81, 82, 79, 71, 65, 67, 5, 69, 69, 70, 67, 65, - 73, 0, 2, 65, 0, 6, 64, 65, 1, 10, 65, 70, 74, - 69, 69, 0, 22, 16, 24, 24, 19, 20, 15, 19, 19, - 4, 13, 19, 66, 9, 62, 62, 60, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 46, 62, 62, 62, - 62, 62, 62, 62, 54, 54, 42, 30, 21, 5, 67, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 57, - 36, 26, 13, 12, 12, 12, 36, 36, 36, 35, 29, - 32, 23, 17, 18, 9, 73, 4, 74, 85, 25, 9, 4, - 83, 79, 74, 79, 75, 68, 73, 80, 68, 64, 3, 64, - 1, 4, 4, 62, 62, 62, 56, 50, 44, 36, 20, 68, - 69, 39, 28, 22, 12, 9, 2, 64, 66, 80, 80, 75, - 70, 76, 69, 64, 69, 74, 64, 3, 6, 3, 6, 9, 5, - 62, 62, 62, 56, 50, 44, 36, 20, 68 }, - - { - - 62, - 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 32, 53, - 58, 55, 21, 108, 65, 69, 74, 10, 11, 69, 6, - 21, 36, 51, 44, 15, 77, 112, 96, 74, 69, 74, - 10, 70, 85, 11, 18, 68, 80, 92, 4, 75, 86, 99, - 7, 73, 83, 4, 80, 83, 93, 65, 76, 70, 85, 70, - 2, 22, 0, 0, 0, 80, 87, 97, 69, 18, 1, 44, 10, - 80, 114, 85, 90, 72, 87, 94, 89, 110, 91, 103, - 96, 115, 80, 87, 91, 90, 24, 65, 79, 116, 72, - 100, 88, 117, 8, 5, 6, 0, 11, 68, 71, 85, 98, - 86, 86, 87, 73, 83, 102, 97, 74, 105, 93, 102, - 105, 111, 112, 64, 76, 69, 69, 4, 9, 67, 73, - 86, 108, 74, 33, 32, 113, 9, 4, 5, 4, 3, 64, - 76, 69, 0, 10, 6, 2, 66, 66, 3, 69, 5, 0, 20, - 33, 29, 19, 14, 19, 12, 17, 20, 64, 21, 18, - 27, 89, 17, 32, 29, 62, 62, 43, 55, 62, 62, - 53, 62, 62, 62, 62, 61, 57, 44, 57, 62, 60, - 62, 62, 62, 55, 46, 62, 52, 62, 19, 62, 62, - 62, 62, 62, 62, 62, 62, 61, 58, 53, 44, 37, - 30, 13, 75, 72, 79, 24, 27, 23, 27, 13, 15, - 13, 29, 4, 68, 2, 76, 70, 112, 104, 66, 5, 10, - 64, 73, 77, 81, 83, 116, 94, 25, 12, 5, 71, - 72, 85, 99, 103, 113, 72, 23, 15, 10, 8, 67, - 66, 67, 72, 83, 66, 32, 31, 29, 10, 9, 66, 73, - 86, 11, 57, 52, 50, 39, 26, 3, 71, 69, 76, 62, - 119, 116, 103, 117, 116, 99, 112, 108, 96, - 108, 107, 111, 91, 95, 92, 105, 105, 87, 79, - 80, 82, 78, 71, 65, 67, 5, 69, 69, 71, 66, 65, - 72, 0, 2, 65, 0, 6, 64, 65, 1, 10, 65, 70, 74, - 69, 69, 64, 21, 16, 23, 23, 19, 19, 15, 19, - 18, 4, 13, 18, 66, 8, 62, 62, 59, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 44, 62, 62, - 62, 62, 62, 62, 61, 52, 52, 40, 29, 19, 5, 68, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 55, - 54, 34, 24, 12, 12, 11, 10, 35, 34, 34, 33, - 27, 30, 21, 16, 17, 8, 73, 3, 75, 86, 24, 8, - 3, 83, 79, 73, 78, 74, 67, 72, 79, 68, 64, 3, - 0, 2, 4, 4, 62, 62, 59, 53, 47, 40, 32, 16, - 71, 69, 39, 28, 22, 12, 9, 2, 0, 65, 79, 80, - 75, 69, 76, 68, 0, 69, 74, 64, 3, 6, 4, 6, 9, - 5, 62, 62, 59, 53, 47, 40, 32, 16, 71 }, - - { - - 62, - 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 30, 51, - 57, 55, 21, 107, 65, 68, 74, 10, 10, 68, 6, - 20, 34, 48, 40, 12, 78, 110, 95, 74, 68, 74, - 10, 71, 85, 11, 17, 68, 80, 92, 4, 75, 85, 98, - 7, 72, 82, 4, 79, 83, 93, 65, 76, 70, 85, 70, - 2, 22, 0, 0, 0, 79, 87, 97, 69, 18, 0, 44, 10, - 80, 112, 84, 89, 71, 84, 93, 88, 108, 90, 102, - 95, 113, 80, 87, 91, 90, 24, 65, 78, 113, 72, - 99, 87, 115, 7, 5, 6, 64, 12, 68, 71, 84, 98, - 86, 85, 86, 73, 82, 101, 96, 74, 104, 92, 97, - 100, 108, 109, 64, 76, 69, 69, 4, 9, 67, 72, - 86, 106, 73, 31, 30, 110, 9, 4, 5, 4, 4, 64, - 74, 68, 0, 10, 6, 2, 65, 65, 2, 69, 5, 0, 19, - 32, 28, 19, 13, 19, 12, 17, 18, 64, 20, 17, - 26, 89, 17, 32, 29, 62, 62, 42, 53, 62, 62, - 51, 62, 62, 62, 62, 57, 55, 43, 55, 62, 58, - 62, 62, 62, 52, 44, 62, 50, 62, 17, 62, 62, - 62, 62, 62, 62, 62, 62, 59, 56, 50, 42, 35, - 29, 12, 75, 72, 80, 23, 26, 22, 26, 12, 14, - 12, 27, 3, 68, 1, 77, 70, 112, 103, 65, 5, 10, - 64, 72, 76, 80, 83, 114, 93, 26, 12, 5, 70, - 71, 84, 97, 101, 111, 71, 23, 15, 10, 9, 66, - 66, 67, 72, 82, 66, 33, 31, 28, 10, 9, 66, 73, - 86, 10, 57, 52, 49, 38, 25, 3, 71, 69, 76, 62, - 118, 115, 102, 116, 114, 98, 110, 106, 95, - 107, 105, 109, 91, 94, 92, 104, 103, 86, 79, - 80, 81, 78, 71, 65, 67, 4, 69, 69, 71, 66, 64, - 71, 0, 2, 64, 1, 6, 0, 64, 1, 9, 65, 70, 74, - 69, 68, 65, 20, 16, 22, 22, 18, 19, 15, 18, - 18, 4, 12, 16, 67, 7, 62, 62, 58, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 42, 62, 62, - 62, 62, 62, 62, 58, 50, 49, 38, 27, 18, 4, 69, - 62, 62, 62, 62, 62, 62, 62, 62, 61, 58, 52, - 51, 32, 23, 10, 11, 10, 9, 33, 33, 32, 31, 26, - 28, 19, 15, 15, 7, 74, 2, 76, 87, 22, 7, 2, - 83, 78, 73, 78, 73, 66, 72, 79, 67, 0, 3, 0, - 3, 4, 4, 62, 62, 57, 50, 44, 36, 28, 12, 74, - 69, 39, 28, 22, 12, 10, 3, 0, 65, 79, 79, 74, - 69, 75, 67, 1, 68, 73, 64, 3, 6, 4, 7, 9, 5, - 62, 62, 57, 50, 44, 36, 28, 12, 74 }, - - { - - 62, - 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 29, 49, - 56, 55, 21, 105, 65, 68, 73, 9, 10, 68, 5, 18, - 33, 46, 37, 10, 80, 107, 94, 74, 68, 73, 9, - 71, 84, 11, 17, 68, 79, 91, 4, 75, 85, 98, 7, - 72, 82, 4, 79, 82, 92, 65, 76, 70, 85, 69, 2, - 22, 0, 0, 0, 79, 87, 97, 68, 17, 0, 43, 9, 80, - 109, 83, 88, 69, 82, 91, 86, 107, 88, 100, 94, - 111, 80, 86, 90, 90, 24, 65, 77, 111, 72, 98, - 87, 113, 7, 4, 5, 64, 12, 68, 70, 84, 97, 85, - 85, 85, 72, 81, 99, 94, 73, 103, 91, 92, 96, - 105, 106, 64, 75, 69, 68, 4, 9, 66, 72, 85, - 104, 73, 29, 28, 107, 9, 5, 5, 4, 4, 0, 73, - 67, 1, 9, 6, 2, 65, 65, 1, 69, 5, 64, 19, 31, - 28, 18, 13, 19, 12, 17, 17, 64, 19, 16, 26, - 89, 17, 31, 28, 60, 62, 41, 51, 62, 62, 49, - 62, 61, 62, 62, 54, 53, 41, 52, 62, 55, 62, - 62, 62, 49, 42, 62, 48, 62, 16, 62, 62, 62, - 62, 62, 62, 62, 62, 57, 53, 48, 40, 33, 27, - 10, 75, 72, 80, 22, 25, 21, 24, 11, 13, 11, - 26, 2, 69, 0, 77, 71, 111, 101, 64, 6, 10, 0, - 72, 76, 80, 82, 112, 91, 26, 13, 6, 70, 70, - 83, 96, 100, 109, 71, 24, 16, 11, 9, 65, 65, - 67, 71, 82, 66, 33, 31, 28, 9, 9, 66, 73, 85, - 10, 56, 51, 48, 37, 25, 3, 70, 69, 76, 62, - 116, 113, 101, 114, 113, 97, 109, 105, 94, - 105, 104, 107, 90, 93, 91, 103, 101, 86, 79, - 80, 81, 77, 71, 66, 67, 4, 69, 69, 72, 65, 64, - 70, 0, 2, 64, 1, 6, 0, 64, 1, 9, 65, 70, 74, - 69, 68, 66, 19, 16, 21, 22, 17, 18, 15, 17, - 17, 4, 12, 15, 67, 6, 61, 62, 57, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 40, 62, 62, - 62, 62, 62, 62, 56, 48, 47, 36, 25, 16, 3, 69, - 62, 62, 62, 62, 62, 62, 62, 62, 59, 56, 50, - 48, 30, 21, 9, 10, 10, 7, 32, 31, 31, 29, 24, - 26, 18, 14, 14, 6, 75, 0, 77, 87, 21, 5, 0, - 82, 78, 72, 77, 72, 65, 72, 78, 67, 0, 3, 1, - 4, 4, 4, 62, 62, 54, 47, 40, 32, 24, 8, 77, - 68, 39, 28, 22, 12, 10, 3, 0, 65, 78, 79, 74, - 68, 75, 66, 2, 68, 73, 0, 4, 6, 4, 7, 9, 5, - 62, 62, 54, 47, 40, 32, 24, 8, 77 }, - - { - - 62, - 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 27, 46, - 55, 55, 20, 103, 66, 68, 72, 9, 9, 68, 4, 16, - 32, 43, 33, 7, 82, 104, 93, 74, 68, 72, 9, 72, - 83, 11, 16, 68, 79, 91, 3, 76, 85, 98, 7, 72, - 82, 4, 79, 82, 92, 65, 76, 70, 85, 69, 2, 22, - 0, 0, 0, 78, 88, 97, 68, 16, 0, 42, 9, 81, - 107, 82, 87, 68, 80, 90, 85, 105, 87, 99, 93, - 109, 80, 86, 90, 90, 24, 65, 76, 109, 72, 98, - 86, 111, 7, 4, 5, 65, 12, 68, 70, 83, 96, 84, - 84, 85, 72, 81, 98, 93, 73, 102, 90, 88, 92, - 102, 104, 64, 75, 69, 68, 3, 9, 66, 72, 85, - 102, 73, 27, 26, 105, 9, 5, 5, 4, 4, 0, 71, - 67, 1, 9, 5, 2, 64, 64, 64, 69, 5, 64, 18, 29, - 27, 18, 12, 19, 12, 16, 16, 64, 18, 15, 25, - 89, 16, 30, 27, 58, 62, 39, 49, 62, 62, 46, - 62, 59, 62, 62, 50, 51, 39, 50, 62, 53, 62, - 62, 62, 46, 40, 62, 46, 62, 14, 62, 62, 62, - 62, 62, 62, 62, 60, 55, 51, 46, 38, 31, 25, 8, - 75, 73, 81, 21, 23, 20, 23, 10, 11, 9, 24, 1, - 69, 64, 78, 72, 111, 100, 0, 6, 10, 0, 71, 75, - 79, 82, 110, 90, 26, 13, 6, 69, 69, 82, 94, - 98, 108, 70, 24, 16, 11, 10, 64, 65, 67, 71, - 81, 67, 34, 31, 27, 9, 9, 66, 73, 85, 10, 56, - 50, 47, 36, 25, 3, 70, 69, 76, 62, 115, 112, - 100, 113, 111, 96, 107, 103, 93, 104, 102, - 105, 90, 93, 91, 102, 100, 86, 79, 80, 80, 77, - 71, 66, 67, 3, 69, 69, 72, 65, 64, 69, 0, 1, - 64, 1, 5, 0, 64, 1, 8, 65, 70, 74, 69, 67, 67, - 18, 16, 19, 21, 16, 17, 14, 16, 16, 4, 12, 14, - 67, 4, 60, 60, 56, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 60, 38, 62, 62, 62, 62, 62, 62, - 53, 45, 44, 34, 23, 15, 2, 70, 62, 62, 62, 62, - 62, 62, 62, 62, 56, 53, 47, 45, 28, 19, 7, 9, - 9, 5, 30, 30, 29, 27, 22, 24, 16, 12, 12, 4, - 76, 64, 78, 88, 19, 4, 64, 82, 78, 72, 77, 71, - 64, 72, 78, 66, 1, 3, 1, 4, 4, 3, 62, 60, 51, - 44, 37, 28, 19, 3, 80, 68, 39, 28, 22, 12, 11, - 3, 0, 65, 78, 79, 74, 68, 75, 66, 2, 68, 73, - 0, 4, 6, 4, 8, 9, 4, 62, 60, 51, 44, 37, 28, - 19, 3, 80 }, - - { - - 62, - 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 26, 44, - 54, 56, 20, 101, 66, 67, 71, 9, 8, 68, 4, 15, - 31, 41, 29, 4, 83, 101, 92, 73, 67, 71, 9, 72, - 82, 11, 16, 67, 79, 90, 3, 76, 85, 98, 7, 72, - 81, 4, 79, 82, 92, 65, 76, 70, 84, 69, 2, 22, - 0, 0, 0, 77, 88, 97, 68, 15, 0, 41, 9, 81, - 105, 80, 86, 66, 78, 88, 84, 103, 85, 98, 91, - 106, 80, 86, 90, 89, 24, 65, 75, 107, 71, 97, - 85, 109, 7, 4, 5, 65, 12, 68, 70, 82, 95, 83, - 83, 84, 71, 80, 97, 91, 72, 100, 89, 83, 87, - 98, 101, 0, 75, 68, 67, 3, 9, 66, 71, 84, 99, - 73, 25, 25, 102, 9, 5, 5, 4, 4, 1, 69, 66, 1, - 9, 5, 2, 0, 0, 65, 68, 5, 64, 17, 28, 26, 18, - 11, 19, 12, 16, 15, 0, 17, 15, 24, 89, 16, 30, - 27, 56, 62, 38, 48, 62, 62, 44, 60, 57, 62, - 62, 47, 49, 37, 48, 62, 51, 62, 62, 62, 44, - 38, 62, 44, 62, 12, 62, 62, 62, 62, 62, 62, - 60, 58, 53, 49, 44, 37, 30, 24, 6, 75, 73, 81, - 21, 22, 19, 22, 9, 10, 8, 22, 0, 69, 65, 79, - 72, 110, 99, 1, 6, 10, 0, 70, 74, 78, 81, 107, - 89, 26, 13, 6, 68, 68, 81, 92, 96, 106, 69, - 25, 17, 12, 11, 0, 65, 66, 71, 80, 67, 35, 31, - 26, 9, 10, 65, 73, 84, 10, 56, 50, 46, 35, 25, - 3, 70, 69, 75, 62, 114, 111, 98, 111, 109, 95, - 105, 101, 92, 102, 100, 103, 89, 92, 90, 101, - 98, 85, 78, 79, 79, 76, 71, 66, 67, 2, 69, 69, - 72, 65, 0, 68, 1, 1, 0, 1, 5, 0, 64, 1, 7, 65, - 69, 73, 69, 66, 67, 17, 16, 18, 20, 16, 17, - 14, 16, 15, 4, 12, 13, 67, 3, 59, 59, 56, 61, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 36, - 62, 62, 62, 62, 62, 62, 50, 43, 42, 33, 22, - 14, 2, 71, 62, 62, 62, 62, 62, 62, 62, 62, 54, - 51, 45, 43, 26, 17, 5, 9, 8, 4, 29, 29, 27, - 25, 21, 23, 14, 11, 10, 3, 76, 65, 78, 89, 17, - 3, 65, 82, 77, 71, 77, 70, 1, 71, 77, 65, 2, - 3, 2, 5, 4, 3, 62, 58, 49, 41, 34, 24, 15, 64, - 83, 68, 39, 28, 23, 13, 12, 4, 1, 64, 78, 79, - 74, 68, 74, 65, 3, 68, 72, 0, 4, 6, 5, 9, 9, - 4, 62, 58, 49, 41, 34, 24, 15, 64, 83 }, - - { - - 62, - 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 25, 42, - 53, 56, 20, 99, 66, 67, 70, 8, 8, 68, 3, 13, - 30, 38, 26, 2, 85, 98, 91, 73, 67, 70, 8, 72, - 81, 11, 15, 67, 78, 89, 3, 76, 85, 98, 7, 72, - 81, 4, 79, 81, 91, 65, 76, 70, 84, 68, 2, 22, - 0, 0, 0, 77, 88, 97, 67, 14, 0, 40, 8, 81, - 102, 79, 85, 64, 76, 87, 82, 102, 84, 96, 90, - 104, 80, 85, 89, 89, 24, 65, 74, 105, 71, 96, - 85, 107, 7, 3, 4, 66, 12, 68, 69, 82, 94, 82, - 83, 83, 71, 79, 95, 90, 71, 99, 88, 78, 83, - 95, 98, 0, 74, 68, 67, 3, 9, 65, 71, 84, 97, - 73, 23, 23, 99, 9, 6, 5, 4, 4, 1, 68, 65, 2, - 8, 5, 2, 0, 0, 66, 68, 5, 65, 17, 27, 26, 17, - 11, 19, 12, 16, 14, 0, 16, 14, 24, 89, 16, 29, - 26, 54, 62, 37, 46, 62, 62, 42, 57, 55, 62, - 62, 43, 47, 35, 45, 61, 48, 62, 62, 62, 41, - 36, 58, 42, 62, 11, 62, 62, 62, 62, 62, 60, - 58, 56, 51, 46, 42, 35, 28, 22, 4, 75, 73, 82, - 20, 21, 18, 20, 8, 9, 7, 21, 64, 70, 66, 79, - 73, 109, 97, 2, 7, 10, 1, 70, 74, 78, 80, 105, - 87, 26, 14, 7, 68, 67, 80, 91, 95, 104, 69, - 26, 18, 13, 11, 1, 64, 66, 70, 80, 67, 35, 31, - 26, 8, 10, 65, 73, 84, 10, 55, 49, 45, 34, 25, - 3, 69, 69, 75, 62, 112, 109, 97, 109, 108, 94, - 104, 100, 91, 100, 99, 101, 88, 91, 90, 100, - 96, 85, 78, 79, 79, 76, 71, 67, 67, 2, 69, 69, - 73, 64, 0, 67, 1, 1, 0, 1, 5, 0, 64, 1, 7, 65, - 69, 73, 69, 66, 68, 16, 16, 17, 20, 15, 16, - 14, 15, 14, 4, 12, 12, 67, 2, 58, 58, 55, 59, - 60, 62, 62, 62, 62, 62, 62, 62, 62, 55, 34, - 62, 62, 62, 62, 62, 62, 48, 41, 39, 31, 20, - 12, 1, 71, 62, 62, 62, 62, 62, 62, 62, 62, 52, - 48, 43, 40, 24, 15, 4, 8, 8, 2, 28, 27, 26, - 23, 19, 21, 13, 10, 9, 2, 77, 67, 79, 89, 16, - 1, 67, 81, 77, 70, 76, 69, 2, 71, 76, 65, 2, - 3, 2, 6, 4, 3, 62, 56, 46, 38, 30, 20, 11, 68, - 86, 67, 39, 28, 23, 13, 12, 4, 1, 64, 77, 79, - 74, 67, 74, 64, 4, 68, 72, 1, 5, 6, 5, 9, 9, - 4, 62, 56, 46, 38, 30, 20, 11, 68, 86 }, - - { - - 62, - 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 23, 40, - 52, 56, 20, 98, 66, 66, 70, 8, 7, 67, 3, 12, - 28, 36, 22, 64, 86, 96, 90, 73, 66, 70, 8, 73, - 81, 11, 15, 67, 78, 89, 3, 76, 84, 97, 7, 71, - 80, 4, 78, 81, 91, 65, 76, 70, 84, 68, 2, 22, - 0, 0, 0, 76, 88, 97, 67, 14, 64, 40, 8, 81, - 100, 78, 84, 0, 73, 85, 81, 100, 82, 95, 89, - 102, 80, 85, 89, 89, 24, 65, 73, 102, 71, 95, - 84, 105, 6, 3, 4, 66, 13, 68, 69, 81, 94, 82, - 82, 82, 70, 78, 94, 88, 71, 98, 87, 73, 78, - 92, 95, 0, 74, 68, 66, 3, 9, 65, 70, 83, 95, - 72, 21, 21, 96, 9, 6, 5, 4, 5, 2, 66, 64, 2, - 8, 5, 2, 1, 1, 67, 68, 5, 65, 16, 26, 25, 17, - 10, 19, 12, 16, 12, 0, 15, 13, 23, 89, 16, 29, - 26, 52, 62, 36, 44, 61, 62, 40, 55, 53, 62, - 62, 40, 45, 34, 43, 57, 46, 62, 62, 62, 38, - 34, 55, 40, 62, 9, 62, 62, 62, 62, 62, 58, 55, - 54, 49, 44, 39, 33, 26, 21, 3, 75, 73, 82, 19, - 20, 17, 19, 7, 8, 6, 19, 65, 70, 67, 80, 73, - 109, 96, 3, 7, 10, 1, 69, 73, 77, 80, 103, 86, - 27, 14, 7, 67, 66, 79, 89, 93, 102, 68, 26, - 18, 13, 12, 2, 64, 66, 70, 79, 67, 36, 31, 25, - 8, 10, 65, 73, 83, 9, 55, 49, 44, 33, 24, 3, - 69, 69, 75, 62, 111, 108, 96, 108, 106, 93, - 102, 98, 90, 99, 97, 99, 88, 90, 89, 99, 94, - 84, 78, 79, 78, 75, 71, 67, 67, 1, 69, 69, 73, - 64, 1, 66, 1, 1, 1, 2, 5, 1, 0, 1, 6, 65, 69, - 73, 69, 65, 69, 15, 16, 16, 19, 14, 16, 14, - 14, 14, 4, 11, 10, 68, 1, 56, 57, 54, 58, 58, - 62, 62, 62, 62, 62, 62, 62, 62, 52, 32, 62, - 62, 62, 62, 62, 62, 45, 39, 37, 29, 18, 11, 0, - 72, 62, 62, 62, 62, 62, 62, 60, 59, 49, 46, - 40, 37, 22, 14, 2, 7, 7, 1, 26, 26, 24, 21, - 18, 19, 11, 9, 7, 1, 78, 68, 80, 90, 14, 0, - 68, 81, 76, 70, 76, 68, 3, 71, 76, 64, 3, 3, - 3, 7, 4, 3, 62, 54, 44, 35, 27, 16, 7, 72, 89, - 67, 39, 28, 23, 13, 13, 5, 1, 64, 77, 78, 73, - 67, 73, 0, 5, 67, 71, 1, 5, 6, 5, 10, 9, 4, - 62, 54, 44, 35, 27, 16, 7, 72, 89 }, - - { - - 62, - 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 22, 38, - 51, 56, 19, 96, 66, 66, 69, 8, 7, 67, 2, 10, - 27, 33, 19, 66, 88, 93, 89, 73, 66, 69, 8, 73, - 80, 11, 14, 67, 78, 88, 3, 76, 84, 97, 7, 71, - 80, 4, 78, 80, 91, 65, 76, 70, 84, 68, 2, 22, - 0, 0, 0, 76, 89, 97, 66, 13, 64, 39, 7, 81, - 97, 77, 83, 2, 71, 84, 79, 98, 81, 94, 88, - 100, 80, 85, 88, 89, 24, 65, 72, 100, 71, 95, - 84, 103, 6, 2, 3, 67, 13, 68, 68, 81, 93, 81, - 82, 81, 70, 78, 92, 87, 70, 97, 86, 68, 74, - 89, 92, 0, 74, 68, 66, 3, 9, 64, 70, 83, 93, - 72, 19, 19, 94, 9, 6, 5, 4, 5, 2, 65, 0, 2, 8, - 5, 2, 1, 2, 68, 68, 5, 66, 16, 25, 25, 17, 10, - 19, 12, 16, 11, 0, 14, 12, 23, 89, 15, 28, 25, - 50, 62, 35, 42, 59, 60, 38, 52, 51, 62, 62, - 36, 43, 32, 41, 54, 43, 58, 62, 62, 35, 32, - 51, 38, 62, 7, 62, 62, 62, 62, 62, 56, 53, 52, - 47, 42, 37, 31, 24, 19, 1, 75, 73, 83, 18, 19, - 16, 18, 6, 6, 5, 17, 66, 71, 68, 81, 74, 108, - 94, 4, 8, 10, 1, 68, 73, 77, 79, 101, 85, 27, - 14, 8, 66, 65, 78, 88, 92, 101, 67, 27, 19, - 14, 12, 3, 0, 66, 70, 79, 67, 36, 31, 24, 8, - 10, 65, 73, 83, 9, 54, 48, 43, 32, 24, 3, 69, - 69, 75, 62, 110, 106, 95, 106, 105, 92, 100, - 96, 89, 97, 95, 97, 87, 89, 89, 98, 93, 84, - 78, 79, 78, 75, 71, 67, 67, 1, 69, 69, 74, 0, - 1, 65, 1, 1, 1, 2, 5, 1, 0, 1, 6, 65, 69, 73, - 69, 65, 70, 14, 16, 15, 18, 13, 15, 14, 13, - 13, 4, 11, 9, 68, 0, 55, 56, 53, 56, 56, 62, - 61, 62, 62, 62, 62, 62, 61, 50, 30, 62, 62, - 62, 62, 62, 59, 43, 36, 34, 27, 16, 9, 64, 73, - 62, 62, 62, 62, 62, 62, 57, 56, 47, 43, 38, - 34, 20, 12, 1, 6, 6, 64, 25, 24, 22, 19, 16, - 17, 9, 8, 6, 0, 79, 69, 81, 91, 13, 64, 69, - 81, 76, 69, 75, 67, 4, 71, 75, 64, 3, 3, 3, 8, - 4, 3, 61, 52, 41, 32, 24, 12, 2, 76, 92, 67, - 39, 28, 23, 13, 13, 5, 1, 64, 76, 78, 73, 66, - 73, 0, 6, 67, 71, 1, 5, 6, 5, 10, 9, 4, 61, - 52, 41, 32, 24, 12, 2, 76, 92 }, - - { - - 62, - 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 21, 36, - 50, 56, 19, 94, 66, 66, 68, 7, 6, 67, 1, 8, - 26, 31, 15, 69, 90, 90, 88, 72, 66, 68, 7, 73, - 79, 11, 14, 67, 77, 87, 3, 76, 84, 97, 7, 71, - 80, 4, 78, 80, 90, 65, 76, 70, 84, 67, 2, 22, - 0, 0, 0, 75, 89, 97, 66, 12, 64, 38, 7, 81, - 95, 76, 82, 4, 69, 82, 78, 97, 79, 92, 87, 97, - 80, 84, 88, 88, 24, 65, 71, 98, 71, 94, 83, - 101, 6, 2, 3, 67, 13, 68, 68, 80, 92, 80, 81, - 80, 69, 77, 91, 85, 69, 95, 85, 0, 70, 86, 89, - 1, 73, 67, 65, 3, 9, 64, 70, 82, 91, 72, 17, - 17, 91, 9, 7, 5, 4, 5, 3, 0, 1, 3, 7, 5, 2, 2, - 2, 69, 67, 5, 66, 15, 24, 24, 16, 9, 19, 12, - 16, 10, 1, 13, 12, 22, 89, 15, 27, 24, 48, 62, - 34, 41, 57, 58, 36, 50, 49, 62, 62, 33, 41, - 30, 38, 51, 41, 55, 62, 62, 33, 30, 48, 36, - 62, 6, 62, 62, 62, 61, 60, 54, 51, 50, 45, 39, - 35, 29, 23, 17, 64, 75, 73, 83, 17, 18, 15, - 16, 5, 5, 4, 16, 67, 71, 69, 81, 75, 107, 93, - 5, 8, 10, 2, 68, 72, 76, 78, 99, 83, 27, 15, - 8, 66, 64, 77, 86, 90, 99, 67, 28, 20, 15, 13, - 4, 0, 65, 69, 78, 67, 37, 31, 24, 7, 10, 65, - 73, 82, 9, 54, 47, 42, 31, 24, 3, 68, 69, 74, - 62, 108, 105, 93, 104, 103, 91, 99, 95, 88, - 95, 94, 95, 86, 88, 88, 97, 91, 84, 78, 78, - 77, 74, 71, 68, 67, 0, 69, 69, 74, 0, 1, 64, - 1, 1, 1, 2, 5, 1, 0, 1, 5, 65, 69, 73, 69, 64, - 71, 13, 16, 14, 18, 13, 14, 14, 13, 12, 4, 11, - 8, 68, 64, 54, 55, 52, 54, 54, 62, 59, 61, 62, - 59, 62, 62, 58, 47, 28, 62, 62, 62, 62, 59, - 56, 40, 34, 32, 25, 15, 8, 64, 73, 62, 62, 62, - 62, 59, 59, 55, 53, 45, 41, 36, 31, 18, 10, - 64, 6, 6, 66, 24, 23, 21, 17, 14, 15, 8, 7, 4, - 64, 79, 71, 82, 91, 11, 66, 71, 80, 76, 68, - 75, 66, 5, 70, 74, 0, 4, 3, 4, 9, 4, 3, 60, - 50, 38, 29, 20, 8, 65, 80, 95, 66, 39, 28, 23, - 13, 14, 5, 2, 0, 76, 78, 73, 66, 73, 1, 7, 67, - 71, 2, 6, 6, 6, 11, 9, 4, 60, 50, 38, 29, 20, - 8, 65, 80, 95 }, - - { - - 61, - 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 19, 34, - 49, 56, 19, 92, 66, 65, 67, 7, 6, 67, 1, 7, - 25, 28, 12, 71, 91, 87, 87, 72, 65, 67, 7, 74, - 78, 11, 13, 67, 77, 87, 3, 76, 84, 97, 7, 71, - 79, 4, 78, 79, 90, 65, 76, 70, 84, 67, 2, 22, - 0, 0, 0, 75, 89, 97, 65, 11, 64, 37, 6, 81, - 92, 75, 81, 5, 67, 81, 76, 95, 78, 91, 86, 95, - 80, 84, 87, 88, 24, 65, 70, 96, 71, 93, 83, - 99, 6, 1, 2, 68, 13, 68, 67, 80, 91, 79, 81, - 79, 69, 76, 89, 84, 69, 94, 84, 5, 65, 83, 86, - 1, 73, 67, 65, 3, 9, 0, 69, 82, 89, 72, 15, - 15, 88, 9, 7, 5, 4, 5, 3, 1, 2, 3, 7, 5, 2, 2, - 3, 70, 67, 5, 67, 15, 23, 24, 16, 9, 19, 12, - 16, 9, 1, 12, 11, 22, 89, 15, 27, 24, 46, 61, - 33, 39, 55, 55, 34, 47, 47, 62, 62, 29, 39, - 28, 36, 48, 38, 52, 61, 62, 30, 28, 44, 34, - 62, 4, 60, 62, 60, 58, 57, 52, 49, 48, 43, 37, - 33, 27, 21, 16, 66, 75, 73, 84, 16, 17, 14, - 15, 4, 4, 3, 14, 68, 72, 70, 82, 75, 107, 91, - 6, 9, 10, 2, 67, 72, 76, 78, 97, 82, 27, 15, - 9, 65, 0, 76, 85, 89, 97, 66, 28, 20, 15, 13, - 5, 1, 65, 69, 78, 67, 37, 31, 23, 7, 10, 65, - 73, 82, 9, 53, 47, 41, 30, 24, 3, 68, 69, 74, - 62, 107, 103, 92, 103, 102, 90, 97, 93, 87, - 94, 92, 93, 86, 87, 88, 96, 89, 83, 78, 78, - 77, 74, 71, 68, 67, 0, 69, 69, 75, 1, 2, 0, 1, - 1, 2, 2, 5, 1, 0, 1, 5, 65, 69, 73, 69, 64, - 72, 12, 16, 13, 17, 12, 14, 14, 12, 11, 4, 11, - 7, 68, 65, 53, 54, 51, 53, 52, 60, 57, 59, 59, - 57, 62, 60, 55, 45, 26, 62, 62, 62, 62, 55, - 53, 38, 32, 29, 23, 13, 6, 65, 74, 62, 62, 62, - 60, 56, 57, 52, 50, 42, 38, 33, 28, 16, 8, 65, - 5, 5, 67, 22, 21, 19, 15, 13, 13, 6, 6, 3, 65, - 80, 72, 83, 92, 10, 67, 72, 80, 75, 68, 74, - 65, 6, 70, 74, 0, 4, 3, 4, 10, 4, 3, 59, 48, - 36, 26, 17, 4, 69, 84, 98, 66, 39, 28, 23, 13, - 14, 6, 2, 0, 75, 78, 73, 65, 72, 2, 8, 67, 70, - 2, 6, 6, 6, 11, 9, 4, 59, 48, 36, 26, 17, 4, - 69, 84, 98 }, - - { - - 60, - 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 18, 32, - 48, 56, 19, 90, 66, 65, 66, 7, 5, 67, 0, 5, - 24, 26, 8, 74, 93, 84, 86, 72, 65, 66, 7, 74, - 77, 11, 13, 67, 77, 86, 3, 76, 84, 97, 7, 71, - 79, 4, 78, 79, 90, 65, 76, 70, 84, 67, 2, 22, - 0, 0, 0, 74, 89, 97, 65, 10, 64, 36, 6, 81, - 90, 74, 80, 7, 65, 79, 75, 93, 76, 90, 85, 93, - 80, 84, 87, 88, 24, 65, 69, 94, 71, 92, 82, - 97, 6, 1, 2, 68, 13, 68, 67, 79, 90, 78, 80, - 78, 68, 75, 88, 82, 68, 93, 83, 10, 2, 80, 83, - 1, 73, 67, 64, 3, 9, 0, 69, 81, 87, 72, 13, - 13, 85, 9, 7, 5, 4, 5, 4, 3, 3, 3, 7, 5, 2, 3, - 4, 71, 67, 5, 67, 14, 22, 23, 16, 8, 19, 12, - 16, 8, 1, 11, 10, 21, 89, 15, 26, 23, 44, 58, - 32, 37, 53, 53, 32, 45, 45, 62, 62, 26, 37, - 26, 34, 45, 36, 49, 57, 62, 27, 26, 41, 32, - 62, 2, 58, 62, 58, 56, 55, 50, 47, 46, 41, 35, - 31, 25, 19, 14, 68, 75, 73, 84, 15, 16, 13, - 14, 3, 3, 2, 12, 69, 72, 71, 83, 76, 106, 90, - 7, 9, 10, 2, 66, 71, 75, 77, 95, 81, 27, 15, - 9, 64, 1, 75, 83, 87, 95, 65, 29, 21, 16, 14, - 6, 1, 65, 69, 77, 67, 38, 31, 22, 7, 10, 65, - 73, 81, 9, 53, 46, 40, 29, 24, 3, 68, 69, 74, - 62, 106, 102, 91, 101, 100, 89, 95, 91, 86, - 92, 90, 91, 85, 86, 87, 95, 87, 83, 78, 78, - 76, 73, 71, 68, 67, 64, 69, 69, 75, 1, 2, 1, - 1, 1, 2, 2, 5, 1, 0, 1, 4, 65, 69, 73, 69, 0, - 73, 11, 16, 12, 16, 11, 13, 14, 11, 10, 4, 11, - 6, 68, 66, 52, 53, 50, 51, 50, 58, 55, 57, 57, - 54, 61, 57, 52, 42, 24, 62, 62, 62, 62, 52, - 50, 35, 30, 27, 21, 11, 5, 66, 75, 62, 62, 62, - 58, 53, 54, 50, 47, 40, 36, 31, 25, 14, 6, 67, - 4, 4, 69, 21, 20, 17, 13, 11, 11, 4, 5, 1, 66, - 81, 73, 84, 93, 8, 68, 73, 80, 75, 67, 74, 64, - 7, 70, 73, 1, 5, 3, 5, 11, 4, 3, 58, 46, 33, - 23, 14, 0, 73, 88, 101, 66, 39, 28, 23, 13, - 15, 6, 2, 0, 75, 78, 73, 65, 72, 3, 9, 67, 70, - 2, 6, 6, 6, 12, 9, 4, 58, 46, 33, 23, 14, 0, - 73, 88, 101 }, - - { - - 58, - 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 16, 29, - 47, 56, 18, 89, 67, 65, 66, 6, 4, 67, 64, 3, - 22, 23, 4, 77, 95, 82, 86, 72, 65, 66, 6, 75, - 77, 11, 12, 67, 77, 86, 2, 77, 84, 97, 6, 71, - 79, 4, 78, 79, 90, 65, 76, 71, 84, 67, 2, 22, - 0, 0, 0, 74, 90, 97, 65, 9, 65, 35, 5, 82, 88, - 73, 79, 8, 0, 78, 74, 92, 75, 89, 84, 91, 80, - 84, 87, 88, 24, 65, 69, 92, 71, 92, 82, 96, 5, - 0, 1, 69, 13, 68, 67, 79, 90, 78, 80, 78, 68, - 75, 87, 81, 68, 92, 82, 14, 6, 77, 81, 1, 73, - 67, 64, 2, 9, 0, 69, 81, 85, 72, 11, 11, 83, - 9, 7, 5, 4, 5, 4, 4, 3, 3, 6, 4, 2, 3, 4, 73, - 67, 5, 68, 13, 20, 22, 15, 7, 19, 12, 15, 6, - 1, 10, 9, 20, 89, 14, 25, 22, 41, 54, 30, 35, - 50, 50, 29, 42, 43, 55, 62, 22, 34, 24, 31, - 41, 33, 45, 52, 59, 24, 24, 37, 30, 62, 0, 55, - 59, 55, 53, 52, 47, 44, 43, 39, 32, 28, 23, - 17, 12, 70, 75, 74, 85, 14, 14, 11, 12, 1, 1, - 0, 10, 70, 73, 72, 84, 77, 106, 89, 7, 9, 10, - 2, 66, 71, 75, 77, 93, 80, 27, 15, 9, 64, 1, - 74, 82, 86, 94, 65, 29, 21, 16, 14, 7, 1, 65, - 69, 77, 68, 38, 30, 21, 6, 10, 65, 73, 81, 8, - 52, 45, 38, 28, 23, 3, 68, 69, 74, 62, 105, - 101, 90, 100, 99, 88, 94, 90, 85, 91, 89, 89, - 85, 86, 87, 94, 86, 83, 78, 78, 76, 73, 71, - 69, 68, 65, 69, 70, 76, 1, 2, 2, 1, 0, 2, 2, - 4, 1, 0, 1, 3, 65, 69, 73, 69, 0, 74, 10, 16, - 10, 15, 10, 12, 13, 10, 9, 4, 10, 4, 69, 68, - 50, 51, 49, 49, 48, 55, 52, 54, 54, 51, 58, - 54, 48, 39, 22, 62, 62, 61, 60, 48, 46, 32, - 27, 24, 19, 9, 3, 67, 76, 59, 60, 60, 55, 50, - 51, 47, 43, 37, 33, 28, 22, 12, 4, 69, 3, 3, - 71, 19, 18, 15, 10, 9, 9, 2, 3, 64, 68, 82, - 75, 85, 94, 6, 70, 75, 80, 75, 67, 74, 0, 8, - 70, 73, 1, 5, 3, 5, 11, 4, 2, 56, 44, 30, 19, - 10, 67, 78, 93, 104, 66, 39, 28, 23, 13, 15, - 6, 2, 0, 75, 78, 73, 65, 72, 3, 9, 67, 70, 2, - 6, 6, 6, 12, 8, 3, 56, 44, 30, 19, 10, 67, 78, - 93, 104 }, - - { - - 57, - 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 15, 27, - 46, 57, 18, 87, 67, 64, 65, 6, 4, 66, 64, 2, - 21, 21, 1, 79, 96, 79, 85, 71, 64, 65, 6, 75, - 76, 11, 12, 66, 76, 85, 2, 77, 83, 96, 6, 70, - 78, 4, 77, 78, 89, 64, 75, 71, 83, 66, 2, 22, - 0, 0, 0, 73, 90, 97, 64, 9, 65, 35, 5, 82, 85, - 71, 77, 10, 3, 76, 72, 90, 73, 87, 82, 88, 80, - 83, 86, 87, 24, 65, 68, 89, 70, 91, 81, 94, 5, - 0, 1, 69, 14, 68, 66, 78, 89, 77, 79, 77, 67, - 74, 85, 79, 67, 90, 80, 19, 11, 73, 78, 2, 72, - 66, 0, 2, 10, 1, 68, 80, 82, 71, 9, 10, 80, 9, - 8, 5, 5, 6, 5, 6, 4, 4, 6, 4, 2, 4, 5, 74, 66, - 5, 68, 13, 19, 22, 15, 7, 19, 12, 15, 5, 2, - 10, 9, 20, 89, 14, 25, 22, 39, 51, 29, 34, 48, - 48, 27, 40, 41, 49, 62, 19, 32, 23, 29, 38, - 31, 42, 48, 55, 22, 22, 34, 28, 62, 64, 53, - 57, 53, 51, 50, 45, 42, 41, 37, 30, 26, 22, - 16, 11, 71, 75, 74, 85, 14, 13, 10, 11, 0, 0, - 64, 9, 71, 73, 73, 84, 77, 105, 87, 8, 10, 10, - 3, 65, 70, 74, 76, 90, 78, 28, 16, 10, 0, 2, - 72, 80, 84, 92, 64, 30, 22, 17, 15, 8, 2, 64, - 68, 76, 68, 39, 30, 21, 6, 11, 64, 73, 80, 8, - 52, 45, 37, 27, 23, 4, 67, 68, 73, 62, 103, - 99, 88, 98, 97, 86, 92, 88, 83, 89, 87, 86, - 84, 85, 86, 92, 84, 82, 77, 77, 75, 72, 70, - 69, 68, 65, 69, 70, 76, 2, 3, 3, 2, 0, 3, 3, - 4, 2, 1, 1, 3, 64, 68, 72, 68, 1, 74, 9, 16, - 9, 15, 10, 12, 13, 10, 9, 4, 10, 3, 69, 69, - 49, 50, 49, 48, 47, 53, 50, 52, 52, 49, 56, - 52, 45, 37, 20, 61, 60, 57, 56, 45, 43, 30, - 25, 22, 18, 8, 2, 67, 76, 57, 58, 58, 53, 48, - 49, 45, 40, 35, 31, 26, 20, 11, 3, 70, 3, 3, - 72, 18, 17, 14, 8, 8, 8, 1, 2, 65, 69, 82, 76, - 85, 94, 5, 71, 76, 79, 74, 66, 73, 2, 10, 69, - 72, 2, 6, 4, 6, 12, 4, 2, 55, 42, 28, 16, 7, - 71, 82, 97, 106, 65, 39, 29, 24, 14, 16, 7, 3, - 1, 74, 77, 72, 64, 71, 4, 10, 66, 69, 3, 7, 6, - 7, 13, 8, 3, 55, 42, 28, 16, 7, 71, 82, 97, - 106 }, - - { - - 56, - 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 14, 25, - 45, 57, 18, 85, 67, 64, 64, 6, 3, 66, 65, 0, - 20, 18, 66, 82, 98, 76, 84, 71, 64, 64, 6, 75, - 75, 11, 11, 66, 76, 84, 2, 77, 83, 96, 6, 70, - 78, 4, 77, 78, 89, 64, 75, 71, 83, 66, 2, 22, - 0, 0, 0, 72, 90, 97, 64, 8, 65, 34, 5, 82, 83, - 70, 76, 12, 5, 75, 71, 88, 72, 86, 81, 86, 80, - 83, 86, 87, 24, 65, 67, 87, 70, 90, 80, 92, 5, - 0, 1, 70, 14, 68, 66, 77, 88, 76, 78, 76, 67, - 73, 84, 78, 66, 89, 79, 24, 15, 70, 75, 2, 72, - 66, 0, 2, 10, 1, 68, 80, 80, 71, 7, 8, 77, 9, - 8, 5, 5, 6, 5, 8, 5, 4, 6, 4, 2, 5, 6, 75, 66, - 5, 68, 12, 18, 21, 15, 6, 19, 12, 15, 4, 2, 9, - 8, 19, 89, 14, 24, 21, 37, 48, 28, 32, 46, 46, - 25, 38, 39, 43, 62, 15, 30, 21, 27, 35, 29, - 39, 44, 51, 19, 20, 31, 26, 62, 66, 51, 55, - 51, 49, 48, 43, 40, 39, 35, 28, 24, 20, 14, 9, - 73, 75, 74, 86, 13, 12, 9, 10, 64, 64, 65, 7, - 72, 73, 74, 85, 78, 104, 86, 9, 10, 10, 3, 64, - 69, 73, 75, 88, 77, 28, 16, 10, 1, 3, 71, 78, - 82, 90, 0, 31, 23, 18, 16, 9, 2, 64, 68, 75, - 68, 40, 30, 20, 6, 11, 64, 73, 80, 8, 52, 44, - 36, 26, 23, 4, 67, 68, 73, 62, 102, 98, 87, - 96, 95, 85, 90, 86, 82, 87, 85, 84, 83, 84, - 86, 91, 82, 82, 77, 77, 74, 72, 70, 69, 68, - 66, 69, 70, 76, 2, 3, 4, 2, 0, 3, 3, 4, 2, 1, - 1, 2, 64, 68, 72, 68, 2, 75, 8, 16, 8, 14, 9, - 11, 13, 9, 8, 4, 10, 2, 69, 70, 48, 49, 48, - 46, 45, 51, 48, 50, 50, 46, 53, 49, 42, 34, - 18, 57, 56, 53, 51, 42, 40, 27, 23, 19, 16, 6, - 1, 68, 77, 55, 56, 55, 51, 45, 46, 42, 37, 33, - 28, 24, 17, 9, 1, 72, 2, 2, 74, 17, 16, 12, 6, - 6, 6, 64, 1, 67, 70, 83, 77, 86, 95, 3, 72, - 77, 79, 74, 65, 73, 3, 11, 69, 71, 3, 7, 4, 6, - 13, 4, 2, 54, 40, 25, 13, 4, 75, 86, 101, 109, - 65, 39, 29, 24, 14, 17, 7, 3, 1, 74, 77, 72, - 64, 71, 5, 11, 66, 69, 3, 7, 6, 7, 14, 8, 3, - 54, 40, 25, 13, 4, 75, 86, 101, 109 }, - - { - - 55, - 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 12, 23, - 44, 57, 18, 83, 67, 0, 0, 6, 3, 66, 65, 64, - 19, 16, 69, 84, 99, 73, 83, 71, 0, 0, 6, 76, - 74, 11, 11, 66, 76, 84, 2, 77, 83, 96, 6, 70, - 77, 4, 77, 77, 89, 64, 75, 71, 83, 66, 2, 22, - 0, 0, 0, 72, 90, 97, 0, 7, 65, 33, 4, 82, 80, - 69, 75, 13, 7, 73, 69, 86, 70, 85, 80, 84, 80, - 83, 85, 87, 24, 65, 66, 85, 70, 89, 80, 90, 5, - 64, 0, 70, 14, 68, 65, 77, 87, 75, 78, 75, 66, - 72, 82, 76, 66, 88, 78, 29, 20, 67, 72, 2, 72, - 66, 1, 2, 10, 2, 67, 79, 78, 71, 5, 6, 74, 9, - 8, 5, 5, 6, 6, 9, 6, 4, 6, 4, 2, 5, 7, 76, 66, - 5, 69, 12, 17, 21, 15, 6, 19, 12, 15, 3, 2, 8, - 7, 19, 89, 14, 24, 21, 35, 45, 27, 30, 44, 43, - 23, 35, 37, 36, 62, 12, 28, 19, 25, 32, 26, - 36, 40, 47, 16, 18, 27, 24, 62, 68, 49, 53, - 49, 46, 45, 41, 38, 37, 33, 26, 22, 18, 12, 8, - 75, 75, 74, 86, 12, 11, 8, 9, 65, 65, 66, 5, - 73, 74, 75, 86, 78, 104, 84, 10, 11, 10, 3, 0, - 69, 73, 75, 86, 76, 28, 16, 11, 2, 4, 70, 77, - 81, 88, 1, 31, 23, 18, 16, 10, 3, 64, 68, 75, - 68, 40, 30, 19, 6, 11, 64, 73, 79, 8, 51, 44, - 35, 25, 23, 4, 67, 68, 73, 62, 101, 96, 86, - 95, 94, 84, 88, 84, 81, 86, 83, 82, 83, 83, - 85, 90, 80, 81, 77, 77, 74, 71, 70, 69, 68, - 66, 69, 70, 77, 3, 4, 5, 2, 0, 4, 3, 4, 2, 1, - 1, 2, 64, 68, 72, 68, 2, 76, 7, 16, 7, 13, 8, - 11, 13, 8, 7, 4, 10, 1, 69, 71, 47, 48, 47, - 45, 43, 49, 46, 48, 47, 44, 50, 46, 39, 32, - 16, 53, 52, 49, 46, 38, 37, 25, 21, 17, 14, 4, - 64, 69, 78, 53, 53, 53, 48, 42, 44, 40, 34, - 30, 26, 21, 14, 7, 64, 73, 1, 1, 75, 15, 14, - 10, 4, 5, 4, 66, 0, 68, 71, 84, 78, 87, 96, 2, - 73, 78, 79, 73, 65, 72, 4, 12, 69, 71, 3, 7, - 4, 7, 14, 4, 2, 53, 38, 23, 10, 1, 79, 90, - 105, 112, 65, 39, 29, 24, 14, 17, 8, 3, 1, 73, - 77, 72, 0, 70, 6, 12, 66, 68, 3, 7, 6, 7, 14, - 8, 3, 53, 38, 23, 10, 1, 79, 90, 105, 112 }, - - { - - 53, - 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 11, 21, - 43, 57, 17, 81, 67, 0, 1, 5, 2, 66, 66, 66, - 18, 13, 73, 87, 101, 70, 82, 71, 0, 1, 5, 76, - 73, 11, 10, 66, 75, 83, 2, 77, 83, 96, 6, 70, - 77, 4, 77, 77, 88, 64, 75, 71, 83, 65, 2, 22, - 0, 0, 0, 71, 91, 97, 0, 6, 65, 32, 4, 82, 78, - 68, 74, 15, 9, 72, 68, 85, 69, 83, 79, 82, 80, - 82, 85, 87, 24, 65, 65, 83, 70, 89, 79, 88, 5, - 64, 0, 71, 14, 68, 65, 76, 86, 74, 77, 74, 66, - 72, 81, 75, 65, 87, 77, 34, 24, 64, 69, 2, 71, - 66, 1, 2, 10, 2, 67, 79, 76, 71, 3, 4, 72, 9, - 9, 5, 5, 6, 6, 11, 7, 5, 5, 4, 2, 6, 7, 77, - 66, 5, 69, 11, 16, 20, 14, 5, 19, 12, 15, 2, - 2, 7, 6, 18, 89, 13, 23, 20, 33, 41, 26, 28, - 42, 41, 21, 33, 35, 30, 62, 8, 26, 17, 22, 29, - 24, 32, 35, 43, 13, 16, 24, 22, 62, 69, 47, - 51, 46, 44, 43, 39, 36, 35, 31, 23, 20, 16, - 10, 6, 77, 75, 74, 87, 11, 10, 7, 7, 66, 67, - 67, 4, 74, 74, 76, 86, 79, 103, 83, 11, 11, - 10, 4, 0, 68, 72, 74, 84, 74, 28, 17, 11, 2, - 5, 69, 75, 79, 87, 1, 32, 24, 19, 17, 11, 3, - 64, 67, 74, 68, 41, 30, 19, 5, 11, 64, 73, 79, - 8, 51, 43, 34, 24, 23, 4, 66, 68, 73, 62, 99, - 95, 85, 93, 92, 83, 87, 83, 80, 84, 82, 80, - 82, 82, 85, 89, 79, 81, 77, 77, 73, 71, 70, - 70, 68, 67, 69, 70, 77, 3, 4, 6, 2, 0, 4, 3, - 4, 2, 1, 1, 1, 64, 68, 72, 68, 3, 77, 6, 16, - 6, 13, 7, 10, 13, 7, 6, 4, 10, 0, 69, 72, 46, - 47, 46, 43, 41, 47, 44, 45, 45, 41, 47, 43, - 36, 29, 14, 48, 48, 45, 41, 35, 33, 22, 18, - 14, 12, 2, 65, 70, 78, 50, 51, 50, 46, 39, 41, - 37, 31, 28, 23, 19, 11, 5, 66, 75, 0, 1, 77, - 14, 13, 9, 2, 3, 2, 67, 64, 70, 72, 85, 80, - 88, 96, 0, 75, 80, 78, 73, 64, 72, 5, 13, 69, - 70, 4, 8, 4, 7, 15, 4, 2, 52, 36, 20, 7, 66, - 83, 95, 109, 115, 64, 39, 29, 24, 14, 18, 8, - 3, 1, 73, 77, 72, 0, 70, 6, 13, 66, 68, 4, 8, - 6, 7, 15, 8, 3, 52, 36, 20, 7, 66, 83, 95, - 109, 115 }, - - { - - 52, - 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 10, 19, - 42, 57, 17, 79, 67, 0, 2, 5, 2, 66, 67, 68, - 17, 11, 76, 89, 103, 67, 81, 70, 0, 2, 5, 76, - 72, 11, 10, 66, 75, 82, 2, 77, 83, 96, 6, 70, - 77, 4, 77, 76, 88, 64, 75, 71, 83, 65, 2, 22, - 0, 0, 0, 71, 91, 97, 1, 5, 65, 31, 3, 82, 75, - 67, 73, 17, 11, 70, 66, 83, 67, 82, 78, 79, - 80, 82, 84, 86, 24, 65, 64, 81, 70, 88, 79, - 86, 5, 65, 64, 71, 14, 68, 64, 76, 85, 73, 77, - 73, 65, 71, 79, 73, 64, 85, 76, 39, 28, 2, 66, - 3, 71, 65, 2, 2, 10, 3, 67, 78, 74, 71, 1, 2, - 69, 9, 9, 5, 5, 6, 7, 12, 8, 5, 5, 4, 2, 6, 8, - 78, 65, 5, 70, 11, 15, 20, 14, 5, 19, 12, 15, - 1, 3, 6, 6, 18, 89, 13, 22, 19, 31, 38, 25, - 27, 40, 39, 19, 30, 33, 24, 62, 5, 24, 15, 20, - 26, 21, 29, 31, 39, 11, 14, 20, 20, 62, 71, - 45, 49, 44, 42, 41, 37, 34, 33, 29, 21, 18, - 14, 9, 4, 79, 75, 74, 87, 10, 9, 6, 6, 67, 68, - 68, 2, 75, 75, 77, 87, 80, 102, 81, 12, 12, - 10, 4, 1, 68, 72, 73, 82, 73, 28, 17, 12, 3, - 6, 68, 74, 78, 85, 2, 33, 25, 20, 17, 12, 4, - 0, 67, 74, 68, 41, 30, 18, 5, 11, 64, 73, 78, - 8, 50, 42, 33, 23, 23, 4, 66, 68, 72, 62, 98, - 93, 83, 91, 91, 82, 85, 81, 79, 82, 80, 78, - 81, 81, 84, 88, 77, 81, 77, 76, 73, 70, 70, - 70, 68, 67, 69, 70, 78, 4, 4, 7, 2, 0, 4, 3, - 4, 2, 1, 1, 1, 64, 68, 72, 68, 3, 78, 5, 16, - 5, 12, 7, 9, 13, 7, 5, 4, 10, 64, 69, 73, 45, - 46, 45, 41, 39, 45, 42, 43, 42, 38, 44, 40, - 33, 27, 12, 44, 44, 41, 36, 32, 30, 20, 16, - 12, 10, 1, 67, 70, 79, 48, 48, 48, 44, 36, 38, - 35, 28, 26, 21, 17, 8, 3, 68, 76, 0, 0, 79, - 13, 11, 7, 0, 1, 0, 69, 65, 71, 73, 85, 81, - 89, 97, 64, 76, 81, 78, 73, 0, 71, 6, 14, 68, - 69, 4, 8, 4, 8, 16, 4, 2, 51, 34, 17, 4, 69, - 87, 99, 113, 118, 64, 39, 29, 24, 14, 18, 8, - 4, 2, 72, 77, 72, 1, 70, 7, 14, 66, 68, 4, 8, - 6, 8, 15, 8, 3, 51, 34, 17, 4, 69, 87, 99, - 113, 118 }, - - { - - 51, - 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 8, 17, - 41, 57, 17, 78, 67, 1, 2, 5, 1, 65, 67, 69, - 15, 8, 80, 92, 104, 65, 80, 70, 1, 2, 5, 77, - 72, 11, 9, 66, 75, 82, 2, 77, 82, 95, 6, 69, - 76, 4, 76, 76, 88, 64, 75, 71, 83, 65, 2, 22, - 0, 0, 0, 70, 91, 97, 1, 5, 66, 31, 3, 82, 73, - 66, 72, 18, 14, 69, 65, 81, 66, 81, 77, 77, - 80, 82, 84, 86, 24, 65, 0, 78, 70, 87, 78, 84, - 4, 65, 64, 72, 15, 68, 64, 75, 85, 73, 76, 72, - 65, 70, 78, 72, 64, 84, 75, 44, 33, 5, 0, 3, - 71, 65, 2, 2, 10, 3, 66, 78, 72, 70, 64, 0, - 66, 9, 9, 5, 5, 7, 7, 14, 9, 5, 5, 4, 2, 7, 9, - 79, 65, 5, 70, 10, 14, 19, 14, 4, 19, 12, 15, - 64, 3, 5, 5, 17, 89, 13, 22, 19, 29, 35, 24, - 25, 37, 36, 17, 28, 31, 17, 62, 1, 22, 14, 18, - 22, 19, 26, 27, 34, 8, 12, 17, 18, 62, 73, 43, - 47, 42, 39, 38, 35, 31, 31, 27, 19, 15, 12, 7, - 3, 80, 75, 74, 88, 9, 8, 5, 5, 68, 69, 69, 0, - 76, 75, 78, 88, 80, 102, 80, 13, 12, 10, 4, 2, - 67, 71, 73, 80, 72, 29, 17, 12, 4, 7, 67, 72, - 76, 83, 3, 33, 25, 20, 18, 13, 4, 0, 67, 73, - 68, 42, 30, 17, 5, 11, 64, 73, 78, 7, 50, 42, - 32, 22, 22, 4, 66, 68, 72, 62, 97, 92, 82, 90, - 89, 81, 83, 79, 78, 81, 78, 76, 81, 80, 84, - 87, 75, 80, 77, 76, 72, 70, 70, 70, 68, 68, - 69, 70, 78, 4, 5, 8, 2, 0, 5, 4, 4, 3, 2, 1, - 0, 64, 68, 72, 68, 4, 79, 4, 16, 4, 11, 6, 9, - 13, 6, 5, 4, 9, 66, 70, 74, 43, 45, 44, 40, - 37, 43, 40, 41, 40, 36, 41, 38, 30, 24, 10, - 40, 40, 37, 32, 28, 27, 17, 14, 9, 8, 64, 68, - 71, 80, 46, 46, 45, 41, 33, 36, 32, 25, 23, - 18, 14, 5, 1, 69, 78, 64, 64, 80, 11, 10, 5, - 65, 0, 65, 71, 66, 73, 74, 86, 82, 90, 98, 66, - 77, 82, 78, 72, 0, 71, 7, 15, 68, 69, 5, 9, 4, - 8, 17, 4, 2, 50, 32, 15, 1, 72, 91, 103, 117, - 121, 64, 39, 29, 24, 14, 19, 9, 4, 2, 72, 76, - 71, 1, 69, 8, 15, 65, 67, 4, 8, 6, 8, 16, 8, - 3, 50, 32, 15, 1, 72, 91, 103, 117, 121 }, - - { - - 50, - 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 7, 15, - 40, 57, 17, 76, 67, 1, 3, 4, 1, 65, 68, 71, - 14, 6, 83, 94, 106, 1, 79, 70, 1, 3, 4, 77, - 71, 11, 9, 66, 74, 81, 2, 77, 82, 95, 6, 69, - 76, 4, 76, 75, 87, 64, 75, 71, 83, 64, 2, 22, - 0, 0, 0, 70, 91, 97, 2, 4, 66, 30, 2, 82, 70, - 65, 71, 20, 16, 67, 0, 80, 64, 79, 76, 75, 80, - 81, 83, 86, 24, 65, 1, 76, 70, 86, 78, 82, 4, - 66, 65, 72, 15, 68, 0, 75, 84, 72, 76, 71, 64, - 69, 76, 70, 0, 83, 74, 49, 37, 8, 3, 3, 70, - 65, 3, 2, 10, 4, 66, 77, 70, 70, 66, 65, 0, 9, - 10, 5, 5, 7, 8, 15, 10, 6, 4, 4, 2, 7, 9, 80, - 65, 5, 71, 10, 13, 19, 13, 4, 19, 12, 15, 65, - 3, 4, 4, 17, 89, 13, 21, 18, 27, 32, 23, 23, - 35, 34, 15, 25, 29, 11, 62, 65, 20, 12, 15, - 19, 16, 23, 22, 30, 5, 10, 13, 16, 62, 74, 41, - 45, 40, 37, 36, 33, 29, 29, 25, 16, 13, 10, 5, - 1, 82, 75, 74, 88, 8, 7, 4, 3, 69, 70, 70, 64, - 77, 76, 79, 88, 81, 101, 78, 14, 13, 10, 5, 2, - 67, 71, 72, 78, 70, 29, 18, 13, 4, 8, 66, 71, - 75, 81, 3, 34, 26, 21, 18, 14, 5, 0, 66, 73, - 68, 42, 30, 17, 4, 11, 64, 73, 77, 7, 49, 41, - 31, 21, 22, 4, 65, 68, 72, 62, 95, 90, 81, 88, - 88, 80, 82, 78, 77, 79, 77, 74, 80, 79, 83, - 86, 73, 80, 77, 76, 72, 69, 70, 71, 68, 68, - 69, 70, 79, 5, 5, 9, 2, 0, 5, 4, 4, 3, 2, 1, - 0, 64, 68, 72, 68, 4, 80, 3, 16, 3, 11, 5, 8, - 13, 5, 4, 4, 9, 67, 70, 75, 42, 44, 43, 38, - 35, 41, 38, 38, 37, 33, 38, 35, 27, 22, 8, 35, - 36, 33, 27, 25, 24, 15, 12, 7, 6, 66, 70, 72, - 80, 43, 43, 43, 39, 30, 33, 30, 22, 21, 16, - 12, 2, 64, 71, 79, 65, 64, 82, 10, 8, 4, 67, - 65, 67, 72, 67, 74, 75, 87, 84, 91, 98, 67, - 79, 84, 77, 72, 1, 70, 8, 16, 68, 68, 5, 9, 4, - 9, 18, 4, 2, 49, 30, 12, 65, 76, 95, 107, 121, - 124, 0, 39, 29, 24, 14, 19, 9, 4, 2, 71, 76, - 71, 2, 69, 9, 16, 65, 67, 5, 9, 6, 8, 16, 8, - 3, 49, 30, 12, 65, 76, 95, 107, 121, 124 }, - - { - - 48, - 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 5, 12, - 39, 57, 16, 74, 68, 1, 4, 4, 0, 65, 69, 73, - 13, 3, 87, 97, 108, 4, 78, 70, 1, 4, 4, 78, - 70, 11, 8, 66, 74, 81, 1, 78, 82, 95, 6, 69, - 76, 4, 76, 75, 87, 64, 75, 71, 83, 64, 2, 22, - 0, 0, 0, 69, 92, 97, 2, 3, 66, 29, 2, 83, 68, - 64, 70, 21, 18, 66, 1, 78, 0, 78, 75, 73, 80, - 81, 83, 86, 24, 65, 2, 74, 70, 86, 77, 80, 4, - 66, 65, 73, 15, 68, 0, 74, 83, 71, 75, 71, 64, - 69, 75, 69, 0, 82, 73, 53, 41, 11, 5, 3, 70, - 65, 3, 1, 10, 4, 66, 77, 68, 70, 68, 67, 2, 9, - 10, 5, 5, 7, 8, 17, 10, 6, 4, 3, 2, 8, 10, 82, - 65, 5, 71, 9, 11, 18, 13, 3, 19, 12, 14, 66, - 3, 3, 3, 16, 89, 12, 20, 17, 25, 28, 21, 21, - 33, 31, 12, 23, 27, 4, 62, 69, 18, 10, 13, 16, - 14, 19, 18, 26, 2, 8, 10, 14, 62, 76, 39, 42, - 37, 34, 33, 30, 27, 26, 23, 14, 11, 8, 3, 64, - 84, 75, 75, 89, 7, 5, 3, 2, 70, 72, 72, 66, - 78, 76, 80, 89, 82, 101, 77, 15, 13, 10, 5, 3, - 66, 70, 72, 76, 69, 29, 18, 13, 5, 9, 65, 69, - 73, 80, 4, 34, 26, 21, 19, 15, 5, 0, 66, 72, - 69, 43, 30, 16, 4, 11, 64, 73, 77, 7, 49, 40, - 30, 20, 22, 4, 65, 68, 72, 62, 94, 89, 80, 87, - 86, 79, 80, 76, 76, 78, 75, 72, 80, 79, 83, - 85, 72, 80, 77, 76, 71, 69, 70, 71, 68, 69, - 69, 70, 79, 5, 5, 10, 2, 64, 5, 4, 3, 3, 2, 1, - 64, 64, 68, 72, 68, 5, 81, 2, 16, 1, 10, 4, 7, - 12, 4, 3, 4, 9, 68, 70, 77, 41, 42, 42, 36, - 33, 39, 36, 36, 35, 30, 35, 32, 24, 19, 6, 31, - 32, 28, 22, 21, 20, 12, 9, 4, 4, 68, 71, 73, - 81, 41, 41, 40, 36, 27, 30, 27, 19, 18, 13, 9, - 64, 66, 73, 81, 66, 65, 84, 8, 7, 2, 69, 67, - 69, 74, 69, 76, 77, 88, 85, 92, 99, 69, 80, - 85, 77, 72, 1, 70, 9, 17, 68, 68, 6, 10, 4, 9, - 18, 4, 1, 48, 28, 9, 68, 79, 99, 112, 126, - 126, 0, 39, 29, 24, 14, 20, 9, 4, 2, 71, 76, - 71, 2, 69, 9, 16, 65, 67, 5, 9, 6, 8, 17, 8, - 2, 48, 28, 9, 68, 79, 99, 112, 126, 126 }, - - { - - 47, - 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 4, 10, - 38, 58, 16, 72, 68, 2, 5, 4, 64, 65, 69, 74, - 12, 1, 91, 100, 109, 7, 77, 69, 2, 5, 4, 78, - 69, 11, 8, 65, 74, 80, 1, 78, 82, 95, 6, 69, - 75, 4, 76, 75, 87, 64, 75, 71, 82, 64, 2, 22, - 0, 0, 0, 68, 92, 97, 2, 2, 66, 28, 2, 83, 66, - 1, 69, 23, 20, 64, 2, 76, 2, 77, 73, 70, 80, - 81, 83, 85, 24, 65, 3, 72, 69, 85, 76, 78, 4, - 66, 65, 73, 15, 68, 0, 73, 82, 70, 74, 70, 0, - 68, 74, 67, 1, 80, 72, 58, 46, 15, 8, 4, 70, - 64, 4, 1, 10, 4, 65, 76, 65, 70, 70, 68, 5, 9, - 10, 5, 5, 7, 9, 19, 11, 6, 4, 3, 2, 9, 11, 83, - 64, 5, 71, 8, 10, 17, 13, 2, 19, 12, 14, 67, - 4, 2, 3, 15, 89, 12, 20, 17, 23, 25, 20, 20, - 31, 29, 10, 21, 25, 65, 62, 72, 16, 8, 11, 13, - 12, 16, 14, 22, 0, 6, 7, 12, 62, 78, 37, 40, - 35, 32, 31, 28, 25, 24, 21, 12, 9, 7, 2, 65, - 86, 75, 75, 89, 7, 4, 2, 1, 71, 73, 73, 68, - 79, 76, 81, 90, 82, 100, 76, 16, 13, 10, 5, 4, - 65, 69, 71, 73, 68, 29, 18, 13, 6, 10, 64, 67, - 71, 78, 5, 35, 27, 22, 20, 16, 5, 1, 66, 71, - 69, 44, 30, 15, 4, 12, 0, 73, 76, 7, 49, 40, - 29, 19, 22, 4, 65, 68, 71, 62, 93, 88, 78, 85, - 84, 78, 78, 74, 75, 76, 73, 70, 79, 78, 82, - 84, 70, 79, 76, 75, 70, 68, 70, 71, 68, 70, - 69, 70, 79, 5, 6, 11, 3, 64, 6, 4, 3, 3, 2, 1, - 65, 64, 67, 71, 68, 6, 81, 1, 16, 0, 9, 4, 7, - 12, 4, 2, 4, 9, 69, 70, 78, 40, 41, 42, 35, - 31, 37, 34, 34, 33, 28, 32, 29, 21, 16, 4, 27, - 28, 24, 17, 18, 17, 9, 7, 2, 3, 69, 72, 73, - 82, 39, 39, 38, 34, 25, 28, 25, 16, 16, 11, 7, - 66, 68, 75, 83, 66, 66, 85, 7, 6, 0, 71, 68, - 70, 76, 70, 78, 78, 88, 86, 92, 100, 71, 81, - 86, 77, 71, 2, 70, 10, 19, 67, 67, 7, 11, 4, - 10, 19, 4, 1, 47, 26, 7, 71, 82, 103, 116, - 126, 126, 0, 39, 29, 25, 15, 21, 10, 5, 3, 71, - 76, 71, 2, 68, 10, 17, 65, 66, 5, 9, 6, 9, 18, - 8, 2, 47, 26, 7, 71, 82, 103, 116, 126, 126 }, - - { - - 46, - 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 3, 8, 37, - 58, 16, 70, 68, 2, 6, 3, 64, 65, 70, 76, 11, - 65, 94, 102, 111, 10, 76, 69, 2, 6, 3, 78, 68, - 11, 7, 65, 73, 79, 1, 78, 82, 95, 6, 69, 75, - 4, 76, 74, 86, 64, 75, 71, 82, 0, 2, 22, 0, 0, - 0, 68, 92, 97, 3, 1, 66, 27, 1, 83, 0, 2, 68, - 25, 22, 0, 4, 75, 3, 75, 72, 68, 80, 80, 82, - 85, 24, 65, 4, 70, 69, 84, 76, 76, 4, 67, 66, - 74, 15, 68, 1, 73, 81, 69, 74, 69, 0, 67, 72, - 66, 2, 79, 71, 62, 50, 18, 11, 4, 69, 64, 4, - 1, 10, 5, 65, 76, 0, 70, 72, 70, 8, 9, 11, 5, - 5, 7, 9, 20, 12, 7, 3, 3, 2, 9, 11, 84, 64, 5, - 72, 8, 9, 17, 12, 2, 19, 12, 14, 68, 4, 1, 2, - 15, 89, 12, 19, 16, 21, 22, 19, 18, 29, 27, 8, - 18, 23, 71, 62, 76, 14, 6, 8, 10, 9, 13, 9, - 18, 66, 4, 3, 10, 62, 79, 35, 38, 33, 30, 29, - 26, 23, 22, 19, 9, 7, 5, 0, 67, 88, 75, 75, - 90, 6, 3, 1, 64, 72, 74, 74, 69, 80, 77, 82, - 90, 83, 99, 74, 17, 14, 10, 6, 4, 65, 69, 70, - 71, 66, 29, 19, 14, 6, 11, 0, 66, 70, 76, 5, - 36, 28, 23, 20, 17, 6, 1, 65, 71, 69, 44, 30, - 15, 3, 12, 0, 73, 76, 7, 48, 39, 28, 18, 22, - 4, 64, 68, 71, 62, 91, 86, 77, 83, 83, 77, 77, - 73, 74, 74, 72, 68, 78, 77, 82, 83, 68, 79, - 76, 75, 70, 68, 70, 72, 68, 70, 69, 70, 80, 6, - 6, 12, 3, 64, 6, 4, 3, 3, 2, 1, 65, 64, 67, - 71, 68, 6, 82, 0, 16, 64, 9, 3, 6, 12, 3, 1, - 4, 9, 70, 70, 79, 39, 40, 41, 33, 29, 35, 32, - 31, 30, 25, 29, 26, 18, 14, 2, 22, 24, 20, 12, - 15, 14, 7, 5, 64, 1, 71, 74, 74, 82, 36, 36, - 35, 32, 22, 25, 22, 13, 14, 8, 5, 69, 70, 77, - 84, 67, 66, 87, 6, 4, 64, 73, 70, 72, 77, 71, - 79, 79, 89, 88, 93, 100, 72, 83, 88, 76, 71, - 3, 69, 11, 20, 67, 66, 7, 11, 4, 10, 20, 4, 1, - 46, 24, 4, 74, 86, 107, 120, 126, 126, 1, 39, - 29, 25, 15, 21, 10, 5, 3, 70, 76, 71, 3, 68, - 11, 18, 65, 66, 6, 10, 6, 9, 18, 8, 2, 46, 24, - 4, 74, 86, 107, 120, 126, 126 }, - - { - - 45, - 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 1, 6, 36, - 58, 16, 69, 68, 3, 6, 3, 65, 64, 70, 77, 9, - 67, 98, 105, 112, 12, 75, 69, 3, 6, 3, 79, 68, - 11, 7, 65, 73, 79, 1, 78, 81, 94, 6, 68, 74, - 4, 75, 74, 86, 64, 75, 71, 82, 0, 2, 22, 0, 0, - 0, 67, 92, 97, 3, 1, 67, 27, 1, 83, 2, 3, 67, - 26, 25, 2, 5, 73, 5, 74, 71, 66, 80, 80, 82, - 85, 24, 65, 5, 67, 69, 83, 75, 74, 3, 67, 66, - 74, 16, 68, 1, 72, 81, 69, 73, 68, 1, 66, 71, - 64, 2, 78, 70, 62, 55, 21, 14, 4, 69, 64, 5, - 1, 10, 5, 64, 75, 2, 69, 74, 72, 11, 9, 11, 5, - 5, 8, 10, 22, 13, 7, 3, 3, 2, 10, 12, 85, 64, - 5, 72, 7, 8, 16, 12, 1, 19, 12, 14, 70, 4, 0, - 1, 14, 89, 12, 19, 16, 19, 19, 18, 16, 26, 24, - 6, 16, 21, 78, 62, 79, 12, 5, 6, 6, 7, 10, 5, - 13, 69, 2, 0, 8, 62, 81, 33, 36, 31, 27, 26, - 24, 20, 20, 17, 7, 4, 3, 65, 68, 89, 75, 75, - 90, 5, 2, 0, 65, 73, 75, 75, 71, 81, 77, 83, - 91, 83, 99, 73, 18, 14, 10, 6, 5, 64, 68, 70, - 69, 65, 30, 19, 14, 7, 12, 1, 64, 68, 74, 6, - 36, 28, 23, 21, 18, 6, 1, 65, 70, 69, 45, 30, - 14, 3, 12, 0, 73, 75, 6, 48, 39, 27, 17, 21, - 4, 64, 68, 71, 62, 90, 85, 76, 82, 81, 76, 75, - 71, 73, 73, 70, 66, 78, 76, 81, 82, 66, 78, - 76, 75, 69, 67, 70, 72, 68, 71, 69, 70, 80, 6, - 7, 13, 3, 64, 7, 5, 3, 4, 3, 1, 66, 64, 67, - 71, 68, 7, 83, 64, 16, 65, 8, 2, 6, 12, 2, 1, - 4, 8, 72, 71, 80, 37, 39, 40, 32, 27, 33, 30, - 29, 28, 23, 26, 24, 15, 11, 0, 18, 20, 16, 8, - 11, 11, 4, 3, 66, 64, 73, 75, 75, 83, 34, 34, - 33, 29, 19, 23, 20, 10, 11, 6, 2, 72, 72, 78, - 86, 68, 67, 88, 4, 3, 66, 75, 71, 74, 79, 72, - 81, 80, 90, 89, 94, 101, 74, 84, 89, 76, 70, - 3, 69, 12, 21, 67, 66, 8, 12, 4, 11, 21, 4, 1, - 45, 22, 2, 77, 89, 111, 124, 126, 126, 1, 39, - 29, 25, 15, 22, 11, 5, 3, 70, 75, 70, 3, 67, - 12, 19, 64, 65, 6, 10, 6, 9, 19, 8, 2, 45, 22, - 2, 77, 89, 111, 124, 126, 126 }, - - { - - 43, - 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 0, 4, 35, - 58, 15, 67, 68, 3, 7, 3, 65, 64, 71, 79, 8, - 70, 101, 107, 114, 15, 74, 69, 3, 7, 3, 79, - 67, 11, 6, 65, 73, 78, 1, 78, 81, 94, 6, 68, - 74, 4, 75, 73, 86, 64, 75, 71, 82, 0, 2, 22, - 0, 0, 0, 67, 93, 97, 4, 0, 67, 26, 0, 83, 5, - 4, 66, 28, 27, 3, 7, 71, 6, 73, 70, 64, 80, - 80, 81, 85, 24, 65, 6, 65, 69, 83, 75, 72, 3, - 68, 67, 75, 16, 68, 2, 72, 80, 68, 73, 67, 1, - 66, 69, 0, 3, 77, 69, 62, 59, 24, 17, 4, 69, - 64, 5, 1, 10, 6, 64, 75, 4, 69, 76, 74, 13, 9, - 11, 5, 5, 8, 10, 23, 14, 7, 3, 3, 2, 10, 13, - 86, 64, 5, 73, 7, 7, 16, 12, 1, 19, 12, 14, - 71, 4, 64, 0, 14, 89, 11, 18, 15, 17, 15, 17, - 14, 24, 22, 4, 13, 19, 84, 62, 83, 10, 3, 4, - 3, 4, 6, 1, 9, 72, 0, 67, 6, 62, 83, 31, 34, - 28, 25, 24, 22, 18, 18, 15, 5, 2, 1, 67, 70, - 91, 75, 75, 91, 4, 1, 64, 66, 74, 77, 76, 73, - 82, 78, 84, 92, 84, 98, 71, 19, 15, 10, 6, 6, - 64, 68, 69, 67, 64, 30, 19, 15, 8, 13, 2, 0, - 67, 73, 7, 37, 29, 24, 21, 19, 7, 1, 65, 70, - 69, 45, 30, 13, 3, 12, 0, 73, 75, 6, 47, 38, - 26, 16, 21, 4, 64, 68, 71, 62, 89, 83, 75, 80, - 80, 75, 73, 69, 72, 71, 68, 64, 77, 75, 81, - 81, 65, 78, 76, 75, 69, 67, 70, 72, 68, 71, - 69, 70, 81, 7, 7, 14, 3, 64, 7, 5, 3, 4, 3, 1, - 66, 64, 67, 71, 68, 7, 84, 65, 16, 66, 7, 1, - 5, 12, 1, 0, 4, 8, 73, 71, 81, 36, 38, 39, 30, - 25, 31, 28, 27, 25, 20, 23, 21, 12, 9, 65, 14, - 16, 12, 3, 8, 7, 2, 0, 69, 66, 75, 77, 76, 84, - 32, 31, 30, 27, 16, 20, 17, 7, 9, 3, 0, 75, - 74, 80, 87, 69, 68, 90, 3, 1, 68, 77, 73, 76, - 81, 73, 82, 81, 91, 90, 95, 102, 75, 85, 90, - 76, 70, 4, 68, 13, 22, 67, 65, 8, 12, 4, 11, - 22, 4, 1, 44, 20, 64, 80, 92, 115, 126, 126, - 126, 1, 39, 29, 25, 15, 22, 11, 5, 3, 69, 75, - 70, 4, 67, 12, 20, 64, 65, 6, 10, 6, 9, 19, 8, - 2, 44, 20, 64, 80, 92, 115, 126, 126, 126 }, - - { - - 42, - 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 64, 2, 34, - 58, 15, 65, 68, 3, 8, 2, 66, 64, 72, 81, 7, - 72, 105, 110, 116, 18, 73, 68, 3, 8, 2, 79, - 66, 11, 6, 65, 72, 77, 1, 78, 81, 94, 6, 68, - 74, 4, 75, 73, 85, 64, 75, 71, 82, 1, 2, 22, - 0, 0, 0, 66, 93, 97, 4, 64, 67, 25, 0, 83, 7, - 5, 65, 30, 29, 5, 8, 70, 8, 71, 69, 2, 80, 79, - 81, 84, 24, 65, 7, 0, 69, 82, 74, 70, 3, 68, - 67, 75, 16, 68, 2, 71, 79, 67, 72, 66, 2, 65, - 68, 2, 4, 75, 68, 62, 62, 27, 20, 5, 68, 0, 6, - 1, 10, 6, 64, 74, 6, 69, 78, 76, 16, 9, 12, 5, - 5, 8, 11, 25, 15, 8, 2, 3, 2, 11, 13, 87, 0, - 5, 73, 6, 6, 15, 11, 0, 19, 12, 14, 72, 5, 65, - 0, 13, 89, 11, 17, 14, 15, 12, 16, 13, 22, 20, - 2, 11, 17, 90, 62, 86, 8, 1, 1, 0, 2, 3, 67, - 5, 74, 65, 70, 4, 62, 84, 29, 32, 26, 23, 22, - 20, 16, 16, 13, 2, 0, 64, 68, 72, 93, 75, 75, - 91, 3, 0, 65, 68, 75, 78, 77, 74, 83, 78, 85, - 92, 85, 97, 70, 20, 15, 10, 7, 6, 0, 67, 68, - 65, 1, 30, 20, 15, 8, 14, 3, 2, 65, 71, 7, 38, - 30, 25, 22, 20, 7, 2, 64, 69, 69, 46, 30, 13, - 2, 12, 0, 73, 74, 6, 47, 37, 25, 15, 21, 4, 0, - 68, 70, 62, 87, 82, 73, 78, 78, 74, 72, 68, - 71, 69, 67, 1, 76, 74, 80, 80, 0, 78, 76, 74, - 68, 66, 70, 73, 68, 72, 69, 70, 81, 7, 7, 15, - 3, 64, 7, 5, 3, 4, 3, 1, 67, 64, 67, 71, 68, - 8, 85, 66, 16, 67, 7, 1, 4, 12, 1, 64, 4, 8, - 74, 71, 82, 35, 37, 38, 28, 23, 29, 26, 24, - 23, 17, 20, 18, 9, 6, 67, 9, 12, 8, 65, 5, 4, - 64, 65, 71, 68, 76, 78, 76, 84, 29, 29, 28, - 25, 13, 17, 15, 4, 7, 1, 65, 78, 76, 82, 89, - 69, 68, 92, 2, 0, 69, 79, 75, 78, 82, 74, 84, - 82, 91, 92, 96, 102, 77, 87, 92, 75, 70, 5, - 68, 14, 23, 66, 64, 9, 13, 4, 12, 23, 4, 1, - 43, 18, 67, 83, 96, 119, 126, 126, 126, 2, 39, - 29, 25, 15, 23, 11, 6, 4, 69, 75, 70, 4, 67, - 13, 21, 64, 65, 7, 11, 6, 10, 20, 8, 2, 43, - 18, 67, 83, 96, 119, 126, 126, 126 }, - - { - - 41, - 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 66, 0, - 33, 58, 15, 0, 68, 4, 9, 2, 66, 64, 72, 82, 6, - 75, 108, 112, 117, 21, 72, 68, 4, 9, 2, 80, - 65, 11, 5, 65, 72, 77, 1, 78, 81, 94, 6, 68, - 73, 4, 75, 72, 85, 64, 75, 71, 82, 1, 2, 22, - 0, 0, 0, 66, 93, 97, 5, 65, 67, 24, 64, 83, - 10, 6, 64, 31, 31, 6, 10, 68, 9, 70, 68, 4, - 80, 79, 80, 84, 24, 65, 8, 2, 69, 81, 74, 68, - 3, 69, 68, 76, 16, 68, 3, 71, 78, 66, 72, 65, - 2, 64, 66, 3, 4, 74, 67, 62, 62, 30, 23, 5, - 68, 0, 6, 1, 10, 7, 0, 74, 8, 69, 80, 78, 19, - 9, 12, 5, 5, 8, 11, 26, 16, 8, 2, 3, 2, 11, - 14, 88, 0, 5, 74, 6, 5, 15, 11, 0, 19, 12, 14, - 73, 5, 66, 64, 13, 89, 11, 17, 14, 13, 9, 15, - 11, 20, 17, 0, 8, 15, 97, 62, 90, 6, 64, 64, - 66, 64, 0, 71, 1, 77, 67, 74, 2, 62, 86, 27, - 30, 24, 20, 19, 18, 14, 14, 11, 0, 65, 66, 70, - 73, 95, 75, 75, 92, 2, 64, 66, 69, 76, 79, 78, - 76, 84, 79, 86, 93, 85, 97, 68, 21, 16, 10, 7, - 7, 0, 67, 68, 0, 2, 30, 20, 16, 9, 15, 4, 3, - 64, 69, 8, 38, 30, 25, 22, 21, 8, 2, 64, 69, - 69, 46, 30, 12, 2, 12, 0, 73, 74, 6, 46, 37, - 24, 14, 21, 4, 0, 68, 70, 62, 86, 80, 72, 77, - 77, 73, 70, 66, 70, 68, 65, 3, 76, 73, 80, 79, - 2, 77, 76, 74, 68, 66, 70, 73, 68, 72, 69, 70, - 82, 8, 8, 16, 3, 64, 8, 5, 3, 4, 3, 1, 67, 64, - 67, 71, 68, 8, 86, 67, 16, 68, 6, 0, 4, 12, 0, - 65, 4, 8, 75, 71, 83, 34, 36, 37, 27, 21, 27, - 24, 22, 20, 15, 17, 15, 6, 4, 69, 5, 8, 4, 70, - 1, 1, 66, 67, 74, 70, 78, 80, 77, 85, 27, 26, - 25, 22, 10, 15, 12, 1, 4, 65, 68, 81, 78, 84, - 90, 70, 69, 93, 0, 65, 71, 81, 76, 80, 84, 75, - 85, 83, 92, 93, 97, 103, 78, 88, 93, 75, 69, - 5, 67, 15, 24, 66, 64, 9, 13, 4, 12, 24, 4, 1, - 42, 16, 69, 86, 99, 123, 126, 126, 126, 2, 39, - 29, 25, 15, 23, 12, 6, 4, 68, 75, 70, 5, 66, - 14, 22, 64, 64, 7, 11, 6, 10, 20, 8, 2, 42, - 16, 69, 86, 99, 123, 126, 126, 126 }, - - { - - 40, - 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 67, 65, - 32, 58, 15, 2, 68, 4, 10, 2, 67, 64, 73, 84, - 5, 77, 112, 115, 119, 24, 71, 68, 4, 10, 2, - 80, 64, 11, 5, 65, 72, 76, 1, 78, 81, 94, 6, - 68, 73, 4, 75, 72, 85, 64, 75, 71, 82, 1, 2, - 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 23, 64, - 83, 12, 7, 0, 33, 33, 8, 11, 66, 11, 69, 67, - 6, 80, 79, 80, 84, 24, 65, 9, 4, 69, 80, 73, - 66, 3, 69, 68, 76, 16, 68, 3, 70, 77, 65, 71, - 64, 3, 0, 65, 5, 5, 73, 66, 62, 62, 33, 26, 5, - 68, 0, 7, 1, 10, 7, 0, 73, 10, 69, 82, 80, 22, - 9, 12, 5, 5, 8, 12, 28, 17, 8, 2, 3, 2, 12, - 15, 89, 0, 5, 74, 5, 4, 14, 11, 64, 19, 12, - 14, 74, 5, 67, 65, 12, 89, 11, 16, 13, 11, 6, - 14, 9, 18, 15, 65, 6, 13, 103, 62, 93, 4, 66, - 66, 69, 66, 66, 75, 66, 80, 69, 77, 0, 62, 88, - 25, 28, 22, 18, 17, 16, 12, 12, 9, 65, 67, 68, - 72, 75, 97, 75, 75, 92, 1, 65, 67, 70, 77, 80, - 79, 78, 85, 79, 87, 94, 86, 96, 67, 22, 16, - 10, 7, 8, 1, 66, 67, 2, 3, 30, 20, 16, 10, 16, - 5, 5, 1, 67, 9, 39, 31, 26, 23, 22, 8, 2, 64, - 68, 69, 47, 30, 11, 2, 12, 0, 73, 73, 6, 46, - 36, 23, 13, 21, 4, 0, 68, 70, 62, 85, 79, 71, - 75, 75, 72, 68, 64, 69, 66, 0, 5, 75, 72, 79, - 78, 4, 77, 76, 74, 67, 65, 70, 73, 68, 73, 69, - 70, 82, 8, 8, 17, 3, 64, 8, 5, 3, 4, 3, 1, 68, - 64, 67, 71, 68, 9, 87, 68, 16, 69, 5, 64, 3, - 12, 64, 66, 4, 8, 76, 71, 84, 33, 35, 36, 25, - 19, 25, 22, 20, 18, 12, 14, 12, 3, 1, 71, 1, - 4, 0, 75, 65, 65, 69, 69, 76, 72, 80, 81, 78, - 86, 25, 24, 23, 20, 7, 12, 10, 65, 2, 67, 70, - 84, 80, 86, 92, 71, 70, 95, 64, 66, 73, 83, - 78, 82, 86, 76, 87, 84, 93, 94, 98, 104, 80, - 89, 94, 75, 69, 6, 67, 16, 25, 66, 0, 10, 14, - 4, 13, 25, 4, 1, 41, 14, 72, 89, 102, 126, - 126, 126, 126, 2, 39, 29, 25, 15, 24, 12, 6, - 4, 68, 75, 70, 5, 66, 15, 23, 64, 64, 7, 11, - 6, 10, 21, 8, 2, 41, 14, 72, 89, 102, 126, - 126, 126, 126 }, - - { - - 38, - 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 69, 68, - 31, 58, 14, 3, 69, 4, 10, 1, 68, 64, 74, 86, - 3, 80, 116, 118, 121, 26, 71, 68, 4, 10, 1, - 81, 64, 11, 4, 65, 72, 76, 0, 79, 81, 94, 5, - 68, 73, 4, 75, 72, 85, 64, 75, 72, 82, 1, 2, - 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 22, 65, - 84, 14, 8, 1, 34, 35, 9, 12, 65, 12, 68, 66, - 8, 80, 79, 80, 84, 24, 65, 9, 6, 69, 80, 73, - 65, 2, 70, 69, 77, 16, 68, 3, 70, 77, 65, 71, - 64, 3, 0, 64, 6, 5, 72, 65, 62, 62, 36, 28, 5, - 68, 0, 7, 0, 10, 7, 0, 73, 12, 69, 84, 82, 24, - 9, 12, 5, 5, 8, 12, 29, 17, 8, 1, 2, 2, 12, - 15, 91, 0, 5, 75, 4, 2, 13, 10, 65, 19, 12, - 13, 76, 5, 68, 66, 11, 89, 10, 15, 12, 8, 2, - 12, 7, 15, 12, 68, 3, 11, 110, 62, 97, 1, 68, - 69, 73, 69, 70, 80, 71, 83, 71, 81, 65, 62, - 90, 22, 25, 19, 15, 14, 13, 9, 9, 7, 68, 70, - 70, 74, 77, 99, 75, 76, 93, 0, 67, 69, 72, 79, - 82, 81, 80, 86, 80, 88, 95, 87, 96, 66, 22, - 16, 10, 7, 8, 1, 66, 67, 4, 4, 30, 20, 16, 10, - 16, 6, 6, 2, 66, 9, 39, 31, 26, 23, 23, 8, 2, - 64, 68, 70, 47, 29, 10, 1, 12, 0, 73, 73, 5, - 45, 35, 21, 12, 20, 4, 0, 68, 70, 62, 84, 78, - 70, 74, 74, 71, 67, 0, 68, 65, 1, 7, 75, 72, - 79, 77, 5, 77, 76, 74, 67, 65, 70, 74, 69, 74, - 69, 71, 83, 8, 8, 18, 3, 65, 8, 5, 2, 4, 3, 1, - 69, 64, 67, 71, 68, 9, 88, 69, 16, 71, 4, 65, - 2, 11, 65, 67, 4, 7, 78, 72, 86, 31, 33, 35, - 23, 17, 22, 19, 17, 15, 9, 11, 9, 64, 65, 73, - 67, 0, 68, 80, 69, 69, 72, 72, 79, 74, 82, 83, - 79, 87, 22, 21, 20, 17, 4, 9, 7, 69, 64, 70, - 73, 87, 82, 88, 94, 72, 71, 97, 66, 68, 75, - 86, 80, 84, 88, 78, 89, 86, 94, 96, 99, 105, - 82, 91, 96, 75, 69, 6, 67, 17, 26, 66, 0, 10, - 14, 4, 13, 25, 4, 0, 39, 12, 75, 93, 106, 126, - 126, 126, 126, 2, 39, 29, 25, 15, 24, 12, 6, - 4, 68, 75, 70, 5, 66, 15, 23, 64, 64, 7, 11, - 6, 10, 21, 7, 1, 39, 12, 75, 93, 106, 126, - 126, 126, 126 }, - - { - - 37, - 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 70, 70, - 30, 59, 14, 5, 69, 5, 11, 1, 68, 0, 74, 87, 2, - 82, 119, 120, 122, 29, 70, 67, 5, 11, 1, 81, - 0, 11, 4, 64, 71, 75, 0, 79, 80, 93, 5, 67, - 72, 4, 74, 71, 84, 0, 74, 72, 81, 2, 2, 22, 0, - 0, 0, 64, 94, 97, 6, 67, 68, 22, 65, 84, 17, - 10, 3, 36, 38, 11, 14, 0, 14, 66, 64, 11, 80, - 78, 79, 83, 24, 65, 10, 9, 68, 79, 72, 0, 2, - 70, 69, 77, 17, 68, 4, 69, 76, 64, 70, 0, 4, - 1, 1, 8, 6, 70, 0, 62, 62, 40, 31, 6, 67, 1, - 8, 0, 11, 8, 1, 72, 15, 68, 86, 83, 27, 9, 13, - 5, 6, 9, 13, 31, 18, 9, 1, 2, 2, 13, 16, 92, - 1, 5, 75, 4, 1, 13, 10, 65, 19, 12, 13, 77, 6, - 68, 66, 11, 89, 10, 15, 12, 6, 64, 11, 6, 13, - 10, 70, 1, 9, 116, 62, 100, 64, 69, 71, 76, - 71, 73, 84, 75, 85, 73, 84, 67, 62, 91, 20, - 23, 17, 13, 12, 11, 7, 7, 5, 70, 72, 71, 75, - 78, 100, 75, 76, 93, 0, 68, 70, 73, 80, 83, - 82, 81, 87, 80, 89, 95, 87, 95, 64, 23, 17, - 10, 8, 9, 2, 65, 66, 7, 6, 31, 21, 17, 11, 17, - 8, 8, 4, 64, 10, 40, 32, 27, 24, 24, 9, 3, 0, - 67, 70, 48, 29, 10, 1, 13, 1, 73, 72, 5, 45, - 35, 20, 11, 20, 5, 1, 67, 69, 62, 82, 76, 68, - 72, 72, 69, 65, 2, 66, 0, 3, 10, 74, 71, 78, - 75, 7, 76, 75, 73, 66, 64, 69, 74, 69, 74, 69, - 71, 83, 9, 9, 19, 4, 65, 9, 6, 2, 5, 4, 1, 69, - 0, 66, 70, 67, 10, 88, 70, 16, 72, 4, 65, 2, - 11, 65, 67, 4, 7, 79, 72, 87, 30, 32, 35, 22, - 16, 20, 17, 15, 13, 7, 9, 7, 67, 67, 75, 71, - 66, 72, 84, 72, 72, 74, 74, 81, 75, 83, 84, - 79, 87, 20, 19, 18, 15, 2, 7, 5, 72, 66, 72, - 75, 89, 83, 89, 95, 72, 71, 98, 67, 69, 76, - 88, 81, 85, 89, 79, 90, 87, 94, 97, 99, 105, - 83, 92, 97, 74, 68, 7, 66, 19, 28, 65, 1, 11, - 15, 5, 14, 26, 4, 0, 38, 10, 77, 96, 109, 126, - 126, 126, 126, 3, 39, 30, 26, 16, 25, 13, 7, - 5, 67, 74, 69, 6, 65, 16, 24, 0, 0, 8, 12, 6, - 11, 22, 7, 1, 38, 10, 77, 96, 109, 126, 126, - 126, 126 }, - - { - - 36, - 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 71, 72, - 29, 59, 14, 7, 69, 5, 12, 1, 69, 0, 75, 89, 1, - 85, 123, 123, 124, 32, 69, 67, 5, 12, 1, 81, - 1, 11, 3, 64, 71, 74, 0, 79, 80, 93, 5, 67, - 72, 4, 74, 71, 84, 0, 74, 72, 81, 2, 2, 22, 0, - 0, 0, 0, 94, 97, 6, 68, 68, 21, 65, 84, 19, - 11, 4, 38, 40, 12, 15, 2, 15, 65, 0, 13, 80, - 78, 79, 83, 24, 65, 11, 11, 68, 78, 71, 2, 2, - 70, 69, 78, 17, 68, 4, 68, 75, 0, 69, 1, 4, 2, - 2, 9, 7, 69, 1, 62, 62, 43, 34, 6, 67, 1, 8, - 0, 11, 8, 1, 72, 17, 68, 88, 85, 30, 9, 13, 5, - 6, 9, 13, 33, 19, 9, 1, 2, 2, 14, 17, 93, 1, - 5, 75, 3, 0, 12, 10, 66, 19, 12, 13, 78, 6, - 69, 67, 10, 89, 10, 14, 11, 4, 67, 10, 4, 11, - 8, 72, 64, 7, 122, 62, 104, 66, 71, 73, 79, - 73, 76, 88, 79, 88, 75, 87, 69, 62, 93, 18, - 21, 15, 11, 10, 9, 5, 5, 3, 72, 74, 73, 77, - 80, 102, 75, 76, 94, 64, 69, 71, 74, 81, 84, - 83, 83, 88, 80, 90, 96, 88, 94, 0, 24, 17, 10, - 8, 10, 3, 64, 65, 9, 7, 31, 21, 17, 12, 18, 9, - 10, 6, 1, 11, 41, 33, 28, 25, 25, 9, 3, 0, 66, - 70, 49, 29, 9, 1, 13, 1, 73, 72, 5, 45, 34, - 19, 10, 20, 5, 1, 67, 69, 62, 81, 75, 67, 70, - 70, 68, 0, 4, 65, 2, 5, 12, 73, 70, 78, 74, 9, - 76, 75, 73, 65, 64, 69, 74, 69, 75, 69, 71, - 83, 9, 9, 20, 4, 65, 9, 6, 2, 5, 4, 1, 70, 0, - 66, 70, 67, 11, 89, 71, 16, 73, 3, 66, 1, 11, - 66, 68, 4, 7, 80, 72, 88, 29, 31, 34, 20, 14, - 18, 15, 13, 11, 4, 6, 4, 70, 70, 77, 75, 70, - 76, 89, 75, 75, 77, 76, 84, 77, 85, 85, 80, - 88, 18, 17, 15, 13, 64, 4, 2, 75, 68, 75, 77, - 92, 85, 91, 97, 73, 72, 100, 68, 70, 78, 90, - 83, 87, 91, 80, 92, 88, 95, 98, 100, 106, 85, - 93, 98, 74, 68, 8, 66, 20, 29, 65, 2, 12, 16, - 5, 14, 27, 4, 0, 37, 8, 80, 99, 112, 126, 126, - 126, 126, 3, 39, 30, 26, 16, 26, 13, 7, 5, 67, - 74, 69, 6, 65, 17, 25, 0, 0, 8, 12, 6, 11, 23, - 7, 1, 37, 8, 80, 99, 112, 126, 126, 126, 126 }, - - { - - 35, - 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 73, 74, - 28, 59, 14, 9, 69, 6, 13, 1, 69, 0, 75, 90, 0, - 87, 126, 125, 125, 35, 68, 67, 6, 13, 1, 82, - 2, 11, 3, 64, 71, 74, 0, 79, 80, 93, 5, 67, - 71, 4, 74, 70, 84, 0, 74, 72, 81, 2, 2, 22, 0, - 0, 0, 0, 94, 97, 7, 69, 68, 20, 66, 84, 22, - 12, 5, 39, 42, 14, 17, 4, 17, 64, 1, 15, 80, - 78, 78, 83, 24, 65, 12, 13, 68, 77, 71, 4, 2, - 71, 70, 78, 17, 68, 5, 68, 74, 1, 69, 2, 5, 3, - 4, 11, 7, 68, 2, 62, 62, 46, 37, 6, 67, 1, 9, - 0, 11, 9, 2, 71, 19, 68, 90, 87, 33, 9, 13, 5, - 6, 9, 14, 34, 20, 9, 1, 2, 2, 14, 18, 94, 1, - 5, 76, 3, 64, 12, 10, 66, 19, 12, 13, 79, 6, - 70, 68, 10, 89, 10, 14, 11, 2, 70, 9, 2, 9, 5, - 74, 67, 5, 126, 62, 107, 68, 73, 75, 82, 76, - 79, 92, 83, 91, 77, 91, 71, 62, 95, 16, 19, - 13, 8, 7, 7, 3, 3, 1, 74, 76, 75, 79, 81, 104, - 75, 76, 94, 65, 70, 72, 75, 82, 85, 84, 85, - 89, 81, 91, 97, 88, 94, 2, 25, 18, 10, 8, 11, - 3, 64, 65, 11, 8, 31, 21, 18, 13, 19, 10, 11, - 7, 3, 12, 41, 33, 28, 25, 26, 10, 3, 0, 66, - 70, 49, 29, 8, 1, 13, 1, 73, 71, 5, 44, 34, - 18, 9, 20, 5, 1, 67, 69, 62, 80, 73, 66, 69, - 69, 67, 2, 6, 64, 3, 7, 14, 73, 69, 77, 73, - 11, 75, 75, 73, 65, 0, 69, 74, 69, 75, 69, 71, - 84, 10, 10, 21, 4, 65, 10, 6, 2, 5, 4, 1, 70, - 0, 66, 70, 67, 11, 90, 72, 16, 74, 2, 67, 1, - 11, 67, 69, 4, 7, 81, 72, 89, 28, 30, 33, 19, - 12, 16, 13, 11, 8, 2, 3, 1, 73, 72, 79, 79, - 74, 80, 94, 79, 78, 79, 78, 86, 79, 87, 87, - 81, 89, 16, 14, 13, 10, 67, 2, 0, 78, 71, 77, - 80, 95, 87, 93, 98, 74, 73, 101, 70, 72, 80, - 92, 84, 89, 93, 81, 93, 89, 96, 99, 101, 107, - 86, 94, 99, 74, 67, 8, 65, 21, 30, 65, 2, 12, - 16, 5, 15, 28, 4, 0, 36, 6, 82, 102, 115, 126, - 126, 126, 126, 3, 39, 30, 26, 16, 26, 14, 7, - 5, 66, 74, 69, 7, 64, 18, 26, 0, 1, 8, 12, 6, - 11, 23, 7, 1, 36, 6, 82, 102, 115, 126, 126, - 126, 126 }, - - { - - 33, - 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 74, 76, - 27, 59, 13, 11, 69, 6, 14, 0, 70, 0, 76, 92, - 64, 90, 126, 126, 126, 38, 67, 67, 6, 14, 0, - 82, 3, 11, 2, 64, 70, 73, 0, 79, 80, 93, 5, - 67, 71, 4, 74, 70, 83, 0, 74, 72, 81, 3, 2, - 22, 0, 0, 0, 1, 95, 97, 7, 70, 68, 19, 66, 84, - 24, 13, 6, 41, 44, 15, 18, 5, 18, 1, 2, 17, - 80, 77, 78, 83, 24, 65, 13, 15, 68, 77, 70, 6, - 2, 71, 70, 79, 17, 68, 5, 67, 73, 2, 68, 3, 5, - 3, 5, 12, 8, 67, 3, 62, 62, 49, 40, 6, 66, 1, - 9, 0, 11, 9, 2, 71, 21, 68, 92, 89, 35, 9, 14, - 5, 6, 9, 14, 36, 21, 10, 0, 2, 2, 15, 18, 95, - 1, 5, 76, 2, 65, 11, 9, 67, 19, 12, 13, 80, 6, - 71, 69, 9, 89, 9, 13, 10, 0, 74, 8, 0, 7, 3, - 76, 69, 3, 126, 62, 111, 70, 75, 78, 85, 78, - 83, 97, 87, 94, 79, 94, 73, 62, 96, 14, 17, - 10, 6, 5, 5, 1, 1, 64, 77, 78, 77, 81, 83, - 106, 75, 76, 95, 66, 71, 73, 77, 83, 87, 85, - 86, 90, 81, 92, 97, 89, 93, 3, 26, 18, 10, 9, - 11, 4, 0, 64, 13, 10, 31, 22, 18, 13, 20, 11, - 13, 9, 4, 12, 42, 34, 29, 26, 27, 10, 3, 1, - 65, 70, 50, 29, 8, 0, 13, 1, 73, 71, 5, 44, - 33, 17, 8, 20, 5, 2, 67, 69, 62, 78, 72, 65, - 67, 67, 66, 3, 7, 0, 5, 8, 16, 72, 68, 77, 72, - 12, 75, 75, 73, 64, 0, 69, 75, 69, 76, 69, 71, - 84, 10, 10, 22, 4, 65, 10, 6, 2, 5, 4, 1, 71, - 0, 66, 70, 67, 12, 91, 73, 16, 75, 2, 68, 0, - 11, 68, 70, 4, 7, 82, 72, 90, 27, 29, 32, 17, - 10, 14, 11, 8, 6, 64, 0, 65, 76, 75, 81, 84, - 78, 84, 99, 82, 82, 82, 81, 89, 81, 89, 88, - 82, 89, 13, 12, 10, 8, 70, 64, 66, 81, 73, 80, - 82, 98, 89, 95, 100, 75, 73, 103, 71, 73, 81, - 94, 86, 91, 94, 82, 95, 90, 97, 101, 102, 107, - 88, 96, 101, 73, 67, 9, 65, 22, 31, 65, 3, 13, - 17, 5, 15, 29, 4, 0, 35, 4, 85, 105, 119, 126, - 126, 126, 126, 4, 39, 30, 26, 16, 27, 14, 7, - 5, 66, 74, 69, 7, 64, 18, 27, 0, 1, 9, 13, 6, - 11, 24, 7, 1, 35, 4, 85, 105, 119, 126, 126, - 126, 126 }, - - { - - 32, - 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 75, 78, - 26, 59, 13, 13, 69, 6, 15, 0, 70, 0, 77, 94, - 65, 92, 126, 126, 126, 41, 66, 66, 6, 15, 0, - 82, 4, 11, 2, 64, 70, 72, 0, 79, 80, 93, 5, - 67, 71, 4, 74, 69, 83, 0, 74, 72, 81, 3, 2, - 22, 0, 0, 0, 1, 95, 97, 8, 71, 68, 18, 67, 84, - 27, 14, 7, 43, 46, 17, 20, 7, 20, 2, 3, 20, - 80, 77, 77, 82, 24, 65, 14, 17, 68, 76, 70, 8, - 2, 72, 71, 79, 17, 68, 6, 67, 72, 3, 68, 4, 6, - 4, 7, 14, 9, 65, 4, 62, 62, 52, 43, 7, 66, 2, - 10, 0, 11, 10, 2, 70, 23, 68, 94, 91, 38, 9, - 14, 5, 6, 9, 15, 37, 22, 10, 0, 2, 2, 15, 19, - 96, 2, 5, 77, 2, 66, 11, 9, 67, 19, 12, 13, - 81, 7, 72, 69, 9, 89, 9, 12, 9, 65, 77, 7, 64, - 5, 1, 78, 72, 1, 126, 62, 114, 72, 77, 80, 88, - 81, 86, 101, 91, 96, 81, 98, 75, 62, 98, 12, - 15, 8, 4, 3, 3, 64, 64, 66, 79, 80, 79, 82, - 85, 108, 75, 76, 95, 67, 72, 74, 78, 84, 88, - 86, 88, 91, 82, 93, 98, 90, 92, 5, 27, 19, 10, - 9, 12, 4, 0, 0, 15, 11, 31, 22, 19, 14, 21, - 12, 14, 10, 6, 13, 43, 35, 30, 26, 28, 11, 4, - 1, 65, 70, 50, 29, 7, 0, 13, 1, 73, 70, 5, 43, - 32, 16, 7, 20, 5, 2, 67, 68, 62, 77, 70, 0, - 65, 66, 65, 5, 9, 1, 7, 10, 18, 71, 67, 76, - 71, 14, 75, 75, 72, 64, 1, 69, 75, 69, 76, 69, - 71, 85, 11, 10, 23, 4, 65, 10, 6, 2, 5, 4, 1, - 71, 0, 66, 70, 67, 12, 92, 74, 16, 76, 1, 68, - 64, 11, 68, 71, 4, 7, 83, 72, 91, 26, 28, 31, - 15, 8, 12, 9, 6, 3, 67, 66, 68, 79, 77, 83, - 88, 82, 88, 104, 85, 85, 84, 83, 91, 83, 90, - 90, 82, 90, 11, 9, 8, 6, 73, 67, 68, 84, 75, - 82, 84, 101, 91, 97, 101, 75, 74, 105, 72, 75, - 83, 96, 88, 93, 96, 83, 96, 91, 97, 102, 103, - 108, 89, 97, 102, 73, 67, 10, 64, 23, 32, 64, - 4, 13, 17, 5, 16, 30, 4, 0, 34, 2, 88, 108, - 122, 126, 126, 126, 126, 4, 39, 30, 26, 16, - 27, 14, 8, 6, 65, 74, 69, 8, 64, 19, 28, 0, 1, - 9, 13, 6, 12, 24, 7, 1, 34, 2, 88, 108, 122, - 126, 126, 126, 126 }, - - { - - 31, - 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 77, 80, - 25, 59, 13, 14, 69, 7, 15, 0, 71, 1, 77, 95, - 67, 95, 126, 126, 126, 43, 65, 66, 7, 15, 0, - 83, 4, 11, 1, 64, 70, 72, 0, 79, 79, 92, 5, - 66, 70, 4, 73, 69, 83, 0, 74, 72, 81, 3, 2, - 22, 0, 0, 0, 2, 95, 97, 8, 71, 69, 18, 67, 84, - 29, 15, 8, 44, 49, 18, 21, 9, 21, 3, 4, 22, - 80, 77, 77, 82, 24, 65, 15, 20, 68, 75, 69, - 10, 1, 72, 71, 80, 18, 68, 6, 66, 72, 3, 67, - 5, 6, 5, 8, 15, 9, 64, 5, 62, 62, 55, 46, 7, - 66, 2, 10, 0, 11, 10, 3, 70, 25, 67, 96, 93, - 41, 9, 14, 5, 6, 10, 15, 39, 23, 10, 0, 2, 2, - 16, 20, 97, 2, 5, 77, 1, 67, 10, 9, 68, 19, - 12, 13, 83, 7, 73, 70, 8, 89, 9, 12, 9, 67, - 80, 6, 66, 2, 65, 80, 74, 64, 126, 62, 118, - 74, 78, 82, 92, 83, 89, 105, 96, 99, 83, 101, - 77, 62, 100, 10, 13, 6, 1, 0, 1, 67, 66, 68, - 81, 83, 81, 84, 86, 109, 75, 76, 96, 68, 73, - 75, 79, 85, 89, 87, 90, 92, 82, 94, 99, 90, - 92, 6, 28, 19, 10, 9, 13, 5, 1, 0, 17, 12, 32, - 22, 19, 15, 22, 13, 16, 12, 8, 14, 43, 35, 30, - 27, 29, 11, 4, 1, 64, 70, 51, 29, 6, 0, 13, 1, - 73, 70, 4, 43, 32, 15, 6, 19, 5, 2, 67, 68, - 62, 76, 69, 1, 64, 64, 64, 7, 11, 2, 8, 12, - 20, 71, 66, 76, 70, 16, 74, 75, 72, 0, 1, 69, - 75, 69, 77, 69, 71, 85, 11, 11, 24, 4, 65, 11, - 7, 2, 6, 5, 1, 72, 0, 66, 70, 67, 13, 93, 75, - 16, 77, 0, 69, 64, 11, 69, 71, 4, 6, 85, 73, - 92, 24, 27, 30, 14, 6, 10, 7, 4, 1, 69, 69, - 70, 82, 80, 85, 92, 86, 92, 108, 89, 88, 87, - 85, 94, 85, 92, 91, 83, 91, 9, 7, 5, 3, 76, - 69, 71, 87, 78, 85, 87, 104, 93, 98, 103, 76, - 75, 106, 74, 76, 85, 98, 89, 95, 98, 84, 98, - 92, 98, 103, 104, 109, 91, 98, 103, 73, 66, - 10, 64, 24, 33, 64, 4, 14, 18, 5, 16, 31, 4, - 0, 33, 0, 90, 111, 125, 126, 126, 126, 126, 4, - 39, 30, 26, 16, 28, 15, 8, 6, 65, 73, 68, 8, - 0, 20, 29, 1, 2, 9, 13, 6, 12, 25, 7, 1, 33, - 0, 90, 111, 125, 126, 126, 126, 126 }, - - { - - 30, - 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 78, 82, - 24, 59, 13, 16, 69, 7, 16, 64, 71, 1, 78, 97, - 68, 97, 126, 126, 126, 46, 64, 66, 7, 16, 64, - 83, 5, 11, 1, 64, 69, 71, 0, 79, 79, 92, 5, - 66, 70, 4, 73, 68, 82, 0, 74, 72, 81, 4, 2, - 22, 0, 0, 0, 2, 95, 97, 9, 72, 69, 17, 68, 84, - 32, 16, 9, 46, 51, 20, 23, 10, 23, 5, 5, 24, - 80, 76, 76, 82, 24, 65, 16, 22, 68, 74, 69, - 12, 1, 73, 72, 80, 18, 68, 7, 66, 71, 4, 67, - 6, 7, 6, 10, 17, 10, 0, 6, 62, 62, 58, 49, 7, - 65, 2, 11, 0, 11, 11, 3, 69, 27, 67, 98, 95, - 44, 9, 15, 5, 6, 10, 16, 40, 24, 11, 64, 2, 2, - 16, 20, 98, 2, 5, 78, 1, 68, 10, 8, 68, 19, - 12, 13, 84, 7, 74, 71, 8, 89, 9, 11, 8, 69, - 83, 5, 68, 0, 67, 82, 77, 66, 126, 62, 121, - 76, 80, 85, 95, 86, 92, 110, 100, 102, 85, - 105, 79, 62, 101, 8, 11, 4, 64, 65, 64, 69, - 68, 70, 84, 85, 83, 86, 88, 111, 75, 76, 96, - 69, 74, 76, 81, 86, 90, 88, 91, 93, 83, 95, - 99, 91, 91, 8, 29, 20, 10, 10, 13, 5, 1, 1, - 19, 14, 32, 23, 20, 15, 23, 14, 17, 13, 10, - 14, 44, 36, 31, 27, 30, 12, 4, 2, 64, 70, 51, - 29, 6, 64, 13, 1, 73, 69, 4, 42, 31, 14, 5, - 19, 5, 3, 67, 68, 62, 74, 67, 2, 1, 0, 0, 8, - 12, 3, 10, 13, 22, 70, 65, 75, 69, 18, 74, 75, - 72, 0, 2, 69, 76, 69, 77, 69, 71, 86, 12, 11, - 25, 4, 65, 11, 7, 2, 6, 5, 1, 72, 0, 66, 70, - 67, 13, 94, 76, 16, 78, 0, 70, 65, 11, 70, 72, - 4, 6, 86, 73, 93, 23, 26, 29, 12, 4, 8, 5, 1, - 65, 72, 72, 73, 85, 82, 87, 97, 90, 96, 113, - 92, 91, 89, 87, 96, 87, 94, 93, 84, 91, 6, 4, - 3, 1, 79, 72, 73, 90, 80, 87, 89, 107, 95, - 100, 104, 77, 75, 108, 75, 78, 86, 100, 91, - 97, 99, 85, 99, 93, 99, 105, 105, 109, 92, - 100, 105, 72, 66, 11, 0, 25, 34, 64, 5, 14, - 18, 5, 17, 32, 4, 0, 32, 65, 93, 114, 126, - 126, 126, 126, 126, 5, 39, 30, 26, 16, 28, 15, - 8, 6, 64, 73, 68, 9, 0, 21, 30, 1, 2, 10, 14, - 6, 12, 25, 7, 1, 32, 65, 93, 114, 126, 126, - 126, 126, 126 }, - - { - - 28, - 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 80, 85, - 23, 59, 12, 18, 70, 7, 17, 64, 72, 1, 79, 99, - 69, 100, 126, 126, 126, 49, 0, 66, 7, 17, 64, - 84, 6, 11, 0, 64, 69, 71, 64, 80, 79, 92, 5, - 66, 70, 4, 73, 68, 82, 0, 74, 72, 81, 4, 2, - 22, 0, 0, 0, 3, 96, 97, 9, 73, 69, 16, 68, 85, - 34, 17, 10, 47, 53, 21, 24, 12, 24, 6, 6, 26, - 80, 76, 76, 82, 24, 65, 17, 24, 68, 74, 68, - 14, 1, 73, 72, 81, 18, 68, 7, 65, 70, 5, 66, - 6, 7, 6, 11, 18, 10, 1, 7, 62, 62, 61, 51, 7, - 65, 2, 11, 64, 11, 11, 3, 69, 29, 67, 100, 97, - 46, 9, 15, 5, 6, 10, 16, 42, 24, 11, 64, 1, 2, - 17, 21, 100, 2, 5, 78, 0, 70, 9, 8, 69, 19, - 12, 12, 85, 7, 75, 72, 7, 89, 8, 10, 7, 71, - 87, 3, 70, 65, 70, 85, 79, 68, 126, 62, 125, - 78, 82, 87, 98, 88, 96, 114, 104, 105, 87, - 108, 81, 62, 103, 6, 8, 1, 67, 68, 67, 71, 71, - 72, 86, 87, 85, 88, 90, 113, 75, 77, 97, 70, - 76, 77, 82, 87, 92, 90, 93, 94, 83, 96, 100, - 92, 91, 9, 30, 20, 10, 10, 14, 6, 2, 1, 21, - 15, 32, 23, 20, 16, 24, 15, 19, 15, 11, 15, - 44, 36, 31, 28, 31, 12, 4, 2, 0, 71, 52, 29, - 5, 64, 13, 1, 73, 69, 4, 42, 30, 13, 4, 19, 5, - 3, 67, 68, 62, 73, 66, 3, 2, 2, 1, 10, 14, 4, - 11, 15, 24, 70, 65, 75, 68, 19, 74, 75, 72, 1, - 2, 69, 76, 69, 78, 69, 71, 86, 12, 11, 26, 4, - 66, 11, 7, 1, 6, 5, 1, 73, 0, 66, 70, 67, 14, - 95, 77, 16, 80, 64, 71, 66, 10, 71, 73, 4, 6, - 87, 73, 95, 22, 24, 28, 10, 2, 6, 3, 64, 67, - 75, 75, 76, 88, 85, 89, 101, 94, 101, 118, 96, - 95, 92, 90, 99, 89, 96, 94, 85, 92, 4, 2, 0, - 65, 82, 75, 76, 93, 83, 90, 92, 110, 97, 102, - 106, 78, 76, 110, 77, 79, 88, 102, 93, 99, - 101, 87, 101, 95, 100, 106, 106, 110, 94, 101, - 106, 72, 66, 11, 0, 26, 35, 64, 5, 15, 19, 5, - 17, 32, 4, 64, 31, 67, 96, 117, 126, 126, 126, - 126, 126, 5, 39, 30, 26, 16, 29, 15, 8, 6, 64, - 73, 68, 9, 0, 21, 30, 1, 2, 10, 14, 6, 12, 26, - 7, 0, 31, 67, 96, 117, 126, 126, 126, 126, 126 }, - - { - - 27, - 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 81, 87, - 22, 60, 12, 20, 70, 8, 18, 64, 73, 1, 79, 100, - 70, 102, 126, 126, 126, 52, 1, 65, 8, 18, 64, - 84, 7, 11, 0, 0, 69, 70, 64, 80, 79, 92, 5, - 66, 69, 4, 73, 68, 82, 0, 74, 72, 80, 4, 2, - 22, 0, 0, 0, 4, 96, 97, 9, 74, 69, 15, 68, 85, - 36, 19, 11, 49, 55, 23, 25, 14, 26, 7, 8, 29, - 80, 76, 76, 81, 24, 65, 18, 26, 67, 73, 67, - 16, 1, 73, 72, 81, 18, 68, 7, 64, 69, 6, 65, - 7, 8, 7, 12, 20, 11, 3, 8, 62, 62, 62, 54, 8, - 65, 3, 12, 64, 11, 11, 4, 68, 32, 67, 102, 98, - 49, 9, 15, 5, 6, 10, 17, 44, 25, 11, 64, 1, 2, - 18, 22, 101, 3, 5, 78, 64, 71, 8, 8, 70, 19, - 12, 12, 86, 8, 76, 72, 6, 89, 8, 10, 7, 73, - 90, 2, 71, 67, 72, 87, 81, 70, 126, 62, 126, - 80, 84, 89, 101, 90, 99, 118, 108, 107, 89, - 111, 83, 62, 105, 4, 6, 64, 69, 70, 69, 73, - 73, 74, 88, 89, 86, 89, 91, 115, 75, 77, 97, - 70, 77, 78, 83, 88, 93, 91, 95, 95, 83, 97, - 101, 92, 90, 10, 31, 20, 10, 10, 15, 7, 3, 2, - 24, 16, 32, 23, 20, 17, 25, 16, 21, 17, 13, - 16, 45, 37, 32, 29, 32, 12, 5, 2, 1, 71, 53, - 29, 4, 64, 14, 2, 73, 68, 4, 42, 30, 12, 3, - 19, 5, 3, 67, 67, 62, 72, 65, 5, 4, 4, 2, 12, - 16, 5, 13, 17, 26, 69, 64, 74, 67, 21, 73, 74, - 71, 2, 3, 69, 76, 69, 79, 69, 71, 86, 12, 12, - 27, 5, 66, 12, 7, 1, 6, 5, 1, 74, 0, 65, 69, - 67, 15, 95, 78, 16, 81, 65, 71, 66, 10, 71, - 74, 4, 6, 88, 73, 96, 21, 23, 28, 9, 0, 4, 1, - 66, 69, 77, 78, 79, 91, 88, 91, 105, 98, 105, - 123, 99, 98, 95, 92, 101, 90, 97, 95, 85, 93, - 2, 0, 65, 67, 84, 77, 78, 96, 85, 92, 94, 112, - 99, 104, 108, 78, 77, 111, 78, 80, 90, 104, - 94, 100, 103, 88, 103, 96, 100, 107, 106, 111, - 96, 102, 107, 72, 65, 12, 0, 27, 37, 0, 6, 16, - 20, 5, 18, 33, 4, 64, 30, 69, 98, 120, 126, - 126, 126, 126, 126, 5, 39, 30, 27, 17, 30, 16, - 9, 7, 64, 73, 68, 9, 1, 22, 31, 1, 3, 10, 14, - 6, 13, 27, 7, 0, 30, 69, 98, 120, 126, 126, - 126, 126, 126 }, - - { - - 26, - 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 82, 89, - 21, 60, 12, 22, 70, 8, 19, 65, 73, 1, 80, 102, - 71, 105, 126, 126, 126, 55, 2, 65, 8, 19, 65, - 84, 8, 11, 64, 0, 68, 69, 64, 80, 79, 92, 5, - 66, 69, 4, 73, 67, 81, 0, 74, 72, 80, 5, 2, - 22, 0, 0, 0, 4, 96, 97, 10, 75, 69, 14, 69, - 85, 39, 20, 12, 51, 57, 24, 27, 15, 27, 9, 9, - 31, 80, 75, 75, 81, 24, 65, 19, 28, 67, 72, - 67, 18, 1, 74, 73, 82, 18, 68, 8, 64, 68, 7, - 65, 8, 8, 8, 14, 21, 12, 4, 9, 62, 62, 62, 57, - 8, 64, 3, 12, 64, 11, 12, 4, 68, 34, 67, 104, - 100, 52, 9, 16, 5, 6, 10, 17, 45, 26, 12, 65, - 1, 2, 18, 22, 102, 3, 5, 79, 64, 72, 8, 7, 70, - 19, 12, 12, 87, 8, 77, 73, 6, 89, 8, 9, 6, 75, - 93, 1, 73, 69, 74, 89, 84, 72, 126, 62, 126, - 82, 86, 92, 104, 93, 102, 123, 112, 110, 91, - 115, 85, 62, 106, 2, 4, 66, 71, 72, 71, 75, - 75, 76, 91, 91, 88, 91, 93, 117, 75, 77, 98, - 71, 78, 79, 85, 89, 94, 92, 96, 96, 84, 98, - 101, 93, 89, 12, 32, 21, 10, 11, 15, 7, 3, 3, - 26, 18, 32, 24, 21, 17, 26, 17, 22, 18, 15, - 16, 46, 38, 33, 29, 33, 13, 5, 3, 1, 71, 53, - 29, 4, 65, 14, 2, 73, 68, 4, 41, 29, 11, 2, - 19, 5, 4, 67, 67, 62, 70, 0, 6, 6, 5, 3, 13, - 17, 6, 15, 18, 28, 68, 0, 74, 66, 23, 73, 74, - 71, 2, 3, 69, 77, 69, 79, 69, 71, 87, 13, 12, - 28, 5, 66, 12, 7, 1, 6, 5, 1, 74, 0, 65, 69, - 67, 15, 96, 79, 16, 82, 65, 72, 67, 10, 72, - 75, 4, 6, 89, 73, 97, 20, 22, 27, 7, 65, 2, - 64, 69, 72, 80, 81, 82, 94, 90, 93, 110, 102, - 109, 126, 102, 101, 97, 94, 104, 92, 99, 97, - 86, 93, 64, 66, 68, 69, 87, 80, 81, 99, 87, - 95, 96, 115, 101, 106, 109, 79, 77, 113, 79, - 82, 91, 106, 96, 102, 104, 89, 104, 97, 101, - 109, 107, 111, 97, 104, 109, 71, 65, 13, 1, - 28, 38, 0, 7, 16, 20, 5, 18, 34, 4, 64, 29, - 71, 101, 123, 126, 126, 126, 126, 126, 6, 39, - 30, 27, 17, 30, 16, 9, 7, 0, 73, 68, 10, 1, - 23, 32, 1, 3, 11, 15, 6, 13, 27, 7, 0, 29, 71, - 101, 123, 126, 126, 126, 126, 126 }, - - { - - 25, - 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 84, 91, - 20, 60, 12, 23, 70, 9, 19, 65, 74, 2, 80, 103, - 73, 107, 126, 126, 126, 57, 3, 65, 9, 19, 65, - 85, 8, 11, 64, 0, 68, 69, 64, 80, 78, 91, 5, - 65, 68, 4, 72, 67, 81, 0, 74, 72, 80, 5, 2, - 22, 0, 0, 0, 5, 96, 97, 10, 75, 70, 14, 69, - 85, 41, 21, 13, 52, 60, 26, 28, 17, 29, 10, - 10, 33, 80, 75, 75, 81, 24, 65, 20, 31, 67, - 71, 66, 20, 0, 74, 73, 82, 19, 68, 8, 0, 68, - 7, 64, 9, 9, 9, 15, 23, 12, 5, 10, 62, 62, 62, - 60, 8, 64, 3, 13, 64, 11, 12, 5, 67, 36, 66, - 106, 102, 55, 9, 16, 5, 6, 11, 18, 47, 27, 12, - 65, 1, 2, 19, 23, 103, 3, 5, 79, 65, 73, 7, 7, - 71, 19, 12, 12, 89, 8, 78, 74, 5, 89, 8, 9, 6, - 77, 96, 0, 75, 72, 77, 91, 86, 74, 126, 62, - 126, 84, 87, 94, 108, 95, 105, 126, 117, 113, - 93, 118, 87, 62, 108, 0, 2, 68, 74, 75, 73, - 78, 77, 78, 93, 94, 90, 93, 94, 118, 75, 77, - 98, 72, 79, 80, 86, 90, 95, 93, 98, 97, 84, - 99, 102, 93, 89, 13, 33, 21, 10, 11, 16, 8, 4, - 3, 28, 19, 33, 24, 21, 18, 27, 18, 24, 20, 17, - 17, 46, 38, 33, 30, 34, 13, 5, 3, 2, 71, 54, - 29, 3, 65, 14, 2, 73, 67, 3, 41, 29, 10, 1, - 18, 5, 4, 67, 67, 62, 69, 1, 7, 7, 7, 4, 15, - 19, 7, 16, 20, 30, 68, 1, 73, 65, 25, 72, 74, - 71, 3, 4, 69, 77, 69, 80, 69, 71, 87, 13, 13, - 29, 5, 66, 13, 8, 1, 7, 6, 1, 75, 0, 65, 69, - 67, 16, 97, 80, 16, 83, 66, 73, 67, 10, 73, - 75, 4, 5, 91, 74, 98, 18, 21, 26, 6, 67, 0, - 66, 71, 74, 82, 84, 84, 97, 93, 95, 114, 106, - 113, 126, 106, 104, 100, 96, 106, 94, 101, 98, - 87, 94, 66, 68, 70, 72, 90, 82, 83, 102, 90, - 97, 99, 118, 103, 107, 111, 80, 78, 114, 81, - 83, 93, 108, 97, 104, 106, 90, 106, 98, 102, - 110, 108, 112, 99, 105, 110, 71, 64, 13, 1, - 29, 39, 0, 7, 17, 21, 5, 19, 35, 4, 64, 28, - 73, 103, 126, 126, 126, 126, 126, 126, 6, 39, - 30, 27, 17, 31, 17, 9, 7, 0, 72, 67, 10, 2, - 24, 33, 2, 4, 11, 15, 6, 13, 28, 7, 0, 28, 73, - 103, 126, 126, 126, 126, 126, 126 }, - - { - - 23, - 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 85, 93, - 19, 60, 11, 25, 70, 9, 20, 65, 74, 2, 81, 105, - 74, 110, 126, 126, 126, 60, 4, 65, 9, 20, 65, - 85, 9, 11, 65, 0, 68, 68, 64, 80, 78, 91, 5, - 65, 68, 4, 72, 66, 81, 0, 74, 72, 80, 5, 2, - 22, 0, 0, 0, 5, 97, 97, 11, 76, 70, 13, 70, - 85, 44, 22, 14, 54, 62, 27, 30, 19, 30, 11, - 11, 35, 80, 75, 74, 81, 24, 65, 21, 33, 67, - 71, 66, 22, 0, 75, 74, 83, 19, 68, 9, 0, 67, - 8, 64, 10, 9, 9, 17, 24, 13, 6, 11, 62, 62, - 62, 62, 8, 64, 3, 13, 64, 11, 13, 5, 67, 38, - 66, 108, 104, 57, 9, 16, 5, 6, 11, 18, 48, 28, - 12, 65, 1, 2, 19, 24, 104, 3, 5, 80, 65, 74, - 7, 7, 71, 19, 12, 12, 90, 8, 79, 75, 5, 89, 7, - 8, 5, 79, 100, 64, 77, 74, 79, 93, 89, 76, - 126, 62, 126, 86, 89, 96, 111, 98, 109, 126, - 121, 116, 95, 122, 89, 62, 110, 65, 0, 71, 76, - 77, 75, 80, 79, 80, 95, 96, 92, 95, 96, 120, - 75, 77, 99, 73, 80, 81, 87, 91, 97, 94, 100, - 98, 85, 100, 103, 94, 88, 15, 34, 22, 10, 11, - 17, 8, 4, 4, 30, 20, 33, 24, 22, 19, 28, 19, - 25, 21, 18, 18, 47, 39, 34, 30, 35, 14, 5, 3, - 2, 71, 54, 29, 2, 65, 14, 2, 73, 67, 3, 40, - 28, 9, 0, 18, 5, 4, 67, 67, 62, 68, 3, 8, 9, - 8, 5, 17, 21, 8, 18, 22, 32, 67, 2, 73, 64, - 26, 72, 74, 71, 3, 4, 69, 77, 69, 80, 69, 71, - 88, 14, 13, 30, 5, 66, 13, 8, 1, 7, 6, 1, 75, - 0, 65, 69, 67, 16, 98, 81, 16, 84, 67, 74, 68, - 10, 74, 76, 4, 5, 92, 74, 99, 17, 20, 25, 4, - 69, 65, 68, 73, 77, 85, 87, 87, 100, 95, 97, - 118, 110, 117, 126, 109, 108, 102, 99, 109, - 96, 103, 100, 88, 95, 68, 71, 73, 74, 93, 85, - 86, 105, 92, 100, 101, 121, 105, 109, 112, 81, - 79, 116, 82, 85, 95, 110, 99, 106, 108, 91, - 107, 99, 103, 111, 109, 113, 100, 106, 111, - 71, 64, 14, 2, 30, 40, 0, 8, 17, 21, 5, 19, - 36, 4, 64, 27, 75, 106, 126, 126, 126, 126, - 126, 126, 6, 39, 30, 27, 17, 31, 17, 9, 7, 1, - 72, 67, 11, 2, 24, 34, 2, 4, 11, 15, 6, 13, - 28, 7, 0, 27, 75, 106, 126, 126, 126, 126, - 126, 126 }, - - { - - 22, - 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 86, 95, - 18, 60, 11, 27, 70, 9, 21, 66, 75, 2, 82, 107, - 75, 112, 126, 126, 126, 62, 5, 64, 9, 21, 66, - 85, 10, 11, 65, 0, 67, 67, 64, 80, 78, 91, 5, - 65, 68, 4, 72, 66, 80, 0, 74, 72, 80, 6, 2, - 22, 0, 0, 0, 6, 97, 97, 11, 77, 70, 12, 70, - 85, 46, 23, 15, 56, 62, 29, 31, 20, 32, 13, - 12, 38, 80, 74, 74, 80, 24, 65, 22, 35, 67, - 70, 65, 24, 0, 75, 74, 83, 19, 68, 9, 1, 66, - 9, 0, 11, 10, 10, 18, 26, 14, 8, 12, 62, 62, - 62, 62, 9, 0, 4, 14, 64, 11, 13, 5, 66, 40, - 66, 110, 106, 60, 9, 17, 5, 6, 11, 19, 50, 29, - 13, 66, 1, 2, 20, 24, 105, 4, 5, 80, 66, 75, - 6, 6, 72, 19, 12, 12, 91, 9, 80, 75, 4, 89, 7, - 7, 4, 81, 103, 65, 78, 76, 81, 95, 91, 78, - 126, 62, 126, 88, 91, 99, 114, 100, 112, 126, - 125, 118, 97, 125, 91, 62, 111, 67, 65, 73, - 78, 79, 77, 82, 81, 82, 98, 98, 94, 96, 98, - 122, 75, 77, 99, 74, 81, 82, 89, 92, 98, 95, - 101, 99, 85, 101, 103, 95, 87, 16, 35, 22, 10, - 12, 17, 9, 5, 5, 32, 22, 33, 25, 22, 19, 29, - 20, 27, 23, 20, 18, 48, 40, 35, 31, 36, 14, 6, - 4, 3, 71, 55, 29, 2, 66, 14, 2, 73, 66, 3, 40, - 27, 8, 64, 18, 5, 5, 67, 66, 62, 66, 4, 10, - 11, 10, 6, 18, 22, 9, 20, 23, 34, 66, 3, 72, - 0, 28, 72, 74, 70, 4, 5, 69, 78, 69, 81, 69, - 71, 88, 14, 13, 31, 5, 66, 13, 8, 1, 7, 6, 1, - 76, 0, 65, 69, 67, 17, 99, 82, 16, 85, 67, 74, - 69, 10, 74, 77, 4, 5, 93, 74, 100, 16, 19, 24, - 2, 71, 67, 70, 76, 79, 88, 90, 90, 103, 98, - 99, 123, 114, 121, 126, 112, 111, 105, 101, - 111, 98, 104, 101, 88, 95, 71, 73, 75, 76, 96, - 88, 88, 108, 94, 102, 103, 124, 107, 111, 114, - 81, 79, 118, 83, 86, 96, 112, 101, 108, 109, - 92, 109, 100, 103, 113, 110, 113, 102, 108, - 113, 70, 64, 15, 2, 31, 41, 1, 9, 18, 22, 5, - 20, 37, 4, 64, 26, 77, 109, 126, 126, 126, - 126, 126, 126, 7, 39, 30, 27, 17, 32, 17, 10, - 8, 1, 72, 67, 11, 2, 25, 35, 2, 4, 12, 16, 6, - 14, 29, 7, 0, 26, 77, 109, 126, 126, 126, 126, - 126, 126 }, - - { - - 21, - 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 88, 97, - 17, 60, 11, 29, 70, 10, 22, 66, 75, 2, 82, - 108, 76, 115, 126, 126, 126, 62, 6, 64, 10, - 22, 66, 86, 11, 11, 66, 0, 67, 67, 64, 80, 78, - 91, 5, 65, 67, 4, 72, 65, 80, 0, 74, 72, 80, - 6, 2, 22, 0, 0, 0, 6, 97, 97, 12, 78, 70, 11, - 71, 85, 49, 24, 16, 57, 62, 30, 33, 22, 33, - 14, 13, 40, 80, 74, 73, 80, 24, 65, 23, 37, - 67, 69, 65, 26, 0, 76, 75, 84, 19, 68, 10, 1, - 65, 10, 0, 12, 10, 11, 20, 27, 14, 9, 13, 62, - 62, 62, 62, 9, 0, 4, 14, 64, 11, 14, 6, 66, - 42, 66, 112, 108, 62, 9, 17, 5, 6, 11, 19, 51, - 30, 13, 66, 1, 2, 20, 25, 106, 4, 5, 81, 66, - 76, 6, 6, 72, 19, 12, 12, 92, 9, 81, 76, 4, - 89, 7, 7, 4, 83, 106, 66, 80, 78, 84, 97, 94, - 80, 126, 62, 126, 90, 93, 101, 117, 103, 115, - 126, 126, 121, 99, 126, 93, 62, 113, 69, 67, - 75, 81, 82, 79, 84, 83, 84, 100, 100, 96, 98, - 99, 124, 75, 77, 100, 75, 82, 83, 90, 93, 99, - 96, 103, 100, 86, 102, 104, 95, 87, 18, 36, - 23, 10, 12, 18, 9, 5, 5, 34, 23, 33, 25, 23, - 20, 30, 21, 28, 24, 22, 19, 48, 40, 35, 31, - 37, 15, 6, 4, 3, 71, 55, 29, 1, 66, 14, 2, 73, - 66, 3, 39, 27, 7, 65, 18, 5, 5, 67, 66, 62, - 65, 6, 11, 12, 11, 7, 20, 24, 10, 21, 25, 36, - 66, 4, 72, 1, 30, 71, 74, 70, 4, 5, 69, 78, - 69, 81, 69, 71, 89, 15, 14, 32, 5, 66, 14, 8, - 1, 7, 6, 1, 76, 0, 65, 69, 67, 17, 100, 83, - 16, 86, 68, 75, 69, 10, 75, 78, 4, 5, 94, 74, - 101, 15, 18, 23, 1, 73, 69, 72, 78, 82, 90, - 93, 93, 106, 100, 101, 126, 118, 125, 126, - 116, 114, 107, 103, 114, 100, 106, 103, 89, - 96, 73, 76, 78, 79, 99, 90, 91, 111, 97, 105, - 106, 126, 109, 113, 115, 82, 80, 119, 85, 88, - 98, 114, 102, 110, 111, 93, 110, 101, 104, - 114, 111, 114, 103, 109, 114, 70, 0, 15, 3, - 32, 42, 1, 9, 18, 22, 5, 20, 38, 4, 64, 25, - 79, 111, 126, 126, 126, 126, 126, 126, 7, 39, - 30, 27, 17, 32, 18, 10, 8, 2, 72, 67, 12, 3, - 26, 36, 2, 5, 12, 16, 6, 14, 29, 7, 0, 25, 79, - 111, 126, 126, 126, 126, 126, 126 }, - - { - - 20, - 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 89, 99, - 16, 60, 11, 31, 70, 10, 23, 66, 76, 2, 83, - 110, 77, 117, 126, 126, 126, 62, 7, 64, 10, - 23, 66, 86, 12, 11, 66, 0, 67, 66, 64, 80, 78, - 91, 5, 65, 67, 4, 72, 65, 80, 0, 74, 72, 80, - 6, 2, 22, 0, 0, 0, 7, 97, 97, 12, 79, 70, 10, - 71, 85, 51, 25, 17, 59, 62, 32, 34, 24, 35, - 15, 14, 42, 80, 74, 73, 80, 24, 65, 24, 39, - 67, 68, 64, 28, 0, 76, 75, 84, 19, 68, 10, 2, - 64, 11, 1, 13, 11, 12, 21, 29, 15, 10, 14, 62, - 62, 62, 62, 9, 0, 4, 15, 64, 11, 14, 6, 65, - 44, 66, 114, 110, 62, 9, 17, 5, 6, 11, 20, 53, - 31, 13, 66, 1, 2, 21, 26, 107, 4, 5, 81, 67, - 77, 5, 6, 73, 19, 12, 12, 93, 9, 82, 77, 3, - 89, 7, 6, 3, 85, 109, 67, 82, 80, 86, 99, 96, - 82, 126, 62, 126, 92, 95, 103, 120, 105, 118, - 126, 126, 124, 101, 126, 95, 62, 115, 71, 69, - 77, 83, 84, 81, 86, 85, 86, 102, 102, 98, 100, - 101, 126, 75, 77, 100, 76, 83, 84, 91, 94, - 100, 97, 105, 101, 86, 103, 105, 96, 86, 19, - 37, 23, 10, 12, 19, 10, 6, 6, 36, 24, 33, 25, - 23, 21, 31, 22, 30, 26, 24, 20, 49, 41, 36, - 32, 38, 15, 6, 4, 4, 71, 56, 29, 0, 66, 14, 2, - 73, 65, 3, 39, 26, 6, 66, 18, 5, 5, 67, 66, - 62, 64, 7, 12, 14, 13, 8, 22, 26, 11, 23, 27, - 38, 65, 5, 71, 2, 32, 71, 74, 70, 5, 6, 69, - 78, 69, 82, 69, 71, 89, 15, 14, 33, 5, 66, 14, - 8, 1, 7, 6, 1, 77, 0, 65, 69, 67, 18, 101, 84, - 16, 87, 69, 76, 70, 10, 76, 79, 4, 5, 95, 74, - 102, 14, 17, 22, 64, 75, 71, 74, 80, 84, 93, - 96, 96, 109, 103, 103, 126, 122, 126, 126, - 119, 117, 110, 105, 116, 102, 108, 104, 90, - 97, 75, 78, 80, 81, 102, 93, 93, 114, 99, 107, - 108, 126, 111, 115, 117, 83, 81, 121, 86, 89, - 100, 116, 104, 112, 113, 94, 112, 102, 105, - 115, 112, 115, 105, 110, 115, 70, 0, 16, 3, - 33, 43, 1, 10, 19, 23, 5, 21, 39, 4, 64, 24, - 81, 114, 126, 126, 126, 126, 126, 126, 7, 39, - 30, 27, 17, 33, 18, 10, 8, 2, 72, 67, 12, 3, - 27, 37, 2, 5, 12, 16, 6, 14, 30, 7, 0, 24, 81, - 114, 126, 126, 126, 126, 126, 126 }, - - { - - 18, - 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 91, 102, - 15, 60, 10, 32, 71, 10, 23, 67, 77, 2, 84, - 112, 79, 120, 126, 126, 126, 62, 7, 64, 10, - 23, 67, 87, 12, 11, 67, 0, 67, 66, 65, 81, 78, - 91, 4, 65, 67, 4, 72, 65, 80, 0, 74, 73, 80, - 6, 2, 22, 0, 0, 0, 7, 98, 97, 12, 80, 71, 9, - 72, 86, 53, 26, 18, 60, 62, 33, 35, 25, 36, - 16, 15, 44, 80, 74, 73, 80, 24, 65, 24, 41, - 67, 68, 64, 29, 64, 77, 76, 85, 19, 68, 10, 2, - 64, 11, 1, 13, 11, 12, 22, 30, 15, 11, 15, 62, - 62, 62, 62, 9, 0, 4, 15, 65, 11, 14, 6, 65, - 46, 66, 116, 112, 62, 9, 17, 5, 6, 11, 20, 54, - 31, 13, 67, 0, 2, 21, 26, 109, 4, 5, 82, 68, - 79, 4, 5, 74, 19, 12, 11, 95, 9, 83, 78, 2, - 89, 6, 5, 2, 88, 113, 69, 84, 83, 89, 102, 99, - 84, 126, 62, 126, 95, 97, 106, 124, 108, 122, - 126, 126, 126, 103, 126, 97, 62, 117, 74, 72, - 80, 86, 87, 84, 89, 88, 88, 105, 105, 100, - 102, 103, 126, 75, 78, 101, 77, 85, 86, 93, - 96, 102, 99, 107, 102, 87, 104, 106, 97, 86, - 20, 37, 23, 10, 12, 19, 10, 6, 6, 38, 25, 33, - 25, 23, 21, 31, 23, 31, 27, 25, 20, 49, 41, - 36, 32, 39, 15, 6, 4, 4, 72, 56, 28, 64, 67, - 14, 2, 73, 65, 2, 38, 25, 4, 67, 17, 5, 5, 67, - 66, 62, 0, 8, 13, 15, 14, 9, 23, 27, 12, 24, - 28, 40, 65, 5, 71, 3, 33, 71, 74, 70, 5, 6, - 69, 79, 70, 83, 69, 72, 90, 15, 14, 34, 5, 67, - 14, 8, 0, 7, 6, 1, 78, 0, 65, 69, 67, 18, 102, - 85, 16, 89, 70, 77, 71, 9, 77, 80, 4, 4, 97, - 75, 104, 12, 15, 21, 66, 77, 74, 77, 83, 87, - 96, 99, 99, 113, 106, 105, 126, 126, 126, 126, - 123, 121, 113, 108, 119, 104, 110, 106, 91, - 98, 78, 81, 83, 84, 105, 96, 96, 118, 102, - 110, 111, 126, 113, 117, 119, 84, 82, 123, 88, - 91, 102, 119, 106, 114, 115, 96, 114, 104, - 106, 117, 113, 116, 107, 112, 117, 70, 0, 16, - 3, 34, 44, 1, 10, 19, 23, 5, 21, 39, 4, 65, - 22, 83, 117, 126, 126, 126, 126, 126, 126, 7, - 39, 30, 27, 17, 33, 18, 10, 8, 2, 72, 67, 12, - 3, 27, 37, 2, 5, 12, 16, 6, 14, 30, 6, 64, 22, - 83, 117, 126, 126, 126, 126, 126, 126 }, - - { - - 17, - 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 92, 104, - 14, 61, 10, 34, 71, 11, 24, 67, 77, 3, 84, - 113, 80, 122, 126, 126, 126, 62, 8, 0, 11, 24, - 67, 87, 13, 11, 67, 1, 66, 65, 65, 81, 77, 90, - 4, 64, 66, 4, 71, 64, 79, 1, 73, 73, 79, 7, 2, - 22, 0, 0, 0, 8, 98, 97, 13, 80, 71, 9, 72, 86, - 56, 28, 20, 62, 62, 35, 37, 27, 38, 18, 17, - 47, 80, 73, 72, 79, 24, 65, 25, 44, 66, 67, 0, - 31, 64, 77, 76, 85, 20, 68, 11, 3, 0, 12, 2, - 14, 12, 13, 24, 32, 16, 13, 17, 62, 62, 62, - 62, 10, 1, 5, 16, 65, 12, 15, 7, 64, 49, 65, - 118, 113, 62, 9, 18, 5, 7, 12, 21, 56, 32, 14, - 67, 0, 2, 22, 27, 110, 5, 5, 82, 68, 80, 4, 5, - 74, 19, 12, 11, 96, 10, 83, 78, 2, 89, 6, 5, - 2, 90, 116, 70, 85, 85, 91, 104, 101, 86, 126, - 62, 126, 97, 98, 108, 126, 110, 125, 126, 126, - 126, 105, 126, 99, 62, 118, 76, 74, 82, 88, - 89, 86, 91, 90, 90, 107, 107, 101, 103, 104, - 126, 75, 78, 101, 77, 86, 87, 94, 97, 103, - 100, 108, 103, 87, 105, 106, 97, 85, 22, 38, - 24, 10, 13, 20, 11, 7, 7, 41, 27, 34, 26, 24, - 22, 32, 25, 33, 29, 27, 21, 50, 42, 37, 33, - 40, 16, 7, 5, 5, 72, 57, 28, 64, 67, 15, 3, - 73, 64, 2, 38, 25, 3, 68, 17, 6, 6, 66, 65, - 62, 2, 10, 15, 17, 16, 11, 25, 29, 14, 26, 30, - 43, 64, 6, 70, 5, 35, 70, 73, 69, 6, 7, 68, - 79, 70, 83, 69, 72, 90, 16, 15, 35, 6, 67, 15, - 9, 0, 8, 7, 1, 78, 1, 64, 68, 66, 19, 102, 86, - 16, 90, 70, 77, 71, 9, 77, 80, 4, 4, 98, 75, - 105, 11, 14, 21, 67, 78, 76, 79, 85, 89, 98, - 101, 101, 116, 108, 107, 126, 126, 126, 126, - 126, 124, 115, 110, 121, 105, 111, 107, 91, - 98, 80, 83, 85, 86, 107, 98, 98, 121, 104, - 112, 113, 126, 114, 118, 120, 84, 82, 124, 89, - 92, 103, 121, 107, 115, 116, 97, 115, 105, - 106, 118, 113, 116, 108, 113, 118, 69, 1, 17, - 4, 36, 46, 2, 11, 20, 24, 6, 22, 40, 4, 65, - 21, 85, 119, 126, 126, 126, 126, 126, 126, 8, - 39, 31, 28, 18, 34, 19, 11, 9, 3, 71, 66, 13, - 4, 28, 38, 3, 6, 13, 17, 6, 15, 31, 6, 64, 21, - 85, 119, 126, 126, 126, 126, 126, 126 }, - - { - - 16, - 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 93, 106, - 13, 61, 10, 36, 71, 11, 25, 67, 78, 3, 85, - 115, 81, 125, 126, 126, 126, 62, 9, 0, 11, 25, - 67, 87, 14, 11, 68, 1, 66, 64, 65, 81, 77, 90, - 4, 64, 66, 4, 71, 64, 79, 1, 73, 73, 79, 7, 2, - 22, 0, 0, 0, 9, 98, 97, 13, 81, 71, 8, 72, 86, - 58, 29, 21, 62, 62, 36, 38, 29, 39, 19, 18, - 49, 80, 73, 72, 79, 24, 65, 26, 46, 66, 66, 1, - 33, 64, 77, 76, 86, 20, 68, 11, 4, 1, 13, 3, - 15, 12, 14, 25, 33, 17, 14, 18, 62, 62, 62, - 62, 10, 1, 5, 16, 65, 12, 15, 7, 64, 51, 65, - 120, 115, 62, 9, 18, 5, 7, 12, 21, 58, 33, 14, - 67, 0, 2, 23, 28, 111, 5, 5, 82, 69, 81, 3, 5, - 75, 19, 12, 11, 97, 10, 84, 79, 1, 89, 6, 4, - 1, 92, 119, 71, 87, 87, 93, 106, 103, 88, 126, - 62, 126, 99, 100, 110, 126, 112, 126, 126, - 126, 126, 107, 126, 101, 62, 120, 78, 76, 84, - 90, 91, 88, 93, 92, 92, 109, 109, 103, 105, - 106, 126, 75, 78, 102, 78, 87, 88, 95, 98, - 104, 101, 110, 104, 87, 106, 107, 98, 84, 23, - 39, 24, 10, 13, 21, 12, 8, 8, 43, 28, 34, 26, - 24, 23, 33, 26, 35, 31, 29, 22, 51, 43, 38, - 34, 41, 16, 7, 5, 6, 72, 58, 28, 65, 67, 15, - 3, 73, 64, 2, 38, 24, 2, 69, 17, 6, 6, 66, 65, - 62, 3, 11, 16, 19, 18, 12, 27, 31, 15, 28, 32, - 45, 0, 7, 70, 6, 37, 70, 73, 69, 7, 7, 68, 79, - 70, 84, 69, 72, 90, 16, 15, 36, 6, 67, 15, 9, - 0, 8, 7, 1, 79, 1, 64, 68, 66, 20, 103, 87, - 16, 91, 71, 78, 72, 9, 78, 81, 4, 4, 99, 75, - 106, 10, 13, 20, 69, 80, 78, 81, 87, 91, 101, - 104, 104, 119, 111, 109, 126, 126, 126, 126, - 126, 126, 118, 112, 124, 107, 113, 108, 92, - 99, 82, 85, 88, 88, 110, 101, 101, 124, 106, - 115, 115, 126, 116, 120, 122, 85, 83, 126, 90, - 93, 105, 123, 109, 117, 118, 98, 117, 106, - 107, 119, 114, 117, 110, 114, 119, 69, 1, 18, - 4, 37, 47, 2, 12, 21, 25, 6, 22, 41, 4, 65, - 20, 87, 122, 126, 126, 126, 126, 126, 126, 8, - 39, 31, 28, 18, 35, 19, 11, 9, 3, 71, 66, 13, - 4, 29, 39, 3, 6, 13, 17, 6, 15, 32, 6, 64, 20, - 87, 122, 126, 126, 126, 126, 126, 126 }, - - { - - 15, - 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 95, 108, - 12, 61, 10, 38, 71, 12, 26, 67, 78, 3, 85, - 116, 82, 126, 126, 126, 126, 62, 10, 0, 12, - 26, 67, 88, 15, 11, 68, 1, 66, 64, 65, 81, 77, - 90, 4, 64, 65, 4, 71, 0, 79, 1, 73, 73, 79, 7, - 2, 22, 0, 0, 0, 9, 98, 97, 14, 82, 71, 7, 73, - 86, 61, 30, 22, 62, 62, 38, 40, 31, 41, 20, - 19, 51, 80, 73, 71, 79, 24, 65, 27, 48, 66, - 65, 1, 35, 64, 78, 77, 86, 20, 68, 12, 4, 2, - 14, 3, 16, 13, 15, 27, 35, 17, 15, 19, 62, 62, - 62, 62, 10, 1, 5, 17, 65, 12, 16, 8, 0, 53, - 65, 122, 117, 62, 9, 18, 5, 7, 12, 22, 59, 34, - 14, 67, 0, 2, 23, 29, 112, 5, 5, 83, 69, 82, - 3, 5, 75, 19, 12, 11, 98, 10, 85, 80, 1, 89, - 6, 4, 1, 94, 122, 72, 89, 89, 96, 108, 106, - 90, 126, 62, 126, 101, 102, 112, 126, 115, - 126, 126, 126, 126, 109, 126, 103, 62, 122, - 80, 78, 86, 93, 94, 90, 95, 94, 94, 111, 111, - 105, 107, 107, 126, 75, 78, 102, 79, 88, 89, - 96, 99, 105, 102, 112, 105, 88, 107, 108, 98, - 84, 25, 40, 25, 10, 13, 22, 12, 8, 8, 45, 29, - 34, 26, 25, 24, 34, 27, 36, 32, 31, 23, 51, - 43, 38, 34, 42, 17, 7, 5, 6, 72, 58, 28, 66, - 67, 15, 3, 73, 0, 2, 37, 24, 1, 70, 17, 6, 6, - 66, 65, 62, 4, 13, 17, 20, 19, 13, 29, 33, 16, - 29, 34, 47, 0, 8, 69, 7, 39, 69, 73, 69, 7, 8, - 68, 79, 70, 84, 69, 72, 91, 17, 16, 37, 6, 67, - 16, 9, 0, 8, 7, 1, 79, 1, 64, 68, 66, 20, 104, - 88, 16, 92, 72, 79, 72, 9, 79, 82, 4, 4, 100, - 75, 107, 9, 12, 19, 70, 82, 80, 83, 89, 94, - 103, 107, 107, 122, 113, 111, 126, 126, 126, - 126, 126, 126, 120, 114, 126, 109, 115, 110, - 93, 100, 84, 88, 90, 91, 113, 103, 103, 126, - 109, 117, 118, 126, 118, 122, 123, 86, 84, - 126, 92, 95, 107, 125, 110, 119, 120, 99, 118, - 107, 108, 120, 115, 118, 111, 115, 120, 69, 2, - 18, 5, 38, 48, 2, 12, 21, 25, 6, 23, 42, 4, - 65, 19, 89, 124, 126, 126, 126, 126, 126, 126, - 8, 39, 31, 28, 18, 35, 20, 11, 9, 4, 71, 66, - 14, 5, 30, 40, 3, 7, 13, 17, 6, 15, 32, 6, 64, - 19, 89, 124, 126, 126, 126, 126, 126, 126 }, - - }, - - { - - { - - 62, - 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 47, 62, - 62, 12, 1, 99, 47, 85, 102, 6, 6, 73, 6, 23, 53, - 62, 62, 21, 97, 126, 117, 74, 85, 102, 6, 93, - 88, 19, 8, 89, 103, 116, 6, 5, 84, 96, 0, 85, - 106, 0, 75, 90, 101, 8, 79, 75, 97, 13, 3, 22, - 0, 0, 0, 83, 86, 97, 72, 22, 1, 29, 88, 126, - 126, 91, 95, 84, 86, 89, 91, 126, 76, 103, 90, - 126, 80, 76, 84, 78, 8, 2, 83, 126, 79, 104, 91, - 126, 65, 79, 72, 92, 7, 68, 71, 98, 86, 88, 82, - 72, 67, 72, 89, 69, 4, 66, 6, 71, 71, 5, 74, 19, - 69, 1, 12, 16, 21, 22, 10, 76, 78, 83, 11, 67, - 90, 67, 72, 75, 80, 83, 64, 32, 64, 94, 75, 0, - 74, 28, 36, 91, 65, 69, 77, 66, 1, 68, 81, 33, - 56, 40, 74, 66, 124, 26, 62, 62, 126, 24, 21, - 29, 34, 32, 26, 21, 23, 30, 20, 27, 16, 8, 5, 3, - 19, 19, 21, 15, 7, 11, 26, 14, 5, 15, 18, 69, - 30, 0, 62, 62, 62, 53, 62, 62, 62, 62, 46, 38, - 34, 30, 48, 43, 73, 29, 32, 19, 47, 27, 27, 35, - 42, 43, 51, 47, 21, 93, 7, 6, 25, 126, 115, 82, - 1, 10, 4, 85, 89, 94, 92, 126, 100, 6, 67, 71, - 77, 85, 88, 104, 98, 126, 82, 15, 2, 66, 70, 75, - 79, 83, 92, 108, 79, 69, 75, 5, 5, 78, 83, 81, - 99, 81, 25, 1, 5, 4, 73, 76, 86, 83, 87, 62, - 126, 126, 120, 126, 114, 117, 118, 117, 113, - 118, 120, 124, 94, 102, 99, 106, 126, 92, 6, 86, - 94, 91, 77, 71, 73, 64, 81, 64, 6, 67, 68, 67, - 68, 77, 64, 68, 78, 8, 4, 65, 9, 19, 3, 70, 76, - 86, 70, 64, 70, 8, 7, 69, 65, 74, 9, 9, 76, 82, - 77, 77, 21, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 52, 62, 62, 62, 62, 62, 62, - 48, 62, 62, 46, 25, 18, 9, 79, 62, 62, 62, 62, - 48, 48, 38, 41, 47, 45, 35, 22, 35, 16, 1, 32, - 37, 39, 40, 47, 33, 34, 22, 21, 3, 11, 3, 78, - 123, 10, 7, 2, 30, 13, 2, 78, 74, 72, 72, 75, - 71, 0, 70, 75, 72, 67, 10, 4, 11, 68, 62, 62, - 62, 62, 56, 51, 40, 25, 64, 71, 26, 19, 14, 7, - 4, 0, 67, 68, 79, 78, 74, 72, 72, 75, 71, 0, 70, - 75, 72, 67, 10, 4, 11, 68, 62, 62, 62, 62, 56, - 51, 40, 25, 64 }, - - { - - 62, - 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 46, - 62, 62, 13, 2, 97, 46, 84, 100, 6, 6, 71, 6, - 22, 52, 62, 60, 19, 97, 125, 115, 73, 84, 100, - 6, 92, 87, 20, 8, 88, 102, 114, 5, 4, 84, 96, - 0, 84, 105, 0, 75, 89, 100, 8, 78, 74, 96, 14, - 3, 22, 0, 0, 0, 82, 86, 97, 71, 22, 1, 29, 87, - 125, 124, 89, 94, 82, 84, 88, 89, 125, 75, - 101, 89, 124, 80, 76, 84, 78, 9, 2, 82, 124, - 78, 103, 90, 125, 65, 78, 72, 91, 8, 68, 70, - 97, 85, 87, 81, 71, 66, 71, 88, 68, 5, 66, 6, - 70, 70, 5, 73, 20, 68, 1, 13, 17, 22, 23, 11, - 76, 77, 82, 11, 67, 89, 67, 71, 74, 79, 81, 1, - 33, 1, 92, 75, 64, 73, 29, 37, 91, 65, 68, 77, - 65, 1, 67, 79, 33, 56, 41, 72, 67, 122, 25, - 62, 62, 125, 24, 21, 29, 34, 32, 26, 21, 23, - 30, 20, 27, 16, 8, 5, 3, 19, 19, 21, 15, 7, - 11, 26, 14, 4, 15, 18, 69, 29, 0, 62, 62, 62, - 52, 62, 62, 62, 62, 45, 37, 32, 29, 46, 42, - 74, 28, 31, 18, 46, 27, 27, 34, 41, 42, 50, - 46, 20, 93, 7, 6, 24, 125, 113, 80, 2, 10, 4, - 84, 88, 93, 91, 125, 98, 7, 66, 70, 76, 83, - 87, 102, 97, 124, 81, 16, 3, 65, 69, 74, 78, - 82, 91, 106, 78, 67, 74, 6, 5, 77, 82, 80, 98, - 80, 26, 2, 6, 5, 72, 75, 85, 82, 86, 62, 125, - 125, 118, 125, 112, 115, 116, 115, 111, 116, - 118, 121, 93, 101, 98, 105, 123, 91, 5, 85, - 93, 90, 76, 71, 72, 64, 80, 64, 6, 67, 68, 66, - 68, 77, 64, 68, 77, 8, 4, 65, 9, 19, 3, 70, - 75, 84, 70, 64, 69, 8, 7, 69, 65, 73, 9, 9, - 75, 81, 76, 76, 20, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 50, 62, 62, - 62, 62, 62, 62, 47, 60, 60, 45, 24, 17, 9, 79, - 62, 62, 62, 60, 46, 47, 37, 39, 46, 43, 34, - 20, 33, 15, 0, 31, 36, 37, 39, 46, 32, 33, 21, - 20, 2, 11, 3, 78, 122, 9, 6, 1, 29, 12, 1, 77, - 73, 71, 71, 73, 70, 1, 69, 73, 71, 66, 11, 5, - 12, 67, 62, 62, 62, 62, 54, 50, 38, 24, 65, - 70, 27, 20, 15, 8, 5, 1, 66, 67, 78, 77, 73, - 71, 71, 73, 70, 1, 69, 73, 71, 66, 11, 5, 12, - 67, 62, 62, 62, 62, 54, 50, 38, 24, 65 }, - - { - - 62, - 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 44, - 60, 62, 14, 2, 95, 44, 84, 99, 6, 6, 70, 5, - 21, 51, 60, 57, 17, 98, 123, 114, 73, 84, 99, - 6, 92, 86, 20, 8, 87, 101, 113, 4, 3, 84, 96, - 0, 84, 104, 0, 75, 89, 100, 8, 78, 74, 95, 14, - 3, 22, 0, 0, 0, 81, 86, 97, 71, 21, 1, 29, 86, - 124, 122, 88, 93, 80, 82, 87, 88, 123, 74, - 100, 88, 122, 81, 76, 84, 78, 9, 2, 81, 122, - 78, 102, 89, 123, 65, 78, 72, 91, 8, 68, 70, - 96, 85, 86, 81, 71, 66, 71, 87, 67, 5, 66, 6, - 70, 70, 5, 73, 20, 68, 1, 13, 17, 22, 23, 11, - 77, 76, 81, 10, 67, 89, 67, 70, 74, 79, 80, 2, - 34, 3, 90, 76, 65, 73, 29, 37, 92, 65, 68, 78, - 64, 1, 67, 78, 33, 56, 41, 71, 68, 121, 24, - 62, 62, 124, 24, 21, 29, 33, 31, 26, 21, 23, - 29, 19, 26, 16, 8, 5, 3, 18, 18, 20, 15, 7, - 11, 25, 13, 3, 14, 17, 69, 28, 64, 62, 62, 62, - 50, 60, 62, 62, 62, 44, 35, 30, 27, 44, 40, - 75, 27, 30, 16, 45, 26, 26, 33, 39, 40, 48, - 44, 18, 93, 6, 5, 22, 124, 112, 79, 3, 10, 4, - 83, 87, 92, 90, 123, 97, 8, 65, 69, 75, 82, - 86, 101, 96, 122, 80, 16, 3, 65, 69, 73, 77, - 81, 90, 105, 78, 66, 73, 6, 5, 76, 81, 80, 97, - 79, 26, 3, 6, 5, 71, 74, 84, 81, 85, 62, 124, - 123, 116, 123, 111, 114, 114, 113, 110, 114, - 116, 119, 92, 100, 97, 104, 120, 91, 4, 85, - 92, 89, 76, 71, 72, 64, 80, 64, 5, 67, 68, 65, - 68, 77, 64, 68, 77, 8, 4, 65, 8, 18, 3, 70, - 75, 83, 71, 64, 68, 7, 7, 69, 65, 73, 9, 9, - 75, 80, 76, 76, 18, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 48, 62, 62, - 62, 62, 62, 61, 45, 58, 58, 43, 23, 16, 8, 79, - 62, 62, 62, 58, 44, 45, 35, 37, 44, 41, 32, - 18, 31, 13, 64, 30, 35, 35, 37, 44, 30, 31, - 20, 19, 1, 10, 2, 78, 121, 8, 5, 64, 28, 11, - 0, 77, 73, 70, 70, 72, 69, 2, 69, 72, 70, 65, - 11, 6, 13, 66, 62, 62, 62, 60, 52, 48, 36, 22, - 66, 69, 27, 20, 16, 9, 6, 1, 65, 67, 77, 77, - 73, 70, 70, 72, 69, 2, 69, 72, 70, 65, 11, 6, - 13, 66, 62, 62, 62, 60, 52, 48, 36, 22, 66 }, - - { - - 62, - 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 42, 59, - 61, 14, 2, 93, 43, 84, 97, 6, 5, 69, 4, 20, - 50, 58, 53, 15, 99, 121, 112, 73, 84, 97, 6, - 91, 85, 21, 8, 86, 100, 112, 3, 2, 84, 97, 0, - 84, 103, 0, 76, 89, 100, 8, 78, 74, 94, 15, 3, - 22, 0, 0, 0, 81, 86, 97, 70, 20, 1, 28, 86, - 123, 120, 87, 92, 79, 81, 86, 87, 121, 73, 99, - 87, 120, 82, 76, 84, 78, 10, 2, 80, 120, 78, - 101, 88, 121, 65, 78, 72, 91, 9, 68, 69, 95, - 85, 85, 81, 71, 66, 70, 86, 67, 5, 66, 6, 70, - 70, 5, 73, 20, 68, 1, 14, 17, 23, 23, 12, 77, - 76, 80, 10, 67, 89, 67, 69, 74, 78, 79, 3, 35, - 4, 88, 76, 66, 72, 29, 37, 93, 65, 67, 78, 64, - 1, 67, 77, 33, 56, 41, 70, 69, 119, 23, 62, - 62, 122, 24, 21, 28, 32, 31, 25, 20, 23, 29, - 18, 25, 16, 8, 5, 2, 18, 17, 19, 14, 7, 11, - 24, 13, 2, 14, 16, 69, 27, 64, 62, 62, 61, 49, - 58, 62, 62, 62, 43, 33, 28, 26, 42, 38, 77, - 26, 29, 14, 44, 25, 25, 32, 38, 38, 46, 42, - 17, 93, 5, 4, 21, 122, 110, 77, 3, 10, 4, 82, - 86, 91, 89, 121, 96, 9, 64, 68, 75, 81, 85, - 99, 95, 120, 80, 17, 4, 64, 68, 72, 77, 81, - 89, 104, 78, 64, 72, 6, 5, 75, 81, 80, 96, 78, - 27, 4, 7, 5, 70, 74, 83, 81, 85, 62, 122, 122, - 115, 121, 110, 112, 113, 112, 108, 112, 114, - 117, 92, 99, 97, 103, 117, 91, 3, 85, 91, 88, - 76, 71, 72, 64, 79, 64, 4, 67, 68, 65, 68, 77, - 64, 68, 77, 7, 4, 65, 7, 17, 3, 70, 75, 82, - 72, 64, 67, 6, 7, 69, 65, 72, 9, 8, 74, 79, - 76, 76, 17, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 46, 62, 62, 62, 62, - 62, 59, 43, 56, 55, 41, 22, 15, 7, 79, 62, 62, - 62, 56, 42, 43, 34, 35, 42, 39, 30, 16, 29, - 11, 65, 29, 34, 33, 36, 42, 29, 29, 18, 17, 0, - 9, 1, 78, 120, 7, 3, 65, 27, 10, 64, 77, 72, - 70, 70, 71, 68, 3, 69, 71, 69, 64, 12, 7, 13, - 65, 62, 62, 62, 58, 50, 46, 34, 20, 67, 69, - 28, 21, 17, 9, 7, 2, 65, 66, 77, 77, 72, 70, - 70, 71, 68, 3, 69, 71, 69, 64, 12, 7, 13, 65, - 62, 62, 62, 58, 50, 46, 34, 20, 67 }, - - { - - 62, - 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 40, 57, - 60, 15, 2, 92, 41, 84, 96, 5, 5, 68, 3, 18, - 48, 56, 50, 12, 100, 119, 111, 73, 84, 96, 5, - 91, 84, 21, 7, 86, 99, 110, 2, 0, 85, 97, 0, - 83, 102, 64, 76, 89, 100, 8, 78, 74, 94, 15, - 3, 22, 0, 0, 0, 80, 87, 97, 70, 19, 1, 28, 85, - 122, 118, 86, 91, 77, 79, 86, 86, 119, 72, 98, - 86, 117, 82, 77, 84, 79, 10, 1, 79, 117, 77, - 101, 88, 119, 65, 78, 72, 91, 9, 68, 69, 94, - 85, 85, 80, 71, 66, 70, 85, 66, 5, 67, 5, 70, - 70, 5, 73, 20, 68, 1, 14, 17, 23, 23, 12, 78, - 75, 80, 9, 67, 88, 67, 68, 73, 78, 77, 5, 36, - 6, 86, 77, 67, 72, 30, 37, 94, 65, 67, 79, 0, - 1, 67, 76, 33, 56, 41, 68, 70, 118, 22, 62, - 62, 121, 23, 21, 28, 32, 30, 25, 20, 23, 28, - 17, 24, 15, 8, 5, 2, 17, 17, 18, 14, 6, 10, - 23, 12, 1, 13, 15, 69, 25, 65, 62, 62, 59, 47, - 57, 62, 62, 62, 42, 31, 25, 24, 40, 36, 78, - 24, 28, 13, 43, 24, 24, 30, 36, 36, 44, 41, - 15, 93, 4, 3, 19, 121, 109, 76, 4, 10, 4, 81, - 85, 90, 89, 119, 94, 10, 64, 68, 74, 79, 84, - 98, 94, 117, 79, 17, 4, 64, 68, 71, 76, 80, - 89, 103, 78, 0, 71, 6, 5, 74, 80, 80, 95, 77, - 27, 5, 7, 5, 69, 73, 82, 80, 84, 62, 121, 120, - 113, 120, 109, 111, 111, 110, 107, 111, 112, - 114, 91, 98, 96, 102, 114, 90, 2, 84, 90, 88, - 76, 71, 72, 65, 79, 65, 3, 67, 68, 64, 68, 77, - 64, 68, 76, 7, 3, 65, 6, 16, 2, 70, 75, 81, - 73, 65, 67, 6, 6, 69, 65, 72, 8, 8, 74, 79, - 76, 76, 15, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 44, 62, 62, 62, 62, - 62, 57, 41, 54, 53, 39, 20, 14, 6, 79, 62, 62, - 62, 54, 40, 41, 32, 33, 40, 37, 28, 14, 26, - 10, 67, 28, 33, 30, 34, 41, 27, 27, 17, 16, - 64, 8, 0, 78, 119, 5, 2, 67, 25, 9, 65, 77, - 72, 69, 69, 70, 68, 3, 68, 70, 68, 0, 12, 8, - 14, 65, 62, 62, 60, 56, 48, 44, 31, 18, 69, - 68, 28, 21, 17, 10, 7, 2, 64, 66, 76, 77, 72, - 69, 69, 70, 68, 3, 68, 70, 68, 0, 12, 8, 14, - 65, 62, 62, 60, 56, 48, 44, 31, 18, 69 }, - - { - - 62, - 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 38, 56, - 59, 16, 2, 90, 39, 83, 94, 5, 5, 67, 2, 17, - 47, 54, 47, 10, 100, 117, 110, 73, 83, 94, 5, - 91, 83, 21, 7, 85, 98, 109, 1, 64, 85, 97, 0, - 83, 101, 64, 76, 89, 100, 8, 77, 74, 93, 16, - 3, 22, 0, 0, 0, 80, 87, 97, 69, 18, 1, 27, 85, - 120, 115, 85, 90, 76, 78, 85, 85, 117, 71, 97, - 85, 115, 83, 77, 84, 79, 10, 1, 78, 115, 77, - 100, 87, 117, 65, 78, 72, 90, 9, 68, 68, 93, - 84, 84, 80, 71, 65, 69, 84, 66, 5, 67, 5, 69, - 70, 5, 73, 21, 68, 1, 15, 18, 23, 23, 12, 78, - 75, 79, 9, 67, 88, 67, 67, 73, 77, 76, 6, 37, - 7, 84, 77, 68, 71, 30, 37, 95, 65, 66, 79, 1, - 1, 67, 74, 33, 56, 41, 67, 71, 116, 21, 62, - 62, 120, 23, 21, 27, 31, 30, 25, 19, 23, 28, - 16, 23, 15, 8, 5, 2, 17, 16, 17, 13, 6, 10, - 22, 12, 0, 12, 15, 69, 24, 65, 62, 62, 58, 46, - 55, 62, 62, 62, 41, 29, 23, 23, 38, 34, 79, - 23, 27, 11, 42, 23, 23, 29, 35, 34, 42, 39, - 14, 93, 3, 2, 17, 119, 107, 75, 4, 10, 4, 80, - 84, 89, 88, 117, 93, 11, 0, 67, 73, 78, 83, - 96, 93, 115, 78, 18, 5, 0, 67, 70, 75, 80, 88, - 102, 77, 1, 70, 6, 5, 73, 80, 79, 94, 76, 27, - 6, 7, 5, 68, 72, 81, 80, 83, 62, 120, 119, - 112, 118, 108, 109, 110, 108, 105, 109, 110, - 112, 90, 97, 95, 101, 111, 90, 1, 84, 89, 87, - 76, 71, 72, 65, 78, 65, 2, 67, 68, 0, 68, 77, - 64, 68, 76, 6, 3, 65, 5, 15, 2, 70, 75, 80, - 73, 65, 66, 5, 6, 69, 65, 72, 8, 7, 74, 78, - 76, 76, 14, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 42, 62, 62, 62, 62, - 62, 55, 40, 52, 50, 37, 19, 13, 5, 79, 62, 62, - 62, 52, 38, 39, 31, 31, 38, 35, 26, 12, 24, 8, - 68, 27, 32, 28, 33, 39, 26, 25, 16, 15, 65, 7, - 64, 78, 118, 4, 1, 68, 24, 8, 66, 77, 71, 69, - 68, 69, 67, 4, 68, 69, 67, 1, 13, 9, 14, 64, - 62, 62, 58, 54, 46, 42, 29, 16, 70, 68, 29, - 22, 18, 11, 8, 3, 64, 66, 75, 77, 71, 69, 68, - 69, 67, 4, 68, 69, 67, 1, 13, 9, 14, 64, 62, - 62, 58, 54, 46, 42, 29, 16, 70 }, - - { - - 62, - 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 37, 54, - 58, 16, 3, 88, 38, 83, 93, 5, 4, 66, 1, 16, - 46, 53, 43, 8, 101, 115, 108, 73, 83, 93, 5, - 90, 82, 22, 7, 84, 97, 108, 64, 65, 85, 98, 0, - 83, 101, 64, 77, 88, 100, 7, 77, 74, 92, 16, - 3, 22, 0, 0, 0, 79, 87, 97, 69, 18, 0, 27, 84, - 119, 113, 84, 89, 74, 76, 84, 84, 115, 70, 96, - 85, 113, 84, 77, 84, 79, 11, 1, 77, 113, 77, - 99, 86, 115, 65, 78, 72, 90, 10, 69, 68, 93, - 84, 83, 80, 70, 65, 69, 83, 65, 5, 67, 5, 69, - 70, 5, 73, 21, 68, 1, 15, 18, 24, 24, 13, 79, - 74, 78, 8, 67, 88, 67, 66, 73, 77, 75, 7, 37, - 9, 83, 78, 69, 71, 30, 37, 95, 66, 66, 80, 1, - 0, 66, 73, 33, 56, 42, 66, 72, 115, 20, 62, - 62, 118, 23, 21, 27, 30, 29, 24, 19, 22, 27, - 16, 23, 15, 7, 5, 1, 16, 15, 16, 13, 6, 10, - 22, 11, 65, 12, 14, 69, 23, 66, 62, 62, 56, - 44, 53, 62, 62, 62, 39, 27, 21, 21, 36, 32, - 81, 22, 25, 9, 40, 22, 22, 28, 33, 32, 40, 37, - 12, 93, 2, 1, 16, 118, 106, 73, 5, 10, 4, 79, - 84, 89, 87, 116, 92, 12, 1, 66, 73, 77, 82, - 95, 92, 113, 78, 18, 5, 0, 67, 69, 75, 79, 87, - 101, 77, 3, 69, 6, 5, 73, 79, 79, 94, 76, 28, - 6, 8, 5, 67, 72, 81, 79, 83, 62, 118, 117, - 110, 116, 106, 108, 108, 107, 104, 107, 108, - 110, 90, 96, 95, 101, 108, 90, 0, 84, 89, 86, - 76, 71, 72, 65, 78, 65, 1, 67, 68, 0, 68, 77, - 64, 68, 76, 6, 3, 65, 4, 14, 2, 70, 75, 79, - 74, 65, 65, 4, 6, 69, 65, 71, 8, 7, 73, 77, - 76, 76, 12, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 40, 62, 62, 62, 62, - 62, 52, 38, 50, 48, 35, 18, 12, 4, 79, 62, 62, - 62, 50, 36, 38, 29, 29, 36, 32, 24, 10, 22, 6, - 69, 26, 30, 26, 31, 37, 24, 23, 14, 13, 66, 6, - 65, 79, 117, 3, 64, 70, 23, 6, 67, 76, 71, 68, - 68, 68, 66, 5, 68, 68, 66, 2, 13, 10, 15, 0, - 62, 62, 56, 52, 44, 40, 27, 14, 71, 67, 29, - 22, 19, 11, 9, 3, 0, 65, 75, 76, 71, 68, 68, - 68, 66, 5, 68, 68, 66, 2, 13, 10, 15, 0, 62, - 62, 56, 52, 44, 40, 27, 14, 71 }, - - { - - 62, - 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 35, 53, - 57, 17, 3, 87, 36, 83, 91, 4, 4, 65, 0, 15, - 45, 51, 40, 5, 102, 113, 107, 73, 83, 91, 4, - 90, 81, 22, 7, 84, 96, 106, 65, 66, 85, 98, 0, - 82, 100, 65, 77, 88, 100, 7, 77, 74, 91, 17, - 3, 22, 0, 0, 0, 79, 87, 97, 68, 17, 0, 26, 84, - 118, 111, 83, 88, 73, 75, 83, 83, 113, 69, 95, - 84, 110, 84, 78, 84, 80, 11, 1, 76, 110, 76, - 99, 86, 113, 65, 78, 72, 90, 10, 69, 67, 92, - 84, 82, 79, 70, 65, 68, 82, 65, 5, 68, 5, 69, - 70, 5, 73, 21, 68, 1, 16, 18, 24, 24, 13, 79, - 74, 78, 8, 67, 87, 67, 65, 72, 76, 73, 9, 38, - 10, 81, 78, 70, 70, 31, 37, 96, 66, 65, 80, 2, - 0, 66, 72, 33, 56, 42, 64, 73, 113, 19, 62, - 62, 117, 23, 21, 26, 30, 29, 24, 18, 22, 27, - 15, 22, 15, 7, 5, 1, 16, 15, 15, 12, 6, 10, - 21, 11, 66, 11, 13, 69, 22, 66, 62, 62, 54, - 43, 52, 62, 62, 62, 38, 25, 19, 20, 34, 30, - 82, 21, 24, 8, 39, 21, 21, 26, 32, 30, 38, 36, - 11, 93, 1, 0, 14, 116, 104, 72, 5, 10, 4, 78, - 83, 88, 87, 114, 90, 13, 2, 66, 72, 75, 81, - 93, 91, 110, 77, 19, 6, 1, 66, 68, 74, 79, 86, - 100, 77, 4, 68, 6, 5, 72, 79, 79, 93, 75, 28, - 7, 8, 5, 66, 71, 80, 79, 82, 62, 117, 116, - 109, 115, 105, 106, 107, 105, 102, 105, 106, - 107, 89, 95, 94, 100, 105, 89, 64, 83, 88, 85, - 76, 71, 72, 65, 77, 66, 0, 67, 68, 1, 68, 77, - 64, 68, 75, 5, 2, 65, 3, 13, 1, 70, 75, 78, - 75, 66, 64, 4, 5, 69, 65, 71, 7, 6, 73, 77, - 76, 76, 11, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 38, 62, 62, 62, 62, - 62, 50, 36, 48, 45, 33, 17, 11, 3, 79, 62, 61, - 62, 48, 34, 36, 28, 27, 34, 30, 22, 8, 20, 5, - 71, 25, 29, 24, 30, 36, 23, 21, 13, 12, 67, 5, - 66, 79, 116, 1, 65, 71, 21, 5, 68, 76, 70, 68, - 67, 67, 65, 5, 67, 67, 65, 3, 14, 11, 15, 0, - 62, 60, 54, 50, 42, 38, 24, 12, 72, 67, 30, - 23, 19, 12, 10, 4, 0, 65, 74, 76, 70, 68, 67, - 67, 65, 5, 67, 67, 65, 3, 14, 11, 15, 0, 62, - 60, 54, 50, 42, 38, 24, 12, 72 }, - - { - - 62, - 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 33, 51, - 56, 17, 3, 85, 34, 83, 90, 4, 3, 64, 64, 13, - 43, 49, 36, 3, 103, 111, 106, 73, 83, 90, 4, - 90, 81, 22, 6, 83, 95, 105, 66, 68, 86, 99, 0, - 82, 99, 65, 78, 88, 100, 7, 77, 74, 91, 17, 3, - 22, 0, 0, 0, 78, 88, 97, 68, 16, 0, 26, 83, - 117, 109, 82, 88, 71, 73, 83, 82, 111, 69, 94, - 83, 108, 85, 78, 85, 80, 11, 0, 76, 108, 76, - 98, 85, 112, 65, 78, 72, 90, 10, 69, 67, 91, - 84, 82, 79, 70, 65, 68, 81, 64, 5, 68, 4, 69, - 70, 4, 73, 21, 68, 1, 16, 18, 24, 24, 13, 80, - 73, 77, 7, 67, 87, 67, 64, 72, 76, 72, 10, 39, - 12, 79, 79, 71, 70, 31, 37, 97, 66, 65, 81, 2, - 0, 66, 71, 33, 56, 42, 0, 74, 112, 18, 59, 62, - 116, 22, 21, 26, 29, 28, 23, 18, 22, 26, 14, - 21, 14, 7, 4, 0, 15, 14, 14, 12, 5, 9, 20, 10, - 67, 10, 12, 69, 20, 67, 62, 62, 52, 41, 50, - 60, 62, 62, 37, 23, 16, 18, 31, 28, 84, 19, - 23, 6, 38, 20, 20, 25, 30, 28, 36, 34, 9, 93, - 0, 64, 12, 115, 103, 71, 6, 10, 4, 78, 82, 87, - 86, 112, 89, 13, 2, 65, 72, 74, 80, 92, 90, - 108, 77, 19, 6, 1, 66, 68, 74, 78, 86, 99, 77, - 5, 67, 6, 5, 71, 78, 79, 92, 74, 28, 8, 8, 5, - 65, 71, 79, 78, 82, 62, 116, 114, 107, 113, - 104, 105, 105, 104, 101, 104, 104, 105, 89, - 94, 94, 99, 102, 89, 65, 83, 87, 85, 76, 71, - 72, 66, 77, 66, 64, 67, 68, 1, 68, 77, 65, 68, - 75, 5, 2, 66, 2, 12, 1, 71, 75, 77, 76, 66, - 64, 3, 5, 69, 66, 71, 7, 6, 73, 76, 76, 76, 9, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 61, 36, 62, 62, 62, 62, 61, 48, 34, - 45, 43, 31, 15, 9, 2, 79, 61, 59, 62, 46, 31, - 34, 26, 24, 32, 28, 20, 6, 17, 3, 72, 23, 28, - 21, 28, 34, 21, 19, 11, 10, 68, 4, 67, 79, - 115, 0, 67, 73, 20, 4, 69, 76, 70, 67, 67, 66, - 65, 6, 67, 66, 65, 4, 14, 11, 16, 1, 61, 58, - 52, 48, 40, 36, 22, 10, 74, 66, 30, 23, 20, - 12, 10, 4, 1, 65, 74, 76, 70, 67, 67, 66, 65, - 6, 67, 66, 65, 4, 14, 11, 16, 1, 61, 58, 52, - 48, 40, 36, 22, 10, 74 }, - - { - - 62, - 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 31, 49, - 56, 18, 3, 83, 33, 82, 88, 4, 3, 0, 64, 12, - 42, 47, 33, 1, 103, 109, 104, 72, 82, 88, 4, - 89, 80, 23, 6, 82, 94, 104, 67, 69, 86, 99, 0, - 82, 98, 65, 78, 88, 100, 7, 76, 73, 90, 17, 3, - 22, 0, 0, 0, 77, 88, 97, 68, 15, 0, 26, 82, - 115, 106, 81, 87, 69, 71, 82, 81, 109, 68, 92, - 82, 106, 86, 78, 85, 80, 12, 0, 75, 106, 76, - 97, 84, 110, 65, 77, 72, 89, 11, 69, 66, 90, - 83, 81, 79, 70, 64, 67, 80, 0, 5, 68, 4, 68, - 69, 4, 73, 22, 68, 1, 16, 19, 25, 24, 14, 80, - 72, 76, 6, 67, 87, 67, 0, 72, 75, 71, 11, 40, - 14, 77, 80, 72, 69, 31, 38, 98, 66, 65, 81, 3, - 0, 66, 69, 33, 56, 42, 1, 75, 111, 17, 57, 62, - 114, 22, 21, 26, 28, 28, 23, 18, 22, 26, 13, - 20, 14, 7, 4, 0, 15, 13, 14, 12, 5, 9, 19, 9, - 68, 10, 12, 69, 19, 67, 62, 62, 51, 40, 48, - 58, 62, 62, 36, 21, 14, 17, 29, 27, 85, 18, - 22, 4, 37, 19, 19, 24, 28, 27, 34, 32, 8, 93, - 0, 65, 11, 113, 101, 69, 7, 10, 4, 77, 81, 86, - 85, 110, 88, 14, 3, 64, 71, 73, 79, 91, 89, - 106, 76, 20, 7, 2, 66, 67, 73, 77, 85, 97, 76, - 7, 66, 7, 5, 70, 77, 78, 91, 73, 29, 9, 9, 6, - 64, 70, 78, 77, 81, 62, 114, 112, 105, 111, - 103, 104, 103, 102, 99, 102, 102, 103, 88, 93, - 93, 98, 98, 89, 66, 83, 86, 84, 75, 71, 72, - 66, 77, 66, 65, 67, 68, 2, 68, 77, 65, 68, 75, - 5, 2, 66, 2, 11, 1, 71, 74, 75, 76, 66, 0, 2, - 5, 69, 66, 70, 7, 6, 72, 75, 75, 75, 7, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 58, 34, 62, 62, 62, 62, 58, 46, 33, 43, - 41, 30, 14, 8, 1, 79, 59, 57, 60, 44, 29, 32, - 25, 22, 30, 26, 18, 4, 15, 1, 73, 22, 27, 19, - 27, 32, 20, 17, 10, 9, 69, 3, 67, 79, 114, 64, - 68, 75, 19, 3, 70, 76, 69, 66, 66, 64, 64, 7, - 67, 65, 64, 5, 15, 12, 17, 2, 60, 57, 50, 46, - 38, 34, 20, 8, 75, 65, 30, 24, 21, 13, 11, 5, - 2, 64, 73, 76, 69, 66, 66, 64, 64, 7, 67, 65, - 64, 5, 15, 12, 17, 2, 60, 57, 50, 46, 38, 34, - 20, 8, 75 }, - - { - - 62, - 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 29, 48, - 55, 19, 3, 82, 31, 82, 87, 3, 3, 1, 65, 11, - 41, 45, 30, 65, 104, 107, 103, 72, 82, 87, 3, - 89, 79, 23, 6, 82, 93, 102, 68, 70, 86, 99, 0, - 81, 97, 66, 78, 88, 100, 7, 76, 73, 89, 18, 3, - 22, 0, 0, 0, 77, 88, 97, 67, 14, 0, 25, 82, - 114, 104, 80, 86, 68, 70, 81, 80, 107, 67, 91, - 81, 103, 86, 79, 85, 81, 12, 0, 74, 103, 75, - 97, 84, 108, 65, 77, 72, 89, 11, 69, 66, 89, - 83, 80, 78, 70, 64, 67, 79, 0, 5, 69, 4, 68, - 69, 4, 73, 22, 68, 1, 17, 19, 25, 24, 14, 81, - 72, 76, 6, 67, 86, 67, 1, 71, 75, 69, 13, 41, - 15, 75, 80, 73, 69, 32, 38, 99, 66, 64, 82, 4, - 0, 66, 68, 33, 56, 42, 3, 76, 109, 16, 54, 62, - 113, 22, 21, 25, 28, 27, 23, 17, 22, 25, 12, - 19, 14, 7, 4, 0, 14, 13, 13, 11, 5, 9, 18, 9, - 69, 9, 11, 69, 18, 68, 60, 62, 49, 38, 47, 56, - 62, 62, 35, 19, 12, 15, 27, 25, 86, 17, 21, 3, - 36, 18, 18, 22, 27, 25, 32, 31, 6, 93, 64, 66, - 9, 112, 100, 68, 7, 10, 4, 76, 80, 85, 85, - 108, 86, 15, 4, 64, 70, 71, 78, 89, 88, 103, - 75, 20, 7, 2, 65, 66, 72, 77, 84, 96, 76, 8, - 65, 7, 5, 69, 77, 78, 90, 72, 29, 10, 9, 6, 0, - 69, 77, 77, 80, 62, 113, 111, 104, 110, 102, - 102, 102, 100, 98, 100, 100, 100, 87, 92, 92, - 97, 95, 88, 67, 82, 85, 83, 75, 71, 72, 66, - 76, 67, 66, 67, 68, 3, 68, 77, 65, 68, 74, 4, - 1, 66, 1, 10, 0, 71, 74, 74, 77, 67, 1, 2, 4, - 69, 66, 70, 6, 5, 72, 75, 75, 75, 6, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 56, 32, 62, 62, 62, 62, 55, 44, 31, 41, 38, - 28, 13, 7, 0, 79, 57, 54, 57, 42, 27, 30, 23, - 20, 28, 24, 16, 2, 13, 0, 75, 21, 26, 17, 25, - 31, 18, 15, 9, 8, 70, 2, 68, 79, 113, 66, 69, - 76, 17, 2, 71, 76, 69, 66, 65, 0, 0, 7, 66, - 64, 0, 6, 15, 13, 17, 2, 60, 55, 48, 44, 36, - 32, 17, 6, 76, 65, 31, 24, 21, 14, 12, 5, 2, - 64, 72, 76, 69, 66, 65, 0, 0, 7, 66, 64, 0, 6, - 15, 13, 17, 2, 60, 55, 48, 44, 36, 32, 17, 6, - 76 }, - - { - - 62, - 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 28, 46, - 54, 19, 4, 80, 30, 82, 85, 3, 2, 2, 66, 10, - 40, 44, 26, 67, 105, 105, 101, 72, 82, 85, 3, - 88, 78, 24, 6, 81, 92, 101, 70, 71, 86, 100, - 0, 81, 97, 66, 79, 87, 100, 6, 76, 73, 88, 18, - 3, 22, 0, 0, 0, 76, 88, 97, 67, 14, 64, 25, - 81, 113, 102, 79, 85, 66, 68, 80, 79, 105, 66, - 90, 81, 101, 87, 79, 85, 81, 13, 0, 73, 101, - 75, 96, 83, 106, 65, 77, 72, 89, 12, 70, 65, - 89, 83, 79, 78, 69, 64, 66, 78, 1, 5, 69, 4, - 68, 69, 4, 73, 22, 68, 1, 17, 19, 26, 25, 15, - 81, 71, 75, 5, 67, 86, 67, 2, 71, 74, 68, 14, - 41, 17, 74, 81, 74, 68, 32, 38, 99, 67, 64, - 82, 4, 64, 65, 67, 33, 56, 43, 4, 77, 108, 15, - 51, 62, 111, 22, 21, 25, 27, 27, 22, 17, 21, - 25, 12, 19, 14, 6, 4, 64, 14, 12, 12, 11, 5, - 9, 18, 8, 71, 9, 10, 69, 17, 68, 57, 62, 47, - 37, 45, 54, 62, 61, 33, 17, 10, 14, 25, 23, - 88, 16, 19, 1, 34, 17, 17, 21, 25, 23, 30, 29, - 5, 93, 65, 67, 8, 110, 98, 66, 8, 10, 4, 75, - 80, 85, 84, 107, 85, 16, 5, 0, 70, 70, 77, 88, - 87, 101, 75, 21, 8, 3, 65, 65, 72, 76, 83, 95, - 76, 10, 64, 7, 5, 69, 76, 78, 90, 72, 30, 10, - 10, 6, 1, 69, 77, 76, 80, 62, 111, 109, 102, - 108, 100, 101, 100, 99, 96, 98, 98, 98, 87, - 91, 92, 97, 92, 88, 68, 82, 85, 82, 75, 71, - 72, 66, 76, 67, 67, 67, 68, 3, 68, 77, 65, 68, - 74, 4, 1, 66, 0, 9, 0, 71, 74, 73, 78, 67, 2, - 1, 4, 69, 66, 69, 6, 5, 71, 74, 75, 75, 4, 62, - 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 53, 30, 62, 62, 62, 62, 53, 41, 29, 39, - 36, 26, 12, 6, 64, 79, 55, 52, 55, 40, 25, 29, - 22, 18, 26, 21, 14, 0, 11, 65, 76, 20, 24, 15, - 24, 29, 17, 13, 7, 6, 71, 1, 69, 80, 112, 67, - 71, 78, 16, 0, 72, 75, 68, 65, 65, 1, 1, 8, - 66, 0, 1, 7, 16, 14, 18, 3, 59, 53, 46, 42, - 34, 30, 15, 4, 77, 64, 31, 25, 22, 14, 13, 6, - 3, 0, 72, 75, 68, 65, 65, 1, 1, 8, 66, 0, 1, - 7, 16, 14, 18, 3, 59, 53, 46, 42, 34, 30, 15, - 4, 77 }, - - { - - 62, - 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 26, 45, - 53, 20, 4, 78, 28, 82, 84, 3, 2, 3, 67, 8, 38, - 42, 23, 69, 106, 103, 100, 72, 82, 84, 3, 88, - 77, 24, 5, 80, 91, 100, 71, 73, 87, 100, 0, - 81, 96, 66, 79, 87, 100, 6, 76, 73, 88, 19, 3, - 22, 0, 0, 0, 76, 89, 97, 66, 13, 64, 24, 81, - 112, 100, 78, 84, 65, 67, 80, 78, 103, 65, 89, - 80, 99, 88, 79, 85, 81, 13, 64, 72, 99, 75, - 95, 82, 104, 65, 77, 72, 89, 12, 70, 65, 88, - 83, 79, 78, 69, 64, 66, 77, 1, 5, 69, 3, 68, - 69, 4, 73, 22, 68, 1, 18, 19, 26, 25, 15, 82, - 71, 74, 5, 67, 86, 67, 3, 71, 74, 67, 15, 42, - 18, 72, 81, 75, 68, 32, 38, 100, 67, 0, 83, 5, - 64, 65, 66, 33, 56, 43, 5, 78, 106, 14, 48, - 60, 110, 21, 21, 24, 26, 26, 22, 16, 21, 24, - 11, 18, 13, 6, 4, 64, 13, 11, 11, 10, 4, 8, - 17, 8, 72, 8, 9, 69, 15, 69, 55, 62, 45, 35, - 43, 52, 62, 58, 32, 15, 7, 12, 23, 21, 89, 14, - 18, 64, 33, 16, 16, 20, 24, 21, 28, 27, 3, 93, - 66, 68, 6, 109, 97, 65, 8, 10, 4, 74, 79, 84, - 83, 105, 84, 17, 5, 1, 69, 69, 76, 86, 86, 99, - 74, 21, 8, 3, 64, 64, 71, 76, 83, 94, 76, 11, - 0, 7, 5, 68, 76, 78, 89, 71, 30, 11, 10, 6, 2, - 68, 76, 76, 79, 62, 110, 108, 101, 106, 99, - 99, 99, 97, 95, 97, 96, 96, 86, 90, 91, 96, - 89, 88, 69, 82, 84, 82, 75, 71, 72, 67, 75, - 67, 68, 67, 68, 4, 68, 77, 65, 68, 74, 3, 1, - 66, 64, 8, 0, 71, 74, 72, 79, 67, 2, 0, 4, 69, - 66, 69, 6, 4, 71, 73, 75, 75, 3, 62, 60, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 50, - 28, 62, 62, 62, 62, 50, 39, 27, 37, 33, 24, - 10, 5, 65, 79, 52, 50, 53, 38, 23, 27, 20, 16, - 24, 19, 12, 65, 8, 67, 77, 19, 23, 12, 22, 27, - 15, 11, 6, 5, 72, 0, 70, 80, 111, 68, 72, 79, - 15, 64, 73, 75, 68, 65, 64, 2, 1, 9, 66, 1, 2, - 8, 16, 15, 18, 4, 59, 51, 44, 40, 32, 28, 13, - 2, 79, 64, 32, 25, 23, 15, 13, 6, 3, 0, 71, - 75, 68, 65, 64, 2, 1, 9, 66, 1, 2, 8, 16, 15, - 18, 4, 59, 51, 44, 40, 32, 28, 13, 2, 79 }, - - { - - 62, - 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 24, 43, - 52, 21, 4, 77, 26, 81, 82, 2, 2, 4, 68, 7, 37, - 40, 20, 72, 106, 101, 99, 72, 81, 82, 2, 88, - 76, 24, 5, 80, 90, 98, 72, 74, 87, 100, 0, 80, - 95, 67, 79, 87, 100, 6, 75, 73, 87, 19, 3, 22, - 0, 0, 0, 75, 89, 97, 66, 12, 64, 24, 80, 110, - 97, 77, 83, 0, 65, 79, 77, 101, 64, 88, 79, - 96, 88, 80, 85, 82, 13, 64, 71, 96, 74, 95, - 82, 102, 65, 77, 72, 88, 12, 70, 64, 87, 82, - 78, 77, 69, 0, 65, 76, 2, 5, 70, 3, 67, 69, 4, - 73, 23, 68, 1, 18, 20, 26, 25, 15, 82, 70, 74, - 4, 67, 85, 67, 4, 70, 73, 65, 17, 43, 20, 70, - 82, 76, 67, 33, 38, 101, 67, 0, 83, 6, 64, 65, - 64, 33, 56, 43, 7, 79, 105, 13, 46, 57, 109, - 21, 21, 24, 26, 26, 22, 16, 21, 24, 10, 17, - 13, 6, 4, 64, 13, 11, 10, 10, 4, 8, 16, 7, 73, - 7, 9, 69, 14, 69, 53, 62, 44, 34, 42, 50, 62, - 56, 31, 13, 5, 11, 21, 19, 90, 13, 17, 65, 32, - 15, 15, 18, 22, 19, 26, 26, 2, 93, 67, 69, 4, - 107, 95, 64, 9, 10, 4, 73, 78, 83, 83, 103, - 82, 18, 6, 1, 68, 67, 75, 85, 85, 96, 73, 22, - 9, 4, 64, 0, 70, 75, 82, 93, 75, 12, 1, 7, 5, - 67, 75, 77, 88, 70, 30, 12, 10, 6, 3, 67, 75, - 75, 78, 62, 109, 106, 99, 105, 98, 98, 97, 95, - 93, 95, 94, 93, 85, 89, 90, 95, 86, 87, 70, - 81, 83, 81, 75, 71, 72, 67, 75, 68, 69, 67, - 68, 5, 68, 77, 65, 68, 73, 3, 0, 66, 65, 7, - 64, 71, 74, 71, 79, 68, 3, 0, 3, 69, 66, 69, - 5, 4, 71, 73, 75, 75, 1, 62, 59, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 60, 48, 26, 62, - 62, 62, 62, 47, 37, 26, 35, 31, 22, 9, 4, 66, - 79, 50, 47, 50, 36, 21, 25, 19, 14, 22, 17, - 10, 67, 6, 68, 79, 18, 22, 10, 21, 26, 14, 9, - 5, 4, 73, 64, 71, 80, 110, 70, 73, 81, 13, 65, - 74, 75, 67, 64, 0, 3, 2, 9, 65, 2, 3, 9, 17, - 16, 19, 4, 58, 49, 42, 38, 30, 26, 10, 0, 80, - 0, 32, 26, 23, 16, 14, 7, 4, 0, 70, 75, 67, - 64, 0, 3, 2, 9, 65, 2, 3, 9, 17, 16, 19, 4, - 58, 49, 42, 38, 30, 26, 10, 0, 80 }, - - { - - 61, - 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 22, 42, - 51, 21, 4, 75, 25, 81, 81, 2, 1, 5, 69, 6, 36, - 38, 16, 74, 107, 99, 97, 72, 81, 81, 2, 87, - 75, 25, 5, 79, 89, 97, 73, 75, 87, 101, 0, 80, - 94, 67, 80, 87, 100, 6, 75, 73, 86, 20, 3, 22, - 0, 0, 0, 75, 89, 97, 65, 11, 64, 23, 80, 109, - 95, 76, 82, 1, 64, 78, 76, 99, 0, 87, 78, 94, - 89, 80, 85, 82, 14, 64, 70, 94, 74, 94, 81, - 100, 65, 77, 72, 88, 13, 70, 64, 86, 82, 77, - 77, 69, 0, 65, 75, 2, 5, 70, 3, 67, 69, 4, 73, - 23, 68, 1, 19, 20, 27, 25, 16, 83, 70, 73, 4, - 67, 85, 67, 5, 70, 73, 64, 18, 44, 21, 68, 82, - 77, 67, 33, 38, 102, 67, 1, 84, 6, 64, 65, 0, - 33, 56, 43, 8, 80, 103, 12, 43, 54, 107, 21, - 21, 23, 25, 25, 21, 15, 21, 23, 9, 16, 13, 6, - 4, 65, 12, 10, 9, 9, 4, 8, 15, 7, 74, 7, 8, - 69, 13, 70, 51, 60, 42, 32, 40, 48, 62, 53, - 30, 11, 3, 9, 19, 17, 92, 12, 16, 67, 31, 14, - 14, 17, 21, 17, 24, 24, 0, 93, 68, 70, 3, 106, - 94, 1, 9, 10, 4, 72, 77, 82, 82, 101, 81, 19, - 7, 2, 68, 66, 74, 83, 84, 94, 73, 22, 9, 4, 0, - 1, 70, 75, 81, 92, 75, 14, 2, 7, 5, 66, 75, - 77, 87, 69, 31, 13, 11, 6, 4, 67, 74, 75, 78, - 62, 107, 105, 98, 103, 97, 96, 96, 94, 92, 93, - 92, 91, 85, 88, 90, 94, 83, 87, 71, 81, 82, - 80, 75, 71, 72, 67, 74, 68, 70, 67, 68, 5, 68, - 77, 65, 68, 73, 2, 0, 66, 66, 6, 64, 71, 74, - 70, 80, 68, 4, 64, 3, 69, 66, 68, 5, 3, 70, - 72, 75, 75, 0, 62, 58, 61, 61, 61, 62, 62, 62, - 61, 62, 62, 62, 57, 45, 24, 62, 60, 59, 60, - 44, 35, 24, 33, 28, 20, 8, 3, 67, 79, 48, 45, - 48, 34, 19, 23, 17, 12, 20, 15, 8, 69, 4, 70, - 80, 17, 21, 8, 19, 24, 12, 7, 3, 2, 74, 65, - 72, 80, 109, 71, 75, 82, 12, 66, 75, 75, 67, - 64, 0, 4, 3, 10, 65, 3, 4, 10, 17, 17, 19, 5, - 58, 47, 40, 36, 28, 24, 8, 65, 81, 0, 33, 26, - 24, 16, 15, 7, 4, 1, 70, 75, 67, 64, 0, 4, 3, - 10, 65, 3, 4, 10, 17, 17, 19, 5, 58, 47, 40, - 36, 28, 24, 8, 65, 81 }, - - { - - 60, - 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 20, 40, - 50, 22, 4, 73, 23, 81, 79, 2, 1, 6, 70, 5, 35, - 36, 13, 76, 108, 97, 96, 72, 81, 79, 2, 87, - 74, 25, 5, 78, 88, 96, 74, 76, 87, 101, 0, 80, - 93, 67, 80, 87, 100, 6, 75, 73, 85, 20, 3, 22, - 0, 0, 0, 74, 89, 97, 65, 10, 64, 23, 79, 108, - 93, 75, 81, 3, 1, 77, 75, 97, 1, 86, 77, 92, - 90, 80, 85, 82, 14, 64, 69, 92, 74, 93, 80, - 98, 65, 77, 72, 88, 13, 70, 0, 85, 82, 76, 77, - 69, 0, 64, 74, 3, 5, 70, 3, 67, 69, 4, 73, 23, - 68, 1, 19, 20, 27, 25, 16, 83, 69, 72, 3, 67, - 85, 67, 6, 70, 72, 0, 19, 45, 23, 66, 83, 78, - 66, 33, 38, 103, 67, 1, 84, 7, 64, 65, 1, 33, - 56, 43, 9, 81, 102, 11, 40, 51, 106, 21, 21, - 23, 24, 25, 21, 15, 21, 23, 8, 15, 13, 6, 4, - 65, 12, 9, 8, 9, 4, 8, 14, 6, 75, 6, 7, 69, - 12, 70, 49, 58, 40, 31, 38, 46, 59, 51, 29, 9, - 1, 8, 17, 15, 93, 11, 15, 69, 30, 13, 13, 16, - 19, 15, 22, 22, 64, 93, 69, 71, 1, 104, 92, 2, - 10, 10, 4, 71, 76, 81, 81, 99, 80, 20, 8, 3, - 67, 65, 73, 82, 83, 92, 72, 23, 10, 5, 0, 2, - 69, 74, 80, 91, 75, 15, 3, 7, 5, 65, 74, 77, - 86, 68, 31, 14, 11, 6, 5, 66, 73, 74, 77, 62, - 106, 103, 96, 101, 96, 95, 94, 92, 90, 91, 90, - 89, 84, 87, 89, 93, 80, 87, 72, 81, 81, 79, - 75, 71, 72, 67, 74, 68, 71, 67, 68, 6, 68, 77, - 65, 68, 73, 2, 0, 66, 67, 5, 64, 71, 74, 69, - 81, 68, 5, 65, 3, 69, 66, 68, 5, 3, 70, 71, - 75, 75, 65, 61, 57, 60, 59, 59, 62, 62, 62, - 59, 60, 62, 61, 54, 42, 22, 61, 57, 55, 55, - 41, 33, 22, 31, 26, 18, 7, 2, 68, 79, 46, 43, - 46, 32, 17, 21, 16, 10, 18, 13, 6, 71, 2, 72, - 81, 16, 20, 6, 18, 22, 11, 5, 2, 1, 75, 66, - 73, 80, 108, 72, 76, 84, 11, 67, 76, 75, 66, - 0, 1, 5, 4, 11, 65, 4, 5, 11, 18, 18, 20, 6, - 57, 45, 38, 34, 26, 22, 6, 67, 82, 1, 33, 27, - 25, 17, 16, 8, 5, 1, 69, 75, 66, 0, 1, 5, 4, - 11, 65, 4, 5, 11, 18, 18, 20, 6, 57, 45, 38, - 34, 26, 22, 6, 67, 82 }, - - { - - 58, - 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 18, 38, - 49, 22, 4, 72, 21, 81, 78, 1, 0, 7, 71, 3, 33, - 34, 9, 79, 109, 95, 95, 72, 81, 78, 1, 87, 74, - 25, 4, 78, 88, 95, 76, 78, 88, 102, 64, 80, - 93, 68, 81, 87, 100, 5, 75, 73, 85, 20, 2, 22, - 0, 0, 0, 74, 90, 97, 65, 9, 65, 22, 79, 107, - 91, 74, 81, 4, 2, 77, 74, 96, 1, 85, 77, 90, - 91, 81, 86, 83, 14, 65, 69, 90, 74, 93, 80, - 97, 65, 77, 72, 88, 13, 71, 0, 85, 82, 76, 77, - 69, 0, 64, 73, 3, 5, 71, 2, 67, 69, 3, 73, 23, - 68, 1, 19, 20, 27, 25, 16, 84, 69, 72, 2, 67, - 85, 68, 6, 70, 72, 1, 20, 45, 24, 65, 84, 80, - 66, 33, 38, 104, 68, 1, 85, 7, 65, 65, 2, 33, - 55, 43, 10, 82, 101, 9, 37, 47, 105, 20, 21, - 22, 23, 24, 20, 14, 20, 22, 7, 14, 12, 5, 3, - 66, 11, 8, 7, 8, 3, 7, 13, 5, 77, 5, 6, 69, - 10, 71, 46, 55, 38, 29, 36, 43, 55, 48, 27, 7, - 65, 6, 14, 13, 95, 9, 13, 71, 28, 12, 12, 14, - 17, 13, 20, 20, 66, 93, 70, 72, 64, 103, 91, - 3, 10, 10, 4, 71, 76, 81, 81, 98, 79, 20, 8, - 3, 67, 64, 72, 81, 83, 90, 72, 23, 10, 5, 0, - 2, 69, 74, 80, 90, 75, 16, 4, 7, 4, 65, 74, - 77, 86, 68, 31, 14, 11, 6, 6, 66, 73, 74, 77, - 62, 105, 102, 95, 100, 95, 94, 93, 91, 89, 90, - 89, 87, 84, 87, 89, 93, 77, 87, 74, 81, 81, - 79, 75, 71, 72, 68, 74, 69, 72, 68, 68, 6, 69, - 77, 66, 68, 73, 1, 64, 67, 68, 4, 65, 72, 74, - 68, 82, 69, 5, 66, 2, 69, 67, 68, 4, 2, 70, - 71, 75, 75, 67, 59, 56, 58, 57, 56, 62, 62, - 62, 56, 57, 62, 58, 50, 39, 20, 57, 53, 51, - 49, 38, 30, 20, 28, 23, 16, 5, 0, 69, 79, 43, - 40, 43, 30, 14, 19, 14, 7, 16, 10, 4, 74, 64, - 74, 83, 14, 18, 3, 16, 20, 9, 3, 0, 64, 76, - 67, 74, 81, 107, 74, 78, 86, 9, 69, 78, 75, - 66, 0, 1, 6, 4, 11, 65, 5, 5, 12, 18, 18, 20, - 6, 56, 43, 36, 31, 23, 20, 3, 69, 84, 1, 33, - 27, 25, 17, 16, 8, 5, 1, 69, 75, 66, 0, 1, 6, - 4, 11, 65, 5, 5, 12, 18, 18, 20, 6, 56, 43, - 36, 31, 23, 20, 3, 69, 84 }, - - { - - 57, - 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 17, 37, - 49, 23, 5, 70, 20, 80, 76, 1, 0, 9, 71, 2, 32, - 33, 6, 81, 109, 93, 93, 71, 80, 76, 1, 86, 73, - 26, 4, 77, 87, 93, 77, 79, 88, 102, 64, 79, - 92, 68, 81, 86, 99, 5, 74, 72, 84, 21, 2, 22, - 0, 0, 0, 73, 90, 97, 64, 9, 65, 22, 78, 105, - 88, 72, 80, 6, 4, 76, 72, 94, 2, 83, 76, 87, - 91, 81, 86, 83, 15, 65, 68, 87, 73, 92, 79, - 95, 65, 76, 72, 87, 14, 71, 1, 84, 81, 75, 76, - 68, 1, 0, 72, 4, 6, 71, 2, 66, 68, 3, 72, 24, - 67, 1, 20, 21, 28, 26, 17, 84, 68, 71, 2, 67, - 84, 68, 7, 69, 71, 3, 22, 46, 26, 0, 84, 81, - 65, 34, 39, 104, 68, 2, 85, 8, 65, 64, 4, 33, - 55, 44, 12, 83, 99, 8, 35, 44, 103, 20, 21, - 22, 23, 24, 20, 14, 20, 22, 7, 14, 12, 5, 3, - 66, 11, 8, 7, 8, 3, 7, 13, 5, 78, 5, 6, 69, 9, - 71, 44, 53, 37, 28, 35, 41, 52, 46, 26, 6, 67, - 5, 12, 12, 96, 8, 12, 72, 27, 12, 12, 13, 16, - 12, 19, 19, 67, 93, 70, 72, 65, 101, 89, 5, - 11, 10, 4, 70, 75, 80, 80, 96, 77, 21, 9, 4, - 66, 1, 71, 79, 82, 87, 71, 24, 11, 6, 1, 3, - 68, 73, 79, 88, 74, 18, 5, 8, 4, 64, 73, 76, - 85, 67, 32, 15, 12, 7, 7, 65, 72, 73, 76, 62, - 103, 100, 93, 98, 93, 92, 91, 89, 87, 88, 87, - 84, 83, 86, 88, 92, 73, 86, 75, 80, 80, 78, - 74, 71, 71, 68, 73, 69, 72, 68, 68, 7, 69, 77, - 66, 68, 72, 1, 64, 67, 68, 4, 65, 72, 73, 66, - 82, 69, 6, 66, 2, 69, 67, 67, 4, 2, 69, 70, - 74, 74, 68, 58, 55, 57, 56, 54, 60, 60, 59, - 54, 55, 59, 56, 47, 37, 18, 54, 50, 48, 44, - 36, 28, 19, 26, 21, 15, 4, 64, 69, 79, 41, 38, - 41, 28, 12, 18, 13, 5, 15, 8, 3, 76, 66, 75, - 84, 13, 17, 1, 15, 19, 8, 2, 64, 65, 77, 67, - 74, 81, 106, 75, 79, 87, 8, 70, 79, 74, 65, 1, - 2, 8, 5, 12, 64, 7, 6, 13, 19, 19, 21, 7, 56, - 42, 35, 29, 21, 19, 1, 70, 85, 2, 34, 28, 26, - 18, 17, 9, 6, 2, 68, 74, 65, 1, 2, 8, 5, 12, - 64, 7, 6, 13, 19, 19, 21, 7, 56, 42, 35, 29, - 21, 19, 1, 70, 85 }, - - { - - 56, - 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 15, 35, - 48, 24, 5, 68, 18, 80, 75, 1, 0, 10, 72, 1, - 31, 31, 3, 83, 110, 91, 92, 71, 80, 75, 1, 86, - 72, 26, 4, 76, 86, 92, 78, 80, 88, 102, 64, - 79, 91, 68, 81, 86, 99, 5, 74, 72, 83, 21, 2, - 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 22, 77, - 104, 86, 71, 79, 8, 6, 75, 71, 92, 3, 82, 75, - 85, 92, 81, 86, 83, 15, 65, 67, 85, 73, 91, - 78, 93, 65, 76, 72, 87, 14, 71, 1, 83, 81, 74, - 76, 68, 1, 0, 71, 5, 6, 71, 2, 66, 68, 3, 72, - 24, 67, 1, 20, 21, 28, 26, 17, 85, 67, 70, 1, - 67, 84, 68, 8, 69, 71, 4, 23, 47, 28, 2, 85, - 82, 65, 34, 39, 105, 68, 2, 86, 9, 65, 64, 5, - 33, 55, 44, 13, 84, 98, 7, 32, 41, 102, 20, - 21, 22, 22, 23, 20, 14, 20, 21, 6, 13, 12, 5, - 3, 66, 10, 7, 6, 8, 3, 7, 12, 4, 79, 4, 5, 69, - 8, 72, 42, 51, 35, 26, 33, 39, 49, 44, 25, 4, - 69, 3, 10, 10, 97, 7, 11, 74, 26, 11, 11, 12, - 14, 10, 17, 17, 69, 93, 71, 73, 67, 100, 88, - 6, 12, 10, 4, 69, 74, 79, 79, 94, 76, 22, 10, - 5, 65, 2, 70, 78, 81, 85, 70, 24, 11, 6, 1, 4, - 67, 72, 78, 87, 74, 19, 6, 8, 4, 0, 72, 76, - 84, 66, 32, 16, 12, 7, 8, 64, 71, 72, 75, 62, - 102, 98, 91, 96, 92, 91, 89, 87, 86, 86, 85, - 82, 82, 85, 87, 91, 70, 86, 76, 80, 79, 77, - 74, 71, 71, 68, 73, 69, 73, 68, 68, 8, 69, 77, - 66, 68, 72, 1, 64, 67, 69, 3, 65, 72, 73, 65, - 83, 69, 7, 67, 2, 69, 67, 67, 4, 2, 69, 69, - 74, 74, 70, 57, 54, 56, 54, 52, 57, 57, 56, - 52, 52, 56, 53, 44, 34, 16, 50, 46, 44, 39, - 33, 26, 17, 24, 19, 13, 3, 65, 70, 79, 39, 36, - 39, 26, 10, 16, 11, 3, 13, 6, 1, 78, 68, 77, - 85, 12, 16, 64, 13, 17, 6, 0, 65, 66, 78, 68, - 75, 81, 105, 76, 80, 89, 7, 71, 80, 74, 65, 2, - 3, 9, 6, 13, 64, 8, 7, 14, 19, 20, 22, 8, 55, - 40, 33, 27, 19, 17, 64, 72, 86, 3, 34, 28, 27, - 19, 18, 9, 7, 2, 67, 74, 65, 2, 3, 9, 6, 13, - 64, 8, 7, 14, 19, 20, 22, 8, 55, 40, 33, 27, - 19, 17, 64, 72, 86 }, - - { - - 55, - 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 13, 34, - 47, 24, 5, 66, 17, 80, 73, 1, 64, 11, 73, 0, - 30, 29, 64, 85, 111, 89, 90, 71, 80, 73, 1, - 85, 71, 27, 4, 75, 85, 91, 79, 81, 88, 103, - 64, 79, 90, 68, 82, 86, 99, 5, 74, 72, 82, 22, - 2, 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 21, 77, - 103, 84, 70, 78, 9, 7, 74, 70, 90, 4, 81, 74, - 83, 93, 81, 86, 83, 16, 65, 66, 83, 73, 90, - 77, 91, 65, 76, 72, 87, 15, 71, 2, 82, 81, 73, - 76, 68, 1, 1, 70, 5, 6, 71, 2, 66, 68, 3, 72, - 24, 67, 1, 21, 21, 29, 26, 18, 85, 67, 69, 1, - 67, 84, 68, 9, 69, 70, 5, 24, 48, 29, 4, 85, - 83, 64, 34, 39, 106, 68, 3, 86, 9, 65, 64, 6, - 33, 55, 44, 14, 85, 96, 6, 29, 38, 100, 20, - 21, 21, 21, 23, 19, 13, 20, 21, 5, 12, 12, 5, - 3, 67, 10, 6, 5, 7, 3, 7, 11, 4, 80, 4, 4, 69, - 7, 72, 40, 49, 33, 25, 31, 37, 46, 41, 24, 2, - 71, 2, 8, 8, 99, 6, 10, 76, 25, 10, 10, 11, - 13, 8, 15, 15, 70, 93, 72, 74, 68, 98, 86, 8, - 12, 10, 4, 68, 73, 78, 78, 92, 75, 23, 11, 6, - 65, 3, 69, 76, 80, 83, 70, 25, 12, 7, 2, 5, - 67, 72, 77, 86, 74, 21, 7, 8, 4, 1, 72, 76, - 83, 65, 33, 17, 13, 7, 9, 64, 70, 72, 75, 62, - 100, 97, 90, 94, 91, 89, 88, 86, 84, 84, 83, - 80, 82, 84, 87, 90, 67, 86, 77, 80, 78, 76, - 74, 71, 71, 68, 72, 69, 74, 68, 68, 8, 69, 77, - 66, 68, 72, 0, 64, 67, 70, 2, 65, 72, 73, 64, - 84, 69, 8, 68, 2, 69, 67, 66, 4, 1, 68, 68, - 74, 74, 71, 56, 53, 55, 52, 50, 55, 55, 53, - 49, 49, 53, 50, 41, 31, 14, 46, 43, 40, 34, - 30, 24, 15, 22, 16, 11, 2, 66, 71, 79, 37, 34, - 37, 24, 8, 14, 10, 1, 11, 4, 64, 80, 70, 79, - 86, 11, 15, 66, 12, 15, 5, 65, 67, 68, 79, 69, - 76, 81, 104, 77, 82, 90, 6, 72, 81, 74, 64, 2, - 3, 10, 7, 14, 64, 9, 8, 15, 20, 21, 22, 9, 55, - 38, 31, 25, 17, 15, 66, 74, 87, 3, 35, 29, 28, - 19, 19, 10, 7, 3, 67, 74, 64, 2, 3, 10, 7, 14, - 64, 9, 8, 15, 20, 21, 22, 9, 55, 38, 31, 25, - 17, 15, 66, 74, 87 }, - - { - - 53, - 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 11, 32, - 46, 25, 5, 65, 15, 80, 72, 0, 64, 12, 74, 65, - 28, 27, 67, 88, 112, 87, 89, 71, 80, 72, 0, - 85, 70, 27, 3, 75, 84, 89, 80, 83, 89, 103, - 64, 78, 89, 69, 82, 86, 99, 5, 74, 72, 82, 22, - 2, 22, 0, 0, 0, 71, 91, 97, 0, 6, 65, 21, 76, - 102, 82, 69, 77, 11, 9, 74, 69, 88, 5, 80, 73, - 80, 93, 82, 86, 84, 16, 66, 65, 80, 72, 90, - 77, 89, 65, 76, 72, 87, 15, 71, 2, 81, 81, 73, - 75, 68, 1, 1, 69, 6, 6, 72, 1, 66, 68, 3, 72, - 24, 67, 1, 21, 21, 29, 26, 18, 86, 66, 69, 0, - 67, 83, 68, 10, 68, 70, 7, 26, 49, 31, 6, 86, - 84, 64, 35, 39, 107, 68, 3, 87, 10, 65, 64, 7, - 33, 55, 44, 16, 86, 95, 5, 26, 35, 99, 19, 21, - 21, 21, 22, 19, 13, 20, 20, 4, 11, 11, 5, 3, - 67, 9, 6, 4, 7, 2, 6, 10, 3, 81, 3, 3, 69, 5, - 73, 38, 47, 31, 23, 30, 35, 42, 39, 23, 0, 74, - 0, 6, 6, 100, 4, 9, 77, 24, 9, 9, 9, 11, 6, - 13, 14, 72, 93, 73, 75, 70, 97, 85, 9, 13, 10, - 4, 67, 72, 77, 78, 90, 73, 24, 11, 6, 64, 5, - 68, 75, 79, 80, 69, 25, 12, 7, 2, 6, 66, 71, - 77, 85, 74, 22, 8, 8, 4, 2, 71, 76, 82, 64, - 33, 18, 13, 7, 10, 0, 69, 71, 74, 62, 99, 95, - 88, 93, 90, 88, 86, 84, 83, 83, 81, 77, 81, - 83, 86, 89, 64, 85, 78, 79, 77, 76, 74, 71, - 71, 69, 72, 70, 75, 68, 68, 9, 69, 77, 66, 68, - 71, 0, 65, 67, 71, 1, 66, 72, 73, 0, 85, 70, - 8, 68, 1, 69, 67, 66, 3, 1, 68, 68, 74, 74, - 73, 55, 52, 54, 51, 47, 52, 52, 50, 47, 46, - 49, 47, 37, 29, 12, 42, 39, 36, 29, 27, 22, - 13, 20, 14, 9, 0, 67, 72, 79, 34, 31, 34, 22, - 6, 12, 8, 64, 9, 2, 66, 82, 73, 80, 88, 10, - 14, 69, 10, 14, 3, 67, 68, 69, 80, 70, 77, 81, - 103, 79, 83, 92, 4, 73, 82, 74, 64, 3, 4, 11, - 7, 14, 0, 10, 9, 16, 20, 22, 23, 9, 54, 36, - 29, 23, 15, 13, 69, 76, 89, 4, 35, 29, 28, 20, - 19, 10, 8, 3, 66, 74, 64, 3, 4, 11, 7, 14, 0, - 10, 9, 16, 20, 22, 23, 9, 54, 36, 29, 23, 15, - 13, 69, 76, 89 }, - - { - - 52, - 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 9, 31, - 45, 26, 5, 0, 13, 79, 70, 0, 64, 13, 75, 66, - 27, 25, 70, 90, 112, 85, 88, 71, 79, 70, 0, - 85, 69, 27, 3, 74, 83, 88, 81, 84, 89, 103, - 64, 78, 88, 69, 82, 86, 99, 5, 73, 72, 81, 23, - 2, 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 20, 76, - 100, 79, 68, 76, 12, 10, 73, 68, 86, 6, 79, - 72, 78, 94, 82, 86, 84, 16, 66, 64, 78, 72, - 89, 76, 87, 65, 76, 72, 86, 15, 71, 3, 80, 80, - 72, 75, 68, 2, 2, 68, 6, 6, 72, 1, 65, 68, 3, - 72, 25, 67, 1, 22, 22, 29, 26, 18, 86, 66, 68, - 0, 67, 83, 68, 11, 68, 69, 8, 27, 50, 32, 8, - 86, 85, 0, 35, 39, 108, 68, 4, 87, 11, 65, 64, - 9, 33, 55, 44, 17, 87, 93, 4, 24, 32, 98, 19, - 21, 20, 20, 22, 19, 12, 20, 20, 3, 10, 11, 5, - 3, 67, 9, 5, 3, 6, 2, 6, 9, 3, 82, 2, 3, 69, - 4, 73, 36, 45, 30, 22, 28, 33, 39, 36, 22, 65, - 76, 64, 4, 4, 101, 3, 8, 79, 23, 8, 8, 8, 10, - 4, 11, 12, 73, 93, 74, 76, 72, 95, 83, 10, 13, - 10, 4, 66, 71, 76, 77, 88, 72, 25, 12, 7, 0, - 6, 67, 73, 78, 78, 68, 26, 13, 8, 3, 7, 65, - 71, 76, 84, 73, 23, 9, 8, 4, 3, 71, 75, 81, 0, - 33, 19, 13, 7, 11, 1, 68, 71, 73, 62, 98, 94, - 87, 91, 89, 86, 85, 82, 81, 81, 79, 75, 80, - 82, 85, 88, 2, 85, 79, 79, 76, 75, 74, 71, 71, - 69, 71, 70, 76, 68, 68, 10, 69, 77, 66, 68, - 71, 64, 65, 67, 72, 0, 66, 72, 73, 1, 85, 70, - 9, 69, 1, 69, 67, 66, 3, 0, 68, 67, 74, 74, - 74, 54, 51, 53, 49, 45, 50, 49, 47, 44, 43, - 46, 44, 34, 26, 10, 38, 36, 32, 24, 24, 20, - 12, 18, 11, 7, 64, 68, 73, 79, 32, 29, 32, 20, - 4, 10, 7, 66, 7, 0, 68, 84, 75, 82, 89, 9, 13, - 71, 9, 12, 2, 69, 69, 70, 81, 71, 78, 81, 102, - 80, 84, 93, 3, 74, 83, 74, 0, 3, 5, 12, 8, 15, - 0, 11, 10, 17, 21, 23, 23, 10, 54, 34, 27, 21, - 13, 11, 71, 78, 90, 4, 36, 30, 29, 21, 20, 11, - 8, 3, 65, 74, 0, 3, 5, 12, 8, 15, 0, 11, 10, - 17, 21, 23, 23, 10, 54, 34, 27, 21, 13, 11, - 71, 78, 90 }, - - { - - 51, - 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 8, 29, - 44, 26, 6, 2, 12, 79, 69, 0, 65, 14, 76, 67, - 26, 24, 74, 92, 113, 83, 86, 71, 79, 69, 0, - 84, 68, 28, 3, 73, 82, 87, 83, 85, 89, 104, - 64, 78, 88, 69, 83, 85, 99, 4, 73, 72, 80, 23, - 2, 22, 0, 0, 0, 70, 91, 97, 1, 5, 66, 20, 75, - 99, 77, 67, 75, 14, 12, 72, 67, 84, 7, 78, 72, - 76, 95, 82, 86, 84, 17, 66, 0, 76, 72, 88, 75, - 85, 65, 76, 72, 86, 16, 72, 3, 80, 80, 71, 75, - 67, 2, 2, 67, 7, 6, 72, 1, 65, 68, 3, 72, 25, - 67, 1, 22, 22, 30, 27, 19, 87, 65, 67, 64, 67, - 83, 68, 12, 68, 69, 9, 28, 50, 34, 9, 87, 86, - 0, 35, 39, 108, 69, 4, 88, 11, 66, 0, 10, 33, - 55, 45, 18, 88, 92, 3, 21, 29, 96, 19, 21, 20, - 19, 21, 18, 12, 19, 19, 3, 10, 11, 4, 3, 68, - 8, 4, 2, 6, 2, 6, 9, 2, 84, 2, 2, 69, 3, 74, - 33, 43, 28, 20, 26, 31, 36, 34, 20, 67, 78, - 66, 2, 2, 103, 2, 6, 81, 21, 7, 7, 7, 8, 2, 9, - 10, 75, 93, 75, 77, 73, 94, 82, 12, 14, 10, 4, - 65, 71, 76, 76, 87, 71, 26, 13, 8, 0, 7, 66, - 72, 77, 76, 68, 26, 13, 8, 3, 8, 65, 70, 75, - 83, 73, 25, 10, 8, 4, 3, 70, 75, 81, 0, 34, - 19, 14, 7, 12, 1, 68, 70, 73, 62, 96, 92, 85, - 89, 87, 85, 83, 81, 80, 79, 77, 73, 80, 81, - 85, 88, 5, 85, 80, 79, 76, 74, 74, 71, 71, 69, - 71, 70, 77, 68, 68, 10, 69, 77, 66, 68, 71, - 64, 65, 67, 73, 64, 66, 72, 73, 2, 86, 70, 10, - 70, 1, 69, 67, 65, 3, 0, 67, 66, 74, 74, 76, - 53, 50, 52, 47, 43, 47, 47, 44, 42, 40, 43, - 41, 31, 23, 8, 35, 32, 28, 19, 22, 17, 10, 16, - 9, 5, 65, 69, 74, 79, 30, 27, 30, 18, 2, 9, 5, - 68, 5, 66, 70, 86, 77, 84, 90, 8, 11, 73, 7, - 10, 0, 71, 71, 72, 82, 72, 79, 82, 101, 81, - 86, 95, 2, 76, 84, 73, 0, 4, 5, 13, 9, 16, 0, - 12, 11, 18, 21, 24, 24, 11, 53, 32, 25, 19, - 11, 9, 73, 80, 91, 5, 36, 30, 30, 21, 21, 11, - 9, 4, 65, 73, 0, 4, 5, 13, 9, 16, 0, 12, 11, - 18, 21, 24, 24, 11, 53, 32, 25, 19, 11, 9, 73, - 80, 91 }, - - { - - 50, - 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 6, 28, - 43, 27, 6, 3, 10, 79, 67, 64, 65, 15, 77, 68, - 25, 22, 77, 95, 114, 81, 85, 71, 79, 67, 64, - 84, 67, 28, 3, 73, 81, 85, 84, 86, 89, 104, - 64, 77, 87, 70, 83, 85, 99, 4, 73, 72, 79, 24, - 2, 22, 0, 0, 0, 70, 91, 97, 2, 4, 66, 19, 75, - 98, 75, 66, 74, 15, 13, 71, 66, 82, 8, 77, 71, - 73, 95, 83, 86, 85, 17, 66, 1, 73, 71, 88, 75, - 83, 65, 76, 72, 86, 16, 72, 4, 79, 80, 70, 74, - 67, 2, 3, 66, 7, 6, 73, 1, 65, 68, 3, 72, 25, - 67, 1, 23, 22, 30, 27, 19, 87, 65, 67, 64, 67, - 82, 68, 13, 67, 68, 11, 30, 51, 35, 11, 87, - 87, 1, 36, 39, 109, 69, 5, 88, 12, 66, 0, 11, - 33, 55, 45, 20, 89, 90, 2, 18, 26, 95, 19, 21, - 19, 19, 21, 18, 11, 19, 19, 2, 9, 11, 4, 3, - 68, 8, 4, 1, 5, 2, 6, 8, 2, 85, 1, 1, 69, 2, - 74, 31, 41, 26, 19, 25, 29, 33, 31, 19, 69, - 80, 67, 0, 0, 104, 1, 5, 82, 20, 6, 6, 5, 7, - 0, 7, 9, 76, 93, 76, 78, 75, 92, 80, 13, 14, - 10, 4, 64, 70, 75, 76, 85, 69, 27, 14, 8, 1, - 9, 65, 70, 76, 73, 67, 27, 14, 9, 4, 9, 64, - 70, 74, 82, 73, 26, 11, 8, 4, 4, 70, 75, 80, - 1, 34, 20, 14, 7, 13, 2, 67, 70, 72, 62, 95, - 91, 84, 88, 86, 83, 82, 79, 78, 77, 75, 70, - 79, 80, 84, 87, 8, 84, 81, 78, 75, 73, 74, 71, - 71, 69, 70, 71, 78, 68, 68, 11, 69, 77, 66, - 68, 70, 65, 66, 67, 74, 65, 67, 72, 73, 3, 87, - 71, 11, 70, 0, 69, 67, 65, 2, 64, 67, 66, 74, - 74, 77, 52, 49, 51, 46, 40, 45, 44, 41, 39, - 37, 40, 38, 28, 21, 6, 31, 29, 24, 14, 19, 15, - 8, 14, 6, 3, 66, 70, 75, 79, 28, 24, 27, 16, - 0, 7, 4, 70, 3, 68, 72, 88, 79, 85, 92, 7, 10, - 75, 6, 9, 64, 73, 72, 73, 83, 73, 80, 82, 100, - 83, 87, 96, 0, 77, 85, 73, 1, 4, 6, 14, 10, - 16, 1, 13, 12, 19, 22, 25, 24, 11, 53, 30, 23, - 17, 9, 7, 76, 82, 92, 5, 37, 31, 30, 22, 22, - 12, 9, 4, 64, 73, 1, 4, 6, 14, 10, 16, 1, 13, - 12, 19, 22, 25, 24, 11, 53, 30, 23, 17, 9, 7, - 76, 82, 92 }, - - { - - 48, - 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 4, 26, - 42, 27, 6, 5, 8, 79, 66, 64, 66, 16, 78, 70, - 23, 20, 81, 97, 115, 79, 84, 71, 79, 66, 64, - 84, 67, 28, 2, 72, 80, 84, 85, 88, 90, 105, - 64, 77, 86, 70, 84, 85, 99, 4, 73, 72, 79, 24, - 2, 22, 0, 0, 0, 69, 92, 97, 2, 3, 66, 19, 74, - 97, 73, 65, 74, 17, 15, 71, 65, 80, 8, 76, 70, - 71, 96, 83, 87, 85, 17, 67, 1, 71, 71, 87, 74, - 82, 65, 76, 72, 86, 16, 72, 4, 78, 80, 70, 74, - 67, 2, 3, 65, 8, 6, 73, 0, 65, 68, 2, 72, 25, - 67, 1, 23, 22, 30, 27, 19, 88, 64, 66, 65, 67, - 82, 68, 14, 67, 68, 12, 31, 52, 37, 13, 88, - 88, 1, 36, 39, 110, 69, 5, 89, 12, 66, 0, 12, - 33, 55, 45, 21, 90, 89, 1, 15, 22, 94, 18, 21, - 19, 18, 20, 17, 11, 19, 18, 1, 8, 10, 4, 2, - 69, 7, 3, 0, 5, 1, 5, 7, 1, 86, 0, 0, 69, 0, - 75, 29, 39, 24, 17, 23, 26, 29, 29, 18, 71, - 83, 69, 66, 65, 106, 64, 4, 84, 19, 5, 5, 4, - 5, 65, 5, 7, 78, 93, 77, 79, 77, 91, 79, 14, - 15, 10, 4, 64, 69, 74, 75, 83, 68, 27, 14, 9, - 1, 10, 64, 69, 75, 71, 67, 27, 14, 9, 4, 9, - 64, 69, 74, 81, 73, 27, 12, 8, 4, 5, 69, 75, - 79, 2, 34, 21, 14, 7, 14, 2, 66, 69, 72, 62, - 94, 89, 82, 86, 85, 82, 80, 78, 77, 76, 73, - 68, 79, 79, 84, 86, 11, 84, 82, 78, 74, 73, - 74, 71, 71, 70, 70, 71, 79, 68, 68, 11, 69, - 77, 67, 68, 70, 65, 66, 68, 75, 66, 67, 73, - 73, 4, 88, 71, 11, 71, 0, 69, 68, 65, 2, 64, - 67, 65, 74, 74, 79, 51, 48, 50, 44, 38, 42, - 41, 38, 37, 34, 36, 35, 24, 18, 4, 27, 25, 20, - 9, 16, 13, 6, 11, 4, 1, 68, 72, 76, 79, 25, - 22, 25, 14, 66, 5, 2, 73, 1, 70, 74, 90, 82, - 87, 93, 5, 9, 78, 4, 7, 66, 75, 74, 75, 84, - 74, 81, 82, 99, 84, 89, 98, 64, 78, 86, 73, 1, - 5, 6, 15, 10, 17, 1, 14, 12, 20, 22, 25, 25, - 12, 52, 28, 21, 15, 7, 5, 78, 84, 94, 6, 37, - 31, 31, 22, 22, 12, 10, 4, 64, 73, 1, 5, 6, - 15, 10, 17, 1, 14, 12, 20, 22, 25, 25, 12, 52, - 28, 21, 15, 7, 5, 78, 84, 94 }, - - { - - 47, - 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 2, 24, - 42, 28, 6, 7, 7, 78, 64, 64, 66, 17, 78, 71, - 22, 18, 84, 99, 115, 77, 82, 70, 78, 64, 64, - 83, 66, 29, 2, 71, 79, 83, 86, 89, 90, 105, - 64, 77, 85, 70, 84, 85, 99, 4, 72, 71, 78, 24, - 2, 22, 0, 0, 0, 68, 92, 97, 2, 2, 66, 19, 73, - 95, 70, 64, 73, 19, 17, 70, 64, 78, 9, 74, 69, - 69, 97, 83, 87, 85, 18, 67, 2, 69, 71, 86, 73, - 80, 65, 75, 72, 85, 17, 72, 5, 77, 79, 69, 74, - 67, 3, 4, 64, 9, 6, 73, 0, 64, 67, 2, 72, 26, - 67, 1, 23, 23, 31, 27, 20, 88, 0, 65, 66, 67, - 82, 68, 15, 67, 67, 13, 32, 53, 39, 15, 89, - 89, 2, 36, 40, 111, 69, 5, 89, 13, 66, 0, 14, - 33, 55, 45, 22, 91, 88, 0, 13, 19, 92, 18, 21, - 19, 17, 20, 17, 11, 19, 18, 0, 7, 10, 4, 2, - 69, 7, 2, 0, 5, 1, 5, 6, 0, 87, 0, 0, 69, 64, - 75, 27, 37, 23, 16, 21, 24, 26, 27, 17, 73, - 85, 70, 68, 66, 107, 65, 3, 86, 18, 4, 4, 3, - 3, 66, 3, 5, 79, 93, 77, 80, 78, 89, 77, 16, - 16, 10, 4, 0, 68, 73, 74, 81, 67, 28, 15, 10, - 2, 11, 0, 68, 74, 69, 66, 28, 15, 10, 4, 10, - 0, 68, 73, 79, 72, 29, 13, 9, 4, 6, 68, 74, - 78, 3, 35, 22, 15, 8, 15, 3, 65, 68, 71, 62, - 92, 87, 80, 84, 84, 81, 78, 76, 75, 74, 71, - 66, 78, 78, 83, 85, 15, 84, 83, 78, 73, 72, - 73, 71, 71, 70, 70, 71, 80, 68, 68, 12, 69, - 77, 67, 68, 70, 65, 66, 68, 75, 67, 67, 73, - 72, 6, 88, 71, 12, 72, 0, 69, 68, 64, 2, 64, - 66, 64, 73, 73, 81, 50, 47, 49, 42, 36, 39, - 39, 35, 35, 32, 33, 33, 21, 15, 2, 23, 22, 17, - 4, 13, 11, 5, 9, 2, 0, 69, 73, 77, 79, 23, 20, - 23, 12, 68, 3, 1, 75, 64, 72, 76, 92, 84, 89, - 94, 4, 8, 80, 3, 5, 67, 77, 75, 76, 85, 75, - 81, 82, 98, 85, 90, 100, 65, 79, 87, 73, 2, 6, - 7, 17, 11, 18, 1, 15, 13, 21, 23, 26, 26, 13, - 51, 27, 19, 13, 5, 3, 80, 86, 95, 7, 37, 32, - 32, 23, 23, 13, 11, 5, 0, 73, 2, 6, 7, 17, 11, - 18, 1, 15, 13, 21, 23, 26, 26, 13, 51, 27, 19, - 13, 5, 3, 80, 86, 95 }, - - { - - 46, - 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 0, 23, - 41, 29, 6, 8, 5, 78, 0, 65, 66, 18, 79, 72, - 21, 16, 87, 102, 116, 75, 81, 70, 78, 0, 65, - 83, 65, 29, 2, 71, 78, 81, 87, 90, 90, 105, - 64, 76, 84, 71, 84, 85, 99, 4, 72, 71, 77, 25, - 2, 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 18, 73, - 94, 68, 0, 72, 20, 18, 69, 0, 76, 10, 73, 68, - 66, 97, 84, 87, 86, 18, 67, 3, 66, 70, 86, 73, - 78, 65, 75, 72, 85, 17, 72, 5, 76, 79, 68, 73, - 67, 3, 4, 0, 9, 6, 74, 0, 64, 67, 2, 72, 26, - 67, 1, 24, 23, 31, 27, 20, 89, 0, 65, 66, 67, - 81, 68, 16, 66, 67, 15, 34, 54, 40, 17, 89, - 90, 2, 37, 40, 112, 69, 6, 90, 14, 66, 0, 15, - 33, 55, 45, 24, 92, 86, 64, 10, 16, 91, 18, - 21, 18, 17, 19, 17, 10, 19, 17, 64, 6, 10, 4, - 2, 69, 6, 2, 64, 4, 1, 5, 5, 0, 88, 64, 64, - 69, 65, 76, 25, 35, 21, 14, 20, 22, 23, 24, - 16, 75, 87, 72, 70, 68, 108, 66, 2, 87, 17, 3, - 3, 1, 2, 68, 1, 4, 81, 93, 78, 81, 80, 88, 76, - 17, 16, 10, 4, 1, 67, 72, 74, 79, 65, 29, 16, - 10, 3, 13, 1, 66, 73, 66, 65, 28, 15, 10, 5, - 11, 1, 68, 72, 78, 72, 30, 14, 9, 4, 7, 68, - 74, 77, 4, 35, 23, 15, 8, 16, 4, 64, 68, 70, - 62, 91, 86, 79, 83, 83, 79, 77, 74, 74, 72, - 69, 0, 77, 77, 82, 84, 18, 83, 84, 77, 72, 71, - 73, 71, 71, 70, 69, 72, 81, 68, 68, 13, 69, - 77, 67, 68, 69, 66, 67, 68, 76, 68, 68, 73, - 72, 7, 89, 72, 13, 72, 64, 69, 68, 64, 1, 65, - 66, 64, 73, 73, 82, 49, 46, 48, 41, 33, 37, - 36, 32, 32, 29, 30, 30, 18, 13, 0, 19, 18, 13, - 64, 10, 9, 3, 7, 64, 65, 70, 74, 78, 79, 21, - 17, 20, 10, 70, 1, 64, 77, 66, 74, 78, 94, 86, - 90, 96, 3, 7, 82, 1, 4, 69, 79, 76, 77, 86, - 76, 82, 82, 97, 87, 91, 101, 67, 80, 88, 73, - 2, 6, 8, 18, 12, 18, 2, 16, 14, 22, 23, 27, - 26, 13, 51, 25, 17, 11, 3, 1, 83, 88, 96, 7, - 38, 32, 32, 24, 24, 13, 11, 5, 1, 73, 2, 6, 8, - 18, 12, 18, 2, 16, 14, 22, 23, 27, 26, 13, 51, - 25, 17, 11, 3, 1, 83, 88, 96 }, - - { - - 45, - 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 64, 21, - 40, 29, 7, 10, 4, 78, 2, 65, 67, 19, 80, 73, - 20, 15, 91, 104, 117, 73, 79, 70, 78, 2, 65, - 82, 64, 30, 2, 70, 77, 80, 89, 91, 90, 106, - 64, 76, 84, 71, 85, 84, 99, 3, 72, 71, 76, 25, - 2, 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 18, 72, - 93, 66, 1, 71, 22, 20, 68, 1, 74, 11, 72, 68, - 64, 98, 84, 87, 86, 19, 67, 4, 64, 70, 85, 72, - 76, 65, 75, 72, 85, 18, 73, 6, 76, 79, 67, 73, - 66, 3, 5, 1, 10, 6, 74, 0, 64, 67, 2, 72, 26, - 67, 1, 24, 23, 32, 28, 21, 89, 1, 64, 67, 67, - 81, 68, 17, 66, 66, 16, 35, 54, 42, 18, 90, - 91, 3, 37, 40, 112, 70, 6, 90, 14, 67, 1, 16, - 33, 55, 46, 25, 93, 85, 65, 7, 13, 89, 18, 21, - 18, 16, 19, 16, 10, 18, 17, 64, 6, 10, 3, 2, - 70, 6, 1, 65, 4, 1, 5, 5, 64, 90, 64, 65, 69, - 66, 76, 22, 33, 19, 13, 18, 20, 20, 22, 14, - 77, 89, 73, 72, 70, 110, 67, 0, 89, 15, 2, 2, - 0, 0, 70, 64, 2, 82, 93, 79, 82, 81, 86, 74, - 19, 17, 10, 4, 2, 67, 72, 73, 78, 64, 30, 17, - 11, 3, 14, 2, 65, 72, 64, 65, 29, 16, 11, 5, - 12, 1, 67, 71, 77, 72, 32, 15, 9, 4, 7, 67, - 74, 77, 4, 36, 23, 16, 8, 17, 4, 64, 67, 70, - 62, 89, 84, 77, 81, 81, 78, 75, 73, 72, 70, - 67, 2, 77, 76, 82, 84, 21, 83, 85, 77, 72, 70, - 73, 71, 71, 70, 69, 72, 82, 68, 68, 13, 69, - 77, 67, 68, 69, 66, 67, 68, 77, 69, 68, 73, - 72, 8, 90, 72, 14, 73, 64, 69, 68, 0, 1, 65, - 65, 0, 73, 73, 84, 48, 45, 47, 39, 31, 34, 34, - 29, 30, 26, 27, 27, 15, 10, 65, 16, 15, 9, 69, - 8, 6, 1, 5, 66, 67, 71, 75, 79, 79, 19, 15, - 18, 8, 72, 0, 65, 79, 68, 77, 80, 96, 88, 92, - 97, 2, 5, 84, 0, 2, 70, 81, 78, 79, 87, 77, - 83, 83, 96, 88, 93, 103, 68, 82, 89, 72, 3, 7, - 8, 19, 13, 19, 2, 17, 15, 23, 24, 28, 27, 14, - 50, 23, 15, 9, 1, 64, 85, 90, 97, 8, 38, 33, - 33, 24, 25, 14, 12, 6, 1, 72, 3, 7, 8, 19, 13, - 19, 2, 17, 15, 23, 24, 28, 27, 14, 50, 23, 15, - 9, 1, 64, 85, 90, 97 }, - - { - - 43, - 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 66, 20, - 39, 30, 7, 12, 2, 78, 3, 65, 67, 20, 81, 75, - 18, 13, 94, 106, 118, 71, 78, 70, 78, 3, 65, - 82, 0, 30, 1, 69, 76, 79, 90, 93, 91, 106, 64, - 76, 83, 71, 85, 84, 99, 3, 72, 71, 76, 26, 2, - 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 17, 72, 92, - 64, 2, 70, 23, 21, 68, 2, 72, 12, 71, 67, 1, - 99, 84, 87, 86, 19, 68, 5, 1, 70, 84, 71, 74, - 65, 75, 72, 85, 18, 73, 6, 75, 79, 67, 73, 66, - 3, 5, 2, 10, 6, 74, 64, 64, 67, 2, 72, 26, 67, - 1, 25, 23, 32, 28, 21, 90, 1, 0, 67, 67, 81, - 68, 18, 66, 66, 17, 36, 55, 43, 20, 90, 92, 3, - 37, 40, 113, 70, 7, 91, 15, 67, 1, 17, 33, 55, - 46, 26, 94, 83, 66, 4, 10, 88, 17, 21, 17, 15, - 18, 16, 9, 18, 16, 65, 5, 9, 3, 2, 70, 5, 0, - 66, 3, 0, 4, 4, 64, 91, 65, 66, 69, 68, 77, - 20, 31, 17, 11, 16, 18, 16, 19, 13, 79, 92, - 75, 74, 72, 111, 69, 64, 91, 14, 1, 1, 64, 64, - 72, 66, 0, 84, 93, 80, 83, 83, 85, 73, 20, 17, - 10, 4, 3, 66, 71, 72, 76, 0, 31, 17, 12, 4, - 15, 3, 0, 71, 1, 64, 29, 16, 11, 6, 13, 2, 67, - 71, 76, 72, 33, 16, 9, 4, 8, 67, 74, 76, 5, - 36, 24, 16, 8, 18, 5, 0, 67, 69, 62, 88, 83, - 76, 79, 80, 76, 74, 71, 71, 69, 65, 4, 76, 75, - 81, 83, 24, 83, 86, 77, 71, 70, 73, 71, 71, - 71, 68, 72, 83, 68, 68, 14, 69, 77, 67, 68, - 69, 67, 67, 68, 78, 70, 68, 73, 72, 9, 91, 72, - 14, 74, 64, 69, 68, 0, 1, 66, 65, 1, 73, 73, - 85, 47, 44, 46, 37, 29, 32, 31, 26, 27, 23, - 23, 24, 11, 7, 67, 12, 11, 5, 74, 5, 4, 64, 3, - 69, 69, 73, 76, 80, 79, 16, 13, 16, 6, 74, 65, - 67, 81, 70, 79, 82, 98, 91, 94, 98, 1, 4, 87, - 65, 0, 72, 83, 79, 80, 88, 78, 84, 83, 95, 89, - 94, 104, 69, 83, 90, 72, 3, 7, 9, 20, 13, 20, - 2, 18, 16, 24, 24, 29, 27, 15, 50, 21, 13, 7, - 64, 66, 87, 92, 99, 8, 39, 33, 34, 25, 25, 14, - 12, 6, 2, 72, 3, 7, 9, 20, 13, 20, 2, 18, 16, - 24, 24, 29, 27, 15, 50, 21, 13, 7, 64, 66, 87, - 92, 99 }, - - { - - 42, - 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 68, 18, - 38, 31, 7, 13, 0, 77, 5, 66, 67, 21, 82, 76, - 17, 11, 97, 109, 118, 69, 77, 70, 77, 5, 66, - 82, 1, 30, 1, 69, 75, 77, 91, 94, 91, 106, 64, - 75, 82, 72, 85, 84, 99, 3, 71, 71, 75, 26, 2, - 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 17, 71, - 90, 2, 3, 69, 25, 23, 67, 3, 70, 13, 70, 66, - 4, 99, 85, 87, 87, 19, 68, 6, 4, 69, 84, 71, - 72, 65, 75, 72, 84, 18, 73, 7, 74, 78, 66, 72, - 66, 4, 6, 3, 11, 6, 75, 64, 0, 67, 2, 72, 27, - 67, 1, 25, 24, 32, 28, 21, 90, 2, 0, 68, 67, - 80, 68, 19, 65, 65, 19, 38, 56, 45, 22, 91, - 93, 4, 38, 40, 114, 70, 7, 91, 16, 67, 1, 19, - 33, 55, 46, 28, 95, 82, 67, 2, 7, 87, 17, 21, - 17, 15, 18, 16, 9, 18, 16, 66, 4, 9, 3, 2, 70, - 5, 0, 67, 3, 0, 4, 3, 65, 92, 66, 66, 69, 69, - 77, 18, 29, 16, 10, 15, 16, 13, 17, 12, 81, - 94, 76, 76, 74, 112, 70, 65, 92, 13, 0, 0, 66, - 66, 74, 68, 64, 85, 93, 81, 84, 85, 83, 71, - 21, 18, 10, 4, 4, 65, 70, 72, 74, 2, 32, 18, - 12, 5, 17, 4, 1, 70, 4, 0, 30, 17, 12, 6, 14, - 3, 66, 70, 75, 71, 34, 17, 9, 4, 9, 66, 73, - 75, 6, 36, 25, 16, 8, 19, 6, 1, 66, 68, 62, - 87, 81, 74, 78, 79, 75, 72, 69, 69, 67, 0, 7, - 75, 74, 80, 82, 27, 82, 87, 76, 70, 69, 73, - 71, 71, 71, 68, 73, 84, 68, 68, 15, 69, 77, - 67, 68, 68, 67, 68, 68, 79, 71, 69, 73, 72, - 10, 91, 73, 15, 74, 65, 69, 68, 0, 0, 66, 65, - 1, 73, 73, 87, 46, 43, 45, 36, 26, 29, 28, 23, - 25, 20, 20, 21, 8, 5, 69, 8, 8, 1, 79, 2, 2, - 65, 1, 71, 71, 74, 77, 81, 79, 14, 10, 13, 4, - 76, 67, 68, 83, 72, 81, 84, 100, 93, 95, 100, - 0, 3, 89, 66, 64, 73, 85, 80, 81, 89, 79, 85, - 83, 94, 91, 95, 106, 71, 84, 91, 72, 4, 8, 10, - 21, 14, 20, 3, 19, 17, 25, 25, 30, 28, 15, 49, - 19, 11, 5, 66, 68, 90, 94, 100, 9, 39, 34, 34, - 26, 26, 15, 13, 6, 3, 72, 4, 8, 10, 21, 14, - 20, 3, 19, 17, 25, 25, 30, 28, 15, 49, 19, 11, - 5, 66, 68, 90, 94, 100 }, - - { - - 41, - 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 70, 17, - 37, 31, 7, 15, 64, 77, 6, 66, 68, 22, 83, 77, - 16, 9, 101, 111, 119, 67, 75, 70, 77, 6, 66, - 81, 2, 31, 1, 68, 74, 76, 92, 95, 91, 107, 64, - 75, 81, 72, 86, 84, 99, 3, 71, 71, 74, 27, 2, - 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 16, 71, - 89, 4, 4, 68, 26, 24, 66, 4, 68, 14, 69, 65, - 6, 100, 85, 87, 87, 20, 68, 7, 6, 69, 83, 70, - 70, 65, 75, 72, 84, 19, 73, 7, 73, 78, 65, 72, - 66, 4, 6, 4, 11, 6, 75, 64, 0, 67, 2, 72, 27, - 67, 1, 26, 24, 33, 28, 22, 91, 2, 1, 68, 67, - 80, 68, 20, 65, 65, 20, 39, 57, 46, 24, 91, - 94, 4, 38, 40, 115, 70, 8, 92, 16, 67, 1, 20, - 33, 55, 46, 29, 96, 80, 68, 64, 4, 85, 17, 21, - 16, 14, 17, 15, 8, 18, 15, 67, 3, 9, 3, 2, 71, - 4, 64, 68, 2, 0, 4, 2, 65, 93, 66, 67, 69, 70, - 78, 16, 27, 14, 8, 13, 14, 10, 14, 11, 83, 96, - 78, 78, 76, 114, 71, 66, 94, 12, 64, 64, 67, - 67, 76, 70, 66, 87, 93, 82, 85, 86, 82, 70, - 23, 18, 10, 4, 5, 64, 69, 71, 72, 3, 33, 19, - 13, 5, 18, 5, 3, 69, 6, 0, 30, 17, 12, 7, 15, - 3, 66, 69, 74, 71, 36, 18, 9, 4, 10, 66, 73, - 74, 7, 37, 26, 17, 8, 20, 6, 2, 66, 68, 62, - 85, 80, 73, 76, 78, 73, 71, 68, 68, 65, 2, 9, - 75, 73, 80, 81, 30, 82, 88, 76, 69, 68, 73, - 71, 71, 71, 67, 73, 85, 68, 68, 15, 69, 77, - 67, 68, 68, 68, 68, 68, 80, 72, 69, 73, 72, - 11, 92, 73, 16, 75, 65, 69, 68, 1, 0, 67, 64, - 2, 73, 73, 88, 45, 42, 44, 34, 24, 27, 26, 20, - 22, 17, 17, 18, 5, 2, 71, 4, 4, 66, 84, 64, 0, - 67, 64, 74, 73, 75, 78, 82, 79, 12, 8, 11, 2, - 78, 69, 70, 85, 74, 83, 86, 102, 95, 97, 101, - 64, 2, 91, 68, 66, 75, 87, 82, 83, 90, 80, 86, - 83, 93, 92, 97, 107, 72, 85, 92, 72, 4, 8, 10, - 22, 15, 21, 3, 20, 18, 26, 25, 31, 28, 16, 49, - 17, 9, 3, 68, 70, 92, 96, 101, 9, 40, 34, 35, - 26, 27, 15, 13, 7, 3, 72, 4, 8, 10, 22, 15, - 21, 3, 20, 18, 26, 25, 31, 28, 16, 49, 17, 9, - 3, 68, 70, 92, 96, 101 }, - - { - - 40, - 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 72, 15, - 36, 32, 7, 17, 66, 77, 8, 66, 68, 23, 84, 78, - 15, 7, 104, 113, 120, 65, 74, 70, 77, 8, 66, - 81, 3, 31, 1, 67, 73, 75, 93, 96, 91, 107, 64, - 75, 80, 72, 86, 84, 99, 3, 71, 71, 73, 27, 2, - 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 16, 70, - 88, 6, 5, 67, 28, 26, 65, 5, 66, 15, 68, 64, - 8, 101, 85, 87, 87, 20, 68, 8, 8, 69, 82, 69, - 68, 65, 75, 72, 84, 19, 73, 8, 72, 78, 64, 72, - 66, 4, 7, 5, 12, 6, 75, 64, 0, 67, 2, 72, 27, - 67, 1, 26, 24, 33, 28, 22, 91, 3, 2, 69, 67, - 80, 68, 21, 65, 64, 21, 40, 58, 48, 26, 92, - 95, 5, 38, 40, 116, 70, 8, 92, 17, 67, 1, 21, - 33, 55, 46, 30, 97, 79, 69, 67, 1, 84, 17, 21, - 16, 13, 17, 15, 8, 18, 15, 68, 2, 9, 3, 2, 71, - 4, 65, 69, 2, 0, 4, 1, 66, 94, 67, 68, 69, 71, - 78, 14, 25, 12, 7, 11, 12, 7, 12, 10, 85, 98, - 79, 80, 78, 115, 72, 67, 96, 11, 65, 65, 68, - 69, 78, 72, 68, 88, 93, 83, 86, 88, 80, 68, - 24, 19, 10, 4, 6, 0, 68, 70, 70, 4, 34, 20, - 14, 6, 19, 6, 4, 68, 8, 1, 31, 18, 13, 7, 16, - 4, 65, 68, 73, 71, 37, 19, 9, 4, 11, 65, 73, - 73, 8, 37, 27, 17, 8, 21, 7, 3, 65, 67, 62, - 84, 78, 71, 74, 77, 72, 69, 66, 66, 0, 4, 11, - 74, 72, 79, 80, 33, 82, 89, 76, 68, 67, 73, - 71, 71, 71, 67, 73, 86, 68, 68, 16, 69, 77, - 67, 68, 68, 68, 68, 68, 81, 73, 69, 73, 72, - 12, 93, 73, 17, 76, 65, 69, 68, 1, 0, 67, 64, - 3, 73, 73, 90, 44, 41, 43, 32, 22, 24, 23, 17, - 20, 14, 14, 15, 2, 64, 73, 0, 1, 70, 89, 67, - 65, 69, 66, 76, 75, 76, 79, 83, 79, 10, 6, 9, - 0, 80, 71, 71, 87, 76, 85, 88, 104, 97, 99, - 102, 65, 1, 93, 69, 68, 76, 89, 83, 84, 91, - 81, 87, 83, 92, 93, 98, 109, 73, 86, 93, 72, - 5, 9, 11, 23, 16, 22, 3, 21, 19, 27, 26, 32, - 29, 17, 48, 15, 7, 1, 70, 72, 94, 98, 102, 10, - 40, 35, 36, 27, 28, 16, 14, 7, 4, 72, 5, 9, - 11, 23, 16, 22, 3, 21, 19, 27, 26, 32, 29, 17, - 48, 15, 7, 1, 70, 72, 94, 98, 102 }, - - { - - 38, - 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 74, 13, - 35, 32, 7, 18, 68, 77, 9, 67, 69, 24, 85, 80, - 13, 5, 108, 116, 121, 0, 73, 70, 77, 9, 67, - 81, 3, 31, 0, 67, 73, 74, 95, 98, 92, 108, 65, - 75, 80, 73, 87, 84, 99, 2, 71, 71, 73, 27, 1, - 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 15, 70, - 87, 8, 6, 67, 29, 27, 65, 6, 65, 15, 67, 64, - 10, 102, 86, 88, 88, 20, 69, 8, 10, 69, 82, - 69, 67, 65, 75, 72, 84, 19, 74, 8, 72, 78, 64, - 72, 66, 4, 7, 6, 12, 6, 76, 65, 0, 67, 1, 72, - 27, 67, 1, 26, 24, 33, 28, 22, 92, 3, 2, 70, - 67, 80, 69, 21, 65, 64, 22, 41, 58, 49, 27, - 93, 97, 5, 38, 40, 117, 71, 8, 93, 17, 68, 1, - 22, 33, 54, 46, 31, 98, 78, 71, 70, 66, 83, - 16, 21, 15, 12, 16, 14, 7, 17, 14, 69, 1, 8, - 2, 1, 72, 3, 66, 70, 1, 64, 3, 0, 67, 96, 68, - 69, 69, 73, 79, 11, 22, 10, 5, 9, 9, 3, 9, 8, - 87, 101, 81, 83, 80, 117, 74, 69, 98, 9, 66, - 66, 70, 71, 80, 74, 70, 90, 93, 84, 87, 90, - 79, 67, 25, 19, 10, 4, 6, 0, 68, 70, 69, 5, - 34, 20, 14, 6, 20, 7, 5, 68, 10, 1, 31, 18, - 13, 7, 16, 4, 65, 68, 72, 71, 38, 20, 9, 3, - 11, 65, 73, 73, 8, 37, 27, 17, 8, 22, 7, 3, - 65, 67, 62, 83, 77, 70, 73, 76, 71, 68, 65, - 65, 1, 5, 13, 74, 72, 79, 80, 36, 82, 91, 76, - 68, 67, 73, 71, 71, 72, 67, 74, 87, 69, 68, - 16, 70, 77, 68, 68, 68, 69, 69, 69, 82, 74, - 70, 74, 72, 13, 94, 74, 17, 77, 66, 69, 69, 1, - 64, 68, 64, 3, 73, 73, 92, 42, 40, 41, 30, 19, - 21, 20, 14, 17, 11, 10, 12, 65, 67, 75, 67, - 66, 74, 95, 70, 68, 71, 69, 79, 77, 78, 81, - 84, 79, 7, 3, 6, 65, 83, 73, 73, 90, 78, 88, - 90, 107, 100, 101, 104, 67, 64, 96, 71, 70, - 78, 91, 85, 86, 92, 82, 88, 84, 91, 95, 100, - 111, 75, 88, 95, 72, 5, 9, 11, 24, 16, 22, 3, - 22, 19, 28, 26, 32, 29, 17, 47, 13, 5, 65, 73, - 74, 97, 100, 104, 10, 40, 35, 36, 27, 28, 16, - 14, 7, 4, 72, 5, 9, 11, 24, 16, 22, 3, 22, 19, - 28, 26, 32, 29, 17, 47, 13, 5, 65, 73, 74, 97, - 100, 104 }, - - { - - 37, - 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 75, 12, - 35, 33, 8, 20, 69, 76, 11, 67, 69, 26, 85, 81, - 12, 4, 111, 118, 121, 2, 71, 69, 76, 11, 67, - 80, 4, 32, 0, 66, 72, 72, 96, 99, 92, 108, 65, - 74, 79, 73, 87, 83, 98, 2, 70, 70, 72, 28, 1, - 22, 0, 0, 0, 64, 94, 97, 6, 67, 68, 15, 69, - 85, 11, 8, 66, 31, 29, 64, 8, 0, 16, 65, 0, - 13, 102, 86, 88, 88, 21, 69, 9, 13, 68, 81, - 68, 65, 65, 74, 72, 83, 20, 74, 9, 71, 77, 0, - 71, 65, 5, 8, 7, 13, 7, 76, 65, 1, 66, 1, 71, - 28, 66, 1, 27, 25, 34, 29, 23, 92, 4, 3, 70, - 67, 79, 69, 22, 64, 0, 24, 43, 59, 51, 29, 93, - 98, 6, 39, 41, 117, 71, 9, 93, 18, 68, 2, 24, - 33, 54, 47, 33, 99, 76, 72, 72, 69, 81, 16, - 21, 15, 12, 16, 14, 7, 17, 14, 69, 1, 8, 2, 1, - 72, 3, 66, 70, 1, 64, 3, 0, 67, 97, 68, 69, - 69, 74, 79, 9, 20, 9, 4, 8, 7, 0, 7, 7, 88, - 103, 82, 85, 81, 118, 75, 70, 99, 8, 66, 66, - 71, 72, 81, 75, 71, 91, 93, 84, 87, 91, 77, - 65, 27, 20, 10, 4, 7, 1, 67, 69, 67, 7, 35, - 21, 15, 7, 22, 8, 7, 67, 13, 2, 32, 19, 14, 8, - 17, 5, 64, 67, 70, 70, 40, 21, 10, 3, 12, 64, - 72, 72, 9, 38, 28, 18, 9, 23, 8, 4, 64, 66, - 62, 81, 75, 68, 71, 74, 69, 66, 0, 0, 3, 7, - 16, 73, 71, 78, 79, 40, 81, 92, 75, 67, 66, - 72, 71, 70, 72, 66, 74, 87, 69, 68, 17, 70, - 77, 68, 68, 67, 69, 69, 69, 82, 74, 70, 74, - 71, 15, 94, 74, 18, 77, 66, 69, 69, 2, 64, 68, - 0, 4, 72, 72, 93, 41, 39, 40, 29, 17, 19, 18, - 11, 15, 9, 7, 10, 68, 69, 77, 70, 69, 77, 100, - 72, 70, 72, 71, 81, 78, 79, 82, 84, 79, 5, 1, - 4, 67, 85, 74, 74, 92, 79, 90, 91, 109, 102, - 102, 105, 68, 65, 98, 72, 71, 79, 92, 86, 87, - 93, 82, 88, 84, 90, 96, 101, 112, 76, 89, 96, - 71, 6, 10, 12, 26, 17, 23, 4, 24, 20, 29, 27, - 33, 30, 18, 47, 12, 4, 67, 75, 75, 99, 101, - 105, 11, 41, 36, 37, 28, 29, 17, 15, 8, 5, 71, - 6, 10, 12, 26, 17, 23, 4, 24, 20, 29, 27, 33, - 30, 18, 47, 12, 4, 67, 75, 75, 99, 101, 105 }, - - { - - 36, - 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 77, 10, - 34, 34, 8, 22, 71, 76, 12, 67, 69, 27, 86, 82, - 11, 2, 114, 120, 122, 4, 70, 69, 76, 12, 67, - 80, 5, 32, 0, 65, 71, 71, 97, 100, 92, 108, - 65, 74, 78, 73, 87, 83, 98, 2, 70, 70, 71, 28, - 1, 22, 0, 0, 0, 0, 94, 97, 6, 68, 68, 15, 68, - 84, 13, 9, 65, 33, 31, 0, 9, 2, 17, 64, 1, 15, - 103, 86, 88, 88, 21, 69, 10, 15, 68, 80, 67, - 0, 65, 74, 72, 83, 20, 74, 9, 70, 77, 1, 71, - 65, 5, 8, 8, 14, 7, 76, 65, 1, 66, 1, 71, 28, - 66, 1, 27, 25, 34, 29, 23, 93, 5, 4, 71, 67, - 79, 69, 23, 64, 0, 25, 44, 60, 53, 31, 94, 99, - 6, 39, 41, 118, 71, 9, 94, 19, 68, 2, 25, 33, - 54, 47, 34, 100, 75, 73, 75, 72, 80, 16, 21, - 15, 11, 15, 14, 7, 17, 13, 70, 0, 8, 2, 1, 72, - 2, 67, 71, 1, 64, 3, 64, 68, 98, 69, 70, 69, - 75, 80, 7, 18, 7, 2, 6, 5, 66, 5, 6, 90, 105, - 84, 87, 83, 119, 76, 71, 101, 7, 67, 67, 72, - 74, 83, 77, 73, 93, 93, 85, 88, 93, 76, 64, - 28, 21, 10, 4, 8, 2, 66, 68, 65, 8, 36, 22, - 16, 8, 23, 9, 8, 66, 15, 3, 32, 19, 14, 8, 18, - 6, 0, 66, 69, 70, 41, 22, 10, 3, 13, 0, 72, - 71, 10, 38, 29, 18, 9, 24, 9, 5, 0, 65, 62, - 80, 73, 66, 69, 73, 68, 64, 2, 1, 5, 9, 18, - 72, 70, 77, 78, 43, 81, 93, 75, 66, 65, 72, - 71, 70, 72, 66, 74, 88, 69, 68, 18, 70, 77, - 68, 68, 67, 69, 69, 69, 83, 75, 70, 74, 71, - 16, 95, 74, 19, 78, 66, 69, 69, 2, 64, 68, 0, - 5, 72, 72, 95, 40, 38, 39, 27, 15, 16, 15, 8, - 13, 6, 4, 7, 71, 72, 79, 74, 73, 81, 105, 75, - 72, 74, 73, 83, 80, 80, 83, 85, 79, 3, 64, 2, - 69, 87, 76, 76, 94, 81, 92, 93, 111, 104, 104, - 106, 69, 66, 100, 74, 73, 81, 94, 87, 88, 94, - 83, 89, 84, 89, 97, 102, 114, 77, 90, 97, 71, - 6, 11, 13, 27, 18, 24, 4, 25, 21, 30, 27, 34, - 31, 19, 46, 10, 2, 69, 77, 77, 101, 103, 106, - 12, 41, 36, 38, 29, 30, 17, 16, 8, 6, 71, 6, - 11, 13, 27, 18, 24, 4, 25, 21, 30, 27, 34, 31, - 19, 46, 10, 2, 69, 77, 77, 101, 103, 106 }, - - { - - 35, - 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 79, 9, - 33, 34, 8, 24, 72, 76, 14, 67, 70, 28, 87, 83, - 10, 0, 118, 122, 123, 6, 68, 69, 76, 14, 67, - 79, 6, 33, 0, 64, 70, 70, 98, 101, 92, 109, - 65, 74, 77, 73, 88, 83, 98, 2, 70, 70, 70, 29, - 1, 22, 0, 0, 0, 0, 94, 97, 7, 69, 68, 14, 68, - 83, 15, 10, 64, 34, 32, 1, 10, 4, 18, 0, 2, - 17, 104, 86, 88, 88, 22, 69, 11, 17, 68, 79, - 66, 2, 65, 74, 72, 83, 21, 74, 10, 69, 77, 2, - 71, 65, 5, 9, 9, 14, 7, 76, 65, 1, 66, 1, 71, - 28, 66, 1, 28, 25, 35, 29, 24, 93, 5, 5, 71, - 67, 79, 69, 24, 64, 1, 26, 45, 61, 54, 33, 94, - 100, 7, 39, 41, 119, 71, 10, 94, 19, 68, 2, - 26, 33, 54, 47, 35, 101, 73, 74, 78, 75, 78, - 16, 21, 14, 10, 15, 13, 6, 17, 13, 71, 64, 8, - 2, 1, 73, 2, 68, 72, 0, 64, 3, 65, 68, 99, 69, - 71, 69, 76, 80, 5, 16, 5, 1, 4, 3, 69, 2, 5, - 92, 107, 85, 89, 85, 121, 77, 72, 103, 6, 68, - 68, 73, 75, 85, 79, 75, 94, 93, 86, 89, 94, - 74, 1, 30, 21, 10, 4, 9, 3, 65, 67, 0, 9, 37, - 23, 17, 8, 24, 10, 10, 65, 17, 3, 33, 20, 15, - 9, 19, 6, 0, 65, 68, 70, 43, 23, 10, 3, 14, 0, - 72, 70, 11, 39, 30, 19, 9, 25, 9, 6, 0, 65, - 62, 78, 72, 65, 67, 72, 66, 0, 3, 3, 7, 11, - 20, 72, 69, 77, 77, 46, 81, 94, 75, 65, 64, - 72, 71, 70, 72, 65, 74, 89, 69, 68, 18, 70, - 77, 68, 68, 67, 70, 69, 69, 84, 76, 70, 74, - 71, 17, 96, 74, 20, 79, 66, 69, 69, 3, 64, 69, - 1, 6, 72, 72, 96, 39, 37, 38, 25, 13, 14, 13, - 5, 10, 3, 1, 4, 74, 75, 81, 78, 76, 85, 110, - 78, 74, 76, 75, 86, 82, 81, 84, 86, 79, 1, 66, - 0, 71, 89, 78, 77, 96, 83, 94, 95, 113, 106, - 106, 107, 70, 67, 102, 75, 75, 82, 96, 89, 90, - 95, 84, 90, 84, 88, 98, 104, 115, 78, 91, 98, - 71, 7, 11, 13, 28, 19, 25, 4, 26, 22, 31, 28, - 35, 31, 20, 46, 8, 0, 71, 79, 79, 103, 105, - 107, 12, 42, 37, 39, 29, 31, 18, 16, 9, 6, 71, - 7, 11, 13, 28, 19, 25, 4, 26, 22, 31, 28, 35, - 31, 20, 46, 8, 0, 71, 79, 79, 103, 105, 107 }, - - { - - 33, - 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 81, 7, - 32, 35, 8, 25, 74, 76, 15, 68, 70, 29, 88, 85, - 8, 65, 121, 125, 124, 8, 67, 69, 76, 15, 68, - 79, 7, 33, 64, 64, 69, 68, 99, 103, 93, 109, - 65, 73, 76, 74, 88, 83, 98, 2, 70, 70, 70, 29, - 1, 22, 0, 0, 0, 1, 95, 97, 7, 70, 68, 14, 67, - 82, 17, 11, 0, 36, 34, 1, 11, 6, 19, 1, 3, 20, - 104, 87, 88, 89, 22, 70, 12, 20, 67, 79, 66, - 4, 65, 74, 72, 83, 21, 74, 10, 68, 77, 2, 70, - 65, 5, 9, 10, 15, 7, 77, 66, 1, 66, 1, 71, 28, - 66, 1, 28, 25, 35, 29, 24, 94, 6, 5, 72, 67, - 78, 69, 25, 0, 1, 28, 47, 62, 56, 35, 95, 101, - 7, 40, 41, 120, 71, 10, 95, 20, 68, 2, 27, 33, - 54, 47, 37, 102, 72, 75, 81, 78, 77, 15, 21, - 14, 10, 14, 13, 6, 17, 12, 72, 65, 7, 2, 1, - 73, 1, 68, 73, 0, 65, 2, 66, 69, 100, 70, 72, - 69, 78, 81, 3, 14, 3, 64, 3, 1, 73, 0, 4, 94, - 110, 87, 91, 87, 122, 79, 73, 104, 5, 69, 69, - 75, 77, 87, 81, 76, 96, 93, 87, 90, 96, 73, 2, - 31, 22, 10, 4, 10, 4, 64, 67, 2, 11, 38, 23, - 17, 9, 26, 11, 11, 64, 20, 4, 33, 20, 15, 9, - 20, 7, 1, 65, 67, 70, 44, 24, 10, 3, 15, 1, - 72, 69, 12, 39, 31, 19, 9, 26, 10, 7, 1, 64, - 62, 77, 70, 0, 66, 71, 65, 2, 5, 4, 8, 13, 23, - 71, 68, 76, 76, 49, 80, 95, 74, 64, 64, 72, - 71, 70, 73, 65, 75, 90, 69, 68, 19, 70, 77, - 68, 68, 66, 70, 70, 69, 85, 77, 71, 74, 71, - 18, 97, 75, 20, 79, 67, 69, 69, 3, 65, 69, 1, - 6, 72, 72, 98, 38, 36, 37, 24, 10, 11, 10, 2, - 8, 0, 66, 1, 78, 77, 83, 82, 80, 89, 115, 81, - 76, 78, 77, 88, 84, 83, 85, 87, 79, 65, 69, - 66, 73, 91, 80, 79, 98, 85, 96, 97, 115, 109, - 107, 109, 71, 68, 105, 77, 76, 84, 98, 90, 91, - 96, 85, 91, 84, 87, 100, 105, 117, 80, 92, 99, - 71, 7, 12, 14, 29, 19, 25, 5, 27, 23, 32, 28, - 36, 32, 20, 45, 6, 65, 73, 81, 81, 106, 107, - 109, 13, 42, 37, 39, 30, 31, 18, 17, 9, 7, 71, - 7, 12, 14, 29, 19, 25, 5, 27, 23, 32, 28, 36, - 32, 20, 45, 6, 65, 73, 81, 81, 106, 107, 109 }, - - { - - 32, - 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 83, 6, - 31, 36, 8, 27, 76, 75, 17, 68, 70, 30, 89, 86, - 7, 67, 124, 126, 124, 10, 66, 69, 75, 17, 68, - 79, 8, 33, 64, 0, 68, 67, 100, 104, 93, 109, - 65, 73, 75, 74, 88, 83, 98, 2, 69, 70, 69, 30, - 1, 22, 0, 0, 0, 1, 95, 97, 8, 71, 68, 13, 67, - 80, 20, 12, 1, 37, 35, 2, 12, 8, 20, 2, 4, 22, - 105, 87, 88, 89, 22, 70, 13, 22, 67, 78, 65, - 6, 65, 74, 72, 82, 21, 74, 11, 67, 76, 3, 70, - 65, 6, 10, 11, 15, 7, 77, 66, 2, 66, 1, 71, - 29, 66, 1, 29, 26, 35, 29, 24, 94, 6, 6, 72, - 67, 78, 69, 26, 0, 2, 29, 48, 62, 57, 37, 95, - 102, 8, 40, 41, 121, 71, 11, 95, 21, 68, 2, - 29, 33, 54, 47, 38, 103, 70, 76, 83, 81, 76, - 15, 21, 13, 9, 14, 13, 5, 17, 12, 73, 66, 7, - 2, 1, 73, 1, 69, 74, 64, 65, 2, 67, 69, 101, - 71, 72, 69, 79, 81, 1, 12, 2, 65, 1, 64, 76, - 66, 3, 96, 112, 88, 93, 89, 123, 80, 74, 106, - 4, 70, 70, 76, 78, 89, 83, 78, 97, 93, 88, 91, - 98, 71, 4, 32, 22, 10, 4, 11, 5, 0, 66, 4, 12, - 39, 24, 18, 10, 27, 12, 13, 0, 22, 5, 34, 21, - 16, 10, 21, 8, 1, 64, 66, 69, 45, 25, 10, 3, - 16, 1, 71, 68, 13, 39, 32, 19, 9, 27, 11, 8, - 1, 0, 62, 76, 69, 1, 64, 70, 0, 3, 7, 6, 10, - 15, 25, 70, 67, 75, 75, 52, 80, 96, 74, 0, 0, - 72, 71, 70, 73, 64, 75, 91, 69, 68, 20, 70, - 77, 68, 68, 66, 71, 70, 69, 86, 78, 71, 74, - 71, 19, 97, 75, 21, 80, 67, 69, 69, 3, 65, 70, - 1, 7, 72, 72, 99, 37, 35, 36, 22, 8, 9, 7, 64, - 5, 66, 69, 65, 81, 80, 85, 86, 83, 93, 120, - 84, 78, 79, 79, 91, 86, 84, 86, 88, 79, 67, - 71, 68, 75, 93, 82, 80, 100, 87, 98, 99, 117, - 111, 109, 110, 72, 69, 107, 78, 78, 85, 100, - 91, 92, 97, 86, 92, 84, 86, 101, 106, 118, 81, - 93, 100, 71, 8, 12, 15, 30, 20, 26, 5, 28, 24, - 33, 29, 37, 32, 21, 45, 4, 67, 75, 83, 83, - 108, 109, 110, 13, 43, 38, 40, 31, 32, 19, 17, - 9, 8, 71, 8, 12, 15, 30, 20, 26, 5, 28, 24, - 33, 29, 37, 32, 21, 45, 4, 67, 75, 83, 83, - 108, 109, 110 }, - - { - - 31, - 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 84, 4, - 30, 36, 9, 29, 77, 75, 18, 68, 71, 31, 90, 87, - 6, 68, 126, 126, 125, 12, 64, 69, 75, 18, 68, - 78, 9, 34, 64, 1, 67, 66, 102, 105, 93, 110, - 65, 73, 75, 74, 89, 82, 98, 1, 69, 70, 68, 30, - 1, 22, 0, 0, 0, 2, 95, 97, 8, 71, 69, 13, 66, - 79, 22, 13, 2, 39, 37, 3, 13, 10, 21, 3, 4, - 24, 106, 87, 88, 89, 23, 70, 14, 24, 67, 77, - 64, 8, 65, 74, 72, 82, 22, 75, 11, 67, 76, 4, - 70, 64, 6, 10, 12, 16, 7, 77, 66, 2, 66, 1, - 71, 29, 66, 1, 29, 26, 36, 30, 25, 95, 7, 7, - 73, 67, 78, 69, 27, 0, 2, 30, 49, 62, 59, 38, - 96, 103, 8, 40, 41, 121, 72, 11, 96, 21, 69, - 3, 30, 33, 54, 48, 39, 104, 69, 77, 86, 84, - 74, 15, 21, 13, 8, 13, 12, 5, 16, 11, 73, 66, - 7, 1, 1, 74, 0, 70, 75, 64, 65, 2, 67, 70, - 103, 71, 73, 69, 80, 82, 65, 10, 0, 67, 64, - 66, 79, 68, 1, 98, 114, 90, 95, 91, 125, 81, - 76, 108, 2, 71, 71, 77, 80, 91, 85, 80, 99, - 93, 89, 92, 99, 70, 5, 34, 23, 10, 4, 12, 5, - 0, 65, 5, 13, 40, 25, 19, 10, 28, 13, 14, 1, - 24, 5, 34, 21, 16, 10, 22, 8, 2, 0, 65, 69, - 47, 26, 10, 3, 16, 2, 71, 68, 13, 40, 32, 20, - 9, 28, 11, 8, 2, 0, 62, 74, 67, 3, 1, 68, 1, - 5, 8, 7, 12, 17, 27, 70, 66, 75, 75, 55, 80, - 97, 74, 0, 1, 72, 71, 70, 73, 64, 75, 92, 69, - 68, 20, 70, 77, 68, 68, 66, 71, 70, 69, 87, - 79, 71, 74, 71, 20, 98, 75, 22, 81, 67, 69, - 69, 4, 65, 70, 2, 8, 72, 72, 101, 36, 34, 35, - 20, 6, 6, 5, 67, 3, 69, 72, 68, 84, 83, 87, - 89, 87, 97, 125, 86, 81, 81, 81, 93, 88, 85, - 87, 89, 79, 69, 73, 70, 77, 95, 83, 82, 102, - 89, 101, 101, 119, 113, 111, 111, 73, 71, 109, - 80, 80, 87, 102, 93, 94, 98, 87, 93, 85, 85, - 102, 108, 120, 82, 95, 101, 70, 8, 13, 15, 31, - 21, 27, 5, 29, 25, 34, 29, 38, 33, 22, 44, 2, - 69, 77, 85, 85, 110, 111, 111, 14, 43, 38, 41, - 31, 33, 19, 18, 10, 8, 70, 8, 13, 15, 31, 21, - 27, 5, 29, 25, 34, 29, 38, 33, 22, 44, 2, 69, - 77, 85, 85, 110, 111, 111 }, - - { - - 30, - 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 86, 3, - 29, 37, 9, 30, 79, 75, 20, 69, 71, 32, 91, 88, - 5, 70, 126, 126, 126, 14, 0, 69, 75, 20, 69, - 78, 10, 34, 64, 1, 66, 64, 103, 106, 93, 110, - 65, 72, 74, 75, 89, 82, 98, 1, 69, 70, 67, 31, - 1, 22, 0, 0, 0, 2, 95, 97, 9, 72, 69, 12, 66, - 78, 24, 14, 3, 40, 38, 4, 14, 12, 22, 4, 5, - 27, 106, 88, 88, 90, 23, 70, 15, 27, 66, 77, - 64, 10, 65, 74, 72, 82, 22, 75, 12, 66, 76, 5, - 69, 64, 6, 11, 13, 16, 7, 78, 66, 2, 66, 1, - 71, 29, 66, 1, 30, 26, 36, 30, 25, 95, 7, 7, - 73, 67, 77, 69, 28, 1, 3, 32, 51, 62, 60, 40, - 96, 104, 9, 41, 41, 122, 72, 12, 96, 22, 69, - 3, 31, 33, 54, 48, 41, 105, 67, 78, 89, 87, - 73, 15, 21, 12, 8, 13, 12, 4, 16, 11, 74, 67, - 7, 1, 1, 74, 0, 70, 76, 65, 65, 2, 68, 70, - 104, 72, 74, 69, 81, 82, 67, 8, 65, 68, 65, - 68, 82, 71, 0, 100, 116, 91, 97, 93, 126, 82, - 77, 109, 1, 72, 72, 79, 81, 93, 87, 81, 100, - 93, 90, 93, 101, 68, 7, 35, 23, 10, 4, 13, 6, - 1, 65, 7, 15, 41, 26, 19, 11, 30, 14, 16, 2, - 27, 6, 35, 22, 17, 11, 23, 9, 2, 1, 64, 69, - 48, 27, 10, 3, 17, 2, 71, 67, 14, 40, 33, 20, - 9, 29, 12, 9, 2, 1, 62, 73, 66, 4, 2, 67, 3, - 6, 10, 9, 14, 19, 30, 69, 65, 74, 74, 58, 79, - 98, 73, 1, 2, 72, 71, 70, 73, 0, 76, 93, 69, - 68, 21, 70, 77, 68, 68, 65, 72, 71, 69, 88, - 80, 72, 74, 71, 21, 99, 76, 23, 81, 68, 69, - 69, 4, 66, 71, 2, 8, 72, 72, 102, 35, 33, 34, - 19, 3, 4, 2, 70, 0, 72, 75, 71, 87, 85, 89, - 93, 90, 101, 126, 89, 83, 83, 83, 96, 90, 86, - 88, 90, 79, 71, 76, 73, 79, 97, 85, 83, 104, - 91, 103, 103, 121, 115, 112, 113, 74, 72, 111, - 81, 81, 88, 104, 94, 95, 99, 88, 94, 85, 84, - 104, 109, 121, 84, 96, 102, 70, 9, 13, 16, 32, - 22, 27, 6, 30, 26, 35, 30, 39, 33, 22, 44, 0, - 71, 79, 87, 87, 113, 113, 112, 14, 44, 39, 41, - 32, 34, 20, 18, 10, 9, 70, 9, 13, 16, 32, 22, - 27, 6, 30, 26, 35, 30, 39, 33, 22, 44, 0, 71, - 79, 87, 87, 113, 113, 112 }, - - { - - 28, - 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 88, 1, - 28, 37, 9, 32, 81, 75, 21, 69, 72, 33, 92, 90, - 3, 72, 126, 126, 126, 16, 1, 69, 75, 21, 69, - 78, 10, 34, 65, 2, 65, 0, 104, 108, 94, 111, - 65, 72, 73, 75, 90, 82, 98, 1, 69, 70, 67, 31, - 1, 22, 0, 0, 0, 3, 96, 97, 9, 73, 69, 12, 65, - 77, 26, 15, 3, 42, 40, 4, 15, 14, 22, 5, 6, - 29, 107, 88, 89, 90, 23, 71, 15, 29, 66, 76, - 0, 11, 65, 74, 72, 82, 22, 75, 12, 65, 76, 5, - 69, 64, 6, 11, 14, 17, 7, 78, 67, 2, 66, 0, - 71, 29, 66, 1, 30, 26, 36, 30, 25, 96, 8, 8, - 74, 67, 77, 69, 29, 1, 3, 33, 52, 62, 62, 42, - 97, 105, 9, 41, 41, 123, 72, 12, 97, 22, 69, - 3, 32, 33, 54, 48, 42, 106, 66, 79, 92, 91, - 72, 14, 21, 12, 7, 12, 11, 4, 16, 10, 75, 68, - 6, 1, 0, 75, 64, 71, 77, 65, 66, 1, 69, 71, - 105, 73, 75, 69, 83, 83, 69, 6, 67, 70, 67, - 71, 86, 73, 64, 102, 119, 93, 100, 95, 126, - 84, 78, 111, 0, 73, 73, 80, 83, 95, 89, 83, - 102, 93, 91, 94, 103, 67, 8, 36, 24, 10, 4, - 13, 7, 2, 64, 9, 16, 41, 26, 20, 11, 31, 15, - 17, 3, 29, 6, 35, 22, 17, 11, 23, 9, 3, 1, 0, - 69, 49, 28, 10, 3, 18, 3, 71, 66, 15, 40, 34, - 20, 9, 30, 12, 10, 3, 1, 62, 72, 64, 6, 4, 66, - 4, 8, 11, 10, 15, 21, 32, 69, 64, 74, 73, 61, - 79, 99, 73, 2, 2, 72, 71, 70, 74, 0, 76, 94, - 69, 68, 21, 70, 77, 69, 68, 65, 72, 71, 70, - 89, 81, 72, 75, 71, 22, 100, 76, 23, 82, 68, - 69, 70, 4, 66, 71, 2, 9, 72, 72, 104, 34, 32, - 33, 17, 1, 1, 64, 73, 65, 75, 79, 74, 91, 88, - 91, 97, 94, 105, 126, 92, 85, 85, 86, 98, 92, - 88, 90, 91, 79, 74, 78, 75, 81, 100, 87, 85, - 107, 93, 105, 105, 123, 118, 114, 114, 76, 73, - 114, 83, 83, 90, 106, 96, 97, 100, 89, 95, 85, - 83, 105, 111, 123, 85, 97, 103, 70, 9, 14, 16, - 33, 22, 28, 6, 31, 26, 36, 30, 39, 34, 23, 43, - 65, 73, 81, 89, 89, 115, 115, 114, 15, 44, 39, - 42, 32, 34, 20, 19, 10, 9, 70, 9, 14, 16, 33, - 22, 28, 6, 31, 26, 36, 30, 39, 34, 23, 43, 65, - 73, 81, 89, 89, 115, 115, 114 }, - - { - - 27, - 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 90, 64, - 28, 38, 9, 34, 82, 74, 23, 69, 72, 34, 92, 91, - 2, 74, 126, 126, 126, 18, 3, 68, 74, 23, 69, - 77, 11, 35, 65, 3, 64, 1, 105, 109, 94, 111, - 65, 72, 72, 75, 90, 82, 98, 1, 68, 69, 66, 31, - 1, 22, 0, 0, 0, 4, 96, 97, 9, 74, 69, 12, 64, - 75, 29, 16, 4, 44, 42, 5, 16, 16, 23, 7, 7, - 31, 108, 88, 89, 90, 24, 71, 16, 31, 66, 75, - 1, 13, 65, 73, 72, 81, 23, 75, 13, 64, 75, 6, - 69, 64, 7, 12, 15, 18, 7, 78, 67, 3, 65, 0, - 71, 30, 66, 1, 30, 27, 37, 30, 26, 96, 9, 9, - 75, 67, 77, 69, 30, 1, 4, 34, 53, 62, 62, 44, - 98, 106, 10, 41, 42, 124, 72, 12, 97, 23, 69, - 3, 34, 33, 54, 48, 43, 107, 65, 80, 94, 94, - 70, 14, 21, 12, 6, 12, 11, 4, 16, 10, 76, 69, - 6, 1, 0, 75, 64, 72, 77, 65, 66, 1, 70, 72, - 106, 73, 75, 69, 84, 83, 71, 4, 68, 71, 69, - 73, 89, 75, 65, 104, 121, 94, 102, 96, 126, - 85, 79, 113, 64, 74, 74, 81, 85, 96, 91, 85, - 103, 93, 91, 95, 104, 65, 10, 38, 25, 10, 4, - 14, 8, 3, 0, 11, 17, 42, 27, 21, 12, 32, 16, - 18, 4, 31, 7, 36, 23, 18, 11, 24, 10, 4, 2, 2, - 68, 51, 29, 11, 3, 19, 4, 70, 65, 16, 41, 35, - 21, 10, 31, 13, 11, 4, 2, 62, 70, 1, 8, 6, 65, - 5, 10, 13, 12, 17, 23, 34, 68, 0, 73, 72, 62, - 79, 100, 73, 3, 3, 71, 71, 70, 74, 0, 76, 95, - 69, 68, 22, 70, 77, 69, 68, 65, 72, 71, 70, - 89, 82, 72, 75, 70, 24, 100, 76, 24, 83, 68, - 69, 70, 5, 66, 71, 3, 10, 71, 71, 106, 33, 31, - 32, 15, 64, 65, 66, 76, 67, 77, 82, 76, 94, - 91, 93, 101, 97, 108, 126, 95, 87, 86, 88, - 100, 93, 89, 91, 92, 79, 76, 80, 77, 83, 102, - 89, 86, 109, 95, 107, 107, 125, 120, 116, 115, - 77, 74, 116, 84, 85, 91, 108, 97, 98, 101, 90, - 95, 85, 82, 106, 112, 125, 86, 98, 104, 70, - 10, 15, 17, 35, 23, 29, 6, 32, 27, 37, 31, 40, - 35, 24, 42, 66, 75, 83, 91, 91, 117, 117, 115, - 16, 44, 40, 43, 33, 35, 21, 20, 11, 10, 70, - 10, 15, 17, 35, 23, 29, 6, 32, 27, 37, 31, 40, - 35, 24, 42, 66, 75, 83, 91, 91, 117, 117, 115 }, - - { - - 26, - 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 92, 65, - 27, 39, 9, 35, 84, 74, 24, 70, 72, 35, 93, 92, - 1, 76, 126, 126, 126, 20, 4, 68, 74, 24, 70, - 77, 12, 35, 65, 3, 0, 3, 106, 110, 94, 111, - 65, 71, 71, 76, 90, 82, 98, 1, 68, 69, 65, 32, - 1, 22, 0, 0, 0, 4, 96, 97, 10, 75, 69, 11, 64, - 74, 31, 17, 5, 45, 43, 6, 17, 18, 24, 8, 8, - 34, 108, 89, 89, 91, 24, 71, 17, 34, 65, 75, - 1, 15, 65, 73, 72, 81, 23, 75, 13, 0, 75, 7, - 68, 64, 7, 12, 16, 18, 7, 79, 67, 3, 65, 0, - 71, 30, 66, 1, 31, 27, 37, 30, 26, 97, 9, 9, - 75, 67, 76, 69, 31, 2, 4, 36, 55, 62, 62, 46, - 98, 107, 10, 42, 42, 125, 72, 13, 98, 24, 69, - 3, 35, 33, 54, 48, 45, 108, 0, 81, 97, 97, 69, - 14, 21, 11, 6, 11, 11, 3, 16, 9, 77, 70, 6, 1, - 0, 75, 65, 72, 78, 66, 66, 1, 71, 72, 107, 74, - 76, 69, 85, 84, 73, 2, 70, 73, 70, 75, 92, 78, - 66, 106, 123, 96, 104, 98, 126, 86, 80, 114, - 65, 75, 75, 83, 86, 98, 93, 86, 105, 93, 92, - 96, 106, 64, 11, 39, 25, 10, 4, 15, 9, 4, 0, - 13, 19, 43, 28, 21, 13, 34, 17, 20, 5, 34, 8, - 36, 23, 18, 12, 25, 11, 4, 3, 3, 68, 52, 30, - 11, 3, 20, 4, 70, 64, 17, 41, 36, 21, 10, 32, - 14, 12, 4, 3, 62, 69, 2, 9, 7, 64, 7, 11, 15, - 13, 19, 25, 37, 67, 1, 72, 71, 62, 78, 101, - 72, 4, 4, 71, 71, 70, 74, 1, 77, 96, 69, 68, - 23, 70, 77, 69, 68, 64, 73, 72, 70, 90, 83, - 73, 75, 70, 25, 101, 77, 25, 83, 69, 69, 70, - 5, 67, 72, 3, 10, 71, 71, 107, 32, 30, 31, 14, - 67, 67, 69, 79, 70, 80, 85, 79, 97, 93, 95, - 105, 101, 112, 126, 98, 89, 88, 90, 103, 95, - 90, 92, 93, 79, 78, 83, 80, 85, 104, 91, 88, - 111, 97, 109, 109, 126, 122, 117, 117, 78, 75, - 118, 86, 86, 93, 110, 98, 99, 102, 91, 96, 85, - 81, 108, 113, 126, 88, 99, 105, 70, 10, 15, - 18, 36, 24, 29, 7, 33, 28, 38, 31, 41, 35, 24, - 42, 68, 77, 85, 93, 93, 120, 119, 116, 16, 45, - 40, 43, 34, 36, 21, 20, 11, 11, 70, 10, 15, - 18, 36, 24, 29, 7, 33, 28, 38, 31, 41, 35, 24, - 42, 68, 77, 85, 93, 93, 120, 119, 116 }, - - { - - 25, - 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 93, 67, - 26, 39, 10, 37, 85, 74, 26, 70, 73, 36, 94, - 93, 0, 77, 126, 126, 126, 22, 6, 68, 74, 26, - 70, 76, 13, 36, 65, 4, 1, 4, 108, 111, 94, - 112, 65, 71, 71, 76, 91, 81, 98, 0, 68, 69, - 64, 32, 1, 22, 0, 0, 0, 5, 96, 97, 10, 75, 70, - 11, 0, 73, 33, 18, 6, 47, 45, 7, 18, 20, 25, - 9, 8, 36, 109, 89, 89, 91, 25, 71, 18, 36, 65, - 74, 2, 17, 65, 73, 72, 81, 24, 76, 14, 0, 75, - 8, 68, 0, 7, 13, 17, 19, 7, 79, 67, 3, 65, 0, - 71, 30, 66, 1, 31, 27, 38, 31, 27, 97, 10, 10, - 76, 67, 76, 69, 32, 2, 5, 37, 56, 62, 62, 47, - 99, 108, 11, 42, 42, 125, 73, 13, 98, 24, 70, - 4, 36, 33, 54, 49, 46, 109, 1, 82, 100, 100, - 67, 14, 21, 11, 5, 11, 10, 3, 15, 9, 77, 70, - 6, 0, 0, 76, 65, 73, 79, 66, 66, 1, 71, 73, - 109, 74, 77, 69, 86, 84, 76, 0, 72, 74, 72, - 77, 95, 80, 68, 108, 125, 97, 106, 100, 126, - 87, 82, 116, 67, 76, 76, 84, 88, 100, 95, 88, - 106, 93, 93, 97, 107, 1, 13, 41, 26, 10, 4, - 16, 9, 4, 1, 14, 20, 44, 29, 22, 13, 35, 18, - 21, 6, 36, 8, 37, 24, 19, 12, 26, 11, 5, 4, 4, - 68, 54, 31, 11, 3, 20, 5, 70, 64, 17, 42, 36, - 22, 10, 33, 14, 12, 5, 3, 62, 67, 4, 11, 9, 1, - 8, 13, 16, 15, 21, 27, 39, 67, 2, 72, 71, 62, - 78, 102, 72, 4, 5, 71, 71, 70, 74, 1, 77, 97, - 69, 68, 23, 70, 77, 69, 68, 64, 73, 72, 70, - 91, 84, 73, 75, 70, 26, 102, 77, 26, 84, 69, - 69, 70, 6, 67, 72, 4, 11, 71, 71, 109, 31, 29, - 30, 12, 69, 70, 71, 82, 72, 83, 88, 82, 100, - 96, 97, 108, 104, 116, 126, 100, 92, 90, 92, - 105, 97, 91, 93, 94, 79, 80, 85, 82, 87, 106, - 92, 89, 113, 99, 112, 111, 126, 124, 119, 118, - 79, 77, 120, 87, 88, 94, 112, 100, 101, 103, - 92, 97, 86, 80, 109, 115, 126, 89, 101, 106, - 69, 11, 16, 18, 37, 25, 30, 7, 34, 29, 39, 32, - 42, 36, 25, 41, 70, 79, 87, 95, 95, 122, 121, - 117, 17, 45, 41, 44, 34, 37, 22, 21, 12, 11, - 69, 11, 16, 18, 37, 25, 30, 7, 34, 29, 39, 32, - 42, 36, 25, 41, 70, 79, 87, 95, 95, 122, 121, - 117 }, - - { - - 23, - 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 95, 68, - 25, 40, 10, 39, 87, 74, 27, 70, 73, 37, 95, - 95, 65, 79, 126, 126, 126, 24, 7, 68, 74, 27, - 70, 76, 14, 36, 66, 5, 2, 5, 109, 113, 95, - 112, 65, 71, 70, 76, 91, 81, 98, 0, 68, 69, - 64, 33, 1, 22, 0, 0, 0, 5, 97, 97, 11, 76, 70, - 10, 0, 72, 35, 19, 7, 48, 46, 7, 19, 22, 26, - 10, 9, 38, 110, 89, 89, 91, 25, 72, 19, 38, - 65, 73, 3, 19, 65, 73, 72, 81, 24, 76, 14, 1, - 75, 8, 68, 0, 7, 13, 18, 19, 7, 79, 68, 3, 65, - 0, 71, 30, 66, 1, 32, 27, 38, 31, 27, 98, 10, - 11, 76, 67, 76, 69, 33, 2, 5, 38, 57, 62, 62, - 49, 99, 109, 11, 42, 42, 126, 73, 14, 99, 25, - 70, 4, 37, 33, 54, 49, 47, 110, 3, 83, 103, - 103, 66, 13, 21, 10, 4, 10, 10, 2, 15, 8, 78, - 71, 5, 0, 0, 76, 66, 74, 80, 67, 67, 0, 72, - 73, 110, 75, 78, 69, 88, 85, 78, 65, 74, 76, - 74, 79, 99, 83, 69, 110, 126, 99, 108, 102, - 126, 89, 83, 118, 68, 77, 77, 85, 89, 102, 97, - 90, 108, 93, 94, 98, 109, 2, 14, 42, 26, 10, - 4, 17, 10, 5, 2, 16, 21, 45, 29, 23, 14, 36, - 19, 23, 7, 38, 9, 37, 24, 19, 13, 27, 12, 5, - 4, 5, 68, 55, 32, 11, 3, 21, 5, 70, 0, 18, 42, - 37, 22, 10, 34, 15, 13, 5, 4, 62, 66, 5, 12, - 11, 2, 10, 14, 18, 16, 22, 29, 41, 66, 3, 71, - 70, 62, 78, 103, 72, 5, 5, 71, 71, 70, 75, 2, - 77, 98, 69, 68, 24, 70, 77, 69, 68, 64, 74, - 72, 70, 92, 85, 73, 75, 70, 27, 103, 77, 26, - 85, 69, 69, 70, 6, 67, 73, 4, 12, 71, 71, 110, - 30, 28, 29, 10, 71, 72, 74, 85, 75, 86, 92, - 85, 104, 99, 99, 112, 108, 120, 126, 103, 94, - 92, 94, 108, 99, 93, 94, 95, 79, 83, 87, 84, - 89, 108, 94, 91, 115, 101, 114, 113, 126, 126, - 121, 119, 80, 78, 123, 89, 90, 96, 114, 101, - 102, 104, 93, 98, 86, 79, 110, 116, 126, 90, - 102, 107, 69, 11, 16, 19, 38, 25, 31, 7, 35, - 30, 40, 32, 43, 36, 26, 41, 72, 81, 89, 97, - 97, 124, 123, 119, 17, 46, 41, 45, 35, 37, 22, - 21, 12, 12, 69, 11, 16, 19, 38, 25, 31, 7, 35, - 30, 40, 32, 43, 36, 26, 41, 72, 81, 89, 97, - 97, 124, 123, 119 }, - - { - - 22, - 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 70, - 24, 41, 10, 40, 89, 73, 29, 71, 73, 38, 96, - 96, 66, 81, 126, 126, 126, 26, 8, 68, 73, 29, - 71, 76, 15, 36, 66, 5, 3, 7, 110, 114, 95, - 112, 65, 70, 69, 77, 91, 81, 98, 0, 67, 69, 0, - 33, 1, 22, 0, 0, 0, 6, 97, 97, 11, 77, 70, 10, - 1, 70, 38, 20, 8, 50, 48, 8, 20, 24, 27, 11, - 10, 41, 110, 90, 89, 92, 25, 72, 20, 41, 64, - 73, 3, 21, 65, 73, 72, 80, 24, 76, 15, 2, 74, - 9, 67, 0, 8, 14, 19, 20, 7, 80, 68, 4, 65, 0, - 71, 31, 66, 1, 32, 28, 38, 31, 27, 98, 11, 11, - 77, 67, 75, 69, 34, 3, 6, 40, 59, 62, 62, 51, - 100, 110, 12, 43, 42, 126, 73, 14, 99, 26, 70, - 4, 39, 33, 54, 49, 49, 111, 4, 84, 105, 106, - 65, 13, 21, 10, 4, 10, 10, 2, 15, 8, 79, 72, - 5, 0, 0, 76, 66, 74, 81, 67, 67, 0, 73, 74, - 111, 76, 78, 69, 89, 85, 80, 67, 75, 77, 75, - 81, 102, 85, 70, 112, 126, 100, 110, 104, 126, - 90, 84, 119, 69, 78, 78, 87, 91, 104, 99, 91, - 109, 93, 95, 99, 111, 4, 16, 43, 27, 10, 4, - 18, 11, 6, 2, 18, 23, 46, 30, 23, 15, 38, 20, - 24, 8, 41, 10, 38, 25, 20, 13, 28, 13, 6, 5, - 6, 67, 56, 33, 11, 3, 22, 6, 69, 1, 19, 42, - 38, 22, 10, 35, 16, 14, 6, 5, 62, 65, 7, 14, - 12, 3, 11, 16, 20, 18, 24, 31, 44, 65, 4, 70, - 69, 62, 77, 104, 71, 6, 6, 71, 71, 70, 75, 2, - 78, 99, 69, 68, 25, 70, 77, 69, 68, 0, 74, 73, - 70, 93, 86, 74, 75, 70, 28, 103, 78, 27, 85, - 70, 69, 70, 6, 68, 73, 4, 12, 71, 71, 112, 29, - 27, 28, 9, 74, 75, 77, 88, 77, 89, 95, 88, - 107, 101, 101, 116, 111, 124, 126, 106, 96, - 93, 96, 110, 101, 94, 95, 96, 79, 85, 90, 87, - 91, 110, 96, 92, 117, 103, 116, 115, 126, 126, - 122, 121, 81, 79, 125, 90, 91, 97, 116, 102, - 103, 105, 94, 99, 86, 78, 112, 117, 126, 92, - 103, 108, 69, 12, 17, 20, 39, 26, 31, 8, 36, - 31, 41, 33, 44, 37, 26, 40, 74, 83, 91, 99, - 99, 126, 125, 120, 18, 46, 42, 45, 36, 38, 23, - 22, 12, 13, 69, 12, 17, 20, 39, 26, 31, 8, 36, - 31, 41, 33, 44, 37, 26, 40, 74, 83, 91, 99, - 99, 126, 125, 120 }, - - { - - 21, - 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 71, - 23, 41, 10, 42, 90, 73, 30, 71, 74, 39, 97, - 97, 67, 83, 126, 126, 126, 28, 10, 68, 73, 30, - 71, 75, 16, 37, 66, 6, 4, 8, 111, 115, 95, - 113, 65, 70, 68, 77, 92, 81, 98, 0, 67, 69, 1, - 34, 1, 22, 0, 0, 0, 6, 97, 97, 12, 78, 70, 9, - 1, 69, 40, 21, 9, 51, 49, 9, 21, 26, 28, 12, - 11, 43, 111, 90, 89, 92, 26, 72, 21, 43, 64, - 72, 4, 23, 65, 73, 72, 80, 25, 76, 15, 3, 74, - 10, 67, 0, 8, 14, 20, 20, 7, 80, 68, 4, 65, 0, - 71, 31, 66, 1, 33, 28, 39, 31, 28, 99, 11, 12, - 77, 67, 75, 69, 35, 3, 6, 41, 60, 62, 62, 53, - 100, 111, 12, 43, 42, 126, 73, 15, 100, 26, - 70, 4, 40, 33, 54, 49, 50, 112, 6, 85, 108, - 109, 0, 13, 21, 9, 3, 9, 9, 1, 15, 7, 80, 73, - 5, 0, 0, 77, 67, 75, 82, 68, 67, 0, 74, 74, - 112, 76, 79, 69, 90, 86, 82, 69, 77, 79, 77, - 83, 105, 88, 71, 114, 126, 102, 112, 106, 126, - 91, 85, 121, 70, 79, 79, 88, 92, 106, 101, 93, - 111, 93, 96, 100, 112, 5, 17, 45, 27, 10, 4, - 19, 12, 7, 3, 20, 24, 47, 31, 24, 15, 39, 21, - 26, 9, 43, 10, 38, 25, 20, 14, 29, 13, 6, 6, - 7, 67, 58, 34, 11, 3, 23, 6, 69, 2, 20, 43, - 39, 23, 10, 36, 16, 15, 6, 5, 62, 0, 8, 15, - 14, 4, 13, 17, 21, 19, 26, 33, 46, 65, 5, 70, - 68, 62, 77, 105, 71, 7, 7, 71, 71, 70, 75, 3, - 78, 100, 69, 68, 25, 70, 77, 69, 68, 0, 75, - 73, 70, 94, 87, 74, 75, 70, 29, 104, 78, 28, - 86, 70, 69, 70, 7, 68, 74, 5, 13, 71, 71, 113, - 28, 26, 27, 7, 76, 77, 79, 91, 80, 92, 98, 91, - 110, 104, 103, 120, 115, 126, 126, 109, 98, - 95, 98, 113, 103, 95, 96, 97, 79, 87, 92, 89, - 93, 112, 98, 94, 119, 105, 118, 117, 126, 126, - 124, 122, 82, 80, 126, 92, 93, 99, 118, 104, - 105, 106, 95, 100, 86, 77, 113, 119, 126, 93, - 104, 109, 69, 12, 17, 20, 40, 27, 32, 8, 37, - 32, 42, 33, 45, 37, 27, 40, 76, 85, 93, 101, - 101, 126, 126, 121, 18, 47, 42, 46, 36, 39, - 23, 22, 13, 13, 69, 12, 17, 20, 40, 27, 32, 8, - 37, 32, 42, 33, 45, 37, 27, 40, 76, 85, 93, - 101, 101, 126, 126, 121 }, - - { - - 20, - 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 101, 73, - 22, 42, 10, 44, 92, 73, 32, 71, 74, 40, 98, - 98, 68, 85, 126, 126, 126, 30, 11, 68, 73, 32, - 71, 75, 17, 37, 66, 7, 5, 9, 112, 116, 95, - 113, 65, 70, 67, 77, 92, 81, 98, 0, 67, 69, 2, - 34, 1, 22, 0, 0, 0, 7, 97, 97, 12, 79, 70, 9, - 2, 68, 42, 22, 10, 53, 51, 10, 22, 28, 29, 13, - 12, 45, 112, 90, 89, 92, 26, 72, 22, 45, 64, - 71, 5, 25, 65, 73, 72, 80, 25, 76, 16, 4, 74, - 11, 67, 0, 8, 15, 21, 21, 7, 80, 68, 4, 65, 0, - 71, 31, 66, 1, 33, 28, 39, 31, 28, 99, 12, 13, - 78, 67, 75, 69, 36, 3, 7, 42, 61, 62, 62, 55, - 101, 112, 13, 43, 42, 126, 73, 15, 100, 27, - 70, 4, 41, 33, 54, 49, 51, 113, 7, 86, 111, - 112, 1, 13, 21, 9, 2, 9, 9, 1, 15, 7, 81, 74, - 5, 0, 0, 77, 67, 76, 83, 68, 67, 0, 75, 75, - 113, 77, 80, 69, 91, 86, 84, 71, 79, 80, 79, - 85, 108, 90, 72, 116, 126, 103, 114, 108, 126, - 92, 86, 123, 71, 80, 80, 89, 94, 108, 103, 95, - 112, 93, 97, 101, 114, 7, 19, 46, 28, 10, 4, - 20, 13, 8, 4, 22, 25, 48, 32, 25, 16, 40, 22, - 27, 10, 45, 11, 39, 26, 21, 14, 30, 14, 7, 7, - 8, 67, 59, 35, 11, 3, 24, 7, 69, 3, 21, 43, - 40, 23, 10, 37, 17, 16, 7, 6, 62, 1, 10, 17, - 16, 5, 14, 19, 23, 21, 28, 35, 48, 64, 6, 69, - 67, 62, 77, 106, 71, 8, 8, 71, 71, 70, 75, 3, - 78, 101, 69, 68, 26, 70, 77, 69, 68, 0, 75, - 73, 70, 95, 88, 74, 75, 70, 30, 105, 78, 29, - 87, 70, 69, 70, 7, 68, 74, 5, 14, 71, 71, 115, - 27, 25, 26, 5, 78, 80, 82, 94, 82, 95, 101, - 94, 113, 107, 105, 124, 118, 126, 126, 112, - 100, 97, 100, 115, 105, 96, 97, 98, 79, 89, - 94, 91, 95, 114, 100, 95, 121, 107, 120, 119, - 126, 126, 126, 123, 83, 81, 126, 93, 95, 100, - 120, 105, 106, 107, 96, 101, 86, 76, 114, 120, - 126, 94, 105, 110, 69, 13, 18, 21, 41, 28, 33, - 8, 38, 33, 43, 34, 46, 38, 28, 39, 78, 87, 95, - 103, 103, 126, 126, 122, 19, 47, 43, 47, 37, - 40, 24, 23, 13, 14, 69, 13, 18, 21, 41, 28, - 33, 8, 38, 33, 43, 34, 46, 38, 28, 39, 78, 87, - 95, 103, 103, 126, 126, 122 }, - - { - - 18, - 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 103, 75, - 21, 42, 10, 45, 94, 73, 33, 72, 75, 41, 99, - 100, 70, 87, 126, 126, 126, 32, 12, 68, 73, - 33, 72, 75, 17, 37, 67, 7, 5, 10, 114, 118, - 96, 114, 66, 70, 67, 78, 93, 81, 98, 64, 67, - 69, 2, 34, 0, 22, 0, 0, 0, 7, 98, 97, 12, 80, - 71, 8, 2, 67, 44, 23, 10, 54, 52, 10, 23, 29, - 29, 14, 12, 47, 113, 91, 90, 93, 26, 73, 22, - 47, 64, 71, 5, 26, 65, 73, 72, 80, 25, 77, 16, - 4, 74, 11, 67, 0, 8, 15, 22, 21, 7, 81, 69, 4, - 65, 64, 71, 31, 66, 1, 33, 28, 39, 31, 28, - 100, 12, 13, 79, 67, 75, 70, 36, 3, 7, 43, 62, - 62, 62, 56, 102, 114, 13, 43, 42, 126, 74, 15, - 101, 27, 71, 4, 42, 33, 53, 49, 52, 114, 8, - 88, 114, 116, 2, 12, 21, 8, 1, 8, 8, 0, 14, 6, - 82, 75, 4, 64, 64, 78, 68, 77, 84, 69, 68, 64, - 76, 76, 115, 78, 81, 69, 93, 87, 87, 74, 81, - 82, 81, 88, 112, 93, 74, 118, 126, 105, 117, - 110, 126, 94, 88, 125, 73, 81, 81, 91, 96, - 110, 105, 97, 114, 93, 98, 102, 116, 8, 20, - 47, 28, 10, 4, 20, 13, 8, 4, 23, 26, 48, 32, - 25, 16, 41, 23, 28, 10, 47, 11, 39, 26, 21, - 14, 30, 14, 7, 7, 9, 67, 60, 36, 11, 2, 24, 7, - 69, 3, 21, 43, 40, 23, 10, 38, 17, 16, 7, 6, - 62, 2, 11, 18, 17, 6, 15, 20, 24, 22, 29, 36, - 50, 64, 6, 69, 67, 62, 77, 108, 71, 8, 8, 71, - 71, 70, 76, 3, 79, 102, 70, 68, 26, 71, 77, - 70, 68, 0, 76, 74, 71, 96, 89, 75, 76, 70, 31, - 106, 79, 29, 88, 71, 69, 71, 7, 69, 75, 5, 14, - 71, 71, 117, 25, 24, 24, 3, 81, 83, 85, 97, - 85, 98, 105, 97, 117, 110, 107, 126, 122, 126, - 126, 115, 103, 99, 103, 118, 107, 98, 99, 99, - 79, 92, 97, 94, 97, 117, 102, 97, 124, 109, - 123, 121, 126, 126, 126, 125, 85, 83, 126, 95, - 97, 102, 122, 107, 108, 108, 97, 102, 87, 75, - 116, 122, 126, 96, 107, 112, 69, 13, 18, 21, - 42, 28, 33, 8, 39, 33, 44, 34, 46, 38, 28, 38, - 80, 89, 98, 106, 105, 126, 126, 124, 19, 47, - 43, 47, 37, 40, 24, 23, 13, 14, 69, 13, 18, - 21, 42, 28, 33, 8, 39, 33, 44, 34, 46, 38, 28, - 38, 80, 89, 98, 106, 105, 126, 126, 124 }, - - { - - 17, - 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 104, 76, - 21, 43, 11, 47, 95, 72, 35, 72, 75, 43, 99, - 101, 71, 88, 126, 126, 126, 34, 14, 67, 72, - 35, 72, 74, 18, 38, 67, 8, 6, 12, 115, 119, - 96, 114, 66, 69, 66, 78, 93, 80, 97, 64, 66, - 68, 3, 35, 0, 22, 0, 0, 0, 8, 98, 97, 13, 80, - 71, 8, 3, 65, 47, 25, 11, 56, 54, 11, 25, 31, - 30, 16, 13, 50, 113, 91, 90, 93, 27, 73, 23, - 50, 0, 70, 6, 28, 65, 72, 72, 79, 26, 77, 17, - 5, 73, 12, 66, 1, 9, 16, 23, 22, 8, 81, 69, 5, - 64, 64, 70, 32, 65, 1, 34, 29, 40, 32, 29, - 100, 13, 14, 79, 67, 74, 70, 37, 4, 8, 45, 62, - 62, 62, 58, 102, 115, 14, 44, 43, 126, 74, 16, - 101, 28, 71, 5, 44, 33, 53, 50, 54, 115, 10, - 89, 116, 119, 4, 12, 21, 8, 1, 8, 8, 0, 14, 6, - 82, 75, 4, 64, 64, 78, 68, 77, 84, 69, 68, 64, - 76, 76, 116, 78, 81, 69, 94, 87, 89, 76, 82, - 83, 82, 90, 115, 95, 75, 119, 126, 106, 119, - 111, 126, 95, 89, 126, 74, 81, 81, 92, 97, - 111, 106, 98, 115, 93, 98, 102, 117, 10, 22, - 49, 29, 10, 4, 21, 14, 9, 5, 25, 28, 49, 33, - 26, 17, 43, 24, 30, 11, 50, 12, 40, 27, 22, - 15, 31, 15, 8, 8, 11, 66, 62, 37, 12, 2, 25, - 8, 68, 4, 22, 44, 41, 24, 11, 39, 18, 17, 8, - 7, 62, 4, 13, 20, 19, 8, 17, 22, 26, 24, 31, - 38, 53, 0, 7, 68, 66, 62, 76, 109, 70, 9, 9, - 70, 71, 69, 76, 4, 79, 102, 70, 68, 27, 71, - 77, 70, 68, 1, 76, 74, 71, 96, 89, 75, 76, 69, - 33, 106, 79, 30, 88, 71, 69, 71, 8, 69, 75, 6, - 15, 70, 70, 118, 24, 23, 23, 2, 83, 85, 87, - 100, 87, 100, 108, 99, 120, 112, 109, 126, - 125, 126, 126, 117, 105, 100, 105, 120, 108, - 99, 100, 99, 79, 94, 99, 96, 99, 119, 103, 98, - 126, 110, 125, 122, 126, 126, 126, 126, 86, - 84, 126, 96, 98, 103, 123, 108, 109, 109, 97, - 102, 87, 74, 117, 123, 126, 97, 108, 113, 68, - 14, 19, 22, 44, 29, 34, 9, 41, 34, 45, 35, 47, - 39, 29, 38, 81, 90, 100, 108, 106, 126, 126, - 125, 20, 48, 44, 48, 38, 41, 25, 24, 14, 15, - 68, 14, 19, 22, 44, 29, 34, 9, 41, 34, 45, 35, - 47, 39, 29, 38, 81, 90, 100, 108, 106, 126, - 126, 125 }, - - { - - 16, - 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 106, 78, - 20, 44, 11, 49, 97, 72, 36, 72, 75, 44, 100, - 102, 72, 90, 126, 126, 126, 36, 15, 67, 72, - 36, 72, 74, 19, 38, 67, 9, 7, 13, 116, 120, - 96, 114, 66, 69, 65, 78, 93, 80, 97, 64, 66, - 68, 4, 35, 0, 22, 0, 0, 0, 9, 98, 97, 13, 81, - 71, 8, 4, 64, 49, 26, 12, 58, 56, 12, 26, 33, - 31, 17, 14, 52, 114, 91, 90, 93, 27, 73, 24, - 52, 0, 69, 7, 30, 65, 72, 72, 79, 26, 77, 17, - 6, 73, 13, 66, 1, 9, 16, 24, 23, 8, 81, 69, 5, - 64, 64, 70, 32, 65, 1, 34, 29, 40, 32, 29, - 101, 14, 15, 80, 67, 74, 70, 38, 4, 8, 46, 62, - 62, 62, 60, 103, 116, 14, 44, 43, 126, 74, 16, - 102, 29, 71, 5, 45, 33, 53, 50, 55, 116, 11, - 90, 119, 122, 5, 12, 21, 8, 0, 7, 8, 0, 14, 5, - 83, 76, 4, 64, 64, 78, 69, 78, 85, 69, 68, 64, - 77, 77, 117, 79, 82, 69, 95, 88, 91, 78, 84, - 85, 84, 92, 118, 97, 76, 121, 126, 108, 121, - 113, 126, 96, 90, 126, 75, 82, 82, 93, 99, - 113, 108, 100, 117, 93, 99, 103, 119, 11, 23, - 50, 30, 10, 4, 22, 15, 10, 6, 27, 29, 50, 34, - 27, 18, 44, 25, 31, 12, 52, 13, 40, 27, 22, - 15, 32, 16, 9, 9, 12, 66, 62, 38, 12, 2, 26, - 9, 68, 5, 23, 44, 42, 24, 11, 40, 19, 18, 9, - 8, 62, 5, 15, 22, 21, 9, 18, 24, 28, 25, 33, - 40, 55, 1, 8, 67, 65, 62, 76, 110, 70, 10, 10, - 70, 71, 69, 76, 4, 79, 103, 70, 68, 28, 71, - 77, 70, 68, 1, 76, 74, 71, 97, 90, 75, 76, 69, - 34, 107, 79, 31, 89, 71, 69, 71, 8, 69, 75, 6, - 16, 70, 70, 120, 23, 22, 22, 0, 85, 88, 90, - 103, 89, 103, 111, 102, 123, 115, 111, 126, - 126, 126, 126, 120, 107, 102, 107, 122, 110, - 100, 101, 100, 79, 96, 101, 98, 101, 121, 105, - 100, 126, 112, 126, 124, 126, 126, 126, 126, - 87, 85, 126, 98, 100, 105, 125, 109, 110, 110, - 98, 103, 87, 73, 118, 124, 126, 98, 109, 114, - 68, 14, 20, 23, 45, 30, 35, 9, 42, 35, 46, 35, - 48, 40, 30, 37, 83, 92, 102, 110, 108, 126, - 126, 126, 21, 48, 44, 49, 39, 42, 25, 25, 14, - 16, 68, 14, 20, 23, 45, 30, 35, 9, 42, 35, 46, - 35, 48, 40, 30, 37, 83, 92, 102, 110, 108, - 126, 126, 126 }, - - { - - 15, - 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 108, 79, - 19, 44, 11, 51, 98, 72, 38, 72, 76, 45, 101, - 103, 73, 92, 126, 126, 126, 38, 17, 67, 72, - 38, 72, 73, 20, 39, 67, 10, 8, 14, 117, 121, - 96, 115, 66, 69, 64, 78, 94, 80, 97, 64, 66, - 68, 5, 36, 0, 22, 0, 0, 0, 9, 98, 97, 14, 82, - 71, 7, 4, 0, 51, 27, 13, 59, 57, 13, 27, 35, - 32, 18, 15, 54, 115, 91, 90, 93, 28, 73, 25, - 54, 0, 68, 8, 32, 65, 72, 72, 79, 27, 77, 18, - 7, 73, 14, 66, 1, 9, 17, 25, 23, 8, 81, 69, 5, - 64, 64, 70, 32, 65, 1, 35, 29, 41, 32, 30, - 101, 14, 16, 80, 67, 74, 70, 39, 4, 9, 47, 62, - 62, 62, 62, 103, 117, 15, 44, 43, 126, 74, 17, - 102, 29, 71, 5, 46, 33, 53, 50, 56, 117, 13, - 91, 122, 125, 7, 12, 21, 7, 64, 7, 7, 64, 14, - 5, 84, 77, 4, 64, 64, 79, 69, 79, 86, 70, 68, - 64, 78, 77, 118, 79, 83, 69, 96, 88, 93, 80, - 86, 86, 86, 94, 121, 100, 77, 123, 126, 109, - 123, 115, 126, 97, 91, 126, 76, 83, 83, 94, - 100, 115, 110, 102, 118, 93, 100, 104, 120, - 13, 25, 52, 30, 10, 4, 23, 16, 11, 7, 29, 30, - 51, 35, 28, 18, 45, 26, 33, 13, 54, 13, 41, - 28, 23, 16, 33, 16, 9, 10, 13, 66, 62, 39, 12, - 2, 27, 9, 68, 6, 24, 45, 43, 25, 11, 41, 19, - 19, 9, 8, 62, 7, 16, 23, 23, 10, 20, 25, 29, - 27, 35, 42, 57, 1, 9, 67, 64, 62, 76, 111, 70, - 11, 11, 70, 71, 69, 76, 5, 79, 104, 70, 68, - 28, 71, 77, 70, 68, 1, 77, 74, 71, 98, 91, 75, - 76, 69, 35, 108, 79, 32, 90, 71, 69, 71, 9, - 69, 76, 7, 17, 70, 70, 121, 22, 21, 21, 65, - 87, 90, 92, 106, 92, 106, 114, 105, 126, 118, - 113, 126, 126, 126, 126, 123, 109, 104, 109, - 125, 112, 101, 102, 101, 79, 98, 103, 100, - 103, 123, 107, 101, 126, 114, 126, 126, 126, - 126, 126, 126, 88, 86, 126, 99, 102, 106, 126, - 111, 112, 111, 99, 104, 87, 72, 119, 126, 126, - 99, 110, 115, 68, 15, 20, 23, 46, 31, 36, 9, - 43, 36, 47, 36, 49, 40, 31, 37, 85, 94, 104, - 112, 110, 126, 126, 126, 21, 49, 45, 50, 39, - 43, 26, 25, 15, 16, 68, 15, 20, 23, 46, 31, - 36, 9, 43, 36, 47, 36, 49, 40, 31, 37, 85, 94, - 104, 112, 110, 126, 126, 126 }, - - }, - - { - - { - - 62, - 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 30, 61, - 62, 54, 14, 118, 6, 78, 65, 1, 14, 73, 13, 64, - 20, 62, 67, 90, 104, 126, 104, 67, 78, 65, 1, - 86, 95, 2, 18, 69, 81, 96, 8, 67, 86, 88, 5, 76, - 94, 9, 69, 81, 88, 67, 74, 74, 80, 72, 5, 22, 0, - 0, 0, 83, 86, 97, 72, 22, 1, 52, 8, 69, 126, - 102, 82, 74, 107, 126, 126, 126, 95, 126, 114, - 126, 123, 115, 122, 115, 0, 68, 84, 104, 70, 93, - 90, 126, 74, 97, 91, 126, 7, 82, 76, 125, 93, - 87, 77, 71, 0, 68, 84, 1, 65, 2, 7, 66, 64, 2, - 78, 13, 11, 28, 19, 25, 18, 17, 19, 46, 12, 13, - 44, 30, 1, 108, 100, 101, 91, 94, 88, 84, 86, - 83, 87, 94, 70, 72, 74, 4, 102, 100, 95, 75, 72, - 75, 71, 17, 69, 1, 65, 26, 72, 6, 9, 1, 72, 62, - 54, 38, 45, 54, 44, 26, 45, 34, 30, 33, 18, 5, - 1, 2, 25, 18, 24, 21, 19, 18, 22, 14, 29, 21, 8, - 12, 17, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 46, 62, 60, 41, 62, 62, 62, - 62, 60, 58, 62, 47, 41, 15, 26, 3, 68, 97, 71, - 21, 13, 9, 1, 5, 0, 72, 74, 91, 67, 36, 24, 19, - 17, 64, 68, 78, 77, 86, 92, 8, 3, 1, 65, 73, 76, - 80, 88, 110, 97, 84, 79, 73, 74, 86, 96, 97, - 117, 78, 30, 15, 10, 1, 71, 79, 86, 90, 97, 62, - 93, 84, 79, 66, 71, 1, 3, 4, 75, 1, 5, 66, 79, - 71, 68, 19, 1, 27, 23, 36, 34, 19, 27, 31, 21, - 15, 1, 17, 64, 104, 97, 96, 88, 85, 85, 85, 88, - 66, 77, 76, 76, 5, 76, 83, 99, 95, 95, 76, 74, - 70, 75, 68, 65, 73, 1, 1, 68, 75, 8, 64, 70, 57, - 44, 47, 49, 50, 52, 48, 47, 40, 40, 43, 37, 19, - 23, 16, 46, 42, 41, 36, 34, 28, 13, 6, 0, 77, - 82, 94, 69, 109, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 61, 50, 28, 5, 62, 62, 33, 62, 62, - 62, 60, 62, 58, 52, 58, 51, 52, 34, 37, 24, 66, - 42, 32, 13, 120, 112, 114, 85, 92, 89, 71, 81, - 80, 68, 70, 7, 68, 13, 74, 62, 62, 62, 62, 60, - 57, 29, 9, 82, 75, 40, 29, 20, 9, 8, 2, 64, 68, - 92, 106, 97, 90, 90, 88, 73, 79, 86, 73, 70, 69, - 66, 64, 5, 4, 62, 62, 62, 62, 60, 54, 43, 27, 67 }, - - { - - 62, - 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 29, - 60, 62, 54, 14, 115, 6, 77, 64, 1, 14, 72, 12, - 65, 20, 62, 68, 91, 104, 124, 102, 67, 77, 64, - 1, 85, 93, 3, 18, 68, 80, 95, 8, 67, 85, 88, - 5, 75, 93, 9, 69, 80, 88, 66, 73, 73, 79, 71, - 5, 22, 0, 0, 0, 82, 86, 97, 71, 22, 1, 52, 8, - 69, 125, 101, 82, 73, 105, 125, 125, 125, 93, - 125, 112, 125, 121, 114, 121, 114, 1, 67, 83, - 103, 69, 92, 89, 125, 73, 96, 90, 125, 8, 81, - 75, 123, 92, 86, 76, 70, 1, 67, 83, 2, 64, 2, - 7, 65, 64, 2, 77, 13, 11, 28, 19, 25, 18, 17, - 19, 45, 12, 13, 43, 29, 1, 107, 99, 100, 90, - 93, 87, 83, 85, 82, 86, 92, 70, 72, 73, 3, - 101, 99, 95, 74, 72, 74, 70, 17, 68, 1, 65, - 25, 71, 6, 8, 1, 72, 62, 54, 38, 45, 54, 44, - 26, 45, 34, 29, 33, 18, 5, 1, 2, 25, 18, 24, - 21, 19, 17, 22, 14, 28, 20, 8, 11, 16, 89, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 60, 44, 62, 59, 40, 62, 62, 62, 62, 58, - 56, 61, 45, 39, 15, 25, 2, 68, 97, 70, 22, 14, - 10, 2, 5, 0, 71, 73, 90, 66, 37, 25, 20, 17, - 0, 67, 77, 76, 85, 91, 9, 4, 2, 64, 72, 75, - 79, 87, 108, 96, 82, 78, 72, 73, 85, 95, 96, - 115, 77, 31, 16, 11, 2, 70, 78, 85, 89, 96, - 62, 92, 83, 78, 66, 70, 1, 4, 5, 74, 2, 6, 65, - 78, 71, 68, 19, 2, 27, 23, 35, 34, 19, 26, 30, - 21, 15, 1, 16, 64, 103, 96, 95, 87, 84, 84, - 84, 87, 66, 76, 75, 75, 5, 75, 82, 98, 94, 95, - 76, 73, 70, 74, 68, 65, 72, 1, 1, 67, 74, 8, - 64, 70, 57, 44, 47, 49, 49, 52, 48, 47, 40, - 40, 43, 37, 19, 22, 15, 45, 41, 40, 35, 33, - 27, 13, 6, 0, 76, 81, 93, 69, 108, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 61, 59, 48, 27, 5, - 62, 62, 32, 62, 62, 62, 58, 62, 56, 50, 56, - 49, 50, 33, 35, 23, 67, 41, 31, 12, 118, 110, - 112, 84, 91, 88, 69, 80, 79, 68, 69, 9, 66, - 15, 73, 62, 62, 62, 62, 58, 55, 27, 7, 83, 74, - 41, 29, 20, 9, 9, 2, 64, 68, 91, 105, 96, 89, - 89, 86, 72, 78, 85, 72, 69, 68, 65, 0, 6, 4, - 62, 62, 62, 62, 59, 53, 41, 26, 67 }, - - { - - 62, - 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 28, - 59, 61, 54, 14, 113, 6, 76, 0, 1, 13, 72, 11, - 66, 19, 60, 70, 92, 105, 121, 101, 67, 76, 0, - 1, 85, 92, 3, 17, 68, 80, 94, 8, 67, 85, 88, - 5, 75, 92, 9, 69, 80, 88, 66, 73, 73, 79, 71, - 5, 22, 0, 0, 0, 81, 86, 97, 71, 21, 1, 52, 8, - 69, 124, 100, 82, 73, 104, 123, 123, 124, 92, - 123, 111, 123, 120, 113, 120, 113, 2, 67, 82, - 102, 69, 92, 88, 123, 73, 96, 90, 124, 8, 81, - 75, 122, 92, 85, 76, 70, 1, 67, 82, 2, 64, 1, - 7, 65, 64, 2, 77, 13, 11, 27, 19, 24, 18, 17, - 19, 43, 12, 13, 41, 28, 0, 106, 98, 99, 89, - 92, 86, 82, 84, 82, 85, 91, 70, 72, 73, 2, - 101, 98, 95, 74, 72, 73, 70, 16, 67, 1, 65, - 24, 70, 5, 7, 1, 73, 60, 53, 37, 44, 53, 43, - 25, 44, 34, 28, 32, 18, 5, 1, 2, 24, 17, 23, - 20, 18, 16, 21, 13, 26, 19, 7, 10, 15, 89, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 58, 41, 62, 57, 38, 62, 62, 62, 62, 56, - 54, 58, 43, 37, 14, 23, 1, 69, 97, 70, 22, 14, - 10, 2, 5, 0, 71, 73, 89, 66, 37, 25, 20, 17, - 1, 67, 76, 76, 84, 90, 10, 5, 2, 64, 71, 75, - 79, 86, 107, 95, 81, 77, 72, 73, 84, 94, 95, - 114, 77, 31, 16, 11, 2, 69, 77, 84, 88, 95, - 62, 92, 83, 78, 66, 70, 1, 4, 5, 74, 2, 6, 64, - 78, 71, 68, 18, 2, 26, 22, 34, 33, 19, 25, 29, - 21, 15, 0, 15, 65, 102, 95, 94, 87, 84, 84, - 83, 86, 66, 76, 75, 75, 4, 75, 82, 98, 93, 95, - 76, 73, 70, 73, 68, 65, 71, 1, 1, 67, 73, 7, - 64, 71, 56, 44, 47, 48, 48, 51, 47, 46, 39, - 39, 42, 36, 18, 21, 14, 43, 40, 38, 33, 32, - 26, 12, 5, 0, 76, 81, 93, 70, 107, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 59, 57, 46, 26, 4, - 62, 60, 31, 62, 62, 62, 56, 60, 54, 48, 54, - 47, 48, 31, 33, 21, 68, 39, 29, 10, 117, 109, - 111, 83, 90, 87, 67, 79, 78, 68, 68, 10, 65, - 16, 72, 62, 62, 62, 62, 55, 52, 24, 5, 84, 74, - 41, 29, 20, 9, 9, 2, 64, 68, 90, 104, 95, 88, - 88, 85, 71, 77, 84, 71, 68, 67, 65, 1, 6, 4, - 62, 62, 62, 61, 57, 51, 39, 24, 68 }, - - { - - 62, - 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 26, 57, - 60, 54, 14, 111, 6, 75, 1, 1, 12, 72, 10, 67, - 19, 58, 71, 93, 105, 118, 100, 67, 75, 1, 1, - 84, 91, 4, 17, 68, 79, 93, 7, 68, 85, 88, 5, - 75, 92, 9, 69, 80, 88, 65, 73, 73, 79, 70, 5, - 22, 0, 0, 0, 81, 86, 97, 70, 20, 1, 52, 8, 69, - 123, 99, 82, 72, 103, 121, 121, 122, 91, 121, - 110, 121, 119, 112, 119, 112, 3, 67, 81, 101, - 69, 91, 88, 121, 73, 95, 89, 123, 8, 81, 74, - 120, 91, 84, 76, 70, 1, 67, 81, 3, 0, 1, 7, - 65, 64, 2, 77, 13, 10, 27, 19, 23, 18, 17, 19, - 41, 12, 12, 39, 27, 64, 105, 97, 98, 88, 91, - 86, 81, 84, 81, 84, 90, 70, 72, 73, 1, 100, - 97, 95, 74, 72, 72, 70, 15, 66, 1, 65, 23, 69, - 5, 6, 1, 74, 59, 52, 37, 43, 52, 42, 25, 43, - 33, 27, 31, 18, 5, 1, 1, 23, 16, 22, 19, 17, - 15, 20, 13, 24, 18, 7, 9, 14, 89, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 55, - 39, 62, 55, 37, 62, 61, 62, 59, 54, 51, 56, - 41, 34, 13, 21, 0, 70, 97, 70, 23, 14, 10, 2, - 5, 0, 71, 73, 89, 66, 37, 25, 20, 17, 2, 66, - 76, 75, 84, 89, 11, 5, 3, 64, 70, 74, 78, 86, - 106, 94, 80, 76, 71, 73, 83, 93, 94, 113, 76, - 31, 16, 11, 2, 68, 77, 83, 87, 94, 62, 91, 82, - 77, 66, 70, 1, 4, 5, 74, 2, 6, 64, 78, 71, 68, - 18, 3, 25, 21, 33, 32, 19, 24, 28, 21, 15, 0, - 14, 65, 101, 94, 93, 86, 83, 83, 83, 85, 66, - 76, 75, 74, 4, 75, 82, 97, 92, 95, 76, 73, 70, - 72, 68, 65, 70, 1, 1, 67, 72, 6, 64, 72, 55, - 43, 46, 47, 47, 50, 46, 45, 38, 38, 41, 35, - 17, 20, 13, 42, 39, 37, 31, 30, 25, 11, 5, 64, - 76, 81, 93, 70, 106, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 57, 54, 44, 24, 3, 61, 59, 29, - 62, 62, 60, 54, 58, 52, 46, 52, 45, 45, 29, - 31, 19, 69, 37, 27, 9, 116, 108, 110, 82, 89, - 86, 66, 78, 77, 68, 67, 12, 0, 18, 71, 62, 62, - 62, 62, 52, 49, 21, 3, 85, 74, 41, 29, 20, 9, - 9, 2, 64, 68, 90, 103, 94, 87, 87, 84, 71, 77, - 83, 71, 68, 67, 65, 1, 6, 4, 62, 62, 62, 59, - 55, 49, 37, 22, 69 }, - - { - - 62, - 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 25, 56, - 58, 54, 14, 108, 5, 74, 1, 1, 11, 72, 9, 68, - 18, 56, 73, 94, 106, 115, 99, 67, 74, 1, 1, - 84, 90, 4, 16, 68, 79, 93, 7, 68, 84, 88, 5, - 75, 91, 8, 70, 80, 88, 65, 72, 73, 78, 70, 5, - 22, 0, 0, 0, 80, 87, 97, 70, 19, 1, 52, 8, 69, - 122, 98, 82, 72, 101, 120, 119, 121, 90, 120, - 108, 119, 118, 112, 118, 112, 3, 67, 80, 100, - 69, 91, 87, 119, 73, 95, 89, 122, 8, 80, 74, - 119, 91, 84, 76, 69, 1, 67, 81, 3, 0, 0, 6, - 65, 64, 2, 77, 13, 10, 26, 19, 23, 18, 17, 18, - 39, 12, 12, 37, 26, 65, 104, 96, 97, 87, 91, - 85, 80, 83, 81, 83, 89, 70, 72, 72, 0, 100, - 96, 95, 74, 72, 72, 70, 14, 65, 1, 65, 21, 68, - 4, 5, 1, 75, 57, 51, 36, 42, 51, 41, 24, 42, - 33, 25, 30, 17, 5, 1, 1, 22, 16, 21, 19, 16, - 14, 19, 12, 22, 17, 6, 8, 13, 89, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 53, - 36, 62, 54, 35, 62, 59, 62, 57, 51, 49, 53, - 39, 32, 12, 20, 65, 71, 97, 70, 23, 15, 10, 2, - 5, 0, 71, 73, 88, 65, 38, 25, 20, 17, 3, 66, - 75, 75, 83, 89, 12, 6, 3, 64, 70, 74, 78, 85, - 105, 94, 79, 76, 71, 73, 82, 92, 94, 112, 76, - 32, 16, 11, 2, 67, 76, 83, 86, 93, 62, 91, 82, - 77, 66, 70, 1, 4, 5, 73, 2, 6, 0, 78, 71, 68, - 17, 3, 24, 20, 32, 31, 19, 22, 27, 20, 15, 64, - 13, 66, 101, 94, 92, 86, 83, 83, 82, 84, 67, - 76, 75, 74, 3, 75, 82, 97, 91, 95, 76, 72, 70, - 72, 68, 65, 69, 1, 0, 67, 71, 6, 65, 73, 54, - 43, 46, 46, 46, 49, 45, 44, 37, 37, 40, 34, - 16, 19, 12, 40, 37, 35, 29, 29, 24, 10, 4, 64, - 76, 81, 93, 71, 106, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 60, 55, 52, 42, 23, 2, 59, 57, 28, - 62, 62, 58, 52, 55, 50, 44, 50, 43, 43, 27, - 29, 17, 70, 35, 25, 7, 115, 107, 109, 82, 88, - 85, 64, 77, 76, 68, 66, 13, 1, 19, 71, 62, 62, - 62, 62, 49, 46, 18, 1, 86, 74, 41, 29, 20, 9, - 9, 2, 64, 68, 89, 102, 93, 86, 87, 83, 70, 76, - 82, 70, 67, 66, 64, 2, 7, 4, 62, 62, 62, 57, - 53, 47, 35, 20, 70 }, - - { - - 62, - 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 23, 54, - 57, 54, 14, 106, 5, 73, 2, 1, 11, 71, 8, 69, - 18, 54, 75, 95, 106, 112, 97, 67, 73, 2, 1, - 84, 89, 4, 16, 68, 79, 92, 7, 69, 84, 88, 5, - 75, 90, 8, 70, 80, 88, 64, 72, 72, 78, 69, 5, - 22, 0, 0, 0, 80, 87, 97, 69, 18, 1, 52, 8, 69, - 121, 97, 82, 71, 100, 118, 117, 119, 89, 118, - 107, 117, 117, 111, 117, 111, 4, 67, 79, 99, - 69, 90, 86, 117, 73, 95, 88, 120, 9, 80, 73, - 118, 90, 83, 76, 69, 2, 66, 80, 4, 1, 0, 6, - 65, 64, 2, 77, 13, 9, 25, 19, 22, 18, 17, 18, - 37, 12, 11, 36, 25, 66, 103, 95, 96, 86, 90, - 84, 79, 82, 80, 82, 88, 70, 72, 72, 64, 99, - 95, 95, 73, 72, 71, 70, 13, 64, 1, 65, 20, 67, - 4, 4, 1, 75, 56, 50, 36, 41, 50, 40, 23, 42, - 33, 24, 29, 17, 5, 1, 0, 22, 15, 20, 18, 15, - 13, 19, 11, 20, 16, 5, 7, 12, 89, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 51, - 34, 60, 52, 33, 62, 57, 60, 55, 49, 47, 50, - 37, 29, 11, 18, 66, 71, 97, 70, 23, 15, 10, 2, - 5, 0, 71, 73, 88, 65, 38, 25, 20, 17, 4, 65, - 74, 75, 82, 88, 13, 7, 3, 0, 69, 73, 77, 85, - 104, 93, 77, 75, 71, 72, 81, 91, 93, 111, 75, - 32, 17, 11, 2, 66, 75, 82, 85, 92, 62, 91, 82, - 76, 66, 70, 1, 4, 5, 73, 2, 7, 0, 78, 71, 68, - 16, 4, 23, 19, 31, 31, 19, 21, 26, 20, 15, 65, - 12, 66, 100, 93, 91, 85, 82, 82, 82, 83, 67, - 76, 75, 74, 2, 75, 82, 96, 90, 95, 76, 72, 70, - 71, 68, 65, 68, 1, 0, 67, 70, 5, 65, 73, 53, - 43, 45, 46, 45, 48, 44, 43, 37, 36, 39, 33, - 15, 18, 11, 39, 36, 34, 27, 28, 23, 9, 3, 65, - 76, 80, 93, 71, 105, 62, 62, 62, 62, 62, 62, - 62, 62, 60, 58, 53, 50, 40, 21, 1, 57, 55, 27, - 61, 62, 56, 50, 53, 48, 42, 48, 41, 40, 25, - 27, 15, 71, 33, 23, 6, 114, 105, 108, 81, 87, - 84, 1, 76, 75, 68, 65, 15, 3, 21, 70, 62, 62, - 62, 62, 47, 43, 16, 64, 87, 74, 41, 29, 20, 9, - 9, 2, 64, 68, 89, 101, 92, 85, 86, 82, 69, 76, - 81, 69, 66, 65, 64, 2, 7, 4, 62, 62, 62, 56, - 51, 45, 33, 18, 71 }, - - { - - 62, - 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 22, 53, - 56, 54, 14, 104, 5, 73, 3, 1, 10, 71, 7, 70, - 17, 53, 76, 96, 107, 109, 96, 67, 73, 3, 1, - 83, 88, 5, 15, 67, 78, 91, 6, 69, 84, 88, 5, - 74, 90, 8, 70, 79, 88, 64, 72, 72, 78, 69, 5, - 22, 0, 0, 0, 79, 87, 97, 69, 18, 0, 52, 8, 69, - 120, 97, 82, 71, 99, 116, 115, 118, 88, 116, - 106, 115, 116, 110, 116, 110, 5, 67, 78, 99, - 68, 90, 86, 115, 73, 94, 88, 119, 9, 80, 73, - 116, 90, 82, 75, 69, 2, 66, 79, 4, 1, 64, 6, - 65, 64, 2, 77, 13, 9, 25, 19, 21, 18, 17, 18, - 35, 12, 11, 34, 24, 67, 103, 94, 96, 86, 89, - 84, 78, 82, 80, 82, 86, 70, 72, 72, 65, 99, - 94, 95, 73, 72, 70, 69, 12, 64, 1, 65, 19, 66, - 3, 3, 1, 76, 54, 49, 35, 41, 49, 40, 23, 41, - 32, 23, 28, 17, 5, 1, 0, 21, 14, 19, 17, 15, - 12, 18, 11, 18, 15, 5, 6, 11, 89, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 54, 48, - 31, 58, 50, 32, 62, 54, 57, 52, 47, 44, 48, - 34, 27, 10, 16, 67, 72, 97, 69, 24, 15, 11, 2, - 5, 0, 71, 73, 87, 65, 38, 26, 20, 17, 5, 65, - 74, 74, 82, 87, 14, 7, 4, 0, 68, 73, 77, 84, - 103, 92, 76, 74, 70, 72, 81, 91, 92, 109, 75, - 32, 17, 11, 3, 66, 75, 81, 85, 91, 62, 90, 81, - 76, 66, 70, 1, 4, 5, 73, 3, 7, 1, 78, 71, 69, - 16, 4, 22, 18, 30, 30, 19, 20, 25, 20, 15, 65, - 11, 67, 99, 92, 90, 85, 82, 82, 81, 83, 67, - 75, 74, 73, 2, 75, 82, 96, 89, 95, 76, 72, 70, - 70, 68, 65, 67, 0, 0, 67, 70, 4, 65, 74, 52, - 42, 45, 45, 44, 48, 44, 42, 36, 36, 38, 32, - 14, 17, 10, 37, 35, 32, 25, 26, 21, 8, 3, 65, - 76, 80, 92, 72, 104, 62, 62, 62, 62, 62, 62, - 62, 62, 58, 55, 51, 47, 38, 20, 1, 56, 54, 25, - 59, 62, 54, 48, 51, 46, 40, 45, 39, 38, 23, - 25, 14, 73, 31, 21, 4, 113, 104, 107, 80, 86, - 83, 2, 75, 74, 68, 64, 16, 4, 22, 69, 62, 62, - 62, 59, 44, 41, 13, 66, 89, 73, 41, 29, 20, 9, - 9, 2, 64, 68, 88, 100, 92, 84, 85, 81, 69, 75, - 80, 69, 66, 65, 64, 3, 7, 4, 62, 62, 61, 54, - 50, 44, 30, 17, 72 }, - - { - - 62, - 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 20, 51, - 54, 54, 14, 101, 4, 72, 3, 1, 9, 71, 6, 71, - 17, 51, 78, 97, 107, 106, 95, 67, 72, 3, 1, - 83, 87, 5, 15, 67, 78, 91, 6, 70, 83, 88, 5, - 74, 89, 7, 70, 79, 88, 0, 71, 72, 77, 68, 5, - 22, 0, 0, 0, 79, 87, 97, 68, 17, 0, 52, 8, 69, - 119, 96, 82, 70, 97, 115, 113, 116, 87, 115, - 104, 113, 115, 109, 115, 110, 6, 67, 77, 98, - 68, 89, 85, 113, 73, 94, 87, 118, 9, 79, 72, - 115, 89, 82, 75, 68, 2, 66, 78, 5, 2, 64, 5, - 65, 64, 2, 77, 13, 8, 24, 19, 21, 18, 17, 17, - 33, 12, 10, 32, 23, 68, 102, 93, 95, 85, 88, - 83, 77, 81, 79, 81, 85, 70, 72, 71, 66, 98, - 93, 95, 73, 72, 70, 69, 11, 0, 1, 65, 17, 65, - 3, 2, 1, 77, 53, 48, 35, 40, 48, 39, 22, 40, - 32, 22, 27, 17, 5, 1, 64, 20, 14, 18, 17, 14, - 11, 17, 10, 16, 14, 4, 5, 10, 89, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 60, 61, 52, 46, - 29, 56, 49, 30, 62, 52, 55, 50, 44, 42, 45, - 32, 24, 9, 15, 69, 73, 97, 69, 24, 16, 11, 2, - 5, 0, 71, 73, 87, 64, 39, 26, 20, 17, 6, 64, - 73, 74, 81, 86, 15, 8, 4, 0, 67, 72, 76, 84, - 102, 92, 75, 74, 70, 72, 80, 90, 92, 108, 74, - 33, 17, 11, 3, 65, 74, 80, 84, 90, 62, 90, 81, - 75, 66, 70, 1, 4, 5, 72, 3, 7, 1, 78, 71, 69, - 15, 5, 21, 17, 29, 29, 19, 19, 24, 19, 15, 66, - 10, 67, 98, 92, 89, 84, 81, 81, 81, 82, 67, - 75, 74, 73, 1, 75, 82, 95, 88, 95, 76, 71, 70, - 70, 68, 65, 66, 0, 0, 67, 69, 4, 66, 75, 51, - 42, 44, 44, 43, 47, 43, 41, 35, 35, 37, 31, - 13, 16, 9, 36, 33, 31, 23, 25, 20, 7, 2, 66, - 76, 80, 92, 72, 103, 62, 62, 62, 62, 62, 62, - 62, 61, 56, 53, 49, 45, 36, 18, 0, 54, 52, 24, - 57, 62, 52, 46, 49, 44, 38, 43, 37, 35, 21, - 23, 12, 74, 29, 19, 3, 112, 103, 106, 80, 85, - 82, 4, 74, 73, 68, 0, 18, 6, 24, 69, 62, 62, - 61, 56, 41, 38, 10, 68, 90, 73, 41, 29, 20, 9, - 9, 2, 64, 68, 88, 99, 91, 83, 84, 80, 68, 75, - 79, 68, 65, 64, 0, 3, 8, 4, 62, 62, 59, 52, - 48, 42, 28, 15, 73 }, - - { - - 62, - 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 19, 50, - 53, 54, 14, 99, 4, 71, 4, 1, 8, 71, 5, 73, 16, - 49, 80, 98, 108, 104, 94, 67, 71, 4, 1, 83, - 86, 5, 14, 67, 78, 90, 5, 70, 83, 89, 5, 74, - 89, 7, 71, 79, 88, 0, 71, 72, 77, 68, 5, 22, - 0, 0, 0, 78, 88, 97, 68, 16, 0, 52, 8, 69, - 118, 95, 82, 70, 96, 113, 111, 115, 86, 113, - 103, 112, 114, 109, 114, 109, 6, 67, 76, 97, - 68, 89, 85, 112, 73, 94, 87, 117, 9, 79, 72, - 114, 89, 81, 75, 68, 2, 66, 78, 5, 2, 65, 5, - 65, 64, 2, 77, 13, 8, 23, 19, 20, 18, 17, 17, - 31, 12, 10, 30, 22, 69, 101, 92, 94, 84, 88, - 83, 76, 81, 79, 80, 84, 70, 72, 71, 68, 98, - 92, 95, 73, 73, 69, 69, 10, 1, 1, 65, 16, 64, - 2, 1, 1, 78, 51, 47, 34, 39, 47, 38, 21, 39, - 31, 20, 26, 16, 5, 1, 64, 19, 13, 17, 16, 13, - 10, 16, 9, 14, 12, 3, 4, 9, 89, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 61, 58, 58, 49, 43, - 26, 54, 47, 28, 61, 50, 52, 47, 42, 39, 42, - 30, 22, 8, 13, 70, 74, 98, 69, 24, 16, 11, 2, - 5, 0, 71, 73, 86, 64, 39, 26, 20, 17, 7, 64, - 73, 74, 81, 86, 16, 8, 4, 0, 67, 72, 76, 83, - 101, 91, 74, 73, 70, 72, 79, 89, 91, 107, 74, - 33, 17, 11, 3, 64, 74, 80, 83, 90, 62, 90, 81, - 75, 66, 70, 1, 4, 5, 72, 3, 7, 2, 78, 71, 69, - 14, 5, 20, 16, 28, 28, 19, 17, 22, 19, 15, 67, - 9, 68, 98, 91, 88, 84, 81, 81, 80, 81, 68, 75, - 74, 73, 0, 75, 82, 95, 88, 96, 76, 71, 70, 69, - 68, 65, 66, 0, 64, 67, 68, 3, 66, 76, 50, 41, - 44, 43, 41, 46, 42, 40, 34, 34, 36, 30, 12, - 15, 8, 34, 32, 29, 21, 23, 19, 6, 1, 66, 76, - 80, 92, 73, 103, 62, 62, 62, 62, 62, 62, 61, - 58, 54, 51, 47, 42, 34, 17, 64, 52, 50, 22, - 55, 61, 49, 43, 46, 41, 36, 41, 34, 33, 19, - 20, 10, 75, 27, 17, 1, 111, 102, 105, 79, 84, - 82, 5, 73, 73, 68, 0, 19, 7, 25, 68, 62, 62, - 58, 53, 38, 35, 7, 70, 91, 73, 41, 29, 20, 9, - 9, 2, 64, 68, 87, 99, 90, 82, 84, 79, 68, 74, - 79, 68, 65, 64, 0, 4, 8, 3, 62, 62, 57, 50, - 46, 40, 26, 13, 74 }, - - { - - 62, - 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 18, 49, - 52, 54, 14, 97, 4, 70, 5, 1, 8, 70, 4, 74, 15, - 47, 81, 99, 109, 101, 92, 67, 70, 5, 1, 82, - 85, 6, 13, 67, 77, 89, 5, 70, 83, 89, 5, 74, - 88, 7, 71, 79, 88, 0, 71, 71, 77, 68, 5, 22, - 0, 0, 0, 77, 88, 97, 68, 15, 0, 52, 8, 69, - 117, 94, 82, 70, 95, 111, 109, 113, 84, 111, - 102, 110, 113, 108, 113, 108, 7, 66, 75, 96, - 68, 88, 84, 110, 73, 93, 87, 115, 10, 79, 72, - 112, 89, 80, 75, 68, 3, 65, 77, 5, 2, 65, 5, - 64, 64, 2, 76, 13, 8, 23, 19, 19, 18, 17, 17, - 29, 12, 10, 29, 21, 69, 100, 91, 93, 83, 87, - 82, 75, 80, 79, 79, 83, 70, 72, 71, 69, 97, - 91, 95, 72, 73, 68, 69, 9, 2, 1, 65, 15, 0, 1, - 0, 1, 78, 50, 46, 34, 38, 46, 37, 21, 39, 31, - 19, 25, 16, 5, 1, 64, 19, 12, 16, 15, 12, 9, - 16, 9, 13, 11, 3, 3, 8, 89, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 59, 56, 56, 46, 41, 23, - 53, 45, 27, 59, 48, 50, 45, 40, 37, 40, 28, - 20, 8, 11, 71, 74, 98, 69, 25, 16, 11, 3, 5, - 0, 70, 73, 85, 64, 39, 26, 21, 17, 8, 0, 72, - 73, 80, 85, 17, 9, 5, 1, 66, 71, 76, 82, 100, - 90, 72, 72, 69, 71, 78, 88, 90, 106, 73, 33, - 18, 12, 3, 0, 73, 79, 82, 89, 62, 89, 80, 74, - 66, 70, 1, 5, 6, 72, 3, 8, 3, 78, 71, 69, 14, - 5, 19, 16, 27, 28, 19, 16, 21, 19, 15, 67, 8, - 69, 97, 90, 87, 84, 80, 81, 79, 80, 68, 75, - 74, 72, 0, 75, 82, 95, 87, 96, 76, 71, 70, 68, - 68, 65, 65, 0, 64, 67, 67, 2, 66, 76, 49, 41, - 44, 43, 40, 45, 41, 39, 34, 33, 35, 30, 12, - 14, 7, 33, 31, 27, 19, 22, 18, 6, 1, 66, 75, - 79, 92, 74, 102, 62, 62, 62, 62, 62, 62, 59, - 56, 52, 49, 45, 40, 32, 16, 65, 50, 49, 21, - 53, 59, 47, 41, 44, 39, 34, 39, 32, 31, 18, - 18, 8, 76, 25, 15, 64, 110, 100, 103, 78, 83, - 81, 7, 72, 72, 68, 1, 21, 8, 27, 67, 62, 62, - 56, 50, 36, 32, 5, 72, 92, 73, 41, 29, 20, 9, - 10, 2, 64, 68, 86, 98, 89, 81, 83, 77, 67, 73, - 78, 67, 64, 0, 0, 5, 8, 3, 62, 61, 56, 49, 44, - 38, 24, 11, 74 }, - - { - - 62, - 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 16, 47, - 50, 54, 14, 94, 3, 69, 5, 1, 7, 70, 3, 75, 15, - 45, 83, 100, 109, 98, 91, 67, 69, 5, 1, 82, - 84, 6, 13, 67, 77, 89, 5, 71, 82, 89, 5, 74, - 87, 6, 71, 79, 88, 1, 70, 71, 76, 67, 5, 22, - 0, 0, 0, 77, 88, 97, 67, 14, 0, 52, 8, 69, - 116, 93, 82, 69, 93, 110, 107, 112, 83, 110, - 100, 108, 112, 107, 112, 108, 8, 66, 74, 95, - 68, 88, 83, 108, 73, 93, 86, 114, 10, 78, 71, - 111, 88, 80, 75, 67, 3, 65, 76, 6, 3, 66, 4, - 64, 64, 2, 76, 13, 7, 22, 19, 19, 18, 17, 16, - 27, 12, 9, 27, 20, 70, 99, 90, 92, 82, 86, 81, - 74, 79, 78, 78, 82, 70, 72, 70, 70, 97, 90, - 95, 72, 73, 68, 69, 8, 3, 1, 65, 13, 1, 1, 64, - 1, 79, 48, 45, 33, 37, 45, 36, 20, 38, 31, 18, - 24, 16, 5, 1, 65, 18, 12, 15, 15, 11, 8, 15, - 8, 11, 10, 2, 2, 7, 89, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 57, 54, 53, 44, 39, 21, 51, - 44, 25, 56, 46, 48, 43, 37, 35, 37, 26, 17, 7, - 10, 73, 75, 98, 69, 25, 17, 11, 3, 5, 0, 70, - 73, 85, 0, 40, 26, 21, 17, 9, 0, 71, 73, 79, - 84, 18, 10, 5, 1, 65, 71, 75, 82, 99, 90, 71, - 72, 69, 71, 77, 87, 90, 105, 73, 34, 18, 12, - 3, 1, 72, 78, 81, 88, 62, 89, 80, 74, 66, 70, - 1, 5, 6, 71, 3, 8, 3, 78, 71, 69, 13, 6, 18, - 15, 26, 27, 19, 15, 20, 18, 15, 68, 7, 69, 96, - 90, 86, 83, 80, 80, 79, 79, 68, 75, 74, 72, - 64, 75, 82, 94, 86, 96, 76, 70, 70, 68, 68, - 65, 64, 0, 64, 67, 66, 2, 67, 77, 48, 41, 43, - 42, 39, 44, 40, 38, 33, 32, 34, 29, 11, 13, 6, - 31, 29, 26, 17, 21, 17, 5, 0, 67, 75, 79, 92, - 74, 101, 62, 62, 62, 62, 62, 60, 57, 53, 50, - 47, 43, 38, 30, 14, 66, 48, 47, 20, 51, 57, - 45, 39, 42, 37, 32, 37, 30, 28, 16, 16, 6, 77, - 23, 13, 65, 109, 99, 102, 78, 82, 80, 9, 71, - 71, 68, 2, 22, 10, 28, 67, 62, 60, 53, 47, 33, - 29, 2, 74, 93, 73, 41, 29, 20, 9, 10, 2, 64, - 68, 86, 97, 88, 80, 82, 76, 66, 73, 77, 66, 0, - 1, 1, 5, 9, 3, 60, 59, 54, 47, 42, 36, 22, 9, - 75 }, - - { - - 62, - 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 15, 46, - 49, 54, 14, 92, 3, 69, 6, 1, 6, 70, 2, 76, 14, - 44, 84, 101, 110, 95, 90, 67, 69, 6, 1, 81, - 83, 7, 12, 66, 76, 88, 4, 71, 82, 89, 5, 73, - 87, 6, 71, 78, 88, 1, 70, 71, 76, 67, 5, 22, - 0, 0, 0, 76, 88, 97, 67, 14, 64, 52, 8, 69, - 115, 93, 82, 69, 92, 108, 105, 110, 82, 108, - 99, 106, 111, 106, 111, 107, 9, 66, 73, 95, - 67, 87, 83, 106, 73, 92, 86, 113, 10, 78, 71, - 109, 88, 79, 74, 67, 3, 65, 75, 6, 3, 66, 4, - 64, 64, 2, 76, 13, 7, 22, 19, 18, 18, 17, 16, - 25, 12, 9, 25, 19, 71, 99, 89, 92, 82, 85, 81, - 73, 79, 78, 78, 80, 70, 72, 70, 71, 96, 89, - 95, 72, 73, 67, 68, 7, 3, 1, 65, 12, 2, 0, 65, - 1, 80, 47, 44, 33, 37, 44, 36, 20, 37, 30, 17, - 23, 16, 5, 1, 65, 17, 11, 14, 14, 11, 7, 14, - 8, 9, 9, 2, 1, 6, 89, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 54, 52, 51, 41, 36, 18, 49, 42, - 24, 54, 43, 45, 40, 35, 32, 35, 23, 15, 6, 8, - 74, 76, 98, 68, 26, 17, 12, 3, 5, 0, 70, 73, - 84, 0, 40, 27, 21, 17, 10, 1, 71, 72, 79, 83, - 19, 10, 6, 1, 64, 70, 75, 81, 98, 89, 70, 71, - 68, 71, 77, 87, 89, 103, 72, 34, 18, 12, 4, 1, - 72, 77, 81, 87, 62, 88, 79, 73, 66, 70, 1, 5, - 6, 71, 4, 8, 4, 78, 71, 70, 13, 6, 17, 14, 25, - 26, 19, 14, 19, 18, 15, 68, 6, 70, 95, 89, 85, - 83, 79, 80, 78, 79, 68, 74, 73, 71, 64, 75, - 82, 94, 85, 96, 76, 70, 70, 67, 68, 65, 0, 64, - 64, 67, 66, 1, 67, 78, 47, 40, 43, 41, 38, 44, - 40, 37, 32, 32, 33, 28, 10, 12, 5, 30, 28, 24, - 15, 19, 15, 4, 0, 67, 75, 79, 91, 75, 100, 62, - 62, 62, 62, 62, 58, 55, 51, 48, 44, 41, 35, - 28, 13, 66, 47, 46, 18, 49, 54, 43, 37, 40, - 35, 30, 34, 28, 26, 14, 14, 5, 79, 21, 11, 67, - 108, 98, 101, 77, 81, 79, 10, 70, 70, 68, 3, - 24, 11, 30, 66, 61, 59, 51, 44, 30, 27, 64, - 76, 95, 72, 41, 29, 20, 9, 10, 2, 64, 68, 85, - 96, 88, 79, 81, 75, 66, 72, 76, 66, 0, 1, 1, - 6, 9, 3, 59, 58, 52, 45, 41, 35, 19, 8, 76 }, - - { - - 62, - 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 13, 44, - 48, 54, 14, 90, 3, 68, 7, 1, 5, 70, 1, 77, 14, - 42, 86, 102, 110, 92, 89, 67, 68, 7, 1, 81, - 82, 7, 12, 66, 76, 87, 4, 72, 82, 89, 5, 73, - 86, 6, 72, 78, 88, 2, 70, 71, 76, 66, 5, 22, - 0, 0, 0, 76, 89, 97, 66, 13, 64, 52, 8, 69, - 114, 92, 82, 68, 91, 106, 103, 109, 81, 106, - 98, 104, 110, 106, 110, 106, 9, 66, 72, 94, - 67, 87, 82, 104, 73, 92, 85, 112, 10, 78, 70, - 108, 87, 78, 74, 67, 3, 65, 75, 7, 4, 67, 4, - 64, 64, 2, 76, 13, 6, 21, 19, 17, 18, 17, 16, - 23, 12, 8, 23, 18, 72, 98, 88, 91, 81, 85, 80, - 72, 78, 77, 77, 79, 70, 72, 70, 72, 96, 88, - 95, 72, 73, 66, 68, 6, 4, 1, 65, 11, 3, 0, 66, - 1, 81, 45, 43, 32, 36, 43, 35, 19, 36, 30, 15, - 22, 15, 5, 1, 66, 16, 10, 13, 13, 10, 6, 13, - 7, 7, 8, 1, 0, 5, 89, 62, 62, 61, 62, 62, 62, - 62, 62, 61, 52, 50, 48, 39, 34, 16, 47, 40, - 22, 52, 41, 43, 38, 33, 30, 32, 21, 12, 5, 6, - 75, 77, 98, 68, 26, 17, 12, 3, 5, 0, 70, 73, - 84, 0, 40, 27, 21, 17, 11, 1, 70, 72, 78, 83, - 20, 11, 6, 1, 64, 70, 74, 81, 97, 88, 69, 70, - 68, 71, 76, 86, 88, 102, 72, 34, 18, 12, 4, 2, - 71, 77, 80, 86, 62, 88, 79, 73, 66, 70, 1, 5, - 6, 71, 4, 8, 4, 78, 71, 70, 12, 7, 16, 13, 24, - 25, 19, 12, 18, 18, 15, 69, 5, 70, 95, 88, 84, - 82, 79, 79, 78, 78, 69, 74, 73, 71, 65, 75, - 82, 93, 84, 96, 76, 70, 70, 66, 68, 65, 1, 64, - 65, 67, 65, 0, 67, 79, 46, 40, 42, 40, 37, 43, - 39, 36, 31, 31, 32, 27, 9, 11, 4, 28, 27, 23, - 13, 18, 14, 3, 64, 68, 75, 79, 91, 75, 100, - 62, 62, 62, 62, 62, 56, 53, 48, 46, 42, 39, - 33, 26, 11, 67, 45, 44, 17, 47, 52, 41, 35, - 37, 33, 28, 32, 26, 23, 12, 12, 3, 80, 19, 9, - 68, 107, 97, 100, 76, 80, 78, 12, 69, 69, 68, - 4, 25, 13, 31, 65, 59, 57, 48, 41, 27, 24, 67, - 78, 96, 72, 41, 29, 20, 9, 10, 2, 64, 68, 85, - 95, 87, 78, 81, 74, 65, 72, 75, 65, 1, 2, 1, - 6, 9, 3, 58, 56, 50, 43, 39, 33, 17, 6, 77 }, - - { - - 62, - 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 12, 43, - 46, 54, 14, 87, 2, 67, 7, 1, 5, 69, 0, 78, 13, - 40, 88, 103, 111, 89, 87, 67, 67, 7, 1, 81, - 81, 7, 11, 66, 76, 87, 4, 72, 81, 89, 5, 73, - 85, 5, 72, 78, 88, 2, 69, 70, 75, 66, 5, 22, - 0, 0, 0, 75, 89, 97, 66, 12, 64, 52, 8, 69, - 113, 91, 82, 68, 89, 105, 101, 107, 80, 105, - 96, 102, 109, 105, 109, 106, 10, 66, 71, 93, - 67, 86, 81, 102, 73, 92, 85, 110, 11, 77, 70, - 107, 87, 78, 74, 66, 4, 64, 74, 7, 4, 67, 3, - 64, 64, 2, 76, 13, 6, 20, 19, 17, 18, 17, 15, - 21, 12, 8, 22, 17, 73, 97, 87, 90, 80, 84, 79, - 71, 77, 77, 76, 78, 70, 72, 69, 73, 95, 87, - 95, 71, 73, 66, 68, 5, 5, 1, 65, 9, 4, 64, 67, - 1, 81, 44, 42, 32, 35, 42, 34, 18, 36, 30, 14, - 21, 15, 5, 1, 66, 16, 10, 12, 13, 9, 5, 13, 6, - 5, 7, 0, 64, 4, 89, 61, 62, 59, 62, 61, 60, - 60, 60, 59, 50, 48, 46, 36, 32, 13, 45, 39, - 20, 49, 39, 41, 36, 30, 28, 29, 19, 10, 4, 5, - 77, 77, 98, 68, 26, 18, 12, 3, 5, 0, 70, 73, - 83, 1, 41, 27, 21, 17, 12, 2, 69, 72, 77, 82, - 21, 12, 6, 2, 0, 69, 74, 80, 96, 88, 67, 70, - 68, 70, 75, 85, 88, 101, 71, 35, 19, 12, 4, 3, - 70, 76, 79, 85, 62, 88, 79, 72, 66, 70, 1, 5, - 6, 70, 4, 9, 5, 78, 71, 70, 11, 7, 15, 12, 23, - 25, 19, 11, 17, 17, 15, 70, 4, 71, 94, 88, 83, - 82, 78, 79, 77, 77, 69, 74, 73, 71, 66, 75, - 82, 93, 83, 96, 76, 69, 70, 66, 68, 65, 2, 64, - 65, 67, 64, 0, 68, 79, 45, 40, 42, 40, 36, 42, - 38, 35, 31, 30, 31, 26, 8, 10, 3, 27, 25, 21, - 11, 17, 13, 2, 65, 68, 75, 78, 91, 76, 99, 62, - 62, 62, 62, 60, 54, 51, 46, 44, 40, 37, 31, - 24, 10, 68, 43, 42, 16, 45, 50, 39, 33, 35, - 31, 26, 30, 24, 21, 10, 10, 1, 81, 17, 7, 70, - 106, 95, 99, 76, 79, 77, 14, 68, 68, 68, 5, - 27, 14, 33, 65, 58, 55, 46, 38, 25, 21, 69, - 80, 97, 72, 41, 29, 20, 9, 10, 2, 64, 68, 84, - 94, 86, 77, 80, 73, 64, 71, 74, 64, 2, 3, 2, - 7, 10, 3, 56, 55, 49, 42, 37, 31, 15, 4, 78 }, - - { - - 61, - 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 10, 41, - 45, 54, 14, 85, 2, 66, 8, 1, 4, 69, 64, 79, - 13, 38, 89, 104, 111, 86, 86, 67, 66, 8, 1, - 80, 80, 8, 11, 66, 75, 86, 3, 73, 81, 89, 5, - 73, 85, 5, 72, 78, 88, 3, 69, 70, 75, 65, 5, - 22, 0, 0, 0, 75, 89, 97, 65, 11, 64, 52, 8, - 69, 112, 90, 82, 67, 88, 103, 99, 106, 79, - 103, 95, 100, 108, 104, 108, 105, 11, 66, 70, - 92, 67, 86, 81, 100, 73, 91, 84, 109, 11, 77, - 69, 105, 86, 77, 74, 66, 4, 64, 73, 8, 5, 68, - 3, 64, 64, 2, 76, 13, 5, 20, 19, 16, 18, 17, - 15, 19, 12, 7, 20, 16, 74, 96, 86, 89, 79, 83, - 79, 70, 77, 76, 75, 77, 70, 72, 69, 74, 95, - 86, 95, 71, 73, 65, 68, 4, 6, 1, 65, 8, 5, 64, - 68, 1, 82, 42, 41, 31, 34, 41, 33, 18, 35, 29, - 13, 20, 15, 5, 1, 67, 15, 9, 11, 12, 8, 4, 12, - 6, 3, 6, 0, 65, 3, 89, 60, 61, 58, 62, 59, 58, - 58, 58, 56, 47, 46, 43, 34, 29, 11, 43, 37, - 19, 47, 37, 38, 33, 28, 25, 27, 17, 7, 3, 3, - 78, 78, 98, 68, 27, 18, 12, 3, 5, 0, 70, 73, - 83, 1, 41, 27, 21, 17, 13, 2, 69, 71, 77, 81, - 22, 12, 7, 2, 1, 69, 73, 80, 95, 87, 66, 69, - 67, 70, 74, 84, 87, 100, 71, 35, 19, 12, 4, 4, - 70, 75, 78, 84, 62, 87, 78, 72, 66, 70, 1, 5, - 6, 70, 4, 9, 5, 78, 71, 70, 11, 8, 14, 11, 22, - 24, 19, 10, 16, 17, 15, 70, 3, 71, 93, 87, 82, - 81, 78, 78, 77, 76, 69, 74, 73, 70, 66, 75, - 82, 92, 82, 96, 76, 69, 70, 65, 68, 65, 3, 64, - 65, 67, 0, 64, 68, 80, 44, 39, 41, 39, 35, 41, - 37, 34, 30, 29, 30, 25, 7, 9, 2, 25, 24, 20, - 9, 15, 12, 1, 65, 69, 75, 78, 91, 76, 98, 62, - 62, 61, 61, 57, 52, 49, 43, 42, 38, 35, 28, - 22, 8, 69, 41, 41, 14, 43, 48, 37, 31, 33, 29, - 24, 28, 22, 18, 8, 8, 64, 82, 15, 5, 71, 105, - 94, 98, 75, 78, 76, 15, 67, 67, 68, 6, 28, 16, - 34, 64, 56, 54, 43, 35, 22, 18, 72, 82, 98, - 72, 41, 29, 20, 9, 10, 2, 64, 68, 84, 93, 85, - 76, 79, 72, 64, 71, 73, 64, 2, 3, 2, 7, 10, 3, - 55, 53, 47, 40, 35, 29, 13, 2, 79 }, - - { - - 60, - 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 9, 40, - 44, 54, 14, 83, 2, 65, 9, 1, 3, 69, 65, 80, - 12, 36, 91, 105, 112, 83, 85, 67, 65, 9, 1, - 80, 79, 8, 10, 66, 75, 85, 3, 73, 81, 89, 5, - 73, 84, 5, 72, 78, 88, 3, 69, 70, 75, 65, 5, - 22, 0, 0, 0, 74, 89, 97, 65, 10, 64, 52, 8, - 69, 111, 89, 82, 67, 87, 101, 97, 104, 78, - 101, 94, 98, 107, 103, 107, 104, 12, 66, 69, - 91, 67, 85, 80, 98, 73, 91, 84, 108, 11, 77, - 69, 104, 86, 76, 74, 66, 4, 64, 72, 8, 5, 68, - 3, 64, 64, 2, 76, 13, 5, 19, 19, 15, 18, 17, - 15, 17, 12, 7, 18, 15, 75, 95, 85, 88, 78, 82, - 78, 69, 76, 76, 74, 76, 70, 72, 69, 75, 94, - 85, 95, 71, 73, 64, 68, 3, 7, 1, 65, 7, 6, 65, - 69, 1, 83, 41, 40, 31, 33, 40, 32, 17, 34, 29, - 12, 19, 15, 5, 1, 67, 14, 8, 10, 11, 7, 3, 11, - 5, 1, 5, 64, 66, 2, 89, 58, 60, 56, 60, 57, - 56, 56, 56, 54, 45, 44, 41, 31, 27, 8, 41, 35, - 17, 45, 35, 36, 31, 26, 23, 24, 15, 5, 2, 1, - 79, 79, 98, 68, 27, 18, 12, 3, 5, 0, 70, 73, - 82, 1, 41, 27, 21, 17, 14, 3, 68, 71, 76, 80, - 23, 13, 7, 2, 2, 68, 73, 79, 94, 86, 65, 68, - 67, 70, 73, 83, 86, 99, 70, 35, 19, 12, 4, 5, - 69, 74, 77, 83, 62, 87, 78, 71, 66, 70, 1, 5, - 6, 70, 4, 9, 6, 78, 71, 70, 10, 8, 13, 10, 21, - 23, 19, 9, 15, 17, 15, 71, 2, 72, 92, 86, 81, - 81, 77, 78, 76, 75, 69, 74, 73, 70, 67, 75, - 82, 92, 81, 96, 76, 69, 70, 64, 68, 65, 4, 64, - 65, 67, 1, 65, 68, 81, 43, 39, 41, 38, 34, 40, - 36, 33, 29, 28, 29, 24, 6, 8, 1, 24, 23, 18, - 7, 14, 11, 0, 66, 69, 75, 78, 91, 77, 97, 62, - 62, 59, 59, 54, 50, 47, 41, 40, 36, 33, 26, - 20, 7, 70, 39, 39, 13, 41, 46, 35, 29, 31, 27, - 22, 26, 20, 16, 6, 6, 66, 83, 13, 3, 73, 104, - 93, 97, 74, 77, 75, 17, 66, 66, 68, 7, 30, 17, - 36, 0, 55, 52, 41, 32, 19, 15, 75, 84, 99, 72, - 41, 29, 20, 9, 10, 2, 64, 68, 83, 92, 84, 75, - 78, 71, 0, 70, 72, 0, 3, 4, 2, 8, 10, 3, 54, - 52, 45, 38, 33, 27, 11, 0, 80 }, - - { - - 58, - 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 7, 38, - 42, 53, 14, 81, 1, 65, 9, 0, 2, 69, 67, 82, - 11, 34, 93, 106, 113, 81, 84, 68, 65, 9, 0, - 80, 78, 8, 9, 66, 75, 85, 2, 74, 81, 90, 5, - 73, 84, 4, 73, 78, 88, 3, 69, 70, 75, 65, 4, - 22, 0, 0, 0, 74, 90, 97, 65, 9, 65, 52, 7, 69, - 110, 89, 82, 67, 86, 100, 96, 103, 77, 100, - 93, 97, 106, 103, 106, 104, 12, 66, 69, 91, - 67, 85, 80, 97, 73, 91, 84, 107, 11, 77, 69, - 103, 86, 76, 74, 66, 4, 64, 72, 8, 5, 69, 2, - 64, 65, 2, 76, 12, 4, 18, 19, 14, 17, 17, 14, - 15, 11, 6, 16, 14, 76, 95, 85, 88, 78, 82, 78, - 68, 76, 76, 74, 75, 71, 72, 69, 77, 94, 85, - 95, 71, 74, 64, 68, 2, 7, 1, 65, 5, 6, 66, 70, - 1, 84, 39, 39, 30, 32, 39, 31, 16, 33, 28, 10, - 18, 14, 4, 1, 68, 13, 7, 9, 10, 6, 2, 10, 4, - 64, 3, 65, 68, 0, 89, 56, 58, 54, 58, 55, 53, - 53, 53, 51, 42, 41, 38, 28, 24, 5, 39, 33, 15, - 42, 32, 33, 28, 23, 20, 21, 12, 2, 1, 64, 81, - 80, 99, 68, 27, 18, 12, 3, 5, 64, 70, 73, 82, - 1, 41, 27, 21, 17, 15, 3, 68, 71, 76, 80, 23, - 13, 7, 2, 2, 68, 73, 79, 93, 86, 64, 68, 67, - 70, 73, 83, 86, 98, 70, 35, 19, 12, 4, 5, 69, - 74, 77, 83, 62, 87, 78, 71, 66, 70, 1, 5, 6, - 70, 4, 9, 6, 78, 71, 71, 9, 8, 12, 9, 20, 22, - 18, 7, 13, 16, 14, 72, 0, 73, 92, 86, 80, 81, - 77, 78, 76, 75, 70, 74, 73, 70, 68, 75, 82, - 92, 81, 97, 76, 69, 70, 64, 69, 65, 4, 65, 66, - 67, 1, 66, 69, 82, 42, 38, 40, 37, 32, 39, 35, - 32, 28, 27, 28, 23, 5, 6, 64, 22, 21, 16, 5, - 12, 9, 64, 67, 70, 75, 78, 91, 78, 97, 62, 61, - 57, 56, 51, 47, 44, 38, 37, 33, 30, 23, 17, 5, - 71, 37, 37, 11, 39, 43, 32, 26, 28, 24, 20, - 23, 17, 13, 4, 3, 68, 85, 11, 1, 75, 103, 92, - 96, 74, 77, 75, 18, 66, 66, 68, 7, 31, 18, 37, - 0, 53, 50, 38, 28, 16, 12, 78, 87, 101, 72, - 41, 28, 19, 9, 10, 2, 65, 68, 83, 92, 84, 75, - 78, 70, 0, 70, 72, 0, 3, 4, 2, 8, 10, 2, 52, - 50, 43, 36, 31, 25, 8, 65, 81 }, - - { - - 57, - 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 6, 37, - 41, 53, 14, 78, 1, 64, 10, 0, 2, 68, 68, 83, - 11, 33, 94, 107, 113, 78, 82, 68, 64, 10, 0, - 79, 76, 9, 9, 65, 74, 84, 2, 74, 80, 90, 5, - 72, 83, 4, 73, 77, 88, 4, 68, 69, 74, 64, 4, - 22, 0, 0, 0, 73, 90, 97, 64, 9, 65, 52, 7, 69, - 108, 88, 82, 66, 84, 98, 94, 101, 75, 98, 91, - 95, 104, 102, 105, 103, 13, 65, 68, 90, 66, - 84, 79, 95, 72, 90, 83, 105, 12, 76, 68, 101, - 85, 75, 73, 65, 5, 0, 71, 9, 6, 69, 2, 0, 65, - 2, 75, 12, 4, 18, 19, 14, 17, 17, 14, 14, 11, - 6, 15, 13, 76, 94, 84, 87, 77, 81, 77, 67, 75, - 75, 73, 73, 71, 72, 68, 78, 93, 84, 95, 70, - 74, 0, 67, 2, 8, 1, 65, 4, 7, 66, 71, 1, 84, - 38, 39, 30, 32, 39, 31, 16, 33, 28, 9, 18, 14, - 4, 1, 68, 13, 7, 9, 10, 6, 1, 10, 4, 65, 2, - 65, 69, 64, 89, 55, 57, 53, 57, 54, 51, 51, - 51, 49, 40, 39, 36, 26, 22, 3, 38, 32, 14, 40, - 30, 31, 26, 21, 18, 19, 10, 0, 1, 65, 82, 80, - 99, 67, 28, 19, 13, 4, 5, 64, 69, 72, 81, 2, - 42, 28, 22, 17, 16, 4, 67, 70, 75, 79, 24, 14, - 8, 3, 3, 67, 72, 78, 91, 85, 1, 67, 66, 69, - 72, 82, 85, 96, 69, 36, 20, 13, 5, 6, 68, 73, - 76, 82, 62, 86, 77, 70, 66, 69, 1, 6, 7, 69, - 5, 10, 7, 77, 71, 71, 9, 9, 12, 9, 19, 22, 18, - 6, 12, 16, 14, 72, 64, 73, 91, 85, 79, 80, 76, - 77, 75, 74, 70, 73, 72, 69, 68, 74, 81, 91, - 80, 97, 76, 68, 70, 0, 69, 65, 5, 65, 66, 66, - 2, 66, 69, 82, 42, 38, 40, 37, 31, 39, 35, 32, - 28, 27, 28, 23, 5, 5, 65, 21, 20, 15, 4, 11, - 8, 64, 67, 70, 74, 77, 90, 78, 96, 60, 59, 55, - 54, 49, 45, 42, 36, 35, 31, 28, 21, 15, 4, 71, - 36, 36, 10, 38, 41, 30, 24, 26, 22, 18, 21, - 15, 11, 3, 1, 69, 86, 10, 0, 76, 101, 90, 94, - 73, 76, 74, 20, 65, 65, 68, 8, 33, 20, 39, 1, - 52, 49, 36, 25, 14, 10, 80, 89, 102, 71, 42, - 28, 19, 9, 11, 2, 65, 68, 82, 91, 83, 74, 77, - 68, 1, 69, 71, 1, 4, 5, 3, 9, 11, 2, 51, 49, - 42, 35, 30, 24, 6, 66, 81 }, - - { - - 56, - 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 5, 36, - 40, 53, 14, 76, 1, 0, 11, 0, 1, 68, 69, 84, - 10, 31, 96, 108, 114, 75, 81, 68, 0, 11, 0, - 79, 75, 9, 8, 65, 74, 83, 2, 74, 80, 90, 5, - 72, 82, 4, 73, 77, 88, 4, 68, 69, 74, 64, 4, - 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 52, 7, 69, - 107, 87, 82, 66, 83, 96, 92, 100, 74, 96, 90, - 93, 103, 101, 104, 102, 14, 65, 67, 89, 66, - 84, 78, 93, 72, 90, 83, 104, 12, 76, 68, 100, - 85, 74, 73, 65, 5, 0, 70, 9, 6, 70, 2, 0, 65, - 2, 75, 12, 4, 17, 19, 13, 17, 17, 14, 12, 11, - 6, 13, 12, 77, 93, 83, 86, 76, 80, 76, 66, 74, - 75, 72, 72, 71, 72, 68, 79, 93, 83, 95, 70, - 74, 1, 67, 1, 9, 1, 65, 3, 8, 67, 72, 1, 85, - 36, 38, 29, 31, 38, 30, 15, 32, 28, 8, 17, 14, - 4, 1, 68, 12, 6, 8, 9, 5, 0, 9, 3, 67, 1, 66, - 70, 65, 89, 53, 56, 51, 55, 52, 49, 49, 49, - 46, 38, 37, 33, 23, 20, 0, 36, 30, 12, 38, 28, - 29, 24, 19, 16, 16, 8, 65, 0, 67, 83, 81, 99, - 67, 28, 19, 13, 4, 5, 64, 69, 72, 80, 2, 42, - 28, 22, 17, 17, 4, 66, 70, 74, 78, 25, 15, 8, - 3, 4, 67, 72, 77, 90, 84, 2, 66, 66, 69, 71, - 81, 84, 95, 69, 36, 20, 13, 5, 7, 67, 72, 75, - 81, 62, 86, 77, 70, 66, 69, 1, 6, 7, 69, 5, - 10, 8, 77, 71, 71, 8, 9, 11, 8, 18, 21, 18, 5, - 11, 16, 14, 73, 65, 74, 90, 84, 78, 80, 76, - 77, 74, 73, 70, 73, 72, 69, 69, 74, 81, 91, - 79, 97, 76, 68, 70, 1, 69, 65, 6, 65, 66, 66, - 3, 67, 69, 83, 41, 38, 40, 36, 30, 38, 34, 31, - 27, 26, 27, 22, 4, 4, 66, 19, 19, 13, 2, 10, - 7, 65, 68, 70, 74, 77, 90, 79, 95, 58, 57, 53, - 52, 46, 43, 40, 33, 33, 29, 26, 19, 13, 3, 72, - 34, 34, 9, 36, 39, 28, 22, 24, 20, 16, 19, 13, - 9, 1, 64, 71, 87, 8, 65, 78, 100, 89, 93, 72, - 75, 73, 22, 64, 64, 68, 9, 34, 21, 40, 2, 51, - 47, 33, 22, 11, 7, 83, 91, 103, 71, 42, 28, - 19, 9, 11, 2, 65, 68, 81, 90, 82, 73, 76, 67, - 2, 68, 70, 2, 5, 6, 3, 10, 11, 2, 50, 47, 40, - 33, 28, 22, 4, 68, 82 }, - - { - - 55, - 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 3, 34, - 39, 53, 14, 74, 1, 1, 12, 0, 0, 68, 70, 85, - 10, 29, 97, 109, 114, 72, 80, 68, 1, 12, 0, - 78, 74, 10, 8, 65, 73, 82, 1, 75, 80, 90, 5, - 72, 82, 4, 73, 77, 88, 5, 68, 69, 74, 0, 4, - 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 52, 7, 69, - 106, 86, 82, 65, 82, 94, 90, 98, 73, 94, 89, - 91, 102, 100, 103, 101, 15, 65, 66, 88, 66, - 83, 78, 91, 72, 89, 82, 103, 12, 76, 67, 98, - 84, 73, 73, 65, 5, 0, 69, 10, 7, 70, 2, 0, 65, - 2, 75, 12, 3, 17, 19, 12, 17, 17, 14, 10, 11, - 5, 11, 11, 78, 92, 82, 85, 75, 79, 76, 65, 74, - 74, 71, 71, 71, 72, 68, 80, 92, 82, 95, 70, - 74, 2, 67, 0, 10, 1, 65, 2, 9, 67, 73, 1, 86, - 35, 37, 29, 30, 37, 29, 15, 31, 27, 7, 16, 14, - 4, 1, 69, 11, 5, 7, 8, 4, 64, 8, 3, 69, 0, 66, - 71, 66, 89, 52, 54, 50, 53, 50, 47, 47, 47, - 44, 35, 35, 31, 21, 17, 65, 34, 28, 11, 36, - 26, 26, 21, 17, 13, 14, 6, 68, 64, 69, 84, 82, - 99, 67, 29, 19, 13, 4, 5, 64, 69, 72, 80, 2, - 42, 28, 22, 17, 18, 5, 66, 69, 74, 77, 26, 15, - 9, 3, 5, 66, 71, 77, 89, 83, 3, 65, 65, 69, - 70, 80, 83, 94, 68, 36, 20, 13, 5, 8, 67, 71, - 74, 80, 62, 85, 76, 69, 66, 69, 1, 6, 7, 69, - 5, 10, 8, 77, 71, 71, 8, 10, 10, 7, 17, 20, - 18, 4, 10, 16, 14, 73, 66, 74, 89, 83, 77, 79, - 75, 76, 74, 72, 70, 73, 72, 68, 69, 74, 81, - 90, 78, 97, 76, 68, 70, 2, 69, 65, 7, 65, 66, - 66, 4, 68, 69, 84, 40, 37, 39, 35, 29, 37, 33, - 30, 26, 25, 26, 21, 3, 3, 67, 18, 18, 12, 0, - 8, 6, 66, 68, 71, 74, 77, 90, 79, 94, 56, 55, - 51, 50, 43, 41, 38, 31, 31, 27, 24, 16, 11, 1, - 73, 32, 33, 7, 34, 37, 26, 20, 22, 18, 14, 17, - 11, 6, 64, 66, 73, 88, 6, 67, 79, 99, 88, 92, - 71, 74, 72, 23, 0, 0, 68, 10, 36, 23, 42, 3, - 49, 46, 31, 19, 8, 4, 86, 93, 104, 71, 42, 28, - 19, 9, 11, 2, 65, 68, 81, 89, 81, 72, 75, 66, - 2, 68, 69, 2, 5, 6, 3, 10, 11, 2, 49, 46, 38, - 31, 26, 20, 2, 70, 83 }, - - { - - 53, - 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 2, 33, - 37, 53, 14, 71, 0, 2, 12, 0, 64, 68, 71, 86, - 9, 27, 99, 110, 115, 69, 79, 68, 2, 12, 0, 78, - 73, 10, 7, 65, 73, 82, 1, 75, 79, 90, 5, 72, - 81, 3, 74, 77, 88, 5, 67, 69, 73, 0, 4, 22, 0, - 0, 0, 71, 91, 97, 0, 6, 65, 52, 7, 69, 105, - 85, 82, 65, 80, 93, 88, 97, 72, 93, 87, 89, - 101, 100, 102, 101, 15, 65, 65, 87, 66, 83, - 77, 89, 72, 89, 82, 102, 12, 75, 67, 97, 84, - 73, 73, 64, 5, 0, 69, 10, 7, 71, 1, 0, 65, 2, - 75, 12, 3, 16, 19, 12, 17, 17, 13, 8, 11, 5, - 9, 10, 79, 91, 81, 84, 74, 79, 75, 64, 73, 74, - 70, 70, 71, 72, 67, 81, 92, 81, 95, 70, 74, 2, - 67, 64, 11, 1, 65, 0, 10, 68, 74, 1, 87, 33, - 36, 28, 29, 36, 28, 14, 30, 27, 5, 15, 13, 4, - 1, 69, 10, 5, 6, 8, 3, 65, 7, 2, 71, 64, 67, - 72, 67, 89, 50, 53, 48, 51, 48, 45, 44, 45, - 41, 33, 33, 28, 18, 15, 68, 32, 27, 9, 33, 24, - 24, 19, 14, 11, 11, 4, 70, 65, 70, 86, 83, 99, - 67, 29, 20, 13, 4, 5, 64, 69, 72, 79, 3, 43, - 28, 22, 17, 19, 5, 65, 69, 73, 77, 27, 16, 9, - 3, 5, 66, 71, 76, 88, 83, 4, 65, 65, 69, 69, - 79, 83, 93, 68, 37, 20, 13, 5, 9, 66, 71, 73, - 79, 62, 85, 76, 69, 66, 69, 1, 6, 7, 68, 5, - 10, 9, 77, 71, 71, 7, 10, 9, 6, 16, 19, 18, 2, - 9, 15, 14, 74, 67, 75, 89, 83, 76, 79, 75, 76, - 73, 71, 71, 73, 72, 68, 70, 74, 81, 90, 77, - 97, 76, 67, 70, 2, 69, 65, 8, 65, 67, 66, 5, - 68, 70, 85, 39, 37, 39, 34, 28, 36, 32, 29, - 25, 24, 25, 20, 2, 2, 68, 16, 16, 10, 65, 7, - 5, 67, 69, 71, 74, 77, 90, 80, 94, 53, 52, 49, - 47, 40, 39, 36, 28, 29, 25, 22, 14, 9, 0, 74, - 30, 31, 6, 32, 35, 24, 18, 19, 16, 12, 15, 9, - 4, 66, 68, 75, 89, 4, 69, 81, 98, 87, 91, 71, - 73, 71, 25, 1, 1, 68, 11, 37, 24, 43, 3, 48, - 44, 28, 16, 5, 1, 89, 95, 105, 71, 42, 28, 19, - 9, 11, 2, 65, 68, 80, 88, 80, 71, 75, 65, 3, - 67, 68, 3, 6, 7, 4, 11, 12, 2, 47, 44, 36, 29, - 24, 18, 0, 72, 84 }, - - { - - 52, - 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 0, 31, - 36, 53, 14, 69, 0, 3, 13, 0, 64, 67, 72, 87, - 9, 25, 101, 111, 115, 66, 77, 68, 3, 13, 0, - 78, 72, 10, 7, 65, 73, 81, 1, 76, 79, 90, 5, - 72, 80, 3, 74, 77, 88, 6, 67, 68, 73, 1, 4, - 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 52, 7, 69, - 104, 84, 82, 64, 79, 91, 86, 95, 71, 91, 86, - 87, 100, 99, 101, 100, 16, 65, 64, 86, 66, 82, - 76, 87, 72, 89, 81, 100, 13, 75, 66, 96, 83, - 72, 73, 64, 6, 1, 68, 11, 8, 71, 1, 0, 65, 2, - 75, 12, 2, 15, 19, 11, 17, 17, 13, 6, 11, 4, - 8, 9, 80, 90, 80, 83, 73, 78, 74, 0, 72, 73, - 69, 69, 71, 72, 67, 82, 91, 80, 95, 69, 74, 3, - 67, 65, 12, 1, 65, 64, 11, 68, 75, 1, 87, 32, - 35, 28, 28, 35, 27, 13, 30, 27, 4, 14, 13, 4, - 1, 70, 10, 4, 5, 7, 2, 66, 7, 1, 73, 65, 68, - 73, 68, 89, 48, 52, 46, 49, 47, 43, 42, 43, - 39, 31, 31, 26, 16, 13, 70, 30, 25, 7, 31, 22, - 22, 17, 12, 9, 8, 2, 73, 66, 72, 87, 83, 99, - 67, 29, 20, 13, 4, 5, 64, 69, 72, 79, 3, 43, - 28, 22, 17, 20, 6, 64, 69, 72, 76, 28, 17, 9, - 4, 6, 65, 70, 76, 87, 82, 6, 64, 65, 68, 68, - 78, 82, 92, 67, 37, 21, 13, 5, 10, 65, 70, 72, - 78, 62, 85, 76, 68, 66, 69, 1, 6, 7, 68, 5, - 11, 9, 77, 71, 71, 6, 11, 8, 5, 15, 19, 18, 1, - 8, 15, 14, 75, 68, 75, 88, 82, 75, 78, 74, 75, - 73, 70, 71, 73, 72, 68, 71, 74, 81, 89, 76, - 97, 76, 67, 70, 3, 69, 65, 9, 65, 67, 66, 6, - 69, 70, 85, 38, 37, 38, 34, 27, 35, 31, 28, - 25, 23, 24, 19, 1, 1, 69, 15, 15, 9, 67, 6, 4, - 68, 70, 72, 74, 76, 90, 80, 93, 51, 50, 47, - 45, 38, 37, 34, 26, 27, 23, 20, 12, 7, 65, 75, - 28, 29, 5, 30, 33, 22, 16, 17, 14, 10, 13, 7, - 1, 68, 70, 77, 90, 2, 71, 82, 97, 85, 90, 70, - 72, 70, 27, 2, 2, 68, 12, 39, 26, 45, 4, 46, - 42, 26, 13, 3, 65, 91, 97, 106, 71, 42, 28, - 19, 9, 11, 2, 65, 68, 80, 87, 79, 70, 74, 64, - 4, 67, 67, 4, 7, 8, 4, 11, 12, 2, 46, 43, 35, - 28, 22, 16, 65, 74, 85 }, - - { - - 51, - 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 64, 30, - 35, 53, 14, 67, 0, 3, 14, 0, 65, 67, 73, 88, - 8, 24, 102, 112, 116, 0, 76, 68, 3, 14, 0, 77, - 71, 11, 6, 64, 72, 80, 0, 76, 79, 90, 5, 71, - 80, 3, 74, 76, 88, 6, 67, 68, 73, 1, 4, 22, 0, - 0, 0, 70, 91, 97, 1, 5, 66, 52, 7, 69, 103, - 84, 82, 64, 78, 89, 84, 94, 70, 89, 85, 85, - 99, 98, 100, 99, 17, 65, 0, 86, 65, 82, 76, - 85, 72, 88, 81, 99, 13, 75, 66, 94, 83, 71, - 72, 64, 6, 1, 67, 11, 8, 72, 1, 0, 65, 2, 75, - 12, 2, 15, 19, 10, 17, 17, 13, 4, 11, 4, 6, 8, - 81, 90, 79, 83, 73, 77, 74, 1, 72, 73, 69, 67, - 71, 72, 67, 83, 91, 79, 95, 69, 74, 4, 66, 66, - 12, 1, 65, 65, 12, 69, 76, 1, 88, 30, 34, 27, - 28, 34, 27, 13, 29, 26, 3, 13, 13, 4, 1, 70, - 9, 3, 4, 6, 2, 67, 6, 1, 75, 66, 68, 74, 69, - 89, 47, 50, 45, 47, 45, 41, 40, 41, 36, 28, - 29, 23, 13, 10, 73, 28, 23, 6, 29, 19, 19, 14, - 10, 6, 6, 64, 75, 67, 74, 88, 84, 99, 66, 30, - 20, 14, 4, 5, 64, 69, 72, 78, 3, 43, 29, 22, - 17, 21, 6, 64, 68, 72, 75, 29, 17, 10, 4, 7, - 65, 70, 75, 86, 81, 7, 0, 64, 68, 68, 78, 81, - 90, 67, 37, 21, 13, 6, 10, 65, 69, 72, 77, 62, - 84, 75, 68, 66, 69, 1, 6, 7, 68, 6, 11, 10, - 77, 71, 72, 6, 11, 7, 4, 14, 18, 18, 0, 7, 15, - 14, 75, 69, 76, 87, 81, 74, 78, 74, 75, 72, - 70, 71, 72, 71, 67, 71, 74, 81, 89, 75, 97, - 76, 67, 70, 4, 69, 65, 10, 66, 67, 66, 6, 70, - 70, 86, 37, 36, 38, 33, 26, 35, 31, 27, 24, - 23, 23, 18, 0, 0, 70, 13, 14, 7, 69, 4, 2, 69, - 70, 72, 74, 76, 89, 81, 92, 49, 48, 45, 43, - 35, 35, 32, 23, 25, 20, 18, 9, 5, 66, 75, 27, - 28, 3, 28, 30, 20, 14, 15, 12, 8, 10, 5, 64, - 70, 72, 78, 92, 0, 73, 84, 96, 84, 89, 69, 71, - 69, 28, 3, 3, 68, 13, 40, 27, 46, 5, 45, 41, - 23, 10, 0, 67, 94, 99, 108, 70, 42, 28, 19, 9, - 11, 2, 65, 68, 79, 86, 79, 69, 73, 0, 4, 66, - 66, 4, 7, 8, 4, 12, 12, 2, 45, 41, 33, 26, 21, - 15, 68, 75, 86 }, - - { - - 50, - 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 66, 28, - 33, 53, 14, 64, 64, 4, 14, 0, 66, 67, 74, 89, - 8, 22, 104, 113, 116, 3, 75, 68, 4, 14, 0, 77, - 70, 11, 6, 64, 72, 80, 0, 77, 78, 90, 5, 71, - 79, 2, 74, 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, - 0, 0, 70, 91, 97, 2, 4, 66, 52, 7, 69, 102, - 83, 82, 0, 76, 88, 82, 92, 69, 88, 83, 83, 98, - 97, 99, 99, 18, 65, 1, 85, 65, 81, 75, 83, 72, - 88, 80, 98, 13, 74, 65, 93, 82, 71, 72, 0, 6, - 1, 66, 12, 9, 72, 0, 0, 65, 2, 75, 12, 1, 14, - 19, 10, 17, 17, 12, 2, 11, 3, 4, 7, 82, 89, - 78, 82, 72, 76, 73, 2, 71, 72, 68, 66, 71, 72, - 66, 84, 90, 78, 95, 69, 74, 4, 66, 67, 13, 1, - 65, 67, 13, 69, 77, 1, 89, 29, 33, 27, 27, 33, - 26, 12, 28, 26, 2, 12, 13, 4, 1, 71, 8, 3, 3, - 6, 1, 68, 5, 0, 77, 67, 69, 75, 70, 89, 45, - 49, 43, 45, 43, 39, 37, 39, 34, 26, 27, 21, - 11, 8, 75, 26, 22, 4, 26, 17, 17, 12, 7, 4, 3, - 66, 78, 68, 75, 90, 85, 99, 66, 30, 21, 14, 4, - 5, 64, 69, 72, 78, 4, 44, 29, 22, 17, 22, 7, - 0, 68, 71, 74, 30, 18, 10, 4, 8, 64, 69, 75, - 85, 81, 8, 0, 64, 68, 67, 77, 81, 89, 66, 38, - 21, 13, 6, 11, 64, 68, 71, 76, 62, 84, 75, 67, - 66, 69, 1, 6, 7, 67, 6, 11, 10, 77, 71, 72, 5, - 12, 6, 3, 13, 17, 18, 64, 6, 14, 14, 76, 70, - 76, 86, 81, 73, 77, 73, 74, 72, 69, 71, 72, - 71, 67, 72, 74, 81, 88, 74, 97, 76, 66, 70, 4, - 69, 65, 11, 66, 67, 66, 7, 70, 71, 87, 36, 36, - 37, 32, 25, 34, 30, 26, 23, 22, 22, 17, 64, - 64, 71, 12, 12, 6, 71, 3, 1, 70, 71, 73, 74, - 76, 89, 81, 91, 47, 46, 43, 40, 32, 33, 30, - 21, 23, 18, 16, 7, 3, 68, 76, 25, 26, 2, 26, - 28, 18, 12, 13, 10, 6, 8, 3, 67, 72, 74, 80, - 93, 65, 75, 85, 95, 83, 88, 69, 70, 68, 30, 4, - 4, 68, 14, 42, 29, 48, 5, 43, 39, 21, 7, 66, - 70, 97, 101, 109, 70, 42, 28, 19, 9, 11, 2, - 65, 68, 79, 85, 78, 68, 72, 1, 5, 66, 65, 5, - 8, 9, 5, 12, 13, 2, 43, 40, 31, 24, 19, 13, - 70, 77, 87 }, - - { - - 48, - 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 67, 27, - 32, 53, 14, 1, 64, 5, 15, 0, 67, 67, 75, 91, - 7, 20, 106, 114, 117, 5, 74, 68, 5, 15, 0, 77, - 69, 11, 5, 64, 72, 79, 64, 77, 78, 91, 5, 71, - 79, 2, 75, 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, - 0, 0, 69, 92, 97, 2, 3, 66, 52, 7, 69, 101, - 82, 82, 0, 75, 86, 80, 91, 68, 86, 82, 82, 97, - 97, 98, 98, 18, 65, 2, 84, 65, 81, 75, 82, 72, - 88, 80, 97, 13, 74, 65, 92, 82, 70, 72, 0, 6, - 1, 66, 12, 9, 73, 0, 0, 65, 2, 75, 12, 1, 13, - 19, 9, 17, 17, 12, 0, 11, 3, 2, 6, 83, 88, 77, - 81, 71, 76, 73, 3, 71, 72, 67, 65, 71, 72, 66, - 86, 90, 77, 95, 69, 75, 5, 66, 68, 14, 1, 65, - 68, 14, 70, 78, 1, 90, 27, 32, 26, 26, 32, 25, - 11, 27, 25, 0, 11, 12, 4, 1, 71, 7, 2, 2, 5, - 0, 69, 4, 64, 79, 69, 70, 76, 71, 89, 43, 47, - 41, 43, 41, 37, 35, 37, 31, 23, 25, 18, 8, 5, - 78, 24, 20, 2, 24, 15, 14, 9, 5, 1, 0, 68, 80, - 69, 77, 91, 86, 100, 66, 30, 21, 14, 4, 5, 64, - 69, 72, 77, 4, 44, 29, 22, 17, 23, 7, 0, 68, - 71, 74, 31, 18, 10, 4, 8, 64, 69, 74, 84, 80, - 9, 1, 64, 68, 66, 76, 80, 88, 66, 38, 21, 13, - 6, 12, 64, 68, 70, 76, 62, 84, 75, 67, 66, 69, - 1, 6, 7, 67, 6, 11, 11, 77, 71, 72, 4, 12, 5, - 2, 12, 16, 18, 66, 4, 14, 14, 77, 71, 77, 86, - 80, 72, 77, 73, 74, 71, 68, 72, 72, 71, 67, - 73, 74, 81, 88, 74, 98, 76, 66, 70, 5, 69, 65, - 11, 66, 68, 66, 8, 71, 71, 88, 35, 35, 37, 31, - 23, 33, 29, 25, 22, 21, 21, 16, 65, 65, 72, - 10, 11, 4, 73, 1, 0, 71, 72, 73, 74, 76, 89, - 82, 91, 44, 43, 41, 38, 29, 30, 27, 18, 21, - 16, 14, 4, 1, 69, 77, 23, 24, 0, 24, 26, 15, - 9, 10, 7, 4, 6, 0, 69, 74, 77, 82, 94, 67, 77, - 87, 94, 82, 87, 68, 69, 68, 31, 5, 4, 68, 14, - 43, 30, 49, 6, 42, 37, 18, 4, 69, 73, 100, - 103, 110, 70, 42, 28, 19, 9, 11, 2, 65, 68, - 78, 85, 77, 67, 72, 2, 5, 65, 65, 5, 8, 9, 5, - 13, 13, 1, 42, 38, 29, 22, 17, 11, 72, 79, 88 }, - - { - - 47, - 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 68, 26, - 31, 53, 14, 3, 64, 6, 16, 0, 67, 66, 76, 92, - 6, 18, 107, 115, 118, 8, 72, 68, 6, 16, 0, 76, - 68, 12, 4, 64, 71, 78, 64, 77, 78, 91, 5, 71, - 78, 2, 75, 76, 88, 7, 66, 67, 72, 2, 4, 22, 0, - 0, 0, 68, 92, 97, 2, 2, 66, 52, 7, 69, 100, - 81, 82, 0, 74, 84, 78, 89, 66, 84, 81, 80, 96, - 96, 97, 97, 19, 64, 3, 83, 65, 80, 74, 80, 72, - 87, 80, 95, 14, 74, 65, 90, 82, 69, 72, 0, 7, - 2, 65, 12, 9, 73, 0, 1, 65, 2, 74, 12, 1, 13, - 19, 8, 17, 17, 12, 65, 11, 3, 1, 5, 83, 87, - 76, 80, 70, 75, 72, 4, 70, 72, 66, 64, 71, 72, - 66, 87, 89, 76, 95, 68, 75, 6, 66, 69, 15, 1, - 65, 69, 15, 71, 79, 1, 90, 26, 31, 26, 25, 31, - 24, 11, 27, 25, 64, 10, 12, 4, 1, 71, 7, 1, 1, - 4, 64, 70, 4, 64, 80, 70, 70, 77, 72, 89, 42, - 46, 40, 42, 40, 35, 33, 35, 29, 21, 23, 16, 5, - 3, 81, 23, 18, 1, 22, 13, 12, 7, 3, 64, 65, - 70, 82, 69, 79, 92, 86, 100, 66, 31, 21, 14, - 5, 5, 64, 68, 72, 76, 4, 44, 29, 23, 17, 24, - 8, 1, 67, 70, 73, 32, 19, 11, 5, 9, 0, 69, 73, - 83, 79, 11, 2, 0, 67, 65, 75, 79, 87, 65, 38, - 22, 14, 6, 13, 0, 67, 69, 75, 62, 83, 74, 66, - 66, 69, 1, 7, 8, 67, 6, 12, 12, 77, 71, 72, 4, - 12, 4, 2, 11, 16, 18, 67, 3, 14, 14, 77, 72, - 78, 85, 79, 71, 77, 72, 74, 70, 67, 72, 72, - 71, 66, 73, 74, 81, 88, 73, 98, 76, 66, 70, 6, - 69, 65, 12, 66, 68, 66, 9, 72, 71, 88, 34, 35, - 37, 31, 22, 32, 28, 24, 22, 20, 20, 16, 65, - 66, 73, 9, 10, 2, 75, 0, 64, 71, 72, 73, 73, - 75, 89, 83, 90, 42, 41, 39, 36, 27, 28, 25, - 16, 19, 14, 12, 2, 64, 70, 78, 21, 23, 64, 22, - 24, 13, 7, 8, 5, 2, 4, 65, 71, 75, 79, 84, 95, - 69, 79, 89, 93, 80, 85, 67, 68, 67, 33, 6, 5, - 68, 15, 45, 31, 51, 7, 41, 36, 16, 1, 71, 76, - 102, 105, 111, 70, 42, 28, 19, 9, 12, 2, 65, - 68, 77, 84, 76, 66, 71, 4, 6, 64, 64, 6, 9, - 10, 5, 14, 13, 1, 41, 37, 28, 21, 15, 9, 74, - 81, 88 }, - - { - - 46, - 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 70, 24, - 29, 53, 14, 6, 65, 7, 16, 0, 68, 66, 77, 93, - 6, 16, 109, 116, 118, 11, 71, 68, 7, 16, 0, - 76, 67, 12, 4, 64, 71, 78, 64, 78, 77, 91, 5, - 71, 77, 1, 75, 76, 88, 8, 65, 67, 71, 3, 4, - 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 52, 7, 69, - 99, 80, 82, 1, 72, 83, 76, 88, 65, 83, 79, 78, - 95, 95, 96, 97, 20, 64, 4, 82, 65, 80, 73, 78, - 72, 87, 79, 94, 14, 73, 64, 89, 81, 69, 72, 1, - 7, 2, 64, 13, 10, 74, 64, 1, 65, 2, 74, 12, 0, - 12, 19, 8, 17, 17, 11, 67, 11, 2, 64, 4, 84, - 86, 75, 79, 69, 74, 71, 5, 69, 71, 65, 0, 71, - 72, 65, 88, 89, 75, 95, 68, 75, 6, 66, 70, 16, - 1, 65, 71, 16, 71, 80, 1, 91, 24, 30, 25, 24, - 30, 23, 10, 26, 25, 65, 9, 12, 4, 1, 72, 6, 1, - 0, 4, 65, 71, 3, 65, 82, 71, 71, 78, 73, 89, - 40, 45, 38, 40, 38, 33, 30, 33, 26, 19, 21, - 13, 3, 1, 83, 21, 17, 64, 19, 11, 10, 5, 0, - 66, 68, 72, 85, 70, 80, 94, 87, 100, 66, 31, - 22, 14, 5, 5, 64, 68, 72, 76, 5, 45, 29, 23, - 17, 25, 8, 2, 67, 69, 72, 33, 20, 11, 5, 10, - 0, 68, 73, 82, 79, 12, 2, 0, 67, 64, 74, 79, - 86, 65, 39, 22, 14, 6, 14, 1, 66, 68, 74, 62, - 83, 74, 66, 66, 69, 1, 7, 8, 66, 6, 12, 12, - 77, 71, 72, 3, 13, 3, 1, 10, 15, 18, 68, 2, - 13, 14, 78, 73, 78, 84, 79, 70, 76, 72, 73, - 70, 66, 72, 72, 71, 66, 74, 74, 81, 87, 72, - 98, 76, 65, 70, 6, 69, 65, 13, 66, 68, 66, 10, - 72, 72, 89, 33, 35, 36, 30, 21, 31, 27, 23, - 21, 19, 19, 15, 66, 67, 74, 7, 8, 1, 77, 64, - 65, 72, 73, 74, 73, 75, 89, 83, 89, 40, 39, - 37, 33, 24, 26, 23, 13, 17, 12, 10, 0, 66, 72, - 79, 19, 21, 65, 20, 22, 11, 5, 6, 3, 0, 2, 67, - 74, 77, 81, 86, 96, 71, 81, 90, 92, 79, 84, - 67, 67, 66, 35, 7, 6, 68, 16, 46, 33, 52, 7, - 39, 34, 13, 65, 74, 79, 105, 107, 112, 70, 42, - 28, 19, 9, 12, 2, 65, 68, 77, 83, 75, 65, 70, - 5, 7, 64, 0, 7, 10, 11, 6, 14, 14, 1, 39, 35, - 26, 19, 13, 7, 76, 83, 89 }, - - { - - 45, - 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 71, 23, - 28, 53, 14, 8, 65, 7, 17, 0, 69, 66, 78, 94, - 5, 15, 110, 117, 119, 14, 70, 68, 7, 17, 0, - 75, 66, 13, 3, 0, 70, 77, 65, 78, 77, 91, 5, - 70, 77, 1, 75, 75, 88, 8, 65, 67, 71, 3, 4, - 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 52, 7, 69, - 98, 80, 82, 1, 71, 81, 74, 86, 64, 81, 78, 76, - 94, 94, 95, 96, 21, 64, 5, 82, 64, 79, 73, 76, - 72, 86, 79, 93, 14, 73, 64, 87, 81, 68, 71, 1, - 7, 2, 0, 13, 10, 74, 64, 1, 65, 2, 74, 12, 0, - 12, 19, 7, 17, 17, 11, 69, 11, 2, 66, 3, 85, - 86, 74, 79, 69, 73, 71, 6, 69, 71, 65, 2, 71, - 72, 65, 89, 88, 74, 95, 68, 75, 7, 65, 71, 16, - 1, 65, 72, 17, 72, 81, 1, 92, 23, 29, 25, 24, - 29, 23, 10, 25, 24, 66, 8, 12, 4, 1, 72, 5, 0, - 64, 3, 65, 72, 2, 65, 84, 72, 71, 79, 74, 89, - 39, 43, 37, 38, 36, 31, 28, 31, 24, 16, 19, - 11, 0, 65, 86, 19, 15, 65, 17, 8, 7, 2, 65, - 69, 70, 75, 87, 71, 82, 95, 88, 100, 65, 32, - 22, 15, 5, 5, 64, 68, 72, 75, 5, 45, 30, 23, - 17, 26, 9, 2, 66, 69, 71, 34, 20, 12, 5, 11, - 1, 68, 72, 81, 78, 13, 3, 1, 67, 64, 74, 78, - 84, 64, 39, 22, 14, 7, 14, 1, 65, 68, 73, 62, - 82, 73, 65, 66, 69, 1, 7, 8, 66, 7, 12, 13, - 77, 71, 73, 3, 13, 2, 0, 9, 14, 18, 69, 1, 13, - 14, 78, 74, 79, 83, 78, 69, 76, 71, 73, 69, - 66, 72, 71, 70, 65, 74, 74, 81, 87, 71, 98, - 76, 65, 70, 7, 69, 65, 14, 67, 68, 66, 10, 73, - 72, 90, 32, 34, 36, 29, 20, 31, 27, 22, 20, - 19, 18, 14, 67, 68, 75, 6, 7, 64, 79, 66, 67, - 73, 73, 74, 73, 75, 88, 84, 88, 38, 37, 35, - 31, 21, 24, 21, 11, 15, 9, 8, 66, 68, 73, 79, - 18, 20, 67, 18, 19, 9, 3, 4, 1, 65, 64, 69, - 76, 79, 83, 87, 98, 73, 83, 92, 91, 78, 83, - 66, 66, 65, 36, 8, 7, 68, 17, 48, 34, 54, 8, - 38, 33, 11, 68, 77, 81, 108, 109, 114, 69, 42, - 28, 19, 9, 12, 2, 65, 68, 76, 82, 75, 64, 69, - 6, 7, 0, 1, 7, 10, 11, 6, 15, 14, 1, 38, 34, - 24, 17, 12, 6, 79, 84, 90 }, - - { - - 43, - 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 73, 21, - 27, 53, 14, 10, 65, 8, 18, 0, 70, 66, 79, 95, - 5, 13, 112, 118, 119, 17, 69, 68, 8, 18, 0, - 75, 65, 13, 3, 0, 70, 76, 65, 79, 77, 91, 5, - 70, 76, 1, 76, 75, 88, 9, 65, 67, 71, 4, 4, - 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 52, 7, 69, - 97, 79, 82, 2, 70, 79, 72, 85, 0, 79, 77, 74, - 93, 94, 94, 95, 21, 64, 6, 81, 64, 79, 72, 74, - 72, 86, 78, 92, 14, 73, 0, 86, 80, 67, 71, 1, - 7, 2, 0, 14, 11, 75, 64, 1, 65, 2, 74, 12, 64, - 11, 19, 6, 17, 17, 11, 71, 11, 1, 68, 2, 86, - 85, 73, 78, 68, 73, 70, 7, 68, 70, 64, 3, 71, - 72, 65, 90, 88, 73, 95, 68, 75, 8, 65, 72, 17, - 1, 65, 73, 18, 72, 82, 1, 93, 21, 28, 24, 23, - 28, 22, 9, 24, 24, 68, 7, 11, 4, 1, 73, 4, 64, - 65, 2, 66, 73, 1, 66, 86, 73, 72, 80, 75, 89, - 37, 42, 35, 36, 34, 29, 26, 29, 21, 14, 17, 8, - 65, 67, 88, 17, 13, 67, 15, 6, 5, 0, 67, 71, - 73, 77, 90, 72, 84, 96, 89, 100, 65, 32, 22, - 15, 5, 5, 64, 68, 72, 75, 5, 45, 30, 23, 17, - 27, 9, 3, 66, 68, 71, 35, 21, 12, 5, 11, 1, - 67, 72, 80, 77, 14, 4, 1, 67, 0, 73, 77, 83, - 64, 39, 22, 14, 7, 15, 2, 65, 67, 72, 62, 82, - 73, 65, 66, 69, 1, 7, 8, 66, 7, 12, 13, 77, - 71, 73, 2, 14, 1, 64, 8, 13, 18, 71, 0, 13, - 14, 79, 75, 79, 83, 77, 68, 75, 71, 72, 69, - 65, 73, 71, 70, 65, 75, 74, 81, 86, 70, 98, - 76, 65, 70, 8, 69, 65, 15, 67, 69, 66, 11, 74, - 72, 91, 31, 34, 35, 28, 19, 30, 26, 21, 19, - 18, 17, 13, 68, 69, 76, 4, 6, 65, 81, 67, 68, - 74, 74, 75, 73, 75, 88, 84, 88, 35, 34, 33, - 29, 18, 22, 19, 8, 13, 7, 6, 68, 70, 75, 80, - 16, 18, 68, 16, 17, 7, 1, 1, 64, 67, 66, 71, - 79, 81, 85, 89, 99, 75, 85, 93, 90, 77, 82, - 65, 65, 64, 38, 9, 8, 68, 18, 49, 36, 55, 9, - 36, 31, 8, 71, 80, 84, 111, 111, 115, 69, 42, - 28, 19, 9, 12, 2, 65, 68, 76, 81, 74, 0, 69, - 7, 8, 0, 2, 8, 11, 12, 6, 15, 14, 1, 37, 32, - 22, 15, 10, 4, 81, 86, 91 }, - - { - - 42, - 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 74, 20, - 25, 53, 14, 13, 66, 9, 18, 0, 70, 65, 80, 96, - 4, 11, 114, 119, 120, 20, 67, 68, 9, 18, 0, - 75, 64, 13, 2, 0, 70, 76, 65, 79, 76, 91, 5, - 70, 75, 0, 76, 75, 88, 9, 64, 66, 70, 4, 4, - 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 52, 7, 69, - 96, 78, 82, 2, 68, 78, 70, 83, 1, 78, 75, 72, - 92, 93, 93, 95, 22, 64, 7, 80, 64, 78, 71, 72, - 72, 86, 78, 90, 15, 72, 0, 85, 80, 67, 71, 2, - 8, 3, 1, 14, 11, 75, 65, 1, 65, 2, 74, 12, 64, - 10, 19, 6, 17, 17, 10, 73, 11, 1, 69, 1, 87, - 84, 72, 77, 67, 72, 69, 8, 67, 70, 0, 4, 71, - 72, 64, 91, 87, 72, 95, 67, 75, 8, 65, 73, 18, - 1, 65, 75, 19, 73, 83, 1, 93, 20, 27, 24, 22, - 27, 21, 8, 24, 24, 69, 6, 11, 4, 1, 73, 4, 64, - 66, 2, 67, 74, 1, 67, 88, 74, 73, 81, 76, 89, - 35, 41, 33, 34, 33, 27, 23, 27, 19, 12, 15, 6, - 68, 69, 91, 15, 12, 69, 12, 4, 3, 65, 70, 73, - 76, 79, 92, 73, 85, 98, 89, 100, 65, 32, 23, - 15, 5, 5, 64, 68, 72, 74, 6, 46, 30, 23, 17, - 28, 10, 4, 66, 67, 70, 36, 22, 12, 6, 12, 2, - 67, 71, 79, 77, 16, 4, 1, 66, 1, 72, 77, 82, - 0, 40, 23, 14, 7, 16, 3, 64, 66, 71, 62, 82, - 73, 64, 66, 69, 1, 7, 8, 65, 7, 13, 14, 77, - 71, 73, 1, 14, 0, 65, 7, 13, 18, 72, 64, 12, - 14, 80, 76, 80, 82, 77, 67, 75, 70, 72, 68, - 64, 73, 71, 70, 65, 76, 74, 81, 86, 69, 98, - 76, 64, 70, 8, 69, 65, 16, 67, 69, 66, 12, 74, - 73, 91, 30, 34, 35, 28, 18, 29, 25, 20, 19, - 17, 16, 12, 69, 70, 77, 3, 4, 67, 83, 68, 69, - 75, 75, 75, 73, 74, 88, 85, 87, 33, 32, 31, - 26, 16, 20, 17, 6, 11, 5, 4, 70, 72, 76, 81, - 14, 16, 69, 14, 15, 5, 64, 64, 66, 69, 68, 73, - 81, 83, 87, 91, 100, 77, 87, 95, 89, 75, 81, - 65, 64, 0, 40, 10, 9, 68, 19, 51, 37, 57, 9, - 35, 29, 6, 74, 82, 87, 113, 113, 116, 69, 42, - 28, 19, 9, 12, 2, 65, 68, 75, 80, 73, 1, 68, - 8, 9, 1, 3, 9, 12, 13, 7, 16, 15, 1, 35, 31, - 21, 14, 8, 2, 83, 88, 92 }, - - { - - 41, - 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 76, 18, - 24, 53, 14, 15, 66, 10, 19, 0, 71, 65, 81, 97, - 4, 9, 115, 120, 120, 23, 66, 68, 10, 19, 0, - 74, 0, 14, 2, 0, 69, 75, 66, 80, 76, 91, 5, - 70, 75, 0, 76, 75, 88, 10, 64, 66, 70, 5, 4, - 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 52, 7, 69, - 95, 77, 82, 3, 67, 76, 68, 82, 2, 76, 74, 70, - 91, 92, 92, 94, 23, 64, 8, 79, 64, 78, 71, 70, - 72, 85, 77, 89, 15, 72, 1, 83, 79, 66, 71, 2, - 8, 3, 2, 15, 12, 76, 65, 1, 65, 2, 74, 12, 65, - 10, 19, 5, 17, 17, 10, 75, 11, 0, 71, 0, 88, - 83, 71, 76, 66, 71, 69, 9, 67, 69, 1, 5, 71, - 72, 64, 92, 87, 71, 95, 67, 75, 9, 65, 74, 19, - 1, 65, 76, 20, 73, 84, 1, 94, 18, 26, 23, 21, - 26, 20, 8, 23, 23, 70, 5, 11, 4, 1, 74, 3, 65, - 67, 1, 68, 75, 0, 67, 90, 75, 73, 82, 77, 89, - 34, 39, 32, 32, 31, 25, 21, 25, 16, 9, 13, 3, - 70, 72, 93, 13, 10, 70, 10, 2, 0, 68, 72, 76, - 78, 81, 95, 74, 87, 99, 90, 100, 65, 33, 23, - 15, 5, 5, 64, 68, 72, 74, 6, 46, 30, 23, 17, - 29, 10, 4, 65, 67, 69, 37, 22, 13, 6, 13, 2, - 66, 71, 78, 76, 17, 5, 2, 66, 2, 71, 76, 81, - 0, 40, 23, 14, 7, 17, 3, 0, 65, 70, 62, 81, - 72, 64, 66, 69, 1, 7, 8, 65, 7, 13, 14, 77, - 71, 73, 1, 15, 64, 66, 6, 12, 18, 73, 65, 12, - 14, 80, 77, 80, 81, 76, 66, 74, 70, 71, 68, 0, - 73, 71, 70, 64, 76, 74, 81, 85, 68, 98, 76, - 64, 70, 9, 69, 65, 17, 67, 69, 66, 13, 75, 73, - 92, 29, 33, 34, 27, 17, 28, 24, 19, 18, 16, - 15, 11, 70, 71, 78, 1, 3, 68, 85, 70, 70, 76, - 75, 76, 73, 74, 88, 85, 86, 31, 30, 29, 24, - 13, 18, 15, 3, 9, 3, 2, 73, 74, 78, 82, 12, - 15, 71, 12, 13, 3, 66, 66, 68, 71, 70, 75, 84, - 85, 89, 93, 101, 79, 89, 96, 88, 74, 80, 64, - 0, 1, 41, 11, 10, 68, 20, 52, 39, 58, 10, 33, - 28, 3, 77, 85, 90, 116, 115, 117, 69, 42, 28, - 19, 9, 12, 2, 65, 68, 75, 79, 72, 2, 67, 9, 9, - 1, 4, 9, 12, 13, 7, 16, 15, 1, 34, 29, 19, 12, - 6, 0, 85, 90, 93 }, - - { - - 40, - 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 77, 17, - 23, 53, 14, 17, 66, 11, 20, 0, 72, 65, 82, 98, - 3, 7, 117, 121, 121, 26, 65, 68, 11, 20, 0, - 74, 1, 14, 1, 0, 69, 74, 66, 80, 76, 91, 5, - 70, 74, 0, 76, 75, 88, 10, 64, 66, 70, 5, 4, - 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 52, 7, 69, - 94, 76, 82, 3, 66, 74, 66, 80, 3, 74, 73, 68, - 90, 91, 91, 93, 24, 64, 9, 78, 64, 77, 70, 68, - 72, 85, 77, 88, 15, 72, 1, 82, 79, 65, 71, 2, - 8, 3, 3, 15, 12, 76, 65, 1, 65, 2, 74, 12, 65, - 9, 19, 4, 17, 17, 10, 77, 11, 0, 73, 64, 89, - 82, 70, 75, 65, 70, 68, 10, 66, 69, 2, 6, 71, - 72, 64, 93, 86, 70, 95, 67, 75, 10, 65, 75, - 20, 1, 65, 77, 21, 74, 85, 1, 95, 17, 25, 23, - 20, 25, 19, 7, 22, 23, 71, 4, 11, 4, 1, 74, 2, - 66, 68, 0, 69, 76, 64, 68, 92, 76, 74, 83, 78, - 89, 32, 38, 30, 30, 29, 23, 19, 23, 14, 7, 11, - 1, 73, 74, 96, 11, 8, 72, 8, 0, 65, 70, 74, - 78, 81, 83, 97, 75, 89, 100, 91, 100, 65, 33, - 23, 15, 5, 5, 64, 68, 72, 73, 6, 46, 30, 23, - 17, 30, 11, 5, 65, 66, 68, 38, 23, 13, 6, 14, - 3, 66, 70, 77, 75, 18, 6, 2, 66, 3, 70, 75, - 80, 1, 40, 23, 14, 7, 18, 4, 1, 64, 69, 62, - 81, 72, 0, 66, 69, 1, 7, 8, 65, 7, 13, 15, 77, - 71, 73, 0, 15, 65, 67, 5, 11, 18, 74, 66, 12, - 14, 81, 78, 81, 80, 75, 65, 74, 69, 71, 67, 1, - 73, 71, 70, 64, 77, 74, 81, 85, 67, 98, 76, - 64, 70, 10, 69, 65, 18, 67, 69, 66, 14, 76, - 73, 93, 28, 33, 34, 26, 16, 27, 23, 18, 17, - 15, 14, 10, 71, 72, 79, 0, 2, 70, 87, 71, 71, - 77, 76, 76, 73, 74, 88, 86, 85, 29, 28, 27, - 22, 10, 16, 13, 1, 7, 1, 0, 75, 76, 79, 83, - 10, 13, 72, 10, 11, 1, 68, 68, 70, 73, 72, 77, - 86, 87, 91, 95, 102, 81, 91, 98, 87, 73, 79, - 0, 1, 2, 43, 12, 11, 68, 21, 54, 40, 60, 11, - 32, 26, 1, 80, 88, 93, 119, 117, 118, 69, 42, - 28, 19, 9, 12, 2, 65, 68, 74, 78, 71, 3, 66, - 10, 10, 2, 5, 10, 13, 14, 7, 17, 15, 1, 33, - 28, 17, 10, 4, 65, 87, 92, 94 }, - - { - - 38, - 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 79, 15, - 21, 52, 14, 19, 67, 11, 20, 64, 73, 65, 84, - 100, 2, 5, 119, 122, 122, 28, 64, 69, 11, 20, - 64, 74, 2, 14, 0, 0, 69, 74, 67, 81, 76, 92, - 5, 70, 74, 64, 77, 75, 88, 10, 64, 66, 70, 5, - 3, 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 52, 6, - 69, 93, 76, 82, 3, 65, 73, 65, 79, 4, 73, 72, - 67, 89, 91, 90, 93, 24, 64, 9, 78, 64, 77, 70, - 67, 72, 85, 77, 87, 15, 72, 1, 81, 79, 65, 71, - 2, 8, 3, 3, 15, 12, 77, 66, 1, 66, 2, 74, 11, - 66, 8, 19, 3, 16, 17, 9, 79, 10, 64, 75, 65, - 90, 82, 70, 75, 65, 70, 68, 11, 66, 69, 2, 7, - 72, 72, 64, 95, 86, 70, 95, 67, 76, 10, 65, - 76, 20, 1, 65, 79, 21, 75, 86, 1, 96, 15, 24, - 22, 19, 24, 18, 6, 21, 22, 73, 3, 10, 3, 1, - 75, 1, 67, 69, 64, 70, 77, 65, 69, 94, 78, 75, - 85, 80, 89, 30, 36, 28, 28, 27, 20, 16, 20, - 11, 4, 8, 65, 76, 77, 99, 9, 6, 74, 5, 66, 68, - 73, 77, 81, 84, 86, 100, 76, 91, 102, 92, 101, - 65, 33, 23, 15, 5, 5, 65, 68, 72, 73, 6, 46, - 30, 23, 17, 31, 11, 5, 65, 66, 68, 38, 23, 13, - 6, 14, 3, 66, 70, 76, 75, 19, 6, 2, 66, 3, 70, - 75, 79, 1, 40, 23, 14, 7, 18, 4, 1, 64, 69, - 62, 81, 72, 0, 66, 69, 1, 7, 8, 65, 7, 13, 15, - 77, 71, 74, 64, 15, 66, 68, 4, 10, 17, 76, 68, - 11, 13, 82, 80, 82, 80, 75, 64, 74, 69, 71, - 67, 1, 74, 71, 70, 64, 78, 74, 81, 85, 67, 99, - 76, 64, 70, 10, 70, 65, 18, 68, 70, 66, 14, - 77, 74, 94, 27, 32, 33, 25, 14, 26, 22, 17, - 16, 14, 13, 9, 72, 74, 81, 65, 0, 72, 89, 73, - 73, 78, 77, 77, 73, 74, 88, 87, 85, 26, 25, - 25, 19, 7, 13, 10, 65, 4, 65, 66, 78, 79, 81, - 84, 8, 11, 74, 8, 8, 65, 71, 71, 73, 75, 75, - 80, 89, 89, 94, 97, 104, 83, 93, 100, 86, 72, - 78, 0, 1, 2, 44, 12, 11, 68, 21, 55, 41, 61, - 11, 30, 24, 65, 84, 91, 96, 122, 120, 120, 69, - 42, 27, 18, 9, 12, 2, 66, 68, 74, 78, 71, 3, - 66, 11, 10, 2, 5, 10, 13, 14, 7, 17, 15, 0, - 31, 26, 15, 8, 2, 67, 90, 94, 95 }, - - { - - 37, - 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 80, 14, - 20, 52, 14, 22, 67, 12, 21, 64, 73, 64, 85, - 101, 2, 4, 120, 123, 122, 31, 1, 69, 12, 21, - 64, 73, 4, 15, 0, 1, 68, 73, 67, 81, 75, 92, - 5, 69, 73, 64, 77, 74, 88, 11, 0, 65, 69, 6, - 3, 22, 0, 0, 0, 64, 94, 97, 6, 67, 68, 52, 6, - 69, 91, 75, 82, 4, 0, 71, 0, 77, 6, 71, 70, - 65, 87, 90, 89, 92, 25, 0, 10, 77, 0, 76, 69, - 65, 71, 84, 76, 85, 16, 71, 2, 79, 78, 64, 70, - 3, 9, 4, 4, 16, 13, 77, 66, 2, 66, 2, 73, 11, - 66, 8, 19, 3, 16, 17, 9, 80, 10, 64, 76, 66, - 90, 81, 69, 74, 64, 69, 67, 12, 65, 68, 3, 9, - 72, 72, 0, 96, 85, 69, 95, 66, 76, 11, 64, 76, - 21, 1, 65, 80, 22, 75, 87, 1, 96, 14, 24, 22, - 19, 24, 18, 6, 21, 22, 74, 3, 10, 3, 1, 75, 1, - 67, 69, 64, 70, 78, 65, 69, 95, 79, 75, 86, - 81, 89, 29, 35, 27, 27, 26, 18, 14, 18, 9, 2, - 6, 67, 78, 79, 101, 8, 5, 75, 3, 68, 70, 75, - 79, 83, 86, 88, 102, 76, 92, 103, 92, 101, 64, - 34, 24, 16, 6, 5, 65, 67, 71, 72, 7, 47, 31, - 24, 17, 32, 12, 6, 64, 65, 67, 39, 24, 14, 7, - 15, 4, 65, 69, 74, 74, 21, 7, 3, 65, 4, 69, - 74, 77, 2, 41, 24, 15, 8, 19, 5, 2, 0, 68, 62, - 80, 71, 1, 66, 68, 1, 8, 9, 64, 8, 14, 16, 76, - 71, 74, 64, 16, 66, 68, 3, 10, 17, 77, 69, 11, - 13, 82, 81, 82, 79, 74, 0, 73, 68, 70, 66, 2, - 74, 70, 69, 0, 78, 73, 80, 84, 66, 99, 76, 0, - 70, 11, 70, 65, 19, 68, 70, 65, 15, 77, 74, - 94, 27, 32, 33, 25, 13, 26, 22, 17, 16, 14, - 13, 9, 72, 75, 82, 66, 64, 73, 90, 74, 74, 78, - 77, 77, 72, 73, 87, 87, 84, 24, 23, 23, 17, 5, - 11, 8, 67, 2, 67, 68, 80, 81, 82, 84, 7, 10, - 75, 7, 6, 67, 73, 73, 75, 77, 77, 82, 91, 90, - 96, 98, 105, 84, 94, 101, 84, 70, 76, 1, 2, 3, - 46, 13, 12, 68, 22, 57, 43, 62, 12, 29, 23, - 67, 87, 93, 98, 124, 122, 121, 68, 43, 27, 18, - 9, 13, 2, 66, 68, 73, 77, 70, 4, 65, 13, 11, - 3, 6, 11, 14, 15, 8, 18, 16, 0, 30, 25, 14, 7, - 1, 68, 92, 95, 95 }, - - { - - 36, - 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 81, 13, - 19, 52, 14, 24, 67, 13, 22, 64, 74, 64, 86, - 102, 1, 2, 122, 124, 123, 34, 2, 69, 13, 22, - 64, 73, 5, 15, 64, 1, 68, 72, 67, 81, 75, 92, - 5, 69, 72, 64, 77, 74, 88, 11, 0, 65, 69, 6, - 3, 22, 0, 0, 0, 0, 94, 97, 6, 68, 68, 52, 6, - 69, 90, 74, 82, 4, 1, 69, 2, 76, 7, 69, 69, 0, - 86, 89, 88, 91, 26, 0, 11, 76, 0, 76, 68, 0, - 71, 84, 76, 84, 16, 71, 2, 78, 78, 0, 70, 3, - 9, 4, 5, 16, 13, 78, 66, 2, 66, 2, 73, 11, 66, - 7, 19, 2, 16, 17, 9, 82, 10, 64, 78, 67, 91, - 80, 68, 73, 0, 68, 66, 13, 64, 68, 4, 10, 72, - 72, 0, 97, 85, 68, 95, 66, 76, 12, 64, 77, 22, - 1, 65, 81, 23, 76, 88, 1, 97, 12, 23, 21, 18, - 23, 17, 5, 20, 22, 75, 2, 10, 3, 1, 75, 0, 68, - 70, 65, 71, 79, 66, 70, 97, 80, 76, 87, 82, - 89, 27, 34, 25, 25, 24, 16, 12, 16, 6, 0, 4, - 70, 81, 81, 104, 6, 3, 77, 1, 70, 72, 77, 81, - 85, 89, 90, 104, 77, 94, 104, 93, 101, 64, 34, - 24, 16, 6, 5, 65, 67, 71, 71, 7, 47, 31, 24, - 17, 33, 12, 7, 64, 64, 66, 40, 25, 14, 7, 16, - 4, 65, 68, 73, 73, 22, 8, 3, 65, 5, 68, 73, - 76, 2, 41, 24, 15, 8, 20, 6, 3, 1, 67, 62, 80, - 71, 1, 66, 68, 1, 8, 9, 64, 8, 14, 17, 76, 71, - 74, 65, 16, 67, 69, 2, 9, 17, 78, 70, 11, 13, - 83, 82, 83, 78, 73, 1, 73, 68, 70, 65, 3, 74, - 70, 69, 0, 79, 73, 80, 84, 65, 99, 76, 0, 70, - 12, 70, 65, 20, 68, 70, 65, 16, 78, 74, 95, - 26, 32, 33, 24, 12, 25, 21, 16, 15, 13, 12, 8, - 73, 76, 83, 68, 65, 75, 92, 75, 75, 79, 78, - 77, 72, 73, 87, 88, 83, 22, 21, 21, 15, 2, 9, - 6, 70, 0, 69, 70, 82, 83, 83, 85, 5, 8, 76, 5, - 4, 69, 75, 75, 77, 79, 79, 84, 93, 92, 98, - 100, 106, 86, 96, 103, 83, 69, 75, 2, 3, 4, - 48, 14, 13, 68, 23, 58, 44, 62, 13, 28, 21, - 70, 90, 96, 101, 126, 124, 122, 68, 43, 27, - 18, 9, 13, 2, 66, 68, 72, 76, 69, 5, 64, 14, - 12, 4, 7, 12, 15, 16, 8, 19, 16, 0, 29, 23, - 12, 5, 64, 70, 94, 97, 96 }, - - { - - 35, - 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 83, 11, - 18, 52, 14, 26, 67, 14, 23, 64, 75, 64, 87, - 103, 1, 0, 123, 125, 123, 37, 3, 69, 14, 23, - 64, 72, 6, 16, 64, 1, 67, 71, 68, 82, 75, 92, - 5, 69, 72, 64, 77, 74, 88, 12, 0, 65, 69, 7, - 3, 22, 0, 0, 0, 0, 94, 97, 7, 69, 68, 52, 6, - 69, 89, 73, 82, 5, 2, 67, 4, 74, 8, 67, 68, 2, - 85, 88, 87, 90, 27, 0, 12, 75, 0, 75, 68, 2, - 71, 83, 75, 83, 16, 71, 3, 76, 77, 1, 70, 3, - 9, 4, 6, 17, 14, 78, 66, 2, 66, 2, 73, 11, 67, - 7, 19, 1, 16, 17, 9, 84, 10, 65, 80, 68, 92, - 79, 67, 72, 1, 67, 66, 14, 64, 67, 5, 11, 72, - 72, 0, 98, 84, 67, 95, 66, 76, 13, 64, 78, 23, - 1, 65, 82, 24, 76, 89, 1, 98, 11, 22, 21, 17, - 22, 16, 5, 19, 21, 76, 1, 10, 3, 1, 76, 64, - 69, 71, 66, 72, 80, 67, 70, 99, 81, 76, 88, - 83, 89, 26, 32, 24, 23, 22, 14, 10, 14, 4, 66, - 2, 72, 83, 84, 106, 4, 1, 78, 64, 72, 75, 80, - 83, 88, 91, 92, 107, 78, 96, 105, 94, 101, 64, - 35, 24, 16, 6, 5, 65, 67, 71, 71, 7, 47, 31, - 24, 17, 34, 13, 7, 0, 64, 65, 41, 25, 15, 7, - 17, 5, 64, 68, 72, 72, 23, 9, 4, 65, 6, 67, - 72, 75, 3, 41, 24, 15, 8, 21, 6, 4, 2, 66, 62, - 79, 70, 2, 66, 68, 1, 8, 9, 64, 8, 14, 17, 76, - 71, 74, 65, 17, 68, 70, 1, 8, 17, 79, 71, 11, - 13, 83, 83, 83, 77, 72, 2, 72, 67, 69, 65, 4, - 74, 70, 69, 1, 79, 73, 80, 83, 64, 99, 76, 0, - 70, 13, 70, 65, 21, 68, 70, 65, 17, 79, 74, - 96, 25, 31, 32, 23, 11, 24, 20, 15, 14, 12, - 11, 7, 74, 77, 84, 69, 66, 76, 94, 77, 76, 80, - 78, 78, 72, 73, 87, 88, 82, 20, 19, 19, 13, - 64, 7, 4, 72, 65, 71, 72, 85, 85, 85, 86, 3, - 7, 78, 3, 2, 71, 77, 77, 79, 81, 81, 86, 96, - 94, 100, 102, 107, 88, 98, 104, 82, 68, 74, 3, - 4, 5, 49, 15, 14, 68, 24, 60, 46, 62, 14, 26, - 20, 72, 93, 99, 104, 126, 126, 123, 68, 43, - 27, 18, 9, 13, 2, 66, 68, 72, 75, 68, 6, 0, - 15, 12, 4, 8, 12, 15, 16, 8, 19, 16, 0, 28, - 22, 10, 3, 66, 72, 96, 99, 97 }, - - { - - 33, - 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 84, 10, - 16, 52, 14, 29, 68, 15, 23, 64, 76, 64, 88, - 104, 0, 65, 125, 126, 124, 40, 4, 69, 15, 23, - 64, 72, 7, 16, 65, 1, 67, 71, 68, 82, 74, 92, - 5, 69, 71, 65, 78, 74, 88, 12, 1, 65, 68, 7, - 3, 22, 0, 0, 0, 1, 95, 97, 7, 70, 68, 52, 6, - 69, 88, 72, 82, 5, 4, 66, 6, 73, 9, 66, 66, 4, - 84, 88, 86, 90, 27, 0, 13, 74, 0, 75, 67, 4, - 71, 83, 75, 82, 16, 70, 3, 75, 77, 1, 70, 4, - 9, 4, 6, 17, 14, 79, 67, 2, 66, 2, 73, 11, 67, - 6, 19, 1, 16, 17, 8, 86, 10, 65, 82, 69, 93, - 78, 66, 71, 2, 67, 65, 15, 0, 67, 6, 12, 72, - 72, 1, 99, 84, 66, 95, 66, 76, 13, 64, 79, 24, - 1, 65, 84, 25, 77, 90, 1, 99, 9, 21, 20, 16, - 21, 15, 4, 18, 21, 78, 0, 9, 3, 1, 76, 65, 69, - 72, 66, 73, 81, 68, 71, 101, 82, 77, 89, 84, - 89, 24, 31, 22, 21, 20, 12, 7, 12, 1, 68, 0, - 75, 86, 86, 109, 2, 0, 80, 67, 74, 77, 82, 86, - 90, 94, 94, 109, 79, 97, 107, 95, 101, 64, 35, - 25, 16, 6, 5, 65, 67, 71, 70, 8, 48, 31, 24, - 17, 35, 13, 8, 0, 0, 65, 42, 26, 15, 7, 17, 5, - 64, 67, 71, 72, 24, 9, 4, 65, 7, 66, 72, 74, - 3, 42, 24, 15, 8, 22, 7, 4, 3, 65, 62, 79, 70, - 2, 66, 68, 1, 8, 9, 0, 8, 14, 18, 76, 71, 74, - 66, 17, 69, 71, 0, 7, 17, 81, 72, 10, 13, 84, - 84, 84, 77, 72, 3, 72, 67, 69, 64, 5, 75, 70, - 69, 1, 80, 73, 80, 83, 0, 99, 76, 1, 70, 13, - 70, 65, 22, 68, 71, 65, 18, 79, 75, 97, 24, - 31, 32, 22, 10, 23, 19, 14, 13, 11, 10, 6, 75, - 78, 85, 71, 68, 78, 96, 78, 77, 81, 79, 78, - 72, 73, 87, 89, 82, 17, 16, 17, 10, 67, 5, 2, - 75, 67, 73, 74, 87, 87, 86, 87, 1, 5, 79, 1, - 0, 73, 79, 80, 81, 83, 83, 88, 98, 96, 102, - 104, 108, 90, 100, 106, 81, 67, 73, 3, 5, 6, - 51, 16, 15, 68, 25, 61, 47, 62, 14, 25, 18, - 75, 96, 102, 107, 126, 126, 124, 68, 43, 27, - 18, 9, 13, 2, 66, 68, 71, 74, 67, 7, 0, 16, - 13, 5, 9, 13, 16, 17, 9, 20, 17, 0, 26, 20, 8, - 1, 68, 74, 98, 101, 98 }, - - { - - 32, - 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 86, 8, - 15, 52, 14, 31, 68, 16, 24, 64, 76, 0, 89, - 105, 0, 67, 126, 126, 124, 43, 6, 69, 16, 24, - 64, 72, 8, 16, 65, 1, 67, 70, 68, 83, 74, 92, - 5, 69, 70, 65, 78, 74, 88, 13, 1, 64, 68, 8, - 3, 22, 0, 0, 0, 1, 95, 97, 8, 71, 68, 52, 6, - 69, 87, 71, 82, 6, 5, 64, 8, 71, 10, 64, 65, - 6, 83, 87, 85, 89, 28, 0, 14, 73, 0, 74, 66, - 6, 71, 83, 74, 80, 17, 70, 4, 74, 76, 2, 70, - 4, 10, 5, 7, 18, 15, 79, 67, 2, 66, 2, 73, 11, - 68, 5, 19, 0, 16, 17, 8, 88, 10, 66, 83, 70, - 94, 77, 65, 70, 3, 66, 64, 16, 1, 66, 7, 13, - 72, 72, 1, 100, 83, 65, 95, 65, 76, 14, 64, - 80, 25, 1, 65, 85, 26, 77, 91, 1, 99, 8, 20, - 20, 15, 20, 14, 3, 18, 21, 79, 64, 9, 3, 1, - 77, 65, 70, 73, 67, 74, 82, 68, 72, 103, 83, - 78, 90, 85, 89, 22, 30, 20, 19, 19, 10, 5, 10, - 64, 70, 65, 77, 88, 88, 111, 0, 65, 82, 69, - 76, 79, 84, 88, 92, 97, 96, 112, 80, 99, 108, - 95, 101, 64, 35, 25, 16, 6, 5, 65, 67, 71, 70, - 8, 48, 31, 24, 17, 36, 14, 9, 0, 1, 64, 43, - 27, 15, 8, 18, 6, 0, 67, 70, 71, 26, 10, 4, - 64, 8, 65, 71, 73, 4, 42, 25, 15, 8, 23, 8, 5, - 4, 64, 62, 79, 70, 3, 66, 68, 1, 8, 9, 0, 8, - 15, 18, 76, 71, 74, 67, 18, 70, 72, 64, 7, 17, - 82, 73, 10, 13, 85, 85, 84, 76, 71, 4, 71, 66, - 68, 64, 6, 75, 70, 69, 1, 81, 73, 80, 82, 1, - 99, 76, 1, 70, 14, 70, 65, 23, 68, 71, 65, 19, - 80, 75, 97, 23, 31, 31, 22, 9, 22, 18, 13, 13, - 10, 9, 5, 76, 79, 86, 72, 69, 79, 98, 79, 78, - 82, 80, 79, 72, 72, 87, 89, 81, 15, 14, 15, 8, - 69, 3, 0, 77, 69, 75, 76, 89, 89, 88, 88, 64, - 3, 80, 64, 65, 75, 81, 82, 83, 85, 85, 90, - 101, 98, 104, 106, 109, 92, 102, 107, 80, 65, - 72, 4, 6, 7, 53, 17, 16, 68, 26, 62, 49, 62, - 15, 23, 16, 77, 99, 104, 110, 126, 126, 125, - 68, 43, 27, 18, 9, 13, 2, 66, 68, 71, 73, 66, - 8, 1, 17, 14, 5, 10, 14, 17, 18, 9, 20, 17, 0, - 25, 19, 7, 0, 70, 76, 100, 103, 99 }, - - { - - 31, - 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 87, 7, - 14, 52, 14, 33, 68, 16, 25, 64, 77, 0, 90, - 106, 64, 68, 126, 126, 125, 46, 7, 69, 16, 25, - 64, 71, 9, 17, 66, 2, 66, 69, 69, 83, 74, 92, - 5, 68, 70, 65, 78, 73, 88, 13, 1, 64, 68, 8, - 3, 22, 0, 0, 0, 2, 95, 97, 8, 71, 69, 52, 6, - 69, 86, 71, 82, 6, 6, 1, 10, 70, 11, 1, 64, 8, - 82, 86, 84, 88, 29, 0, 15, 73, 1, 74, 66, 8, - 71, 82, 74, 79, 17, 70, 4, 72, 76, 3, 69, 4, - 10, 5, 8, 18, 15, 80, 67, 2, 66, 2, 73, 11, - 68, 5, 19, 64, 16, 17, 8, 90, 10, 66, 85, 71, - 95, 77, 64, 70, 3, 65, 64, 17, 1, 66, 7, 15, - 72, 72, 1, 101, 83, 64, 95, 65, 76, 15, 0, 81, - 25, 1, 65, 86, 27, 78, 92, 1, 100, 6, 19, 19, - 15, 19, 14, 3, 17, 20, 80, 65, 9, 3, 1, 77, - 66, 71, 74, 68, 74, 83, 69, 72, 105, 84, 78, - 91, 86, 89, 21, 28, 19, 17, 17, 8, 3, 8, 67, - 73, 67, 80, 91, 91, 114, 65, 67, 83, 71, 79, - 82, 87, 90, 95, 99, 99, 114, 81, 101, 109, 96, - 101, 0, 36, 25, 17, 6, 5, 65, 67, 71, 69, 8, - 48, 32, 24, 17, 37, 14, 9, 1, 1, 0, 44, 27, - 16, 8, 19, 6, 0, 66, 69, 70, 27, 11, 5, 64, 8, - 65, 70, 71, 4, 42, 25, 15, 9, 23, 8, 6, 4, 0, - 62, 78, 69, 3, 66, 68, 1, 8, 9, 0, 9, 15, 19, - 76, 71, 75, 67, 18, 71, 73, 65, 6, 17, 83, 74, - 10, 13, 85, 86, 85, 75, 70, 5, 71, 66, 68, 0, - 6, 75, 69, 68, 2, 81, 73, 80, 82, 2, 99, 76, - 1, 70, 15, 70, 65, 24, 69, 71, 65, 19, 81, 75, - 98, 22, 30, 31, 21, 8, 22, 18, 12, 12, 10, 8, - 4, 77, 80, 87, 74, 70, 81, 100, 81, 80, 83, - 80, 79, 72, 72, 86, 90, 80, 13, 12, 13, 6, 72, - 1, 65, 80, 71, 78, 78, 92, 91, 89, 88, 65, 2, - 82, 66, 68, 77, 83, 84, 85, 87, 88, 92, 103, - 100, 106, 107, 111, 94, 104, 109, 79, 64, 71, - 5, 7, 8, 54, 18, 17, 68, 27, 62, 50, 62, 16, - 22, 15, 80, 102, 107, 112, 126, 126, 126, 67, - 43, 27, 18, 9, 13, 2, 66, 68, 70, 72, 66, 9, - 2, 18, 14, 6, 11, 14, 17, 18, 9, 21, 17, 0, - 24, 17, 5, 65, 71, 77, 103, 104, 100 }, - - { - - 30, - 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 89, 5, - 12, 52, 14, 36, 69, 17, 25, 64, 78, 0, 91, - 107, 64, 70, 126, 126, 125, 49, 8, 69, 17, 25, - 64, 71, 10, 17, 66, 2, 66, 69, 69, 84, 73, 92, - 5, 68, 69, 66, 78, 73, 88, 14, 2, 64, 67, 9, - 3, 22, 0, 0, 0, 2, 95, 97, 9, 72, 69, 52, 6, - 69, 85, 70, 82, 7, 8, 2, 12, 68, 12, 2, 1, 10, - 81, 85, 83, 88, 30, 0, 16, 72, 1, 73, 65, 10, - 71, 82, 73, 78, 17, 69, 5, 71, 75, 3, 69, 5, - 10, 5, 9, 19, 16, 80, 68, 2, 66, 2, 73, 11, - 69, 4, 19, 64, 16, 17, 7, 92, 10, 67, 87, 72, - 96, 76, 0, 69, 4, 64, 0, 18, 2, 65, 8, 16, 72, - 72, 2, 102, 82, 0, 95, 65, 76, 15, 0, 82, 26, - 1, 65, 88, 28, 78, 93, 1, 101, 5, 18, 19, 14, - 18, 13, 2, 16, 20, 81, 66, 9, 3, 1, 78, 67, - 71, 75, 68, 75, 84, 70, 73, 107, 85, 79, 92, - 87, 89, 19, 27, 17, 15, 15, 6, 0, 6, 69, 75, - 69, 82, 93, 93, 116, 67, 68, 85, 74, 81, 84, - 89, 93, 97, 102, 101, 117, 82, 102, 111, 97, - 101, 0, 36, 26, 17, 6, 5, 65, 67, 71, 69, 9, - 49, 32, 24, 17, 38, 15, 10, 1, 2, 1, 45, 28, - 16, 8, 20, 7, 1, 66, 68, 70, 28, 11, 5, 64, 9, - 64, 70, 70, 5, 43, 25, 15, 9, 24, 9, 7, 5, 1, - 62, 78, 69, 4, 66, 68, 1, 8, 9, 1, 9, 15, 19, - 76, 71, 75, 68, 19, 72, 74, 66, 5, 17, 84, 75, - 9, 13, 86, 87, 85, 74, 70, 6, 70, 65, 67, 0, - 7, 75, 69, 68, 2, 82, 73, 80, 81, 3, 99, 76, - 2, 70, 15, 70, 65, 25, 69, 71, 65, 20, 81, 76, - 99, 21, 30, 30, 20, 7, 21, 17, 11, 11, 9, 7, - 3, 78, 81, 88, 75, 72, 82, 102, 82, 81, 84, - 81, 80, 72, 72, 86, 90, 79, 11, 10, 11, 3, 75, - 64, 67, 82, 73, 80, 80, 94, 93, 91, 89, 67, 0, - 83, 68, 70, 79, 85, 86, 87, 89, 90, 94, 106, - 102, 108, 109, 112, 96, 106, 110, 78, 0, 70, - 5, 8, 9, 56, 19, 18, 68, 28, 62, 52, 62, 16, - 20, 13, 82, 105, 110, 115, 126, 126, 126, 67, - 43, 27, 18, 9, 13, 2, 66, 68, 70, 71, 65, 10, - 3, 19, 15, 6, 12, 15, 18, 19, 10, 21, 18, 0, - 22, 16, 3, 67, 73, 79, 105, 106, 101 }, - - { - - 28, - 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 90, 4, - 11, 52, 14, 38, 69, 18, 26, 64, 79, 0, 92, - 109, 65, 72, 126, 126, 126, 51, 9, 69, 18, 26, - 64, 71, 11, 17, 67, 2, 66, 68, 70, 84, 73, 93, - 5, 68, 69, 66, 79, 73, 88, 14, 2, 64, 67, 9, - 3, 22, 0, 0, 0, 3, 96, 97, 9, 73, 69, 52, 6, - 69, 84, 69, 82, 7, 9, 4, 14, 67, 13, 4, 2, 11, - 80, 85, 82, 87, 30, 0, 17, 71, 1, 73, 65, 11, - 71, 82, 73, 77, 17, 69, 5, 70, 75, 4, 69, 5, - 10, 5, 9, 19, 16, 81, 68, 2, 66, 2, 73, 11, - 69, 3, 19, 65, 16, 17, 7, 94, 10, 67, 89, 73, - 97, 75, 1, 68, 5, 64, 0, 19, 2, 65, 9, 17, 72, - 72, 2, 104, 82, 1, 95, 65, 77, 16, 0, 83, 27, - 1, 65, 89, 29, 79, 94, 1, 102, 3, 17, 18, 13, - 17, 12, 1, 15, 19, 83, 67, 8, 3, 1, 78, 68, - 72, 76, 69, 76, 85, 71, 74, 109, 87, 80, 93, - 88, 89, 17, 25, 15, 13, 13, 4, 65, 4, 72, 78, - 71, 85, 96, 96, 119, 69, 70, 87, 76, 83, 87, - 92, 95, 100, 105, 103, 119, 83, 104, 112, 98, - 102, 0, 36, 26, 17, 6, 5, 65, 67, 71, 68, 9, - 49, 32, 24, 17, 39, 15, 10, 1, 2, 1, 46, 28, - 16, 8, 20, 7, 1, 65, 67, 69, 29, 12, 5, 64, - 10, 0, 69, 69, 5, 43, 25, 15, 9, 25, 9, 7, 6, - 1, 62, 78, 69, 4, 66, 68, 1, 8, 9, 1, 9, 15, - 20, 76, 71, 75, 69, 19, 73, 75, 67, 4, 17, 86, - 77, 9, 13, 87, 88, 86, 74, 69, 7, 70, 65, 67, - 1, 8, 76, 69, 68, 2, 83, 73, 80, 81, 3, 100, - 76, 2, 70, 16, 70, 65, 25, 69, 72, 65, 21, 82, - 76, 100, 20, 29, 30, 19, 5, 20, 16, 10, 10, 8, - 6, 2, 79, 82, 89, 77, 73, 84, 104, 84, 82, 85, - 82, 80, 72, 72, 86, 91, 79, 8, 7, 9, 1, 78, - 67, 70, 85, 75, 82, 82, 97, 95, 92, 90, 69, - 65, 85, 70, 72, 82, 88, 89, 90, 91, 92, 97, - 108, 104, 111, 111, 113, 98, 108, 112, 77, 1, - 69, 6, 9, 9, 57, 20, 18, 68, 28, 62, 53, 62, - 17, 19, 11, 85, 108, 113, 118, 126, 126, 126, - 67, 43, 27, 18, 9, 13, 2, 66, 68, 69, 71, 64, - 11, 3, 20, 15, 7, 12, 15, 18, 19, 10, 22, 18, - 64, 21, 14, 1, 69, 75, 81, 107, 108, 102 }, - - { - - 27, - 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 91, 3, - 10, 52, 14, 40, 69, 19, 27, 64, 79, 1, 93, - 110, 66, 74, 126, 126, 126, 54, 11, 69, 19, - 27, 64, 70, 12, 18, 68, 2, 65, 67, 70, 84, 73, - 93, 5, 68, 68, 66, 79, 73, 88, 14, 2, 0, 67, - 9, 3, 22, 0, 0, 0, 4, 96, 97, 9, 74, 69, 52, - 6, 69, 83, 68, 82, 7, 10, 6, 16, 65, 15, 6, 3, - 13, 79, 84, 81, 86, 31, 1, 18, 70, 1, 72, 64, - 13, 71, 81, 73, 75, 18, 69, 5, 68, 75, 5, 69, - 5, 11, 6, 10, 19, 16, 81, 68, 3, 66, 2, 72, - 11, 69, 3, 19, 66, 16, 17, 7, 96, 10, 67, 90, - 74, 97, 74, 2, 67, 6, 0, 1, 20, 3, 65, 10, 18, - 72, 72, 2, 105, 81, 2, 95, 64, 77, 17, 0, 84, - 28, 1, 65, 90, 30, 80, 95, 1, 102, 2, 16, 18, - 12, 16, 11, 1, 15, 19, 84, 68, 8, 3, 1, 78, - 68, 73, 77, 70, 77, 86, 71, 74, 110, 88, 80, - 94, 89, 89, 16, 24, 14, 12, 12, 2, 67, 2, 74, - 80, 73, 87, 99, 98, 122, 70, 72, 88, 78, 85, - 89, 94, 97, 102, 107, 105, 121, 83, 106, 113, - 98, 102, 0, 37, 26, 17, 7, 5, 65, 66, 71, 67, - 9, 49, 32, 25, 17, 40, 16, 11, 2, 3, 2, 47, - 29, 17, 9, 21, 8, 1, 64, 66, 68, 31, 13, 6, 0, - 11, 1, 68, 68, 6, 43, 26, 16, 9, 26, 10, 8, 7, - 2, 62, 77, 68, 5, 66, 68, 1, 9, 10, 1, 9, 16, - 21, 76, 71, 75, 69, 19, 74, 75, 68, 4, 17, 87, - 78, 9, 13, 87, 89, 87, 73, 68, 8, 70, 64, 67, - 2, 9, 76, 69, 68, 3, 83, 73, 80, 81, 4, 100, - 76, 2, 70, 17, 70, 65, 26, 69, 72, 65, 22, 83, - 76, 100, 19, 29, 30, 19, 4, 19, 15, 9, 10, 7, - 5, 2, 79, 83, 90, 78, 74, 86, 106, 85, 83, 85, - 82, 80, 71, 71, 86, 92, 78, 6, 5, 7, 64, 80, - 69, 72, 87, 77, 84, 84, 99, 97, 93, 91, 71, - 66, 86, 72, 74, 84, 90, 91, 92, 93, 94, 99, - 110, 105, 113, 113, 114, 100, 110, 114, 76, 3, - 67, 7, 10, 10, 59, 21, 19, 68, 29, 62, 54, 62, - 18, 18, 10, 87, 111, 115, 121, 126, 126, 126, - 67, 43, 27, 18, 9, 14, 2, 66, 68, 68, 70, 0, - 12, 4, 22, 16, 8, 13, 16, 19, 20, 10, 23, 18, - 64, 20, 13, 0, 70, 77, 83, 109, 110, 102 }, - - { - - 26, - 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 93, 1, - 8, 52, 14, 43, 70, 20, 27, 64, 80, 1, 94, 111, - 66, 76, 126, 126, 126, 57, 12, 69, 20, 27, 64, - 70, 13, 18, 68, 2, 65, 67, 70, 85, 72, 93, 5, - 68, 67, 67, 79, 73, 88, 15, 3, 0, 66, 10, 3, - 22, 0, 0, 0, 4, 96, 97, 10, 75, 69, 52, 6, 69, - 82, 67, 82, 8, 12, 7, 18, 64, 16, 7, 5, 15, - 78, 83, 80, 86, 32, 1, 19, 69, 1, 72, 0, 15, - 71, 81, 72, 74, 18, 68, 6, 67, 74, 5, 69, 6, - 11, 6, 11, 20, 17, 82, 69, 3, 66, 2, 72, 11, - 70, 2, 19, 66, 16, 17, 6, 98, 10, 68, 92, 75, - 98, 73, 3, 66, 7, 1, 2, 21, 4, 64, 11, 19, 72, - 72, 3, 106, 81, 3, 95, 64, 77, 17, 0, 85, 29, - 1, 65, 92, 31, 80, 96, 1, 103, 0, 15, 17, 11, - 15, 10, 0, 14, 19, 85, 69, 8, 3, 1, 79, 69, - 73, 78, 70, 78, 87, 72, 75, 112, 89, 81, 95, - 90, 89, 14, 23, 12, 10, 10, 0, 70, 0, 77, 82, - 75, 90, 101, 100, 124, 72, 73, 90, 81, 87, 91, - 96, 100, 104, 110, 107, 124, 84, 107, 115, 99, - 102, 0, 37, 27, 17, 7, 5, 65, 66, 71, 67, 10, - 50, 32, 25, 17, 41, 16, 12, 2, 4, 3, 48, 30, - 17, 9, 22, 8, 2, 64, 65, 68, 32, 13, 6, 0, 12, - 2, 68, 67, 6, 44, 26, 16, 9, 27, 11, 9, 8, 3, - 62, 77, 68, 5, 66, 68, 1, 9, 10, 2, 9, 16, 21, - 76, 71, 75, 70, 20, 75, 76, 69, 3, 17, 88, 79, - 8, 13, 88, 90, 87, 72, 68, 9, 69, 64, 66, 2, - 10, 76, 69, 68, 3, 84, 73, 80, 80, 5, 100, 76, - 3, 70, 17, 70, 65, 27, 69, 72, 65, 23, 83, 77, - 101, 18, 29, 29, 18, 3, 18, 14, 8, 9, 6, 4, 1, - 80, 84, 91, 80, 76, 87, 108, 86, 84, 86, 83, - 81, 71, 71, 86, 92, 77, 4, 3, 5, 67, 83, 71, - 74, 90, 79, 86, 86, 101, 99, 95, 92, 73, 68, - 87, 74, 76, 86, 92, 93, 94, 95, 96, 101, 113, - 107, 115, 115, 115, 102, 112, 115, 75, 4, 66, - 7, 11, 11, 61, 22, 20, 68, 30, 62, 56, 62, 18, - 16, 8, 90, 114, 118, 124, 126, 126, 126, 67, - 43, 27, 18, 9, 14, 2, 66, 68, 68, 69, 1, 13, - 5, 23, 17, 8, 14, 17, 20, 21, 11, 23, 19, 64, - 18, 11, 65, 72, 79, 85, 111, 112, 103 }, - - { - - 25, - 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 94, 0, - 7, 52, 14, 45, 70, 20, 28, 64, 81, 1, 95, 112, - 67, 77, 126, 126, 126, 60, 13, 69, 20, 28, 64, - 69, 14, 19, 69, 3, 64, 66, 71, 85, 72, 93, 5, - 67, 67, 67, 79, 72, 88, 15, 3, 0, 66, 10, 3, - 22, 0, 0, 0, 5, 96, 97, 10, 75, 70, 52, 6, 69, - 81, 67, 82, 8, 13, 9, 20, 1, 17, 9, 6, 17, 77, - 82, 79, 85, 33, 1, 20, 69, 2, 71, 0, 17, 71, - 80, 72, 73, 18, 68, 6, 65, 74, 6, 68, 6, 11, - 6, 12, 20, 17, 82, 69, 3, 66, 2, 72, 11, 70, - 2, 19, 67, 16, 17, 6, 100, 10, 68, 94, 76, 99, - 73, 4, 66, 7, 2, 2, 22, 4, 64, 11, 21, 72, 72, - 3, 107, 80, 4, 95, 64, 77, 18, 1, 86, 29, 1, - 65, 93, 32, 81, 97, 1, 104, 64, 14, 17, 11, - 14, 10, 0, 13, 18, 86, 70, 8, 3, 1, 79, 70, - 74, 79, 71, 78, 88, 73, 75, 114, 90, 81, 96, - 91, 89, 13, 21, 11, 8, 8, 65, 72, 65, 79, 85, - 77, 92, 104, 103, 126, 74, 75, 91, 83, 90, 94, - 99, 102, 107, 112, 110, 126, 85, 109, 116, - 100, 102, 1, 38, 27, 18, 7, 5, 65, 66, 71, 66, - 10, 50, 33, 25, 17, 42, 17, 12, 3, 4, 4, 49, - 30, 18, 9, 23, 9, 2, 0, 64, 67, 33, 14, 7, 0, - 12, 2, 67, 65, 7, 44, 26, 16, 10, 27, 11, 10, - 8, 4, 62, 76, 67, 6, 66, 68, 1, 9, 10, 2, 10, - 16, 22, 76, 71, 76, 70, 20, 76, 77, 70, 2, 17, - 89, 80, 8, 13, 88, 91, 88, 71, 67, 10, 69, 0, - 66, 3, 10, 76, 68, 67, 4, 84, 73, 80, 80, 6, - 100, 76, 3, 70, 18, 70, 65, 28, 70, 72, 65, - 23, 84, 77, 102, 17, 28, 29, 17, 2, 18, 14, 7, - 8, 6, 3, 0, 81, 85, 92, 81, 77, 89, 110, 88, - 86, 87, 83, 81, 71, 71, 85, 93, 76, 2, 1, 3, - 69, 86, 73, 76, 92, 81, 89, 88, 104, 101, 96, - 92, 74, 69, 89, 76, 79, 88, 94, 95, 96, 97, - 99, 103, 115, 109, 117, 116, 117, 104, 114, - 117, 74, 5, 65, 8, 12, 12, 62, 23, 21, 68, 31, - 62, 57, 62, 19, 15, 7, 92, 117, 121, 126, 126, - 126, 126, 66, 43, 27, 18, 9, 14, 2, 66, 68, - 67, 68, 1, 14, 6, 24, 17, 9, 15, 17, 20, 21, - 11, 24, 19, 64, 17, 10, 67, 74, 80, 86, 114, - 113, 104 }, - - { - - 23, - 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 96, 65, - 6, 52, 14, 47, 70, 21, 29, 64, 82, 1, 96, 113, - 67, 79, 126, 126, 126, 62, 14, 69, 21, 29, 64, - 69, 15, 19, 69, 3, 64, 65, 71, 86, 72, 93, 5, - 67, 66, 67, 80, 72, 88, 16, 3, 0, 66, 11, 3, - 22, 0, 0, 0, 5, 97, 97, 11, 76, 70, 52, 6, 69, - 80, 66, 82, 9, 14, 11, 22, 2, 18, 11, 7, 19, - 76, 82, 78, 84, 33, 1, 21, 68, 2, 71, 1, 19, - 71, 80, 71, 72, 18, 68, 7, 64, 73, 7, 68, 6, - 11, 6, 12, 21, 18, 83, 69, 3, 66, 2, 72, 11, - 71, 1, 19, 68, 16, 17, 6, 102, 10, 69, 96, 77, - 100, 72, 5, 65, 8, 2, 3, 23, 5, 0, 12, 22, 72, - 72, 3, 108, 80, 5, 95, 64, 77, 19, 1, 87, 30, - 1, 65, 94, 33, 81, 98, 1, 105, 66, 13, 16, 10, - 13, 9, 64, 12, 18, 88, 71, 7, 3, 1, 80, 71, - 75, 80, 72, 79, 89, 74, 76, 116, 91, 82, 97, - 92, 89, 11, 20, 9, 6, 6, 67, 74, 67, 82, 87, - 79, 95, 106, 105, 126, 76, 77, 93, 85, 92, 96, - 101, 104, 109, 115, 112, 126, 86, 111, 117, - 101, 102, 1, 38, 27, 18, 7, 5, 65, 66, 71, 66, - 10, 50, 33, 25, 17, 43, 17, 13, 3, 5, 4, 50, - 31, 18, 9, 23, 9, 3, 0, 0, 66, 34, 15, 7, 0, - 13, 3, 66, 64, 7, 44, 26, 16, 10, 28, 12, 10, - 9, 5, 62, 76, 67, 6, 66, 68, 1, 9, 10, 2, 10, - 16, 22, 76, 71, 76, 71, 21, 77, 78, 71, 1, 17, - 91, 81, 8, 13, 89, 92, 88, 71, 66, 11, 68, 0, - 65, 3, 11, 77, 68, 67, 4, 85, 73, 80, 79, 7, - 100, 76, 3, 70, 19, 70, 65, 29, 70, 73, 65, - 24, 85, 77, 103, 16, 28, 28, 16, 1, 17, 13, 6, - 7, 5, 2, 64, 82, 86, 93, 83, 78, 90, 112, 89, - 87, 88, 84, 82, 71, 71, 85, 93, 76, 64, 65, 1, - 71, 89, 75, 78, 95, 83, 91, 90, 106, 103, 98, - 93, 76, 71, 90, 78, 81, 90, 96, 98, 98, 99, - 101, 105, 118, 111, 119, 118, 118, 106, 116, - 118, 73, 6, 64, 9, 13, 13, 62, 24, 22, 68, 32, - 62, 59, 62, 20, 13, 5, 95, 120, 124, 126, 126, - 126, 126, 66, 43, 27, 18, 9, 14, 2, 66, 68, - 67, 67, 2, 15, 6, 25, 18, 9, 16, 18, 21, 22, - 11, 24, 19, 64, 16, 8, 69, 76, 82, 88, 116, - 115, 105 }, - - { - - 22, - 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 66, - 4, 52, 14, 50, 71, 22, 29, 64, 82, 2, 97, 114, - 68, 81, 126, 126, 126, 62, 16, 69, 22, 29, 64, - 69, 16, 19, 70, 3, 64, 65, 71, 86, 71, 93, 5, - 67, 65, 68, 80, 72, 88, 16, 4, 1, 65, 11, 3, - 22, 0, 0, 0, 6, 97, 97, 11, 77, 70, 52, 6, 69, - 79, 65, 82, 9, 16, 12, 24, 4, 19, 12, 9, 21, - 75, 81, 77, 84, 34, 1, 22, 67, 2, 70, 2, 21, - 71, 80, 71, 70, 19, 67, 7, 0, 73, 7, 68, 7, - 12, 7, 13, 21, 18, 83, 70, 3, 66, 2, 72, 11, - 71, 0, 19, 68, 16, 17, 5, 104, 10, 69, 97, 78, - 101, 71, 6, 64, 9, 3, 4, 24, 6, 0, 13, 23, 72, - 72, 4, 109, 79, 6, 95, 0, 77, 19, 1, 88, 31, - 1, 65, 96, 34, 82, 99, 1, 105, 67, 12, 16, 9, - 12, 8, 65, 12, 18, 89, 72, 7, 3, 1, 80, 71, - 75, 81, 72, 80, 90, 74, 77, 118, 92, 83, 98, - 93, 89, 9, 19, 7, 4, 5, 69, 77, 69, 84, 89, - 81, 97, 109, 107, 126, 78, 78, 95, 88, 94, 98, - 103, 107, 111, 118, 114, 126, 87, 112, 119, - 101, 102, 1, 38, 28, 18, 7, 5, 65, 66, 71, 65, - 11, 51, 33, 25, 17, 44, 18, 14, 3, 6, 5, 51, - 32, 18, 10, 24, 10, 3, 1, 1, 66, 36, 15, 7, 1, - 14, 4, 66, 0, 8, 45, 27, 16, 10, 29, 13, 11, - 10, 6, 62, 76, 67, 7, 66, 68, 1, 9, 10, 3, 10, - 17, 23, 76, 71, 76, 72, 21, 78, 79, 72, 1, 17, - 92, 82, 7, 13, 90, 93, 89, 70, 66, 12, 68, 1, - 65, 4, 12, 77, 68, 67, 4, 86, 73, 80, 79, 8, - 100, 76, 4, 70, 19, 70, 65, 30, 70, 73, 65, - 25, 85, 78, 103, 15, 28, 28, 16, 0, 16, 12, 5, - 7, 4, 1, 65, 83, 87, 94, 84, 80, 92, 114, 90, - 88, 89, 85, 82, 71, 70, 85, 94, 75, 66, 67, - 64, 74, 91, 77, 80, 97, 85, 93, 92, 108, 105, - 99, 94, 78, 73, 91, 80, 83, 92, 98, 100, 100, - 101, 103, 107, 120, 113, 121, 120, 119, 108, - 118, 120, 72, 8, 0, 9, 14, 14, 62, 25, 23, 68, - 33, 62, 60, 62, 20, 12, 3, 97, 123, 126, 126, - 126, 126, 126, 66, 43, 27, 18, 9, 14, 2, 66, - 68, 66, 66, 3, 16, 7, 26, 19, 10, 17, 19, 22, - 23, 12, 25, 20, 64, 14, 7, 70, 77, 84, 90, - 118, 117, 106 }, - - { - - 21, - 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 68, - 3, 52, 14, 52, 71, 23, 30, 64, 83, 2, 98, 115, - 68, 83, 126, 126, 126, 62, 17, 69, 23, 30, 64, - 68, 17, 20, 70, 3, 0, 64, 72, 87, 71, 93, 5, - 67, 65, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, - 22, 0, 0, 0, 6, 97, 97, 12, 78, 70, 52, 6, 69, - 78, 64, 82, 10, 17, 14, 26, 5, 20, 14, 10, 23, - 74, 80, 76, 83, 35, 1, 23, 66, 2, 70, 2, 23, - 71, 79, 70, 69, 19, 67, 8, 2, 72, 8, 68, 7, - 12, 7, 14, 22, 19, 84, 70, 3, 66, 2, 72, 11, - 72, 0, 19, 69, 16, 17, 5, 106, 10, 70, 99, 79, - 102, 70, 7, 0, 10, 4, 4, 25, 6, 1, 14, 24, 72, - 72, 4, 110, 79, 7, 95, 0, 77, 20, 1, 89, 32, - 1, 65, 97, 35, 82, 100, 1, 106, 69, 11, 15, 8, - 11, 7, 65, 11, 17, 90, 73, 7, 3, 1, 81, 72, - 76, 82, 73, 81, 91, 75, 77, 120, 93, 83, 99, - 94, 89, 8, 17, 6, 2, 3, 71, 79, 71, 87, 92, - 83, 100, 111, 110, 126, 80, 80, 96, 90, 96, - 101, 106, 109, 114, 120, 116, 126, 88, 114, - 120, 102, 102, 1, 39, 28, 18, 7, 5, 65, 66, - 71, 65, 11, 51, 33, 25, 17, 45, 18, 14, 4, 6, - 6, 52, 32, 19, 10, 25, 10, 4, 1, 2, 65, 37, - 16, 8, 1, 15, 5, 65, 1, 8, 45, 27, 16, 10, 30, - 13, 12, 11, 7, 62, 75, 66, 7, 66, 68, 1, 9, - 10, 3, 10, 17, 23, 76, 71, 76, 72, 22, 79, 80, - 73, 0, 17, 93, 83, 7, 13, 90, 94, 89, 69, 65, - 13, 67, 1, 64, 4, 13, 77, 68, 67, 5, 86, 73, - 80, 78, 9, 100, 76, 4, 70, 20, 70, 65, 31, 70, - 73, 65, 26, 86, 78, 104, 14, 27, 27, 15, 64, - 15, 11, 4, 6, 3, 0, 66, 84, 88, 95, 86, 81, - 93, 116, 92, 89, 90, 85, 83, 71, 70, 85, 94, - 74, 68, 69, 66, 76, 94, 79, 82, 100, 87, 95, - 94, 111, 107, 101, 95, 80, 74, 93, 82, 85, 94, - 100, 102, 102, 103, 105, 109, 123, 115, 123, - 122, 120, 110, 120, 121, 71, 9, 1, 10, 15, 15, - 62, 26, 24, 68, 34, 62, 62, 62, 21, 10, 2, - 100, 126, 126, 126, 126, 126, 126, 66, 43, 27, - 18, 9, 14, 2, 66, 68, 66, 65, 4, 17, 8, 27, - 19, 10, 18, 19, 22, 23, 12, 25, 20, 64, 13, 5, - 72, 79, 86, 92, 120, 119, 107 }, - - { - - 20, - 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 100, 69, - 2, 52, 14, 54, 71, 24, 31, 64, 84, 2, 99, 116, - 69, 85, 126, 126, 126, 62, 18, 69, 24, 31, 64, - 68, 18, 20, 71, 3, 0, 0, 72, 87, 71, 93, 5, - 67, 64, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, - 22, 0, 0, 0, 7, 97, 97, 12, 79, 70, 52, 6, 69, - 77, 0, 82, 10, 18, 16, 28, 7, 21, 16, 11, 25, - 73, 79, 75, 82, 36, 1, 24, 65, 2, 69, 3, 25, - 71, 79, 70, 68, 19, 67, 8, 3, 72, 9, 68, 7, - 12, 7, 15, 22, 19, 84, 70, 3, 66, 2, 72, 11, - 72, 64, 19, 70, 16, 17, 5, 108, 10, 70, 101, - 80, 103, 69, 8, 1, 11, 5, 5, 26, 7, 1, 15, 25, - 72, 72, 4, 111, 78, 8, 95, 0, 77, 21, 1, 90, - 33, 1, 65, 98, 36, 83, 101, 1, 107, 70, 10, - 15, 7, 10, 6, 66, 10, 17, 91, 74, 7, 3, 1, 81, - 73, 77, 83, 74, 82, 92, 76, 78, 122, 94, 84, - 100, 95, 89, 6, 16, 4, 0, 1, 73, 81, 73, 89, - 94, 85, 102, 114, 112, 126, 82, 82, 98, 92, - 98, 103, 108, 111, 116, 123, 118, 126, 89, - 116, 121, 103, 102, 1, 39, 28, 18, 7, 5, 65, - 66, 71, 64, 11, 51, 33, 25, 17, 46, 19, 15, 4, - 7, 7, 53, 33, 19, 10, 26, 11, 4, 2, 3, 64, 38, - 17, 8, 1, 16, 6, 64, 2, 9, 45, 27, 16, 10, 31, - 14, 13, 12, 8, 62, 75, 66, 8, 66, 68, 1, 9, - 10, 3, 10, 17, 24, 76, 71, 76, 73, 22, 80, 81, - 74, 64, 17, 94, 84, 7, 13, 91, 95, 90, 68, 64, - 14, 67, 2, 64, 5, 14, 77, 68, 67, 5, 87, 73, - 80, 78, 10, 100, 76, 4, 70, 21, 70, 65, 32, - 70, 73, 65, 27, 87, 78, 105, 13, 27, 27, 14, - 65, 14, 10, 3, 5, 2, 64, 67, 85, 89, 96, 87, - 82, 95, 118, 93, 90, 91, 86, 83, 71, 70, 85, - 95, 73, 70, 71, 68, 78, 97, 81, 84, 102, 89, - 97, 96, 113, 109, 102, 96, 82, 76, 94, 84, 87, - 96, 102, 104, 104, 105, 107, 111, 125, 117, - 125, 124, 121, 112, 122, 123, 70, 10, 2, 11, - 16, 16, 62, 27, 25, 68, 35, 62, 62, 62, 22, 9, - 0, 102, 126, 126, 126, 126, 126, 126, 66, 43, - 27, 18, 9, 14, 2, 66, 68, 65, 64, 5, 18, 9, - 28, 20, 11, 19, 20, 23, 24, 12, 26, 20, 64, - 12, 4, 74, 81, 88, 94, 122, 121, 108 }, - - { - - 18, - 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 102, 71, - 0, 51, 14, 56, 72, 24, 31, 65, 85, 2, 101, - 118, 70, 87, 126, 126, 126, 62, 19, 70, 24, - 31, 65, 68, 19, 20, 72, 3, 0, 0, 73, 88, 71, - 94, 5, 67, 64, 69, 81, 72, 88, 17, 4, 1, 65, - 12, 2, 22, 0, 0, 0, 7, 98, 97, 12, 80, 71, 52, - 5, 69, 76, 0, 82, 10, 19, 17, 29, 8, 22, 17, - 12, 26, 72, 79, 74, 82, 36, 1, 24, 65, 2, 69, - 3, 26, 71, 79, 70, 67, 19, 67, 8, 4, 72, 9, - 68, 7, 12, 7, 15, 22, 19, 85, 71, 3, 67, 2, - 72, 10, 73, 65, 19, 71, 15, 17, 4, 110, 9, 71, - 103, 81, 104, 69, 8, 1, 11, 5, 5, 27, 7, 1, - 15, 26, 73, 72, 4, 113, 78, 8, 95, 0, 78, 21, - 1, 91, 33, 1, 65, 100, 36, 84, 102, 1, 108, - 72, 9, 14, 6, 9, 5, 67, 9, 16, 93, 75, 6, 2, - 1, 82, 74, 78, 84, 75, 83, 93, 77, 79, 124, - 96, 85, 102, 97, 89, 4, 14, 2, 65, 64, 76, 84, - 76, 92, 97, 88, 105, 117, 115, 126, 84, 84, - 100, 95, 101, 106, 111, 114, 119, 126, 121, - 126, 90, 118, 123, 104, 103, 1, 39, 28, 18, 7, - 5, 66, 66, 71, 64, 11, 51, 33, 25, 17, 47, 19, - 15, 4, 7, 7, 53, 33, 19, 10, 26, 11, 4, 2, 4, - 64, 39, 17, 8, 1, 16, 6, 64, 3, 9, 45, 27, 16, - 10, 31, 14, 13, 12, 8, 62, 75, 66, 8, 66, 68, - 1, 9, 10, 3, 10, 17, 24, 76, 71, 77, 74, 22, - 81, 82, 75, 65, 16, 96, 86, 6, 12, 92, 97, 91, - 68, 64, 15, 67, 2, 64, 5, 14, 78, 68, 67, 5, - 88, 73, 80, 78, 10, 101, 76, 4, 70, 21, 71, - 65, 32, 71, 74, 65, 27, 88, 79, 106, 12, 26, - 26, 13, 67, 13, 9, 2, 4, 1, 65, 68, 86, 91, - 98, 89, 84, 97, 120, 95, 92, 92, 87, 84, 71, - 70, 85, 96, 73, 73, 74, 70, 81, 100, 84, 87, - 105, 92, 100, 99, 116, 112, 104, 97, 84, 78, - 96, 86, 90, 99, 105, 107, 107, 107, 110, 114, - 126, 119, 126, 126, 123, 114, 124, 125, 69, - 11, 3, 11, 16, 16, 62, 27, 25, 68, 35, 62, 62, - 62, 22, 7, 65, 105, 126, 126, 126, 126, 126, - 126, 66, 43, 26, 17, 9, 14, 2, 67, 68, 65, 64, - 5, 18, 9, 29, 20, 11, 19, 20, 23, 24, 12, 26, - 20, 65, 10, 2, 76, 83, 90, 96, 125, 123, 109 }, - - { - - 17, - 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 103, 72, - 64, 51, 14, 59, 72, 25, 32, 65, 85, 3, 102, - 119, 70, 88, 126, 126, 126, 62, 21, 70, 25, - 32, 65, 67, 21, 21, 72, 4, 1, 1, 73, 88, 70, - 94, 5, 66, 0, 69, 81, 71, 88, 18, 5, 2, 64, - 13, 2, 22, 0, 0, 0, 8, 98, 97, 13, 80, 71, 52, - 5, 69, 74, 1, 82, 11, 21, 19, 31, 10, 24, 19, - 14, 28, 70, 78, 73, 81, 37, 2, 25, 64, 3, 68, - 4, 28, 70, 78, 69, 65, 20, 66, 9, 6, 71, 10, - 67, 8, 13, 8, 16, 23, 20, 85, 71, 4, 67, 2, - 71, 10, 73, 65, 19, 71, 15, 17, 4, 111, 9, 71, - 104, 82, 104, 68, 9, 2, 12, 6, 6, 28, 8, 2, - 16, 28, 73, 72, 5, 114, 77, 9, 95, 1, 78, 22, - 2, 91, 34, 1, 65, 101, 37, 84, 103, 1, 108, - 73, 9, 14, 6, 9, 5, 67, 9, 16, 94, 75, 6, 2, - 1, 82, 74, 78, 84, 75, 83, 94, 77, 79, 125, - 97, 85, 103, 98, 89, 3, 13, 1, 66, 65, 78, 86, - 78, 94, 99, 90, 107, 119, 117, 126, 85, 85, - 101, 97, 103, 108, 113, 116, 121, 126, 123, - 126, 90, 119, 124, 104, 103, 2, 40, 29, 19, 8, - 5, 66, 65, 70, 0, 12, 52, 34, 26, 17, 48, 20, - 16, 5, 8, 8, 54, 34, 20, 11, 27, 12, 5, 3, 6, - 0, 41, 18, 9, 2, 17, 7, 0, 5, 10, 46, 28, 17, - 11, 32, 15, 14, 13, 9, 62, 74, 65, 9, 66, 67, - 1, 10, 11, 4, 11, 18, 25, 75, 71, 77, 74, 23, - 81, 82, 76, 65, 16, 97, 87, 6, 12, 92, 98, 91, - 67, 0, 16, 66, 3, 0, 6, 15, 78, 67, 66, 6, 88, - 72, 79, 77, 11, 101, 76, 5, 70, 22, 71, 65, - 33, 71, 74, 64, 28, 88, 79, 106, 12, 26, 26, - 13, 68, 13, 9, 2, 4, 1, 65, 68, 86, 92, 99, - 90, 85, 98, 121, 96, 93, 92, 87, 84, 70, 69, - 84, 96, 72, 75, 76, 72, 83, 102, 86, 89, 107, - 94, 102, 101, 118, 114, 105, 97, 85, 79, 97, - 87, 92, 101, 107, 109, 109, 109, 112, 116, - 126, 120, 126, 126, 124, 115, 125, 126, 67, - 13, 5, 12, 17, 17, 62, 28, 26, 68, 36, 62, 62, - 62, 23, 6, 66, 107, 126, 126, 126, 126, 126, - 126, 65, 44, 26, 17, 9, 15, 2, 67, 68, 64, 0, - 6, 19, 10, 31, 21, 12, 20, 21, 24, 25, 13, 27, - 21, 65, 9, 1, 77, 84, 91, 97, 126, 124, 109 }, - - { - - 16, - 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 104, 73, - 65, 51, 14, 61, 72, 26, 33, 65, 86, 3, 103, - 120, 71, 90, 126, 126, 126, 62, 22, 70, 26, - 33, 65, 67, 22, 21, 73, 4, 1, 2, 73, 88, 70, - 94, 5, 66, 1, 69, 81, 71, 88, 18, 5, 2, 64, - 13, 2, 22, 0, 0, 0, 9, 98, 97, 13, 81, 71, 52, - 5, 69, 73, 2, 82, 11, 22, 21, 33, 11, 25, 21, - 15, 30, 69, 77, 72, 80, 38, 2, 26, 0, 3, 68, - 5, 30, 70, 78, 69, 64, 20, 66, 9, 7, 71, 11, - 67, 8, 13, 8, 17, 23, 20, 86, 71, 4, 67, 2, - 71, 10, 73, 66, 19, 72, 15, 17, 4, 113, 9, 71, - 106, 83, 105, 67, 10, 3, 13, 7, 7, 29, 9, 2, - 17, 29, 73, 72, 5, 115, 77, 10, 95, 1, 78, 23, - 2, 92, 35, 1, 65, 102, 38, 85, 104, 1, 109, - 75, 8, 13, 5, 8, 4, 68, 8, 16, 95, 76, 6, 2, - 1, 82, 75, 79, 85, 76, 84, 95, 78, 80, 126, - 98, 86, 104, 99, 89, 1, 12, 64, 68, 67, 80, - 88, 80, 97, 101, 92, 110, 122, 119, 126, 87, - 87, 103, 99, 105, 110, 115, 118, 123, 126, - 125, 126, 91, 121, 125, 105, 103, 2, 40, 29, - 19, 8, 5, 66, 65, 70, 1, 12, 52, 34, 26, 17, - 49, 20, 17, 5, 9, 9, 55, 35, 20, 11, 28, 12, - 5, 4, 7, 1, 42, 19, 9, 2, 18, 8, 1, 6, 10, 46, - 28, 17, 11, 33, 16, 15, 14, 10, 62, 74, 65, 9, - 66, 67, 1, 10, 11, 4, 11, 18, 26, 75, 71, 77, - 75, 23, 82, 83, 77, 66, 16, 98, 88, 6, 12, 93, - 99, 92, 66, 1, 17, 66, 3, 0, 7, 16, 78, 67, - 66, 6, 89, 72, 79, 77, 12, 101, 76, 5, 70, 23, - 71, 65, 34, 71, 74, 64, 29, 89, 79, 107, 11, - 26, 26, 12, 69, 12, 8, 1, 3, 0, 66, 69, 87, - 93, 100, 92, 86, 100, 123, 97, 94, 93, 88, 84, - 70, 69, 84, 97, 71, 77, 78, 74, 85, 105, 88, - 91, 110, 96, 104, 103, 120, 116, 106, 98, 87, - 81, 98, 89, 94, 103, 109, 111, 111, 111, 114, - 118, 126, 122, 126, 126, 125, 117, 126, 126, - 66, 14, 6, 13, 18, 18, 62, 29, 27, 68, 37, 62, - 62, 62, 24, 5, 68, 110, 126, 126, 126, 126, - 126, 126, 65, 44, 26, 17, 9, 15, 2, 67, 68, 0, - 1, 7, 20, 11, 32, 22, 13, 21, 22, 25, 26, 13, - 28, 21, 65, 8, 64, 79, 86, 93, 99, 126, 126, - 110 }, - - { - - 15, - 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 106, 75, - 66, 51, 14, 62, 72, 27, 34, 65, 87, 3, 104, - 121, 71, 92, 126, 126, 126, 62, 23, 70, 27, - 34, 65, 66, 23, 22, 73, 4, 2, 3, 74, 89, 70, - 94, 5, 66, 1, 69, 81, 71, 88, 19, 5, 2, 64, - 14, 2, 22, 0, 0, 0, 9, 98, 97, 14, 82, 71, 52, - 5, 69, 72, 3, 82, 12, 23, 23, 35, 13, 26, 23, - 16, 32, 68, 76, 71, 79, 39, 2, 27, 1, 3, 67, - 5, 32, 70, 77, 68, 0, 20, 66, 10, 9, 70, 12, - 67, 8, 13, 8, 18, 24, 21, 86, 71, 4, 67, 2, - 71, 10, 74, 66, 19, 73, 15, 17, 4, 115, 9, 72, - 108, 84, 106, 66, 11, 4, 14, 8, 7, 30, 9, 3, - 18, 30, 73, 72, 5, 116, 76, 11, 95, 1, 78, 24, - 2, 93, 36, 1, 65, 103, 39, 85, 105, 1, 110, - 76, 7, 13, 4, 7, 3, 68, 7, 15, 96, 77, 6, 2, - 1, 83, 76, 80, 86, 77, 85, 96, 79, 80, 126, - 99, 86, 105, 100, 89, 0, 10, 65, 70, 69, 82, - 90, 82, 99, 104, 94, 112, 124, 122, 126, 89, - 89, 104, 101, 107, 113, 118, 120, 126, 126, - 126, 126, 92, 123, 126, 106, 103, 2, 41, 29, - 19, 8, 5, 66, 65, 70, 1, 12, 52, 34, 26, 17, - 50, 21, 17, 6, 9, 10, 56, 35, 21, 11, 29, 13, - 6, 4, 8, 2, 43, 20, 10, 2, 19, 9, 2, 7, 11, - 46, 28, 17, 11, 34, 16, 16, 15, 11, 62, 73, - 64, 10, 66, 67, 1, 10, 11, 4, 11, 18, 26, 75, - 71, 77, 75, 24, 83, 84, 78, 67, 16, 99, 89, 6, - 12, 93, 100, 92, 65, 2, 18, 65, 4, 1, 7, 17, - 78, 67, 66, 7, 89, 72, 79, 76, 13, 101, 76, 5, - 70, 24, 71, 65, 35, 71, 74, 64, 30, 90, 79, - 108, 10, 25, 25, 11, 70, 11, 7, 0, 2, 64, 67, - 70, 88, 94, 101, 93, 87, 101, 125, 99, 95, 94, - 88, 85, 70, 69, 84, 97, 70, 79, 80, 76, 87, - 108, 90, 93, 112, 98, 106, 105, 123, 118, 108, - 99, 89, 82, 100, 91, 96, 105, 111, 113, 113, - 113, 116, 120, 126, 124, 126, 126, 126, 119, - 126, 126, 65, 15, 7, 14, 19, 19, 62, 30, 28, - 68, 38, 62, 62, 62, 25, 3, 69, 112, 126, 126, - 126, 126, 126, 126, 65, 44, 26, 17, 9, 15, 2, - 67, 68, 0, 2, 8, 21, 12, 33, 22, 13, 22, 22, - 25, 26, 13, 28, 21, 65, 7, 65, 81, 88, 95, - 101, 126, 126, 111 }, - - }, - - }; + { + + 62, + 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 30, 61, 62, + 54, 14, 118, 6, 78, 65, 1, 14, 73, 13, 64, 20, 62, + 67, 90, 104, 126, 104, 67, 78, 65, 1, 86, 95, 2, + 18, 69, 81, 96, 8, 67, 86, 88, 5, 76, 94, 9, 69, + 81, 88, 67, 74, 74, 80, 72, 5, 22, 0, 0, 0, 83, + 86, 97, 72, 22, 1, 18, 78, 96, 126, 98, 101, 67, + 82, 94, 83, 110, 91, 102, 93, 126, 92, 89, 96, + 108, 17, 65, 6, 93, 74, 92, 87, 126, 9, 3, 4, 69, + 15, 68, 69, 88, 85, 78, 75, 77, 9, 13, 68, 13, 21, + 81, 0, 70, 67, 6, 76, 28, 64, 2, 28, 38, 39, 34, + 27, 93, 73, 73, 17, 14, 100, 10, 10, 10, 2, 7, 7, + 0, 3, 1, 6, 69, 6, 24, 12, 68, 64, 2, 0, 13, 24, + 19, 11, 15, 3, 4, 4, 30, 19, 20, 78, 3, 69, 35, + 23, 19, 14, 17, 19, 12, 16, 24, 1, 17, 9, 9, 5, 0, + 12, 6, 10, 11, 8, 18, 27, 10, 82, 8, 78, 17, 32, + 84, 56, 62, 60, 59, 62, 62, 57, 57, 54, 44, 36, + 33, 43, 29, 70, 67, 4, 67, 33, 31, 28, 34, 32, 25, + 20, 22, 0, 4, 64, 94, 89, 108, 76, 19, 18, 11, 64, + 4, 70, 75, 82, 102, 77, 39, 21, 15, 8, 4, 71, 83, + 87, 119, 5, 34, 27, 25, 20, 8, 5, 64, 74, 90, 70, + 34, 32, 21, 4, 5, 72, 81, 97, 5, 58, 49, 45, 36, + 23, 5, 70, 79, 85, 62, 106, 106, 87, 114, 110, 98, + 110, 106, 103, 107, 108, 112, 96, 95, 91, 93, 94, + 86, 67, 80, 85, 70, 3, 5, 2, 13, 13, 14, 9, 22, + 17, 12, 14, 11, 22, 16, 8, 22, 19, 13, 10, 14, 0, + 64, 69, 4, 70, 19, 32, 20, 10, 29, 25, 11, 23, 31, + 19, 25, 13, 6, 20, 52, 49, 52, 52, 54, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 34, 62, 62, 62, 62, 62, + 62, 54, 37, 36, 6, 82, 75, 97, 125, 62, 62, 62, + 57, 55, 53, 41, 44, 31, 32, 22, 19, 16, 65, 71, 3, + 0, 65, 39, 43, 40, 31, 40, 39, 23, 31, 34, 21, 6, + 10, 2, 86, 23, 12, 4, 79, 71, 69, 70, 66, 68, 73, + 69, 70, 67, 1, 70, 66, 65, 0, 62, 62, 62, 62, 62, + 60, 54, 36, 4, 66, 28, 21, 18, 15, 7, 3, 1, 66, + 76, 85, 81, 77, 81, 80, 73, 74, 83, 71, 67, 2, 66, + 66, 4, 4, 62, 62, 62, 62, 61, 57, 46, 29, 1 }, + + { + + 62, + 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 29, 60, + 62, 54, 14, 115, 6, 77, 64, 1, 14, 72, 12, 65, + 20, 62, 68, 91, 104, 124, 102, 67, 77, 64, 1, + 85, 93, 3, 18, 68, 80, 95, 8, 67, 85, 88, 5, 75, + 93, 9, 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, + 0, 0, 82, 86, 97, 71, 22, 1, 18, 77, 95, 124, + 96, 99, 65, 80, 92, 82, 108, 89, 100, 92, 125, + 91, 88, 95, 107, 18, 64, 7, 92, 73, 91, 86, 124, + 9, 3, 4, 69, 16, 68, 68, 87, 84, 77, 74, 76, 9, + 13, 67, 13, 21, 80, 0, 69, 67, 6, 75, 28, 64, 2, + 28, 37, 39, 34, 27, 92, 72, 72, 17, 14, 99, 10, + 10, 10, 3, 7, 7, 1, 4, 2, 6, 68, 6, 24, 12, 68, + 64, 2, 0, 13, 23, 19, 11, 15, 4, 5, 4, 29, 19, + 20, 77, 3, 69, 35, 23, 19, 14, 17, 19, 12, 16, + 24, 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 18, 27, + 10, 81, 8, 77, 17, 31, 83, 55, 62, 59, 58, 61, + 62, 56, 56, 52, 43, 35, 32, 41, 28, 71, 67, 4, + 67, 32, 30, 27, 33, 31, 24, 19, 21, 0, 4, 64, + 93, 88, 107, 75, 20, 18, 11, 0, 5, 69, 74, 81, + 100, 76, 39, 21, 15, 8, 5, 70, 82, 86, 117, 5, + 35, 28, 25, 20, 9, 5, 64, 73, 89, 70, 35, 32, + 21, 4, 6, 71, 80, 96, 5, 58, 49, 45, 36, 23, 5, + 69, 78, 84, 62, 105, 105, 86, 112, 108, 97, 108, + 104, 101, 105, 106, 110, 95, 94, 90, 92, 92, 85, + 67, 79, 84, 69, 3, 5, 2, 13, 13, 13, 8, 22, 17, + 13, 14, 11, 22, 16, 8, 22, 19, 13, 10, 14, 0, + 64, 68, 5, 70, 19, 32, 20, 10, 29, 25, 12, 23, + 30, 19, 25, 13, 6, 19, 52, 49, 52, 51, 53, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 33, 62, 62, 62, + 62, 62, 62, 53, 36, 35, 6, 81, 74, 95, 122, 62, + 62, 62, 56, 53, 52, 40, 42, 30, 31, 21, 18, 15, + 66, 71, 3, 0, 66, 38, 42, 39, 30, 39, 38, 22, + 30, 33, 20, 5, 9, 1, 86, 23, 12, 4, 78, 70, 68, + 69, 65, 67, 71, 68, 69, 66, 3, 68, 65, 0, 2, 62, + 62, 62, 62, 62, 58, 51, 34, 2, 65, 29, 22, 19, + 16, 8, 4, 2, 65, 75, 84, 80, 76, 80, 78, 71, 73, + 82, 70, 66, 3, 65, 65, 4, 4, 62, 62, 62, 62, 58, + 54, 43, 26, 64 }, + + { + + 62, + 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 28, 59, + 61, 54, 14, 113, 6, 76, 0, 1, 13, 72, 11, 66, + 19, 60, 70, 92, 105, 121, 101, 67, 76, 0, 1, 85, + 92, 3, 17, 68, 80, 94, 8, 67, 85, 88, 5, 75, 92, + 9, 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, 0, + 0, 81, 86, 97, 71, 21, 1, 18, 77, 95, 122, 94, + 97, 64, 78, 91, 81, 107, 88, 99, 91, 123, 91, + 88, 95, 106, 18, 64, 7, 91, 73, 90, 86, 123, 9, + 3, 4, 69, 16, 68, 68, 87, 84, 77, 74, 76, 9, 13, + 67, 13, 21, 80, 0, 69, 67, 6, 75, 27, 64, 2, 27, + 36, 38, 33, 26, 91, 72, 72, 16, 13, 99, 9, 10, + 10, 3, 7, 7, 2, 4, 2, 6, 68, 6, 23, 12, 69, 64, + 2, 64, 13, 22, 19, 11, 14, 4, 5, 4, 28, 19, 19, + 77, 3, 70, 34, 23, 19, 14, 17, 19, 12, 16, 24, + 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 17, 26, 9, + 81, 8, 77, 16, 30, 83, 53, 62, 57, 56, 59, 60, + 54, 54, 50, 41, 33, 30, 39, 26, 72, 67, 4, 68, + 31, 29, 26, 32, 29, 23, 18, 20, 64, 3, 65, 93, + 88, 106, 75, 20, 18, 11, 0, 5, 69, 74, 81, 99, + 75, 39, 21, 15, 8, 5, 70, 81, 85, 115, 5, 35, + 28, 25, 20, 9, 5, 64, 73, 88, 70, 35, 32, 21, 4, + 6, 71, 80, 95, 5, 57, 48, 44, 35, 23, 5, 69, 78, + 84, 62, 104, 104, 85, 111, 107, 96, 107, 103, + 100, 104, 105, 108, 94, 93, 90, 91, 91, 85, 68, + 79, 83, 69, 3, 4, 2, 12, 12, 12, 7, 21, 17, 13, + 14, 10, 21, 16, 8, 21, 18, 13, 10, 13, 0, 64, + 68, 5, 70, 18, 31, 19, 10, 28, 24, 12, 22, 29, + 19, 25, 12, 5, 17, 51, 48, 51, 50, 52, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 32, 62, 62, 62, 62, + 62, 62, 51, 35, 34, 6, 80, 74, 94, 120, 60, 60, + 62, 54, 51, 50, 38, 40, 29, 29, 20, 16, 14, 67, + 72, 2, 0, 67, 37, 41, 37, 28, 37, 36, 21, 28, + 31, 19, 4, 8, 0, 87, 22, 11, 3, 78, 70, 68, 68, + 65, 66, 70, 67, 68, 65, 4, 67, 64, 1, 3, 62, 62, + 62, 62, 60, 55, 48, 31, 0, 65, 29, 22, 19, 16, + 9, 4, 2, 65, 75, 84, 80, 75, 80, 77, 70, 73, 81, + 69, 65, 3, 65, 64, 4, 4, 62, 62, 62, 60, 55, 50, + 39, 23, 67 }, + + { + + 62, + 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 26, 57, + 60, 54, 14, 111, 6, 75, 1, 1, 12, 72, 10, 67, + 19, 58, 71, 93, 105, 118, 100, 67, 75, 1, 1, 84, + 91, 4, 17, 68, 79, 93, 7, 68, 85, 88, 5, 75, 92, + 9, 69, 80, 88, 65, 73, 73, 79, 70, 5, 22, 0, 0, + 0, 81, 86, 97, 70, 20, 1, 18, 77, 95, 120, 92, + 96, 1, 76, 90, 80, 105, 87, 98, 90, 121, 90, 88, + 94, 105, 18, 64, 7, 91, 73, 90, 85, 121, 9, 2, + 3, 70, 16, 68, 68, 86, 84, 76, 74, 75, 9, 13, + 67, 13, 20, 80, 0, 69, 67, 6, 75, 26, 64, 2, 26, + 35, 37, 32, 25, 91, 71, 72, 15, 13, 98, 9, 10, + 10, 3, 7, 7, 3, 4, 2, 6, 67, 6, 22, 12, 70, 64, + 2, 64, 12, 21, 19, 11, 13, 4, 5, 4, 26, 19, 18, + 77, 3, 70, 33, 23, 19, 14, 17, 19, 12, 16, 24, + 1, 16, 9, 9, 5, 0, 11, 5, 9, 10, 7, 16, 25, 9, + 81, 7, 77, 15, 28, 83, 52, 62, 55, 54, 57, 58, + 52, 52, 48, 39, 32, 29, 37, 24, 73, 67, 4, 68, + 30, 28, 25, 30, 28, 21, 17, 19, 65, 3, 65, 93, + 88, 106, 74, 20, 18, 11, 0, 5, 69, 74, 80, 98, + 75, 39, 21, 15, 8, 6, 69, 80, 84, 113, 5, 35, + 28, 25, 20, 10, 5, 64, 73, 88, 70, 35, 32, 20, + 4, 6, 71, 80, 94, 5, 57, 48, 43, 34, 23, 5, 69, + 77, 83, 62, 103, 103, 85, 110, 106, 95, 105, + 102, 99, 103, 103, 107, 94, 92, 90, 91, 89, 85, + 68, 79, 83, 69, 2, 4, 2, 11, 11, 11, 6, 21, 16, + 13, 13, 10, 21, 15, 8, 20, 18, 12, 10, 12, 0, + 65, 68, 5, 71, 18, 31, 18, 10, 27, 24, 12, 21, + 28, 18, 24, 11, 5, 16, 50, 47, 51, 49, 51, 61, + 62, 62, 62, 62, 62, 62, 62, 62, 31, 62, 62, 62, + 62, 62, 62, 49, 34, 33, 6, 79, 74, 93, 118, 58, + 58, 62, 52, 49, 48, 37, 38, 27, 28, 19, 15, 12, + 68, 73, 2, 64, 68, 36, 39, 36, 26, 35, 34, 19, + 27, 29, 17, 3, 6, 65, 88, 21, 10, 2, 78, 69, 68, + 68, 64, 66, 69, 66, 67, 64, 5, 66, 0, 3, 4, 62, + 62, 62, 62, 58, 52, 45, 28, 65, 64, 30, 23, 20, + 16, 10, 5, 2, 64, 74, 84, 79, 75, 79, 76, 69, + 73, 81, 69, 65, 3, 64, 0, 4, 4, 62, 62, 62, 57, + 52, 46, 35, 19, 69 }, + + { + + 62, + 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 25, 56, + 58, 54, 14, 108, 5, 74, 1, 1, 11, 72, 9, 68, 18, + 56, 73, 94, 106, 115, 99, 67, 74, 1, 1, 84, 90, + 4, 16, 68, 79, 93, 7, 68, 84, 88, 5, 75, 91, 8, + 70, 80, 88, 65, 72, 73, 78, 70, 5, 22, 0, 0, 0, + 80, 87, 97, 70, 19, 1, 18, 77, 95, 119, 91, 94, + 2, 75, 89, 79, 104, 85, 97, 89, 119, 90, 87, 94, + 104, 18, 64, 7, 90, 73, 89, 85, 120, 8, 2, 3, + 70, 16, 68, 68, 86, 84, 76, 74, 75, 9, 12, 67, + 13, 20, 80, 0, 69, 67, 6, 75, 26, 65, 2, 26, 34, + 36, 31, 24, 90, 71, 72, 14, 12, 98, 8, 10, 9, 3, + 7, 7, 4, 5, 2, 5, 67, 5, 21, 11, 71, 64, 2, 65, + 12, 20, 18, 10, 13, 5, 5, 4, 25, 18, 17, 77, 3, + 71, 33, 23, 19, 14, 17, 19, 12, 16, 23, 1, 16, + 9, 9, 5, 64, 11, 5, 9, 10, 7, 16, 24, 8, 81, 7, + 77, 14, 27, 83, 50, 62, 53, 52, 55, 56, 50, 50, + 46, 37, 30, 27, 34, 22, 74, 67, 3, 69, 29, 27, + 24, 29, 26, 20, 16, 17, 65, 2, 66, 93, 88, 105, + 74, 20, 18, 11, 0, 5, 69, 74, 80, 97, 74, 39, + 21, 15, 8, 6, 69, 80, 84, 111, 5, 35, 28, 25, + 20, 10, 5, 64, 73, 87, 70, 35, 31, 20, 4, 6, 71, + 80, 94, 5, 56, 47, 42, 33, 23, 5, 69, 77, 83, + 62, 102, 102, 84, 108, 105, 94, 104, 100, 98, + 101, 102, 105, 93, 92, 89, 90, 88, 84, 69, 79, + 82, 69, 2, 3, 1, 10, 10, 10, 5, 20, 16, 13, 13, + 9, 20, 15, 8, 19, 17, 12, 9, 11, 64, 65, 68, 5, + 71, 17, 30, 17, 10, 26, 23, 12, 20, 27, 18, 24, + 10, 4, 14, 49, 47, 50, 48, 49, 60, 62, 62, 62, + 62, 62, 62, 62, 62, 29, 62, 62, 62, 62, 62, 62, + 47, 33, 31, 6, 78, 73, 92, 116, 57, 56, 60, 51, + 47, 46, 35, 36, 26, 26, 17, 13, 11, 69, 74, 1, + 64, 69, 34, 38, 34, 25, 33, 32, 18, 25, 27, 16, + 2, 5, 66, 88, 20, 10, 1, 78, 69, 67, 67, 64, 65, + 68, 66, 66, 0, 6, 65, 1, 4, 5, 62, 62, 62, 61, + 55, 49, 42, 25, 68, 64, 30, 23, 20, 17, 10, 5, + 3, 64, 74, 83, 79, 74, 79, 75, 68, 73, 80, 68, + 64, 3, 64, 1, 4, 4, 62, 62, 61, 54, 49, 42, 31, + 16, 72 }, + + { + + 62, + 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 23, 54, + 57, 54, 14, 106, 5, 73, 2, 1, 11, 71, 8, 69, 18, + 54, 75, 95, 106, 112, 97, 67, 73, 2, 1, 84, 89, + 4, 16, 68, 79, 92, 7, 69, 84, 88, 5, 75, 90, 8, + 70, 80, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0, + 80, 87, 97, 69, 18, 1, 18, 76, 95, 117, 89, 93, + 4, 73, 87, 78, 103, 84, 96, 88, 117, 89, 87, 93, + 103, 18, 64, 7, 90, 73, 89, 84, 118, 8, 2, 3, + 70, 16, 68, 67, 85, 84, 76, 74, 74, 9, 12, 67, + 13, 20, 79, 0, 68, 67, 6, 75, 25, 65, 2, 25, 33, + 36, 30, 23, 89, 70, 72, 13, 12, 97, 8, 10, 9, 3, + 7, 7, 5, 5, 2, 5, 67, 5, 20, 11, 72, 64, 2, 65, + 11, 19, 18, 10, 12, 5, 5, 4, 24, 18, 16, 77, 3, + 71, 32, 23, 19, 14, 17, 19, 12, 16, 23, 1, 16, + 9, 9, 5, 64, 11, 5, 8, 10, 7, 15, 23, 8, 81, 6, + 77, 13, 26, 83, 49, 61, 52, 51, 53, 54, 48, 48, + 44, 35, 28, 25, 32, 21, 75, 67, 3, 69, 28, 26, + 23, 28, 25, 18, 15, 16, 66, 2, 66, 93, 88, 105, + 74, 20, 18, 11, 0, 5, 68, 73, 79, 96, 74, 39, + 21, 15, 8, 6, 68, 79, 83, 109, 5, 35, 28, 25, + 20, 10, 5, 64, 73, 86, 70, 36, 31, 19, 4, 6, 71, + 80, 93, 5, 56, 46, 41, 32, 23, 5, 69, 77, 82, + 62, 101, 101, 83, 107, 104, 93, 103, 99, 97, + 100, 100, 103, 92, 91, 89, 90, 87, 84, 69, 78, + 81, 69, 1, 3, 1, 10, 9, 9, 4, 19, 15, 13, 12, 9, + 20, 15, 8, 18, 16, 12, 9, 10, 64, 65, 68, 5, 71, + 16, 30, 17, 10, 25, 22, 12, 19, 26, 17, 23, 9, + 3, 12, 48, 46, 50, 47, 48, 58, 62, 62, 62, 62, + 62, 62, 62, 62, 28, 62, 62, 62, 62, 62, 61, 45, + 32, 30, 6, 77, 73, 91, 114, 55, 55, 58, 49, 45, + 44, 34, 34, 25, 24, 16, 11, 9, 70, 75, 1, 64, + 70, 33, 36, 32, 23, 32, 31, 16, 24, 26, 14, 1, + 4, 67, 89, 20, 9, 0, 77, 68, 67, 67, 0, 64, 67, + 65, 65, 1, 8, 64, 2, 5, 7, 62, 62, 62, 58, 53, + 46, 39, 22, 70, 64, 31, 24, 21, 17, 11, 5, 3, 0, + 73, 83, 79, 73, 78, 74, 67, 72, 79, 68, 64, 3, + 0, 2, 4, 4, 62, 62, 58, 51, 46, 39, 27, 12, 75 }, + + { + + 62, + 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 22, 53, + 56, 54, 14, 104, 5, 73, 3, 1, 10, 71, 7, 70, 17, + 53, 76, 96, 107, 109, 96, 67, 73, 3, 1, 83, 88, + 5, 15, 67, 78, 91, 6, 69, 84, 88, 5, 74, 90, 8, + 70, 79, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0, + 79, 87, 97, 69, 18, 0, 18, 76, 94, 115, 87, 91, + 5, 71, 86, 77, 101, 83, 95, 88, 116, 89, 87, 93, + 103, 19, 64, 7, 89, 72, 88, 84, 117, 8, 1, 2, + 71, 16, 68, 67, 85, 84, 75, 74, 74, 9, 12, 66, + 13, 19, 79, 0, 68, 67, 6, 75, 24, 65, 2, 24, 32, + 35, 30, 23, 89, 70, 72, 13, 11, 97, 7, 10, 9, 3, + 7, 7, 5, 5, 2, 5, 66, 5, 19, 11, 72, 65, 2, 66, + 11, 18, 18, 10, 11, 5, 5, 4, 22, 18, 15, 77, 3, + 72, 31, 23, 18, 14, 17, 19, 12, 16, 23, 1, 15, + 9, 8, 5, 64, 10, 4, 8, 9, 6, 14, 22, 7, 81, 6, + 76, 12, 24, 83, 47, 59, 50, 49, 51, 52, 46, 46, + 42, 33, 27, 24, 30, 19, 76, 67, 3, 70, 27, 25, + 22, 26, 23, 17, 14, 15, 67, 1, 67, 93, 88, 104, + 73, 20, 18, 11, 1, 5, 68, 73, 79, 95, 73, 38, + 21, 15, 8, 7, 68, 78, 82, 107, 5, 36, 28, 25, + 20, 11, 5, 64, 72, 86, 70, 36, 31, 19, 4, 6, 70, + 79, 92, 5, 55, 46, 40, 32, 23, 5, 68, 76, 82, + 62, 101, 100, 83, 106, 103, 92, 101, 98, 96, 99, + 99, 102, 92, 90, 89, 89, 85, 84, 70, 78, 81, 69, + 1, 2, 1, 9, 8, 8, 3, 19, 15, 13, 12, 8, 19, 14, + 8, 18, 16, 11, 9, 10, 64, 66, 68, 5, 72, 16, 29, + 16, 9, 24, 22, 13, 19, 25, 17, 23, 9, 3, 11, 47, + 45, 49, 46, 47, 57, 62, 62, 62, 62, 62, 62, 62, + 61, 27, 62, 62, 62, 62, 62, 59, 43, 31, 29, 6, + 76, 73, 89, 111, 53, 53, 56, 47, 43, 42, 32, 32, + 23, 23, 15, 10, 8, 71, 76, 0, 65, 71, 32, 35, + 31, 21, 30, 29, 15, 22, 24, 13, 64, 2, 69, 90, + 19, 8, 64, 77, 68, 67, 66, 0, 64, 65, 64, 64, 2, + 9, 1, 3, 7, 8, 62, 62, 60, 56, 50, 44, 36, 20, + 72, 0, 31, 24, 21, 17, 12, 6, 3, 0, 73, 83, 78, + 73, 78, 73, 66, 72, 79, 67, 0, 3, 0, 3, 4, 4, + 62, 62, 56, 48, 42, 35, 24, 9, 77 }, + + { + + 62, + 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 20, 51, + 54, 54, 14, 101, 4, 72, 3, 1, 9, 71, 6, 71, 17, + 51, 78, 97, 107, 106, 95, 67, 72, 3, 1, 83, 87, + 5, 15, 67, 78, 91, 6, 70, 83, 88, 5, 74, 89, 7, + 70, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0, + 79, 87, 97, 68, 17, 0, 18, 76, 94, 114, 85, 90, + 7, 69, 85, 76, 100, 81, 94, 87, 114, 88, 86, 92, + 102, 19, 64, 7, 89, 72, 88, 83, 115, 7, 1, 2, + 71, 16, 68, 67, 84, 84, 75, 74, 73, 9, 11, 66, + 13, 19, 79, 0, 68, 67, 6, 75, 24, 65, 2, 24, 31, + 34, 29, 22, 88, 69, 72, 12, 11, 96, 7, 10, 8, 3, + 7, 7, 6, 6, 2, 5, 66, 5, 18, 11, 73, 65, 2, 66, + 10, 17, 17, 10, 11, 6, 5, 4, 21, 17, 14, 77, 3, + 72, 31, 23, 18, 14, 17, 19, 12, 16, 23, 1, 15, + 9, 8, 5, 64, 10, 4, 7, 9, 6, 14, 21, 7, 81, 5, + 76, 11, 23, 83, 46, 57, 48, 47, 49, 50, 44, 44, + 40, 31, 25, 22, 27, 17, 77, 67, 2, 70, 26, 24, + 21, 25, 22, 15, 13, 14, 67, 1, 67, 93, 88, 104, + 73, 20, 18, 11, 1, 5, 68, 73, 78, 94, 73, 38, + 21, 15, 8, 7, 67, 77, 82, 105, 5, 36, 28, 25, + 20, 11, 5, 64, 72, 85, 70, 36, 30, 18, 4, 6, 70, + 79, 92, 5, 55, 45, 39, 31, 23, 5, 68, 76, 81, + 62, 100, 99, 82, 104, 102, 91, 100, 96, 95, 97, + 97, 100, 91, 89, 88, 89, 84, 83, 70, 78, 80, 69, + 0, 2, 0, 8, 7, 7, 2, 18, 14, 13, 11, 8, 19, 14, + 8, 17, 15, 11, 8, 9, 64, 66, 68, 5, 72, 15, 29, + 15, 9, 23, 21, 13, 18, 24, 16, 22, 8, 2, 9, 46, + 45, 49, 45, 45, 55, 62, 62, 62, 62, 62, 62, 62, + 59, 25, 62, 62, 62, 62, 62, 56, 41, 30, 28, 6, + 75, 72, 88, 109, 52, 51, 54, 46, 41, 40, 31, 30, + 22, 21, 13, 8, 6, 72, 77, 0, 65, 72, 30, 33, 29, + 20, 28, 27, 13, 21, 22, 11, 65, 1, 70, 90, 18, + 8, 65, 77, 67, 66, 66, 1, 0, 64, 0, 0, 3, 10, 2, + 4, 8, 9, 62, 61, 58, 53, 48, 41, 33, 17, 74, 0, + 32, 25, 22, 18, 13, 6, 4, 1, 72, 82, 78, 72, 77, + 72, 65, 72, 78, 67, 0, 3, 1, 4, 4, 4, 62, 62, + 53, 45, 39, 31, 20, 5, 80 }, + + { + + 62, + 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 19, 50, + 53, 54, 14, 99, 4, 71, 4, 1, 8, 71, 5, 73, 16, + 49, 80, 98, 108, 104, 94, 67, 71, 4, 1, 83, 86, + 5, 14, 67, 78, 90, 5, 70, 83, 89, 5, 74, 89, 7, + 71, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0, + 78, 88, 97, 68, 16, 0, 18, 76, 94, 112, 84, 88, + 8, 68, 84, 75, 99, 80, 93, 86, 112, 88, 86, 92, + 101, 19, 64, 7, 88, 72, 87, 83, 114, 7, 0, 1, + 72, 16, 68, 67, 84, 84, 75, 74, 73, 8, 11, 66, + 13, 18, 79, 0, 68, 67, 5, 75, 23, 66, 2, 23, 29, + 33, 28, 21, 88, 69, 72, 11, 10, 96, 6, 9, 8, 3, + 7, 7, 7, 6, 2, 4, 66, 4, 17, 10, 74, 65, 2, 67, + 10, 16, 17, 9, 10, 6, 5, 4, 19, 17, 13, 77, 3, + 73, 30, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, + 9, 8, 4, 65, 9, 3, 7, 8, 5, 13, 20, 6, 81, 5, + 76, 10, 21, 83, 44, 55, 46, 45, 47, 47, 42, 42, + 38, 29, 23, 20, 25, 15, 78, 67, 2, 71, 25, 22, + 19, 23, 20, 14, 11, 12, 68, 0, 68, 93, 88, 103, + 73, 20, 18, 11, 1, 5, 68, 73, 78, 93, 72, 38, + 21, 15, 8, 7, 67, 77, 81, 104, 5, 36, 28, 25, + 19, 11, 5, 64, 72, 85, 70, 36, 30, 18, 4, 6, 70, + 79, 91, 5, 54, 44, 38, 30, 22, 5, 68, 76, 81, + 62, 99, 98, 82, 103, 101, 91, 99, 95, 94, 96, + 96, 99, 91, 89, 88, 88, 83, 83, 71, 78, 80, 69, + 0, 1, 0, 7, 6, 5, 1, 17, 14, 13, 11, 7, 18, 13, + 7, 16, 14, 10, 8, 8, 65, 67, 68, 5, 73, 14, 28, + 14, 9, 22, 20, 13, 17, 23, 16, 22, 7, 1, 7, 45, + 44, 48, 43, 44, 54, 62, 62, 62, 62, 62, 62, 62, + 56, 24, 62, 62, 62, 62, 61, 54, 39, 28, 26, 6, + 75, 72, 87, 107, 50, 49, 52, 44, 38, 38, 29, 28, + 20, 19, 12, 6, 5, 73, 78, 64, 66, 73, 29, 32, + 27, 18, 26, 25, 12, 19, 20, 10, 66, 64, 72, 91, + 17, 7, 66, 77, 67, 66, 65, 1, 0, 0, 0, 1, 4, 11, + 3, 5, 9, 10, 61, 59, 56, 51, 45, 38, 30, 14, 77, + 0, 32, 25, 22, 18, 13, 6, 4, 1, 72, 82, 78, 72, + 77, 71, 64, 72, 78, 66, 1, 3, 1, 4, 4, 3, 62, + 61, 51, 42, 36, 27, 16, 2, 83 }, + + { + + 62, + 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 18, 49, + 52, 54, 14, 97, 4, 70, 5, 1, 8, 70, 4, 74, 15, + 47, 81, 99, 109, 101, 92, 67, 70, 5, 1, 82, 85, + 6, 13, 67, 77, 89, 5, 70, 83, 89, 5, 74, 88, 7, + 71, 79, 88, 0, 71, 71, 77, 68, 5, 22, 0, 0, 0, + 77, 88, 97, 68, 15, 0, 18, 75, 94, 110, 82, 86, + 9, 66, 82, 74, 97, 79, 91, 85, 110, 88, 86, 92, + 100, 19, 64, 7, 87, 72, 86, 82, 113, 7, 0, 1, + 72, 16, 68, 66, 83, 83, 74, 74, 73, 8, 11, 66, + 13, 18, 78, 0, 67, 67, 5, 74, 22, 66, 2, 22, 28, + 33, 27, 20, 87, 69, 71, 10, 9, 96, 5, 9, 8, 4, + 7, 7, 8, 6, 2, 4, 65, 4, 17, 10, 75, 65, 2, 68, + 10, 15, 17, 9, 9, 6, 5, 4, 18, 17, 13, 77, 3, + 74, 29, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, + 9, 8, 4, 65, 9, 3, 7, 8, 5, 12, 20, 6, 81, 5, + 76, 9, 20, 83, 42, 54, 45, 44, 45, 45, 41, 41, + 36, 27, 22, 19, 23, 14, 79, 67, 2, 72, 24, 21, + 18, 22, 19, 13, 10, 11, 69, 64, 69, 93, 87, 102, + 72, 21, 18, 11, 1, 6, 67, 72, 77, 92, 71, 38, + 21, 15, 8, 8, 67, 76, 80, 102, 5, 36, 28, 25, + 19, 12, 5, 64, 72, 84, 70, 37, 30, 18, 4, 7, 70, + 79, 90, 5, 54, 44, 38, 29, 22, 5, 68, 75, 80, + 62, 98, 97, 81, 102, 99, 90, 97, 94, 92, 95, 95, + 97, 90, 88, 88, 87, 81, 83, 72, 77, 79, 69, 0, + 0, 0, 7, 5, 4, 0, 17, 14, 13, 11, 7, 17, 13, 7, + 15, 14, 10, 8, 7, 65, 67, 67, 6, 73, 14, 27, 14, + 9, 22, 20, 13, 16, 22, 16, 22, 6, 1, 6, 45, 43, + 47, 42, 43, 53, 60, 60, 62, 62, 62, 62, 62, 54, + 23, 62, 62, 62, 62, 58, 52, 38, 27, 25, 6, 74, + 72, 86, 105, 48, 48, 50, 42, 36, 37, 28, 26, 19, + 18, 11, 5, 4, 74, 78, 64, 66, 74, 28, 31, 26, + 16, 25, 24, 11, 18, 19, 9, 67, 65, 73, 92, 17, + 6, 66, 76, 67, 66, 64, 2, 1, 1, 1, 2, 5, 13, 4, + 6, 11, 12, 60, 58, 54, 49, 42, 35, 27, 11, 79, + 1, 32, 25, 23, 18, 14, 7, 4, 2, 71, 82, 77, 71, + 77, 70, 1, 71, 77, 65, 2, 3, 2, 5, 4, 3, 62, 59, + 49, 40, 33, 24, 12, 64, 85 }, + + { + + 62, + 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 16, 47, + 50, 54, 14, 94, 3, 69, 5, 1, 7, 70, 3, 75, 15, + 45, 83, 100, 109, 98, 91, 67, 69, 5, 1, 82, 84, + 6, 13, 67, 77, 89, 5, 71, 82, 89, 5, 74, 87, 6, + 71, 79, 88, 1, 70, 71, 76, 67, 5, 22, 0, 0, 0, + 77, 88, 97, 67, 14, 0, 18, 75, 94, 109, 80, 85, + 11, 64, 81, 73, 96, 77, 90, 84, 108, 87, 85, 91, + 99, 19, 64, 7, 87, 72, 86, 82, 111, 6, 0, 1, 72, + 16, 68, 66, 83, 83, 74, 74, 72, 8, 10, 66, 13, + 18, 78, 0, 67, 67, 5, 74, 22, 66, 2, 22, 27, 32, + 26, 19, 86, 68, 71, 9, 9, 95, 5, 9, 7, 4, 7, 7, + 9, 7, 2, 4, 65, 4, 16, 10, 76, 65, 2, 68, 9, 14, + 16, 9, 9, 7, 5, 4, 17, 16, 12, 77, 3, 74, 29, + 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, 9, 8, 4, + 65, 9, 3, 6, 8, 5, 12, 19, 5, 81, 4, 76, 8, 19, + 83, 41, 52, 43, 42, 43, 43, 39, 39, 34, 25, 20, + 17, 20, 12, 80, 67, 1, 72, 23, 20, 17, 21, 17, + 11, 9, 10, 69, 64, 69, 93, 87, 102, 72, 21, 18, + 11, 1, 6, 67, 72, 77, 91, 71, 38, 21, 15, 8, 8, + 66, 75, 80, 100, 5, 36, 28, 25, 19, 12, 5, 64, + 72, 83, 70, 37, 29, 17, 4, 7, 70, 79, 90, 5, 53, + 43, 37, 28, 22, 5, 68, 75, 80, 62, 97, 96, 80, + 100, 98, 89, 96, 92, 91, 93, 93, 95, 89, 87, 87, + 87, 80, 82, 72, 77, 78, 69, 64, 0, 64, 6, 4, 3, + 64, 16, 13, 13, 10, 6, 17, 13, 7, 14, 13, 10, 7, + 6, 65, 67, 67, 6, 73, 13, 27, 13, 9, 21, 19, 13, + 15, 21, 15, 21, 5, 0, 4, 44, 43, 47, 41, 41, 51, + 58, 58, 62, 62, 62, 62, 62, 52, 21, 59, 62, 59, + 62, 56, 49, 36, 26, 24, 6, 73, 71, 85, 103, 47, + 46, 48, 41, 34, 35, 26, 24, 18, 16, 9, 3, 2, 75, + 79, 65, 66, 75, 26, 29, 24, 15, 23, 22, 9, 16, + 17, 7, 68, 66, 74, 92, 16, 6, 67, 76, 66, 65, + 64, 2, 2, 2, 2, 3, 6, 14, 5, 7, 12, 13, 60, 56, + 52, 46, 40, 32, 24, 8, 81, 1, 33, 26, 23, 19, + 15, 7, 5, 2, 71, 81, 77, 70, 76, 69, 2, 71, 76, + 65, 2, 3, 2, 6, 4, 3, 62, 57, 46, 37, 30, 20, 8, + 68, 88 }, + + { + + 62, + 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 15, 46, + 49, 54, 14, 92, 3, 69, 6, 1, 6, 70, 2, 76, 14, + 44, 84, 101, 110, 95, 90, 67, 69, 6, 1, 81, 83, + 7, 12, 66, 76, 88, 4, 71, 82, 89, 5, 73, 87, 6, + 71, 78, 88, 1, 70, 71, 76, 67, 5, 22, 0, 0, 0, + 76, 88, 97, 67, 14, 64, 18, 75, 93, 107, 78, 83, + 12, 1, 80, 72, 94, 76, 89, 84, 107, 87, 85, 91, + 99, 20, 64, 7, 86, 71, 85, 81, 110, 6, 64, 0, + 73, 16, 68, 66, 82, 83, 73, 74, 72, 8, 10, 65, + 13, 17, 78, 0, 67, 67, 5, 74, 21, 66, 2, 21, 26, + 31, 26, 19, 86, 68, 71, 9, 8, 95, 4, 9, 7, 4, 7, + 7, 9, 7, 2, 4, 64, 4, 15, 10, 76, 66, 2, 69, 9, + 13, 16, 9, 8, 7, 5, 4, 15, 16, 11, 77, 3, 75, + 28, 22, 17, 14, 17, 18, 11, 16, 22, 0, 13, 9, 7, + 4, 65, 8, 2, 6, 7, 4, 11, 18, 5, 81, 4, 75, 7, + 17, 83, 39, 50, 41, 40, 41, 41, 37, 37, 32, 23, + 19, 16, 18, 10, 81, 67, 1, 73, 22, 19, 16, 19, + 16, 10, 8, 9, 70, 65, 70, 93, 87, 101, 71, 21, + 18, 11, 2, 6, 67, 72, 76, 90, 70, 37, 21, 15, 8, + 9, 66, 74, 79, 98, 5, 37, 28, 25, 19, 13, 5, 64, + 71, 83, 70, 37, 29, 17, 4, 7, 69, 78, 89, 5, 53, + 43, 36, 28, 22, 5, 67, 74, 79, 62, 97, 95, 80, + 99, 97, 88, 94, 91, 90, 92, 92, 94, 89, 86, 87, + 86, 78, 82, 73, 77, 78, 69, 64, 64, 64, 5, 3, 2, + 65, 16, 13, 13, 10, 6, 16, 12, 7, 14, 13, 9, 7, + 6, 65, 68, 67, 6, 74, 13, 26, 12, 8, 20, 19, 14, + 15, 20, 15, 21, 5, 0, 3, 43, 42, 46, 40, 40, 50, + 56, 56, 61, 60, 62, 62, 60, 49, 20, 57, 62, 56, + 62, 53, 47, 34, 25, 23, 6, 72, 71, 83, 100, 45, + 44, 46, 39, 32, 33, 25, 22, 16, 15, 8, 2, 1, 76, + 80, 65, 67, 76, 25, 28, 23, 13, 21, 20, 8, 15, + 15, 6, 70, 68, 76, 93, 15, 5, 68, 76, 66, 65, 0, + 3, 2, 4, 3, 4, 7, 15, 7, 8, 14, 14, 59, 55, 50, + 44, 37, 30, 21, 6, 83, 2, 33, 26, 24, 19, 16, 8, + 5, 3, 70, 81, 76, 70, 76, 68, 3, 71, 76, 64, 3, + 3, 3, 7, 4, 3, 62, 55, 44, 34, 26, 16, 5, 71, 90 }, + + { + + 62, + 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 13, 44, + 48, 54, 14, 90, 3, 68, 7, 1, 5, 70, 1, 77, 14, + 42, 86, 102, 110, 92, 89, 67, 68, 7, 1, 81, 82, + 7, 12, 66, 76, 87, 4, 72, 82, 89, 5, 73, 86, 6, + 72, 78, 88, 2, 70, 71, 76, 66, 5, 22, 0, 0, 0, + 76, 89, 97, 66, 13, 64, 18, 75, 93, 105, 77, 82, + 14, 2, 79, 71, 93, 75, 88, 83, 105, 86, 85, 90, + 98, 20, 64, 7, 86, 71, 85, 81, 108, 6, 64, 0, + 73, 16, 68, 66, 82, 83, 73, 74, 71, 8, 10, 65, + 13, 17, 78, 0, 67, 67, 5, 74, 20, 67, 2, 20, 25, + 30, 25, 18, 85, 67, 71, 8, 8, 94, 4, 9, 7, 4, 7, + 7, 10, 7, 2, 3, 64, 3, 14, 9, 77, 66, 2, 69, 8, + 12, 16, 8, 7, 7, 5, 4, 14, 16, 10, 77, 3, 75, + 27, 22, 17, 14, 17, 18, 11, 16, 21, 0, 13, 9, 7, + 4, 66, 8, 2, 5, 7, 4, 10, 17, 4, 81, 3, 75, 6, + 16, 83, 38, 48, 39, 38, 39, 39, 35, 35, 30, 21, + 17, 14, 16, 8, 82, 67, 1, 73, 21, 18, 15, 18, + 14, 8, 7, 7, 71, 65, 70, 93, 87, 101, 71, 21, + 18, 11, 2, 6, 67, 72, 76, 89, 70, 37, 21, 15, 8, + 9, 65, 74, 78, 96, 5, 37, 28, 25, 19, 13, 5, 64, + 71, 82, 70, 37, 29, 16, 4, 7, 69, 78, 88, 5, 52, + 42, 35, 27, 22, 5, 67, 74, 79, 62, 96, 94, 79, + 98, 96, 87, 93, 90, 89, 91, 90, 92, 88, 86, 87, + 86, 77, 82, 73, 77, 77, 69, 65, 64, 64, 4, 2, 1, + 66, 15, 12, 13, 9, 5, 16, 12, 7, 13, 12, 9, 7, + 5, 66, 68, 67, 6, 74, 12, 26, 11, 8, 19, 18, 14, + 14, 19, 14, 20, 4, 64, 1, 42, 41, 46, 39, 39, + 48, 54, 54, 59, 57, 62, 62, 57, 47, 19, 54, 62, + 53, 58, 50, 44, 32, 24, 21, 6, 71, 71, 82, 98, + 43, 42, 44, 37, 30, 31, 23, 20, 15, 13, 7, 0, + 64, 77, 81, 66, 67, 77, 24, 26, 21, 11, 19, 18, + 6, 13, 13, 4, 71, 69, 77, 94, 14, 4, 69, 76, 65, + 65, 0, 3, 3, 5, 3, 5, 8, 16, 8, 9, 15, 15, 59, + 53, 48, 41, 35, 27, 18, 3, 86, 2, 34, 27, 24, + 19, 16, 8, 5, 3, 70, 81, 76, 69, 75, 67, 4, 71, + 75, 64, 3, 3, 3, 8, 4, 3, 61, 53, 41, 31, 23, + 12, 1, 75, 93 }, + + { + + 62, + 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 12, 43, + 46, 54, 14, 87, 2, 67, 7, 1, 5, 69, 0, 78, 13, + 40, 88, 103, 111, 89, 87, 67, 67, 7, 1, 81, 81, + 7, 11, 66, 76, 87, 4, 72, 81, 89, 5, 73, 85, 5, + 72, 78, 88, 2, 69, 70, 75, 66, 5, 22, 0, 0, 0, + 75, 89, 97, 66, 12, 64, 18, 74, 93, 104, 75, 80, + 15, 4, 77, 70, 92, 73, 87, 82, 103, 86, 84, 90, + 97, 20, 64, 7, 85, 71, 84, 80, 107, 5, 64, 0, + 73, 16, 68, 65, 81, 83, 73, 74, 71, 8, 9, 65, + 13, 17, 77, 0, 66, 67, 5, 74, 20, 67, 2, 20, 24, + 30, 24, 17, 84, 67, 71, 7, 7, 94, 3, 9, 6, 4, 7, + 7, 11, 8, 2, 3, 64, 3, 13, 9, 78, 66, 2, 70, 8, + 11, 15, 8, 7, 8, 5, 4, 13, 15, 9, 77, 3, 76, 27, + 22, 17, 14, 17, 18, 11, 16, 21, 0, 13, 9, 7, 4, + 66, 8, 2, 5, 7, 4, 10, 16, 4, 81, 3, 75, 5, 15, + 83, 36, 46, 38, 37, 37, 37, 33, 33, 28, 19, 15, + 12, 13, 7, 83, 67, 0, 74, 20, 17, 14, 17, 13, 7, + 6, 6, 71, 66, 71, 93, 87, 100, 71, 21, 18, 11, + 2, 6, 66, 71, 75, 88, 69, 37, 21, 15, 8, 9, 65, + 73, 78, 94, 5, 37, 28, 25, 19, 13, 5, 64, 71, + 81, 70, 38, 28, 16, 4, 7, 69, 78, 88, 5, 52, 41, + 34, 26, 22, 5, 67, 74, 78, 62, 95, 93, 78, 96, + 95, 86, 92, 88, 88, 89, 89, 90, 87, 85, 86, 85, + 76, 81, 74, 76, 76, 69, 65, 65, 65, 4, 1, 0, 67, + 14, 12, 13, 9, 5, 15, 12, 7, 12, 11, 9, 6, 4, + 66, 68, 67, 6, 74, 11, 25, 11, 8, 18, 17, 14, + 13, 18, 14, 20, 3, 65, 64, 41, 41, 45, 38, 37, + 47, 52, 52, 57, 55, 62, 61, 54, 45, 17, 51, 62, + 50, 54, 48, 42, 30, 23, 20, 6, 70, 70, 81, 96, + 42, 41, 42, 36, 28, 29, 22, 18, 14, 11, 5, 65, + 65, 78, 82, 66, 67, 78, 22, 25, 19, 10, 18, 17, + 5, 12, 12, 3, 72, 70, 78, 94, 14, 4, 70, 75, 65, + 64, 1, 4, 4, 6, 4, 6, 9, 18, 9, 10, 16, 17, 58, + 51, 46, 39, 32, 24, 15, 0, 88, 2, 34, 27, 25, + 20, 17, 8, 6, 4, 69, 80, 76, 68, 75, 66, 5, 70, + 74, 0, 4, 3, 4, 9, 4, 3, 59, 51, 39, 28, 20, 9, + 66, 78, 96 }, + + { + + 61, + 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 10, 41, + 45, 54, 14, 85, 2, 66, 8, 1, 4, 69, 64, 79, 13, + 38, 89, 104, 111, 86, 86, 67, 66, 8, 1, 80, 80, + 8, 11, 66, 75, 86, 3, 73, 81, 89, 5, 73, 85, 5, + 72, 78, 88, 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, + 75, 89, 97, 65, 11, 64, 18, 74, 93, 102, 73, 79, + 17, 6, 76, 69, 90, 72, 86, 81, 101, 85, 84, 89, + 96, 20, 64, 7, 85, 71, 84, 80, 105, 5, 65, 64, + 74, 16, 68, 65, 81, 83, 72, 74, 70, 8, 9, 65, + 13, 16, 77, 0, 66, 67, 5, 74, 19, 67, 2, 19, 23, + 29, 23, 16, 84, 66, 71, 6, 7, 93, 3, 9, 6, 4, 7, + 7, 12, 8, 2, 3, 0, 3, 12, 9, 79, 66, 2, 70, 7, + 10, 15, 8, 6, 8, 5, 4, 11, 15, 8, 77, 3, 76, 26, + 22, 17, 14, 17, 18, 11, 16, 21, 0, 12, 9, 7, 4, + 66, 7, 1, 4, 6, 3, 9, 15, 3, 81, 2, 75, 4, 13, + 83, 35, 44, 36, 35, 35, 35, 31, 31, 26, 17, 14, + 11, 11, 5, 84, 67, 0, 74, 19, 16, 13, 15, 11, 5, + 5, 5, 72, 66, 71, 93, 87, 100, 70, 21, 18, 11, + 2, 6, 66, 71, 75, 87, 69, 37, 21, 15, 8, 10, 64, + 72, 77, 92, 5, 37, 28, 25, 19, 14, 5, 64, 71, + 81, 70, 38, 28, 15, 4, 7, 69, 78, 87, 5, 51, 41, + 33, 25, 22, 5, 67, 73, 78, 62, 94, 92, 78, 95, + 94, 85, 90, 87, 87, 88, 87, 89, 87, 84, 86, 85, + 74, 81, 74, 76, 76, 69, 66, 65, 65, 3, 0, 64, + 68, 14, 11, 13, 8, 4, 15, 11, 7, 11, 11, 8, 6, + 3, 66, 69, 67, 6, 75, 11, 25, 10, 8, 17, 17, 14, + 12, 17, 13, 19, 2, 65, 65, 40, 40, 45, 37, 36, + 45, 50, 50, 55, 52, 60, 59, 51, 42, 16, 48, 62, + 47, 50, 45, 39, 28, 22, 19, 6, 69, 70, 80, 94, + 40, 39, 40, 34, 26, 27, 20, 16, 12, 10, 4, 66, + 67, 79, 83, 67, 68, 79, 21, 23, 18, 8, 16, 15, + 3, 10, 10, 1, 73, 72, 80, 95, 13, 3, 71, 75, 64, + 64, 1, 4, 4, 7, 5, 7, 10, 19, 10, 11, 18, 18, + 58, 50, 44, 36, 30, 21, 12, 66, 90, 3, 35, 28, + 25, 20, 18, 9, 6, 4, 69, 80, 75, 68, 74, 65, 6, + 70, 74, 0, 4, 3, 4, 10, 4, 3, 58, 49, 36, 25, + 17, 5, 70, 82, 98 }, + + { + + 60, + 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 9, 40, 44, + 54, 14, 83, 2, 65, 9, 1, 3, 69, 65, 80, 12, 36, + 91, 105, 112, 83, 85, 67, 65, 9, 1, 80, 79, 8, + 10, 66, 75, 85, 3, 73, 81, 89, 5, 73, 84, 5, 72, + 78, 88, 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, 74, + 89, 97, 65, 10, 64, 18, 74, 93, 100, 71, 77, 18, + 8, 75, 68, 89, 71, 85, 80, 99, 85, 84, 89, 95, + 20, 64, 7, 84, 71, 83, 79, 104, 5, 65, 64, 74, + 16, 68, 65, 80, 83, 72, 74, 70, 8, 9, 65, 13, + 16, 77, 0, 66, 67, 5, 74, 18, 67, 2, 18, 22, 28, + 22, 15, 83, 66, 71, 5, 6, 93, 2, 9, 6, 4, 7, 7, + 13, 8, 2, 3, 0, 3, 11, 9, 80, 66, 2, 71, 7, 9, + 15, 8, 5, 8, 5, 4, 10, 15, 7, 77, 3, 77, 25, 22, + 17, 14, 17, 18, 11, 16, 21, 0, 12, 9, 7, 4, 66, + 7, 1, 4, 6, 3, 8, 14, 3, 81, 2, 75, 3, 12, 83, + 33, 42, 34, 33, 33, 33, 29, 29, 24, 15, 12, 9, + 9, 3, 85, 67, 0, 75, 18, 15, 12, 14, 10, 4, 4, + 4, 73, 67, 72, 93, 87, 99, 70, 21, 18, 11, 2, 6, + 66, 71, 74, 86, 68, 37, 21, 15, 8, 10, 64, 71, + 76, 90, 5, 37, 28, 25, 19, 14, 5, 64, 71, 80, + 70, 38, 28, 15, 4, 7, 69, 78, 86, 5, 51, 40, 32, + 24, 22, 5, 67, 73, 77, 62, 93, 91, 77, 94, 93, + 84, 89, 86, 86, 87, 86, 87, 86, 83, 86, 84, 73, + 81, 75, 76, 75, 69, 66, 66, 65, 2, 64, 65, 69, + 13, 11, 13, 8, 4, 14, 11, 7, 10, 10, 8, 6, 2, + 66, 69, 67, 6, 75, 10, 24, 9, 8, 16, 16, 14, 11, + 16, 13, 19, 1, 66, 67, 39, 39, 44, 36, 35, 44, + 48, 48, 53, 50, 57, 56, 48, 40, 15, 45, 59, 44, + 46, 42, 37, 26, 21, 18, 6, 68, 70, 79, 92, 38, + 37, 38, 32, 24, 25, 19, 14, 11, 8, 3, 68, 68, + 80, 84, 67, 68, 80, 20, 22, 16, 6, 14, 13, 2, 9, + 8, 0, 74, 73, 81, 96, 12, 2, 72, 75, 64, 64, 2, + 5, 5, 8, 6, 8, 11, 20, 11, 12, 19, 19, 57, 48, + 42, 34, 27, 18, 9, 69, 92, 3, 35, 28, 26, 20, + 19, 9, 6, 5, 68, 80, 75, 67, 74, 64, 7, 70, 73, + 1, 5, 3, 5, 11, 4, 3, 57, 47, 34, 22, 14, 1, 74, + 85, 101 }, + + { + + 58, + 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 7, 38, 42, + 53, 14, 81, 1, 65, 9, 0, 2, 69, 67, 82, 11, 34, + 93, 106, 113, 81, 84, 68, 65, 9, 0, 80, 78, 8, + 9, 66, 75, 85, 2, 74, 81, 90, 5, 73, 84, 4, 73, + 78, 88, 3, 69, 70, 75, 65, 4, 22, 0, 0, 0, 74, + 90, 97, 65, 9, 65, 18, 74, 93, 99, 70, 76, 19, + 9, 74, 67, 88, 70, 84, 80, 98, 85, 84, 89, 95, + 20, 64, 7, 84, 71, 83, 79, 103, 4, 66, 65, 75, + 16, 68, 65, 80, 83, 72, 74, 70, 7, 8, 65, 12, + 15, 77, 64, 66, 67, 4, 74, 17, 68, 1, 17, 20, + 27, 21, 14, 83, 66, 71, 4, 5, 93, 1, 8, 5, 4, 7, + 7, 13, 8, 2, 2, 0, 2, 10, 8, 81, 67, 1, 72, 6, + 8, 14, 7, 4, 8, 5, 4, 8, 14, 6, 77, 3, 78, 24, + 21, 16, 14, 17, 17, 10, 16, 20, 64, 11, 9, 6, 3, + 67, 6, 0, 3, 5, 2, 7, 13, 2, 81, 1, 75, 2, 10, + 83, 31, 40, 32, 31, 31, 30, 27, 27, 22, 13, 10, + 7, 6, 1, 87, 68, 64, 76, 17, 13, 10, 12, 8, 2, + 2, 2, 74, 68, 73, 93, 87, 99, 70, 21, 18, 11, 2, + 6, 66, 71, 74, 85, 68, 36, 21, 15, 8, 10, 64, + 71, 76, 89, 4, 37, 28, 24, 18, 14, 5, 64, 71, + 80, 70, 38, 27, 14, 3, 7, 69, 78, 86, 5, 50, 39, + 31, 23, 21, 5, 67, 73, 77, 62, 93, 90, 77, 93, + 92, 84, 88, 85, 85, 86, 85, 86, 86, 83, 86, 84, + 72, 81, 76, 76, 75, 69, 67, 67, 66, 1, 65, 67, + 71, 12, 10, 13, 7, 3, 13, 10, 6, 9, 9, 7, 5, 1, + 67, 70, 67, 6, 76, 9, 23, 8, 7, 15, 15, 14, 10, + 14, 12, 18, 0, 67, 69, 38, 38, 43, 34, 33, 42, + 46, 46, 50, 47, 54, 53, 45, 37, 13, 42, 55, 41, + 41, 39, 34, 24, 19, 16, 6, 68, 70, 78, 90, 36, + 35, 36, 30, 21, 23, 17, 11, 9, 6, 1, 70, 70, 81, + 85, 68, 69, 82, 18, 20, 14, 4, 12, 11, 0, 7, 6, + 65, 76, 75, 83, 97, 11, 1, 73, 75, 64, 64, 2, 5, + 5, 9, 6, 9, 11, 21, 12, 13, 20, 20, 56, 46, 39, + 31, 24, 15, 5, 72, 95, 3, 35, 28, 26, 20, 19, 9, + 6, 5, 68, 80, 75, 67, 74, 0, 8, 70, 73, 1, 5, 3, + 5, 11, 4, 2, 55, 44, 31, 19, 10, 66, 78, 89, 104 }, + + { + + 57, + 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 6, 37, 41, + 53, 14, 78, 1, 64, 10, 0, 2, 68, 68, 83, 11, 33, + 94, 107, 113, 78, 82, 68, 64, 10, 0, 79, 76, 9, + 9, 65, 74, 84, 2, 74, 80, 90, 5, 72, 83, 4, 73, + 77, 88, 4, 68, 69, 74, 64, 4, 22, 0, 0, 0, 73, + 90, 97, 64, 9, 65, 18, 73, 92, 97, 68, 74, 21, + 11, 72, 66, 86, 68, 82, 79, 96, 84, 83, 88, 94, + 21, 0, 8, 83, 70, 82, 78, 101, 4, 66, 65, 75, + 17, 68, 64, 79, 82, 71, 73, 69, 7, 8, 64, 12, + 15, 76, 64, 65, 67, 4, 73, 17, 68, 1, 17, 19, + 27, 21, 14, 82, 65, 70, 4, 5, 92, 1, 8, 5, 5, 7, + 7, 14, 9, 3, 2, 1, 2, 10, 8, 81, 67, 1, 72, 6, + 7, 14, 7, 4, 9, 6, 4, 7, 14, 6, 76, 3, 78, 24, + 21, 16, 14, 17, 17, 10, 16, 20, 64, 11, 9, 6, 3, + 67, 6, 0, 3, 5, 2, 7, 13, 2, 80, 1, 74, 2, 9, + 82, 30, 39, 31, 30, 29, 28, 26, 26, 20, 12, 9, + 6, 4, 0, 88, 68, 64, 76, 16, 12, 9, 11, 7, 1, 1, + 1, 74, 68, 73, 92, 86, 98, 69, 22, 18, 11, 3, 7, + 65, 70, 73, 83, 67, 36, 21, 15, 8, 11, 0, 70, + 75, 87, 4, 38, 29, 24, 18, 15, 5, 64, 70, 79, + 70, 39, 27, 14, 3, 8, 68, 77, 85, 5, 50, 39, 31, + 23, 21, 5, 66, 72, 76, 62, 92, 89, 76, 91, 90, + 83, 86, 83, 83, 84, 83, 84, 85, 82, 85, 83, 70, + 80, 76, 75, 74, 68, 67, 67, 66, 1, 65, 68, 72, + 12, 10, 14, 7, 3, 13, 10, 6, 9, 9, 7, 5, 1, 67, + 70, 66, 7, 76, 9, 23, 8, 7, 15, 15, 15, 10, 13, + 12, 18, 0, 67, 70, 38, 38, 43, 33, 32, 41, 44, + 44, 48, 45, 52, 51, 43, 35, 12, 40, 52, 38, 37, + 37, 32, 23, 18, 15, 6, 67, 69, 76, 87, 35, 34, + 35, 29, 19, 22, 16, 9, 8, 5, 0, 71, 71, 82, 85, + 68, 69, 83, 17, 19, 13, 3, 11, 10, 64, 6, 5, 66, + 77, 76, 84, 97, 11, 1, 73, 74, 0, 0, 3, 6, 6, + 11, 7, 10, 12, 23, 14, 14, 22, 22, 56, 45, 37, + 29, 22, 13, 2, 74, 97, 4, 36, 29, 27, 21, 20, + 10, 7, 6, 67, 79, 74, 66, 73, 2, 10, 69, 72, 2, + 6, 4, 6, 12, 4, 2, 54, 42, 29, 17, 7, 69, 81, + 92, 106 }, + + { + + 56, + 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 5, 36, 40, + 53, 14, 76, 1, 0, 11, 0, 1, 68, 69, 84, 10, 31, + 96, 108, 114, 75, 81, 68, 0, 11, 0, 79, 75, 9, + 8, 65, 74, 83, 2, 74, 80, 90, 5, 72, 82, 4, 73, + 77, 88, 4, 68, 69, 74, 64, 4, 22, 0, 0, 0, 72, + 90, 97, 64, 8, 65, 18, 73, 92, 95, 66, 72, 22, + 13, 71, 65, 85, 67, 81, 78, 94, 84, 83, 88, 93, + 21, 0, 8, 82, 70, 81, 78, 100, 4, 66, 65, 75, + 17, 68, 64, 79, 82, 71, 73, 69, 7, 8, 64, 12, + 15, 76, 64, 65, 67, 4, 73, 16, 68, 1, 16, 18, + 26, 20, 13, 81, 65, 70, 3, 4, 92, 0, 8, 5, 5, 7, + 7, 15, 9, 3, 2, 1, 2, 9, 8, 82, 67, 1, 73, 6, 6, + 14, 7, 3, 9, 6, 4, 6, 14, 5, 76, 3, 79, 23, 21, + 16, 14, 17, 17, 10, 16, 20, 64, 11, 9, 6, 3, 67, + 6, 0, 3, 5, 2, 6, 12, 1, 80, 1, 74, 1, 8, 82, + 28, 37, 29, 28, 27, 26, 24, 24, 18, 10, 7, 4, 2, + 65, 89, 68, 64, 77, 15, 11, 8, 10, 5, 0, 0, 0, + 75, 69, 74, 92, 86, 97, 69, 22, 18, 11, 3, 7, + 65, 70, 73, 82, 66, 36, 21, 15, 8, 11, 0, 69, + 74, 85, 4, 38, 29, 24, 18, 15, 5, 64, 70, 78, + 70, 39, 27, 14, 3, 8, 68, 77, 84, 5, 49, 38, 30, + 22, 21, 5, 66, 72, 76, 62, 91, 88, 75, 90, 89, + 82, 85, 82, 82, 83, 82, 82, 84, 81, 85, 82, 69, + 80, 77, 75, 73, 68, 67, 68, 66, 0, 66, 69, 73, + 11, 10, 14, 7, 2, 12, 10, 6, 8, 8, 7, 5, 0, 67, + 70, 66, 7, 76, 8, 22, 7, 7, 14, 14, 15, 9, 12, + 12, 18, 64, 68, 72, 37, 37, 42, 32, 31, 40, 42, + 42, 46, 43, 49, 48, 40, 33, 11, 37, 49, 35, 33, + 34, 30, 21, 17, 14, 6, 66, 69, 75, 85, 33, 32, + 33, 27, 17, 20, 14, 7, 7, 3, 64, 73, 72, 83, 86, + 69, 69, 84, 16, 18, 11, 1, 9, 8, 65, 4, 3, 67, + 78, 77, 85, 98, 10, 0, 74, 74, 0, 0, 4, 6, 7, + 12, 8, 11, 13, 24, 15, 15, 23, 23, 55, 43, 35, + 27, 19, 10, 64, 77, 99, 4, 36, 29, 27, 21, 21, + 10, 7, 6, 67, 79, 74, 65, 73, 3, 11, 69, 71, 3, + 7, 4, 6, 13, 4, 2, 53, 40, 27, 14, 4, 73, 85, + 95, 109 }, + + { + + 55, + 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 3, 34, 39, + 53, 14, 74, 1, 1, 12, 0, 0, 68, 70, 85, 10, 29, + 97, 109, 114, 72, 80, 68, 1, 12, 0, 78, 74, 10, + 8, 65, 73, 82, 1, 75, 80, 90, 5, 72, 82, 4, 73, + 77, 88, 5, 68, 69, 74, 0, 4, 22, 0, 0, 0, 72, + 90, 97, 0, 7, 65, 18, 73, 92, 93, 64, 71, 24, + 15, 70, 64, 83, 66, 80, 77, 92, 83, 83, 87, 92, + 21, 0, 8, 82, 70, 81, 77, 98, 4, 67, 66, 76, 17, + 68, 64, 78, 82, 70, 73, 68, 7, 8, 64, 12, 14, + 76, 64, 65, 67, 4, 73, 15, 68, 1, 15, 17, 25, + 19, 12, 81, 64, 70, 2, 4, 91, 0, 8, 5, 5, 7, 7, + 16, 9, 3, 2, 2, 2, 8, 8, 83, 67, 1, 73, 5, 5, + 14, 7, 2, 9, 6, 4, 4, 14, 4, 76, 3, 79, 22, 21, + 16, 14, 17, 17, 10, 16, 20, 64, 10, 9, 6, 3, 67, + 5, 64, 2, 4, 1, 5, 11, 1, 80, 0, 74, 0, 6, 82, + 27, 35, 27, 26, 25, 24, 22, 22, 16, 8, 6, 3, 0, + 67, 90, 68, 64, 77, 14, 10, 7, 8, 4, 65, 64, 64, + 76, 69, 74, 92, 86, 97, 68, 22, 18, 11, 3, 7, + 65, 70, 72, 81, 66, 36, 21, 15, 8, 12, 1, 68, + 73, 83, 4, 38, 29, 24, 18, 16, 5, 64, 70, 78, + 70, 39, 27, 13, 3, 8, 68, 77, 83, 5, 49, 38, 29, + 21, 21, 5, 66, 71, 75, 62, 90, 87, 75, 89, 88, + 81, 83, 81, 81, 82, 80, 81, 84, 80, 85, 82, 67, + 80, 77, 75, 73, 68, 68, 68, 66, 64, 67, 70, 74, + 11, 9, 14, 6, 2, 12, 9, 6, 7, 8, 6, 5, 64, 67, + 71, 66, 7, 77, 8, 22, 6, 7, 13, 14, 15, 8, 11, + 11, 17, 65, 68, 73, 36, 36, 42, 31, 30, 38, 40, + 40, 44, 40, 47, 46, 37, 30, 10, 34, 46, 32, 29, + 31, 27, 19, 16, 13, 6, 65, 69, 74, 83, 31, 30, + 31, 25, 15, 18, 13, 5, 5, 2, 65, 74, 74, 84, 87, + 69, 70, 85, 15, 16, 10, 64, 7, 6, 67, 3, 1, 69, + 79, 79, 87, 99, 9, 64, 75, 74, 1, 0, 4, 7, 7, + 13, 9, 12, 14, 25, 16, 16, 25, 24, 55, 42, 33, + 24, 17, 7, 67, 80, 101, 5, 37, 30, 28, 21, 22, + 11, 7, 7, 66, 79, 73, 65, 72, 4, 12, 69, 71, 3, + 7, 4, 7, 14, 4, 2, 52, 38, 24, 11, 1, 77, 89, + 99, 111 }, + + { + + 53, + 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 2, 33, 37, + 53, 14, 71, 0, 2, 12, 0, 64, 68, 71, 86, 9, 27, + 99, 110, 115, 69, 79, 68, 2, 12, 0, 78, 73, 10, + 7, 65, 73, 82, 1, 75, 79, 90, 5, 72, 81, 3, 74, + 77, 88, 5, 67, 69, 73, 0, 4, 22, 0, 0, 0, 71, + 91, 97, 0, 6, 65, 18, 73, 92, 92, 0, 69, 25, 16, + 69, 0, 82, 64, 79, 76, 90, 83, 82, 87, 91, 21, + 0, 8, 81, 70, 80, 77, 97, 3, 67, 66, 76, 17, 68, + 64, 78, 82, 70, 73, 68, 7, 7, 64, 12, 14, 76, + 64, 65, 67, 4, 73, 15, 69, 1, 15, 16, 24, 18, + 11, 80, 64, 70, 1, 3, 91, 64, 8, 4, 5, 7, 7, 17, + 10, 3, 1, 2, 1, 7, 7, 84, 67, 1, 74, 5, 4, 13, + 6, 2, 10, 6, 4, 3, 13, 3, 76, 3, 80, 22, 21, 16, + 14, 17, 17, 10, 16, 19, 64, 10, 9, 6, 3, 68, 5, + 64, 2, 4, 1, 5, 10, 0, 80, 0, 74, 64, 5, 82, 25, + 33, 25, 24, 23, 22, 20, 20, 14, 6, 4, 1, 66, 69, + 91, 68, 65, 78, 13, 9, 6, 7, 2, 66, 65, 66, 76, + 70, 75, 92, 86, 96, 68, 22, 18, 11, 3, 7, 65, + 70, 72, 80, 65, 36, 21, 15, 8, 12, 1, 68, 73, + 81, 4, 38, 29, 24, 18, 16, 5, 64, 70, 77, 70, + 39, 26, 13, 3, 8, 68, 77, 83, 5, 48, 37, 28, 20, + 21, 5, 66, 71, 75, 62, 89, 86, 74, 87, 87, 80, + 82, 79, 80, 80, 79, 79, 83, 80, 84, 81, 66, 79, + 78, 75, 72, 68, 68, 69, 67, 65, 68, 71, 75, 10, + 9, 14, 6, 1, 11, 9, 6, 6, 7, 6, 4, 65, 68, 71, + 66, 7, 77, 7, 21, 5, 7, 12, 13, 15, 7, 10, 11, + 17, 66, 69, 75, 35, 36, 41, 30, 28, 37, 38, 38, + 42, 38, 44, 43, 34, 28, 8, 31, 42, 29, 25, 29, + 25, 17, 15, 11, 6, 64, 68, 73, 81, 30, 28, 29, + 24, 13, 16, 11, 3, 4, 0, 67, 76, 75, 85, 88, 70, + 70, 86, 13, 15, 8, 65, 5, 4, 68, 1, 64, 70, 80, + 80, 88, 99, 8, 64, 76, 74, 1, 1, 5, 7, 8, 14, 9, + 13, 15, 26, 17, 17, 26, 25, 54, 40, 31, 22, 14, + 4, 70, 83, 104, 5, 37, 30, 28, 22, 22, 11, 8, 7, + 66, 78, 73, 64, 72, 5, 13, 69, 70, 4, 8, 4, 7, + 15, 4, 2, 50, 36, 22, 8, 65, 81, 93, 102, 114 }, + + { + + 52, + 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 0, 31, 36, + 53, 14, 69, 0, 3, 13, 0, 64, 67, 72, 87, 9, 25, + 101, 111, 115, 66, 77, 68, 3, 13, 0, 78, 72, 10, + 7, 65, 73, 81, 1, 76, 79, 90, 5, 72, 80, 3, 74, + 77, 88, 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 71, + 91, 97, 1, 5, 65, 18, 72, 92, 90, 2, 68, 27, 18, + 67, 1, 81, 0, 78, 75, 88, 82, 82, 86, 90, 21, 0, + 8, 81, 70, 80, 76, 95, 3, 67, 66, 76, 17, 68, 0, + 77, 82, 70, 73, 67, 7, 7, 64, 12, 14, 75, 64, + 64, 67, 4, 73, 14, 69, 1, 14, 15, 24, 17, 10, + 79, 0, 70, 0, 3, 90, 64, 8, 4, 5, 7, 7, 18, 10, + 3, 1, 2, 1, 6, 7, 85, 67, 1, 74, 4, 3, 13, 6, 1, + 10, 6, 4, 2, 13, 2, 76, 3, 80, 21, 21, 16, 14, + 17, 17, 10, 16, 19, 64, 10, 9, 6, 3, 68, 5, 64, + 1, 4, 1, 4, 9, 0, 80, 64, 74, 65, 4, 82, 24, 31, + 24, 23, 21, 20, 18, 18, 12, 4, 2, 64, 68, 70, + 92, 68, 65, 78, 12, 8, 5, 6, 1, 68, 66, 67, 77, + 70, 75, 92, 86, 96, 68, 22, 18, 11, 3, 7, 64, + 69, 71, 79, 65, 36, 21, 15, 8, 12, 2, 67, 72, + 79, 4, 38, 29, 24, 18, 16, 5, 64, 70, 76, 70, + 40, 26, 12, 3, 8, 68, 77, 82, 5, 48, 36, 27, 19, + 21, 5, 66, 71, 74, 62, 88, 85, 73, 86, 86, 79, + 81, 78, 79, 79, 77, 77, 82, 79, 84, 81, 65, 79, + 78, 74, 71, 68, 69, 69, 67, 65, 69, 72, 76, 9, + 8, 14, 5, 1, 11, 9, 6, 5, 6, 6, 4, 66, 68, 71, + 66, 7, 77, 6, 21, 5, 7, 11, 12, 15, 6, 9, 10, + 16, 67, 70, 77, 34, 35, 41, 29, 27, 35, 36, 36, + 40, 35, 41, 41, 31, 26, 7, 28, 39, 26, 21, 26, + 22, 15, 14, 10, 6, 0, 68, 72, 79, 28, 27, 27, + 22, 11, 14, 10, 1, 3, 65, 68, 78, 77, 86, 89, + 70, 70, 87, 12, 13, 6, 67, 4, 3, 70, 0, 65, 72, + 81, 81, 89, 100, 8, 65, 77, 73, 2, 1, 5, 8, 9, + 15, 10, 14, 16, 28, 18, 18, 27, 27, 54, 38, 29, + 19, 12, 1, 73, 86, 106, 5, 38, 31, 29, 22, 23, + 11, 8, 8, 65, 78, 73, 0, 71, 6, 14, 68, 69, 4, + 8, 4, 8, 16, 4, 2, 49, 34, 19, 5, 68, 84, 97, + 106, 117 }, + + { + + 51, + 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 64, 30, 35, + 53, 14, 67, 0, 3, 14, 0, 65, 67, 73, 88, 8, 24, + 102, 112, 116, 0, 76, 68, 3, 14, 0, 77, 71, 11, + 6, 64, 72, 80, 0, 76, 79, 90, 5, 71, 80, 3, 74, + 76, 88, 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 70, + 91, 97, 1, 5, 66, 18, 72, 91, 88, 4, 66, 28, 20, + 66, 2, 79, 1, 77, 75, 87, 82, 82, 86, 90, 22, 0, + 8, 80, 69, 79, 76, 94, 3, 68, 67, 77, 17, 68, 0, + 77, 82, 69, 73, 67, 7, 7, 0, 12, 13, 75, 64, 64, + 67, 4, 73, 13, 69, 1, 13, 14, 23, 17, 10, 79, 0, + 70, 0, 2, 90, 65, 8, 4, 5, 7, 7, 18, 10, 3, 1, + 3, 1, 5, 7, 85, 68, 1, 75, 4, 2, 13, 6, 0, 10, + 6, 4, 0, 13, 1, 76, 3, 81, 20, 21, 15, 14, 17, + 17, 10, 16, 19, 64, 9, 9, 5, 3, 68, 4, 65, 1, 3, + 0, 3, 8, 64, 80, 64, 73, 66, 2, 82, 22, 29, 22, + 21, 19, 18, 16, 16, 10, 2, 1, 65, 70, 72, 93, + 68, 65, 79, 11, 7, 4, 4, 64, 69, 67, 68, 78, 71, + 76, 92, 86, 95, 67, 22, 18, 11, 4, 7, 64, 69, + 71, 78, 64, 35, 21, 15, 8, 13, 2, 66, 71, 77, 4, + 39, 29, 24, 18, 17, 5, 64, 69, 76, 70, 40, 26, + 12, 3, 8, 67, 76, 81, 5, 47, 36, 26, 19, 21, 5, + 65, 70, 74, 62, 88, 84, 73, 85, 85, 78, 79, 77, + 78, 78, 76, 76, 82, 78, 84, 80, 0, 79, 79, 74, + 71, 68, 69, 70, 67, 66, 70, 73, 77, 9, 8, 14, 5, + 0, 10, 8, 6, 5, 6, 5, 4, 66, 68, 72, 66, 7, 78, + 6, 20, 4, 6, 10, 12, 16, 6, 8, 10, 16, 67, 70, + 78, 33, 34, 40, 28, 26, 34, 34, 34, 38, 33, 39, + 38, 28, 23, 6, 26, 36, 23, 17, 23, 20, 13, 13, + 9, 6, 1, 68, 70, 76, 26, 25, 25, 20, 9, 12, 8, + 64, 1, 66, 69, 79, 78, 87, 90, 71, 71, 88, 11, + 12, 5, 69, 2, 1, 71, 65, 67, 73, 83, 83, 91, + 101, 7, 66, 78, 73, 2, 1, 6, 8, 9, 17, 11, 15, + 17, 29, 20, 19, 29, 28, 53, 37, 27, 17, 9, 64, + 76, 88, 108, 6, 38, 31, 29, 22, 24, 12, 8, 8, + 65, 78, 72, 0, 71, 7, 15, 68, 69, 5, 9, 4, 8, + 17, 4, 2, 48, 32, 17, 2, 72, 88, 100, 109, 119 }, + + { + + 50, + 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 66, 28, 33, + 53, 14, 64, 64, 4, 14, 0, 66, 67, 74, 89, 8, 22, + 104, 113, 116, 3, 75, 68, 4, 14, 0, 77, 70, 11, + 6, 64, 72, 80, 0, 77, 78, 90, 5, 71, 79, 2, 74, + 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 70, + 91, 97, 2, 4, 66, 18, 72, 91, 87, 6, 65, 30, 22, + 65, 3, 78, 3, 76, 74, 85, 81, 81, 85, 89, 22, 0, + 8, 80, 69, 79, 75, 92, 2, 68, 67, 77, 17, 68, 0, + 76, 82, 69, 73, 66, 7, 6, 0, 12, 13, 75, 64, 64, + 67, 4, 73, 13, 69, 1, 13, 13, 22, 16, 9, 78, 1, + 70, 64, 2, 89, 65, 8, 3, 5, 7, 7, 19, 11, 3, 1, + 3, 1, 4, 7, 86, 68, 1, 75, 3, 1, 12, 6, 0, 11, + 6, 4, 64, 12, 0, 76, 3, 81, 20, 21, 15, 14, 17, + 17, 10, 16, 19, 64, 9, 9, 5, 3, 68, 4, 65, 0, 3, + 0, 3, 7, 64, 80, 65, 73, 67, 1, 82, 21, 27, 20, + 19, 17, 16, 14, 14, 8, 0, 64, 67, 73, 74, 94, + 68, 66, 79, 10, 6, 3, 3, 65, 71, 68, 69, 78, 71, + 76, 92, 86, 95, 67, 22, 18, 11, 4, 7, 64, 69, + 70, 77, 64, 35, 21, 15, 8, 13, 3, 65, 71, 75, 4, + 39, 29, 24, 18, 17, 5, 64, 69, 75, 70, 40, 25, + 11, 3, 8, 67, 76, 81, 5, 47, 35, 25, 18, 21, 5, + 65, 70, 73, 62, 87, 83, 72, 83, 84, 77, 78, 75, + 77, 76, 74, 74, 81, 77, 83, 80, 1, 78, 79, 74, + 70, 68, 70, 70, 68, 67, 71, 74, 78, 8, 7, 14, 4, + 0, 10, 8, 6, 4, 5, 5, 3, 67, 68, 72, 66, 7, 78, + 5, 20, 3, 6, 9, 11, 16, 5, 7, 9, 15, 68, 71, 80, + 32, 34, 40, 27, 24, 32, 32, 32, 36, 30, 36, 36, + 25, 21, 4, 23, 32, 20, 13, 21, 17, 11, 12, 8, 6, + 2, 67, 69, 74, 25, 23, 23, 19, 7, 10, 7, 66, 0, + 68, 71, 81, 80, 88, 91, 71, 71, 89, 9, 10, 3, + 70, 0, 64, 73, 66, 69, 75, 84, 84, 92, 101, 6, + 66, 79, 73, 3, 2, 6, 9, 10, 18, 12, 16, 18, 30, + 21, 20, 30, 29, 53, 35, 25, 14, 7, 67, 79, 91, + 110, 6, 39, 32, 30, 23, 25, 12, 9, 9, 64, 77, + 72, 1, 70, 8, 16, 68, 68, 5, 9, 4, 9, 18, 4, 2, + 46, 30, 14, 64, 75, 92, 104, 113, 122 }, + + { + + 48, + 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 67, 27, 32, + 53, 14, 1, 64, 5, 15, 0, 67, 67, 75, 91, 7, 20, + 106, 114, 117, 5, 74, 68, 5, 15, 0, 77, 69, 11, + 5, 64, 72, 79, 64, 77, 78, 91, 5, 71, 79, 2, 75, + 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 69, + 92, 97, 2, 3, 66, 18, 72, 91, 85, 7, 0, 31, 23, + 64, 4, 77, 4, 75, 73, 83, 81, 81, 85, 88, 22, 0, + 8, 79, 69, 78, 75, 91, 2, 69, 68, 78, 17, 68, 0, + 76, 82, 69, 73, 66, 6, 6, 0, 12, 12, 75, 64, 64, + 67, 3, 73, 12, 70, 1, 12, 11, 21, 15, 8, 78, 1, + 70, 65, 1, 89, 66, 7, 3, 5, 7, 7, 20, 11, 3, 0, + 3, 0, 3, 6, 87, 68, 1, 76, 3, 0, 12, 5, 64, 11, + 6, 4, 66, 12, 64, 76, 3, 82, 19, 20, 15, 14, 17, + 16, 9, 16, 18, 65, 8, 9, 5, 2, 69, 3, 66, 0, 2, + 64, 2, 6, 65, 80, 65, 73, 68, 64, 82, 19, 25, + 18, 17, 15, 13, 12, 12, 6, 65, 66, 69, 75, 76, + 95, 68, 66, 80, 9, 4, 1, 1, 67, 72, 70, 71, 79, + 72, 77, 92, 86, 94, 67, 22, 18, 11, 4, 7, 64, + 69, 70, 76, 0, 35, 21, 15, 8, 13, 3, 65, 70, 74, + 4, 39, 29, 24, 17, 17, 5, 64, 69, 75, 70, 40, + 25, 11, 3, 8, 67, 76, 80, 5, 46, 34, 24, 17, 20, + 5, 65, 70, 73, 62, 86, 82, 72, 82, 83, 77, 77, + 74, 76, 75, 73, 73, 81, 77, 83, 79, 2, 78, 80, + 74, 70, 68, 70, 71, 68, 68, 72, 76, 79, 7, 7, + 14, 4, 64, 9, 7, 5, 3, 4, 4, 3, 68, 69, 73, 66, + 7, 79, 4, 19, 2, 6, 8, 10, 16, 4, 6, 9, 15, 69, + 72, 82, 31, 33, 39, 25, 23, 31, 30, 30, 33, 28, + 33, 33, 22, 18, 3, 20, 29, 17, 9, 18, 15, 9, 10, + 6, 6, 2, 67, 68, 72, 23, 21, 21, 17, 4, 8, 5, + 68, 65, 70, 72, 83, 81, 89, 92, 72, 72, 90, 8, + 9, 1, 72, 65, 66, 74, 68, 71, 76, 85, 86, 94, + 102, 5, 67, 80, 73, 3, 2, 7, 9, 10, 19, 12, 17, + 19, 31, 22, 21, 31, 30, 52, 33, 23, 12, 4, 70, + 82, 94, 113, 6, 39, 32, 30, 23, 25, 12, 9, 9, + 64, 77, 72, 1, 70, 9, 17, 68, 68, 6, 10, 4, 9, + 18, 4, 1, 45, 28, 12, 67, 78, 96, 108, 116, 125 }, + + { + + 47, + 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 68, 26, 31, + 53, 14, 3, 64, 6, 16, 0, 67, 66, 76, 92, 6, 18, + 107, 115, 118, 8, 72, 68, 6, 16, 0, 76, 68, 12, + 4, 64, 71, 78, 64, 77, 78, 91, 5, 71, 78, 2, 75, + 76, 88, 7, 66, 67, 72, 2, 4, 22, 0, 0, 0, 68, + 92, 97, 2, 2, 66, 18, 71, 91, 83, 9, 2, 32, 25, + 1, 5, 75, 5, 73, 72, 81, 81, 81, 85, 87, 22, 0, + 8, 78, 69, 77, 74, 90, 2, 69, 68, 78, 17, 68, 1, + 75, 81, 68, 73, 66, 6, 6, 0, 12, 12, 74, 64, 0, + 67, 3, 72, 11, 70, 1, 11, 10, 21, 14, 7, 77, 1, + 69, 66, 0, 89, 67, 7, 3, 6, 7, 7, 21, 11, 3, 0, + 4, 0, 3, 6, 88, 68, 1, 77, 3, 64, 12, 5, 65, 11, + 6, 4, 67, 12, 64, 76, 3, 83, 18, 20, 15, 14, 17, + 16, 9, 16, 18, 65, 8, 9, 5, 2, 69, 3, 66, 0, 2, + 64, 1, 6, 65, 80, 65, 73, 69, 65, 82, 17, 24, + 17, 16, 13, 11, 11, 11, 4, 67, 67, 70, 77, 77, + 96, 68, 66, 81, 8, 3, 0, 0, 68, 73, 71, 72, 80, + 73, 78, 92, 85, 93, 66, 23, 18, 11, 4, 8, 0, 68, + 69, 75, 1, 35, 21, 15, 8, 14, 3, 64, 69, 72, 4, + 39, 29, 24, 17, 18, 5, 64, 69, 74, 70, 41, 25, + 11, 3, 9, 67, 76, 79, 5, 46, 34, 24, 16, 20, 5, + 65, 69, 72, 62, 85, 81, 71, 81, 81, 76, 75, 73, + 74, 74, 72, 71, 80, 76, 83, 78, 4, 78, 81, 73, + 69, 68, 70, 72, 68, 68, 73, 77, 80, 7, 7, 14, 4, + 64, 8, 7, 5, 2, 4, 4, 3, 69, 69, 73, 65, 8, 79, + 4, 18, 2, 6, 8, 10, 16, 3, 5, 9, 15, 70, 72, 83, + 31, 32, 38, 24, 22, 30, 28, 28, 31, 26, 31, 30, + 20, 16, 2, 17, 26, 14, 5, 15, 13, 8, 9, 5, 6, 3, + 67, 67, 70, 21, 20, 19, 15, 2, 7, 4, 70, 66, 71, + 73, 84, 82, 90, 92, 72, 72, 91, 7, 8, 0, 74, 66, + 67, 75, 69, 72, 77, 86, 87, 95, 103, 5, 68, 80, + 72, 3, 2, 8, 10, 11, 20, 13, 18, 20, 33, 23, 22, + 33, 32, 51, 32, 21, 10, 1, 73, 85, 97, 115, 7, + 39, 32, 31, 23, 26, 13, 9, 10, 0, 77, 71, 2, 70, + 10, 19, 67, 67, 7, 11, 4, 10, 19, 4, 1, 44, 26, + 10, 69, 81, 99, 112, 119, 126 }, + + { + + 46, + 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 70, 24, 29, + 53, 14, 6, 65, 7, 16, 0, 68, 66, 77, 93, 6, 16, + 109, 116, 118, 11, 71, 68, 7, 16, 0, 76, 67, 12, + 4, 64, 71, 78, 64, 78, 77, 91, 5, 71, 77, 1, 75, + 76, 88, 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 68, + 92, 97, 3, 1, 66, 18, 71, 91, 82, 11, 3, 34, 27, + 2, 6, 74, 7, 72, 71, 79, 80, 80, 84, 86, 22, 0, + 8, 78, 69, 77, 74, 88, 1, 69, 68, 78, 17, 68, 1, + 75, 81, 68, 73, 65, 6, 5, 0, 12, 12, 74, 64, 0, + 67, 3, 72, 11, 70, 1, 11, 9, 20, 13, 6, 76, 2, + 69, 67, 0, 88, 67, 7, 2, 6, 7, 7, 22, 12, 3, 0, + 4, 0, 2, 6, 89, 68, 1, 77, 2, 65, 11, 5, 65, 12, + 6, 4, 68, 11, 65, 76, 3, 83, 18, 20, 15, 14, 17, + 16, 9, 16, 18, 65, 8, 9, 5, 2, 69, 3, 66, 64, 2, + 64, 1, 5, 66, 80, 66, 73, 70, 66, 82, 16, 22, + 15, 14, 11, 9, 9, 9, 2, 69, 69, 72, 80, 79, 97, + 68, 67, 81, 7, 2, 64, 64, 70, 75, 72, 73, 80, + 73, 78, 92, 85, 93, 66, 23, 18, 11, 4, 8, 0, 68, + 69, 74, 1, 35, 21, 15, 8, 14, 4, 0, 69, 70, 4, + 39, 29, 24, 17, 18, 5, 64, 69, 73, 70, 41, 24, + 10, 3, 9, 67, 76, 79, 5, 45, 33, 23, 15, 20, 5, + 65, 69, 72, 62, 84, 80, 70, 79, 80, 75, 74, 71, + 73, 72, 70, 69, 79, 75, 82, 78, 5, 77, 81, 73, + 68, 68, 71, 72, 69, 69, 74, 78, 81, 6, 6, 14, 3, + 65, 8, 7, 5, 1, 3, 4, 2, 70, 69, 73, 65, 8, 79, + 3, 18, 1, 6, 7, 9, 16, 2, 4, 8, 14, 71, 73, 85, + 30, 32, 38, 23, 20, 28, 26, 26, 29, 23, 28, 28, + 17, 14, 0, 14, 22, 11, 1, 13, 10, 6, 8, 4, 6, 4, + 66, 66, 68, 20, 18, 17, 14, 0, 5, 2, 72, 67, 73, + 75, 86, 84, 91, 93, 73, 72, 92, 5, 6, 65, 75, + 68, 69, 77, 71, 74, 79, 87, 88, 96, 103, 4, 68, + 81, 72, 4, 3, 8, 10, 12, 21, 14, 19, 21, 34, 24, + 23, 34, 33, 51, 30, 19, 7, 64, 76, 88, 100, 117, + 7, 40, 33, 31, 24, 27, 13, 10, 10, 0, 76, 71, 3, + 69, 11, 20, 67, 66, 7, 11, 4, 10, 20, 4, 1, 42, + 24, 7, 72, 84, 103, 116, 123, 126 }, + + { + + 45, + 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 71, 23, 28, + 53, 14, 8, 65, 7, 17, 0, 69, 66, 78, 94, 5, 15, + 110, 117, 119, 14, 70, 68, 7, 17, 0, 75, 66, 13, + 3, 0, 70, 77, 65, 78, 77, 91, 5, 70, 77, 1, 75, + 75, 88, 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 67, + 92, 97, 3, 1, 67, 18, 71, 90, 80, 13, 5, 35, 29, + 3, 7, 72, 8, 71, 71, 78, 80, 80, 84, 86, 23, 0, + 8, 77, 68, 76, 73, 87, 1, 70, 69, 79, 17, 68, 1, + 74, 81, 67, 73, 65, 6, 5, 1, 12, 11, 74, 64, 0, + 67, 3, 72, 10, 70, 1, 10, 8, 19, 13, 6, 76, 2, + 69, 67, 64, 88, 68, 7, 2, 6, 7, 7, 22, 12, 3, 0, + 5, 0, 1, 6, 89, 69, 1, 78, 2, 66, 11, 5, 66, 12, + 6, 4, 70, 11, 66, 76, 3, 84, 17, 20, 14, 14, 17, + 16, 9, 16, 18, 65, 7, 9, 4, 2, 69, 2, 67, 64, 1, + 65, 0, 4, 66, 80, 66, 72, 71, 68, 82, 14, 20, + 13, 12, 9, 7, 7, 7, 0, 71, 70, 73, 82, 81, 98, + 68, 67, 82, 6, 1, 65, 66, 71, 76, 73, 74, 81, + 74, 79, 92, 85, 92, 65, 23, 18, 11, 5, 8, 0, 68, + 68, 73, 2, 34, 21, 15, 8, 15, 4, 1, 68, 68, 4, + 40, 29, 24, 17, 19, 5, 64, 68, 73, 70, 41, 24, + 10, 3, 9, 66, 75, 78, 5, 45, 33, 22, 15, 20, 5, + 64, 68, 71, 62, 84, 79, 70, 78, 79, 74, 72, 70, + 72, 71, 69, 68, 79, 74, 82, 77, 7, 77, 82, 73, + 68, 68, 71, 73, 69, 70, 75, 79, 82, 6, 6, 14, 3, + 65, 7, 6, 5, 1, 3, 3, 2, 70, 69, 74, 65, 8, 80, + 3, 17, 0, 5, 6, 9, 17, 2, 3, 8, 14, 71, 73, 86, + 29, 31, 37, 22, 19, 27, 24, 24, 27, 21, 26, 25, + 14, 11, 64, 12, 19, 8, 66, 10, 8, 4, 7, 3, 6, 5, + 66, 64, 65, 18, 16, 15, 12, 65, 3, 1, 74, 69, + 74, 76, 87, 85, 92, 94, 73, 73, 93, 4, 5, 66, + 77, 70, 71, 78, 72, 76, 80, 89, 90, 98, 104, 3, + 69, 82, 72, 4, 3, 9, 11, 12, 23, 15, 20, 22, 35, + 26, 24, 36, 34, 50, 29, 17, 5, 67, 78, 91, 102, + 119, 8, 40, 33, 32, 24, 28, 14, 10, 11, 1, 76, + 70, 3, 69, 12, 21, 67, 66, 8, 12, 4, 11, 21, 4, + 1, 41, 22, 5, 75, 88, 107, 119, 126, 126 }, + + { + + 43, + 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 73, 21, 27, + 53, 14, 10, 65, 8, 18, 0, 70, 66, 79, 95, 5, 13, + 112, 118, 119, 17, 69, 68, 8, 18, 0, 75, 65, 13, + 3, 0, 70, 76, 65, 79, 77, 91, 5, 70, 76, 1, 76, + 75, 88, 9, 65, 67, 71, 4, 4, 22, 0, 0, 0, 67, + 93, 97, 4, 0, 67, 18, 71, 90, 78, 14, 6, 37, 30, + 4, 8, 71, 9, 70, 70, 76, 79, 80, 83, 85, 23, 0, + 8, 77, 68, 76, 73, 85, 1, 70, 69, 79, 17, 68, 1, + 74, 81, 67, 73, 64, 6, 5, 1, 12, 11, 74, 64, 0, + 67, 3, 72, 9, 71, 1, 9, 7, 18, 12, 5, 75, 3, 69, + 68, 64, 87, 68, 7, 2, 6, 7, 7, 23, 12, 3, 64, 5, + 64, 0, 5, 90, 69, 1, 78, 1, 67, 11, 4, 67, 12, + 6, 4, 71, 11, 67, 76, 3, 84, 16, 20, 14, 14, 17, + 16, 9, 16, 17, 65, 7, 9, 4, 2, 70, 2, 67, 65, 1, + 65, 64, 3, 67, 80, 67, 72, 72, 69, 82, 13, 18, + 11, 10, 7, 5, 5, 5, 65, 73, 72, 75, 84, 83, 99, + 68, 67, 82, 5, 0, 66, 67, 73, 78, 74, 76, 82, + 74, 79, 92, 85, 92, 65, 23, 18, 11, 5, 8, 0, 68, + 68, 72, 2, 34, 21, 15, 8, 15, 5, 1, 67, 66, 4, + 40, 29, 24, 17, 19, 5, 64, 68, 72, 70, 41, 24, + 9, 3, 9, 66, 75, 77, 5, 44, 32, 21, 14, 20, 5, + 64, 68, 71, 62, 83, 78, 69, 77, 78, 73, 71, 69, + 71, 70, 67, 66, 78, 74, 82, 77, 8, 77, 82, 73, + 67, 68, 72, 73, 69, 71, 76, 80, 83, 5, 5, 14, 2, + 66, 7, 6, 5, 0, 2, 3, 2, 71, 70, 74, 65, 8, 80, + 2, 17, 64, 5, 5, 8, 17, 1, 2, 7, 13, 72, 74, 88, + 28, 30, 37, 21, 18, 25, 22, 22, 25, 18, 23, 23, + 11, 9, 65, 9, 16, 5, 70, 7, 5, 2, 6, 1, 6, 6, + 66, 0, 0, 16, 14, 13, 10, 67, 1, 64, 76, 70, 76, + 77, 89, 87, 93, 95, 74, 73, 94, 3, 3, 68, 79, + 72, 73, 80, 74, 78, 82, 90, 91, 99, 105, 2, 70, + 83, 72, 5, 3, 9, 11, 13, 24, 15, 21, 23, 36, 27, + 25, 37, 35, 50, 27, 15, 2, 69, 81, 94, 105, 122, + 8, 41, 34, 32, 24, 28, 14, 10, 11, 1, 76, 70, 4, + 68, 13, 22, 67, 65, 8, 12, 4, 11, 22, 4, 1, 40, + 20, 2, 78, 91, 111, 123, 126, 126 }, + + { + + 42, + 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 74, 20, 25, + 53, 14, 13, 66, 9, 18, 0, 70, 65, 80, 96, 4, 11, + 114, 119, 120, 20, 67, 68, 9, 18, 0, 75, 64, 13, + 2, 0, 70, 76, 65, 79, 76, 91, 5, 70, 75, 0, 76, + 75, 88, 9, 64, 66, 70, 4, 4, 22, 0, 0, 0, 66, + 93, 97, 4, 64, 67, 18, 70, 90, 77, 16, 8, 38, + 32, 6, 9, 70, 11, 69, 69, 74, 79, 79, 83, 84, + 23, 0, 8, 76, 68, 75, 72, 84, 0, 70, 69, 79, 17, + 68, 2, 73, 81, 67, 73, 64, 6, 4, 1, 12, 11, 73, + 64, 1, 67, 3, 72, 9, 71, 1, 9, 6, 18, 11, 4, 74, + 3, 69, 69, 65, 87, 69, 7, 1, 6, 7, 7, 24, 13, 3, + 64, 5, 64, 64, 5, 91, 69, 1, 79, 1, 68, 10, 4, + 67, 13, 6, 4, 72, 10, 68, 76, 3, 85, 16, 20, 14, + 14, 17, 16, 9, 16, 17, 65, 7, 9, 4, 2, 70, 2, + 67, 65, 1, 65, 64, 2, 67, 80, 67, 72, 73, 70, + 82, 11, 16, 10, 9, 5, 3, 3, 3, 67, 75, 74, 77, + 87, 84, 100, 68, 68, 83, 4, 64, 67, 68, 74, 79, + 75, 77, 82, 75, 80, 92, 85, 91, 65, 23, 18, 11, + 5, 8, 1, 67, 67, 71, 3, 34, 21, 15, 8, 15, 5, 2, + 67, 64, 4, 40, 29, 24, 17, 19, 5, 64, 68, 71, + 70, 42, 23, 9, 3, 9, 66, 75, 77, 5, 44, 31, 20, + 13, 20, 5, 64, 68, 70, 62, 82, 77, 68, 75, 77, + 72, 70, 67, 70, 68, 66, 64, 77, 73, 81, 76, 9, + 76, 83, 72, 66, 68, 72, 74, 70, 71, 77, 81, 84, + 4, 5, 14, 2, 66, 6, 6, 5, 64, 1, 3, 1, 72, 70, + 74, 65, 8, 80, 1, 16, 64, 5, 4, 7, 17, 0, 1, 7, + 13, 73, 75, 90, 27, 30, 36, 20, 16, 24, 20, 20, + 23, 16, 20, 20, 8, 7, 67, 6, 12, 2, 74, 5, 3, 0, + 5, 0, 6, 7, 65, 1, 2, 15, 13, 11, 9, 69, 64, 65, + 78, 71, 78, 79, 91, 88, 94, 96, 74, 73, 95, 1, + 2, 70, 80, 73, 74, 81, 75, 79, 83, 91, 92, 100, + 105, 2, 70, 84, 71, 5, 4, 10, 12, 14, 25, 16, + 22, 24, 38, 28, 26, 38, 37, 49, 25, 13, 0, 72, + 84, 97, 108, 124, 8, 41, 34, 33, 25, 29, 14, 11, + 12, 2, 75, 70, 5, 68, 14, 23, 66, 64, 9, 13, 4, + 12, 23, 4, 1, 38, 18, 0, 81, 94, 114, 126, 126, + 126 }, + + { + + 41, + 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 76, 18, 24, + 53, 14, 15, 66, 10, 19, 0, 71, 65, 81, 97, 4, 9, + 115, 120, 120, 23, 66, 68, 10, 19, 0, 74, 0, 14, + 2, 0, 69, 75, 66, 80, 76, 91, 5, 70, 75, 0, 76, + 75, 88, 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 66, + 93, 97, 5, 65, 67, 18, 70, 90, 75, 18, 9, 40, + 34, 7, 10, 68, 12, 68, 68, 72, 78, 79, 82, 83, + 23, 0, 8, 76, 68, 75, 72, 82, 0, 71, 70, 80, 17, + 68, 2, 73, 81, 66, 73, 0, 6, 4, 1, 12, 10, 73, + 64, 1, 67, 3, 72, 8, 71, 1, 8, 5, 17, 10, 3, 74, + 4, 69, 70, 65, 86, 69, 7, 1, 6, 7, 7, 25, 13, 3, + 64, 6, 64, 65, 5, 92, 69, 1, 79, 0, 69, 10, 4, + 68, 13, 6, 4, 74, 10, 69, 76, 3, 85, 15, 20, 14, + 14, 17, 16, 9, 16, 17, 65, 6, 9, 4, 2, 70, 1, + 68, 66, 0, 66, 65, 1, 68, 80, 68, 72, 74, 72, + 82, 10, 14, 8, 7, 3, 1, 1, 1, 69, 77, 75, 78, + 89, 86, 101, 68, 68, 83, 3, 65, 68, 70, 76, 81, + 76, 78, 83, 75, 80, 92, 85, 91, 64, 23, 18, 11, + 5, 8, 1, 67, 67, 70, 3, 34, 21, 15, 8, 16, 6, 3, + 66, 1, 4, 40, 29, 24, 17, 20, 5, 64, 68, 71, 70, + 42, 23, 8, 3, 9, 66, 75, 76, 5, 43, 31, 19, 12, + 20, 5, 64, 67, 70, 62, 81, 76, 68, 74, 76, 71, + 68, 66, 69, 67, 64, 0, 77, 72, 81, 76, 11, 76, + 83, 72, 66, 68, 73, 74, 70, 72, 78, 82, 85, 4, + 4, 14, 1, 67, 6, 5, 5, 65, 1, 2, 1, 73, 70, 75, + 65, 8, 81, 1, 16, 65, 5, 3, 7, 17, 64, 0, 6, 12, + 74, 75, 91, 26, 29, 36, 19, 15, 22, 18, 18, 21, + 13, 18, 18, 5, 4, 68, 3, 9, 64, 78, 2, 0, 65, 4, + 64, 6, 8, 65, 2, 4, 13, 11, 9, 7, 71, 66, 67, + 80, 73, 79, 80, 92, 90, 95, 97, 75, 74, 96, 0, + 0, 71, 82, 75, 76, 83, 77, 81, 85, 92, 94, 102, + 106, 1, 71, 85, 71, 6, 4, 10, 12, 14, 26, 17, + 23, 25, 39, 29, 27, 40, 38, 49, 24, 11, 66, 74, + 87, 100, 111, 126, 9, 42, 35, 33, 25, 30, 15, + 11, 12, 2, 75, 69, 5, 67, 15, 24, 66, 64, 9, 13, + 4, 12, 24, 4, 1, 37, 16, 66, 84, 97, 118, 126, + 126, 126 }, + + { + + 40, + 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 77, 17, 23, + 53, 14, 17, 66, 11, 20, 0, 72, 65, 82, 98, 3, 7, + 117, 121, 121, 26, 65, 68, 11, 20, 0, 74, 1, 14, + 1, 0, 69, 74, 66, 80, 76, 91, 5, 70, 74, 0, 76, + 75, 88, 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 65, + 93, 97, 5, 66, 67, 18, 70, 90, 73, 20, 11, 41, + 36, 8, 11, 67, 13, 67, 67, 70, 78, 79, 82, 82, + 23, 0, 8, 75, 68, 74, 71, 81, 0, 71, 70, 80, 17, + 68, 2, 72, 81, 66, 73, 0, 6, 4, 1, 12, 10, 73, + 64, 1, 67, 3, 72, 7, 71, 1, 7, 4, 16, 9, 2, 73, + 4, 69, 71, 66, 86, 70, 7, 1, 6, 7, 7, 26, 13, 3, + 64, 6, 64, 66, 5, 93, 69, 1, 80, 0, 70, 10, 4, + 69, 13, 6, 4, 75, 10, 70, 76, 3, 86, 14, 20, 14, + 14, 17, 16, 9, 16, 17, 65, 6, 9, 4, 2, 70, 1, + 68, 66, 0, 66, 66, 0, 68, 80, 68, 72, 75, 73, + 82, 8, 12, 6, 5, 1, 64, 64, 64, 71, 79, 77, 80, + 91, 88, 102, 68, 68, 84, 2, 66, 69, 71, 77, 82, + 77, 79, 84, 76, 81, 92, 85, 90, 64, 23, 18, 11, + 5, 8, 1, 67, 66, 69, 4, 34, 21, 15, 8, 16, 6, 4, + 65, 3, 4, 40, 29, 24, 17, 20, 5, 64, 68, 70, 70, + 42, 23, 8, 3, 9, 66, 75, 75, 5, 43, 30, 18, 11, + 20, 5, 64, 67, 69, 62, 80, 75, 67, 73, 75, 70, + 67, 65, 68, 66, 0, 2, 76, 71, 81, 75, 12, 76, + 84, 72, 65, 68, 73, 75, 70, 73, 79, 83, 86, 3, + 4, 14, 1, 67, 5, 5, 5, 66, 0, 2, 1, 74, 70, 75, + 65, 8, 81, 0, 15, 66, 5, 2, 6, 17, 65, 64, 6, + 12, 75, 76, 93, 25, 28, 35, 18, 14, 21, 16, 16, + 19, 11, 15, 15, 2, 2, 69, 0, 6, 67, 82, 64, 65, + 67, 3, 65, 6, 9, 65, 3, 6, 11, 9, 7, 5, 73, 68, + 68, 82, 74, 81, 81, 94, 91, 96, 98, 75, 74, 97, + 64, 64, 73, 84, 77, 78, 84, 78, 83, 86, 93, 95, + 103, 107, 0, 72, 86, 71, 6, 4, 11, 13, 15, 27, + 18, 24, 26, 40, 30, 28, 41, 39, 48, 22, 9, 68, + 77, 90, 103, 114, 126, 9, 42, 35, 34, 25, 31, + 15, 11, 13, 3, 75, 69, 6, 67, 16, 25, 66, 0, 10, + 14, 4, 13, 25, 4, 1, 36, 14, 68, 87, 100, 122, + 126, 126, 126 }, + + { + + 38, + 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 79, 15, 21, + 52, 14, 19, 67, 11, 20, 64, 73, 65, 84, 100, 2, + 5, 119, 122, 122, 28, 64, 69, 11, 20, 64, 74, 2, + 14, 0, 0, 69, 74, 67, 81, 76, 92, 5, 70, 74, 64, + 77, 75, 88, 10, 64, 66, 70, 5, 3, 22, 0, 0, 0, + 65, 94, 97, 5, 67, 68, 18, 70, 90, 72, 21, 12, + 42, 37, 9, 12, 66, 14, 66, 67, 69, 78, 79, 82, + 82, 23, 0, 8, 75, 68, 74, 71, 80, 64, 72, 71, + 81, 17, 68, 2, 72, 81, 66, 73, 0, 5, 3, 1, 11, + 9, 73, 65, 1, 67, 2, 72, 6, 72, 0, 6, 2, 15, 8, + 1, 73, 4, 69, 72, 67, 86, 71, 6, 0, 6, 7, 7, 26, + 13, 3, 65, 6, 65, 67, 4, 94, 70, 0, 81, 64, 71, + 9, 3, 70, 13, 6, 4, 77, 9, 71, 76, 3, 87, 13, + 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1, + 71, 0, 69, 67, 64, 67, 67, 64, 69, 80, 69, 72, + 76, 75, 82, 6, 10, 4, 3, 64, 67, 66, 66, 73, 81, + 79, 82, 94, 90, 104, 69, 69, 85, 1, 68, 71, 73, + 79, 84, 79, 81, 85, 77, 82, 92, 85, 90, 64, 23, + 18, 11, 5, 8, 1, 67, 66, 68, 4, 33, 21, 15, 8, + 16, 6, 4, 65, 4, 3, 40, 29, 23, 16, 20, 5, 64, + 68, 70, 70, 42, 22, 7, 2, 9, 66, 75, 75, 5, 42, + 29, 17, 10, 19, 5, 64, 67, 69, 62, 80, 74, 67, + 72, 74, 70, 66, 64, 67, 65, 1, 3, 76, 71, 81, + 75, 13, 76, 85, 72, 65, 68, 74, 76, 71, 74, 80, + 85, 88, 2, 3, 14, 0, 68, 4, 4, 4, 67, 64, 1, 0, + 75, 71, 76, 65, 8, 82, 64, 14, 67, 4, 1, 5, 17, + 66, 66, 5, 11, 76, 77, 95, 24, 27, 34, 16, 12, + 19, 14, 14, 16, 8, 12, 12, 64, 64, 71, 66, 2, + 70, 87, 67, 68, 69, 1, 67, 6, 9, 65, 4, 8, 9, 7, + 5, 3, 76, 70, 70, 85, 76, 83, 83, 96, 93, 97, + 99, 76, 75, 99, 66, 66, 75, 86, 79, 80, 86, 80, + 85, 88, 95, 97, 105, 108, 64, 73, 87, 71, 6, 4, + 11, 13, 15, 28, 18, 25, 26, 41, 31, 29, 42, 40, + 47, 20, 6, 71, 80, 93, 107, 117, 126, 9, 42, 35, + 34, 25, 31, 15, 11, 13, 3, 75, 69, 6, 67, 17, + 26, 66, 0, 10, 14, 4, 13, 25, 4, 0, 34, 11, 71, + 90, 104, 126, 126, 126, 126 }, + + { + + 37, + 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 80, 14, 20, + 52, 14, 22, 67, 12, 21, 64, 73, 64, 85, 101, 2, + 4, 120, 123, 122, 31, 1, 69, 12, 21, 64, 73, 4, + 15, 0, 1, 68, 73, 67, 81, 75, 92, 5, 69, 73, 64, + 77, 74, 88, 11, 0, 65, 69, 6, 3, 22, 0, 0, 0, + 64, 94, 97, 6, 67, 68, 18, 69, 89, 70, 23, 14, + 44, 39, 11, 13, 64, 16, 64, 66, 67, 77, 78, 81, + 81, 24, 1, 9, 74, 67, 73, 70, 78, 64, 72, 71, + 81, 18, 68, 3, 71, 80, 65, 72, 1, 5, 3, 2, 11, + 9, 72, 65, 2, 67, 2, 71, 6, 72, 0, 6, 1, 15, 8, + 1, 72, 5, 68, 72, 67, 85, 71, 6, 0, 7, 7, 7, 27, + 14, 4, 65, 7, 65, 67, 4, 94, 70, 0, 81, 64, 72, + 9, 3, 70, 14, 7, 4, 78, 9, 71, 75, 3, 87, 13, + 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1, + 71, 0, 69, 67, 64, 67, 67, 64, 69, 79, 69, 71, + 76, 76, 81, 5, 9, 3, 2, 66, 69, 67, 67, 75, 82, + 80, 83, 96, 91, 105, 69, 69, 85, 0, 69, 72, 74, + 80, 85, 80, 82, 85, 77, 82, 91, 84, 89, 0, 24, + 18, 11, 6, 9, 2, 66, 65, 66, 5, 33, 21, 15, 8, + 17, 7, 5, 64, 6, 3, 41, 30, 23, 16, 21, 5, 64, + 67, 69, 70, 43, 22, 7, 2, 10, 65, 74, 74, 5, 42, + 29, 17, 10, 19, 5, 0, 66, 68, 62, 79, 73, 66, + 70, 72, 69, 64, 1, 65, 0, 3, 5, 75, 70, 80, 74, + 15, 75, 85, 71, 64, 67, 74, 76, 71, 74, 80, 86, + 89, 2, 3, 15, 0, 68, 4, 4, 4, 67, 64, 1, 0, 75, + 71, 76, 64, 9, 82, 64, 14, 67, 4, 1, 5, 18, 66, + 67, 5, 11, 76, 77, 96, 24, 27, 34, 15, 11, 18, + 12, 12, 14, 6, 10, 10, 66, 66, 72, 68, 64, 73, + 91, 69, 70, 70, 0, 68, 6, 10, 64, 6, 11, 8, 6, + 4, 2, 78, 71, 71, 87, 77, 84, 84, 97, 94, 98, + 99, 76, 75, 100, 67, 67, 76, 87, 80, 81, 87, 81, + 86, 89, 96, 98, 106, 108, 64, 73, 87, 70, 7, 5, + 12, 14, 16, 30, 19, 26, 27, 43, 33, 30, 44, 42, + 47, 19, 4, 73, 82, 95, 110, 119, 126, 10, 43, + 36, 35, 26, 32, 16, 12, 14, 4, 74, 68, 7, 66, + 19, 28, 65, 1, 11, 15, 5, 14, 26, 4, 0, 33, 9, + 73, 92, 107, 126, 126, 126, 126 }, + + { + + 36, + 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 81, 13, 19, + 52, 14, 24, 67, 13, 22, 64, 74, 64, 86, 102, 1, + 2, 122, 124, 123, 34, 2, 69, 13, 22, 64, 73, 5, + 15, 64, 1, 68, 72, 67, 81, 75, 92, 5, 69, 72, + 64, 77, 74, 88, 11, 0, 65, 69, 6, 3, 22, 0, 0, + 0, 0, 94, 97, 6, 68, 68, 18, 69, 89, 68, 25, 16, + 45, 41, 12, 14, 0, 17, 0, 65, 65, 77, 78, 81, + 80, 24, 1, 9, 73, 67, 72, 70, 77, 64, 72, 71, + 81, 18, 68, 3, 71, 80, 65, 72, 1, 5, 3, 2, 11, + 9, 72, 65, 2, 67, 2, 71, 5, 72, 0, 5, 0, 14, 7, + 0, 71, 5, 68, 73, 68, 85, 72, 6, 0, 7, 7, 7, 28, + 14, 4, 65, 7, 65, 68, 4, 95, 70, 0, 82, 64, 73, + 9, 3, 71, 14, 7, 4, 79, 9, 72, 75, 3, 88, 12, + 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1, + 71, 0, 69, 67, 64, 67, 68, 65, 70, 79, 69, 71, + 77, 77, 81, 3, 7, 1, 0, 68, 71, 69, 69, 77, 84, + 82, 85, 98, 93, 106, 69, 69, 86, 64, 70, 73, 75, + 82, 86, 81, 83, 86, 78, 83, 91, 84, 88, 0, 24, + 18, 11, 6, 9, 2, 66, 65, 65, 6, 33, 21, 15, 8, + 17, 7, 6, 0, 8, 3, 41, 30, 23, 16, 21, 5, 64, + 67, 68, 70, 43, 22, 7, 2, 10, 65, 74, 73, 5, 41, + 28, 16, 9, 19, 5, 0, 66, 68, 62, 78, 72, 65, 69, + 71, 68, 0, 2, 64, 1, 4, 7, 74, 69, 80, 73, 16, + 75, 86, 71, 0, 67, 74, 77, 71, 75, 81, 87, 90, + 1, 3, 15, 0, 69, 3, 4, 4, 68, 65, 1, 0, 76, 71, + 76, 64, 9, 82, 65, 13, 68, 4, 0, 4, 18, 67, 68, + 5, 11, 77, 78, 98, 23, 26, 33, 14, 10, 17, 10, + 10, 12, 4, 7, 7, 69, 68, 73, 71, 67, 76, 95, 72, + 72, 72, 64, 69, 6, 11, 64, 7, 13, 6, 4, 2, 0, + 80, 73, 73, 89, 78, 86, 85, 99, 95, 99, 100, 77, + 75, 101, 68, 68, 78, 89, 82, 83, 88, 83, 88, 90, + 97, 99, 107, 109, 65, 74, 88, 70, 7, 5, 13, 14, + 17, 31, 20, 27, 28, 44, 34, 31, 45, 43, 46, 17, + 2, 75, 85, 98, 113, 122, 126, 10, 43, 36, 35, + 26, 33, 16, 12, 14, 4, 74, 68, 8, 66, 20, 29, + 65, 2, 12, 16, 5, 14, 27, 4, 0, 32, 7, 75, 95, + 110, 126, 126, 126, 126 }, + + { + + 35, + 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 83, 11, + 18, 52, 14, 26, 67, 14, 23, 64, 75, 64, 87, 103, + 1, 0, 123, 125, 123, 37, 3, 69, 14, 23, 64, 72, + 6, 16, 64, 1, 67, 71, 68, 82, 75, 92, 5, 69, 72, + 64, 77, 74, 88, 12, 0, 65, 69, 7, 3, 22, 0, 0, + 0, 0, 94, 97, 7, 69, 68, 18, 69, 89, 66, 27, 17, + 47, 43, 13, 15, 2, 18, 1, 64, 0, 76, 78, 80, 79, + 24, 1, 9, 73, 67, 72, 69, 75, 64, 73, 72, 82, + 18, 68, 3, 70, 80, 64, 72, 2, 5, 3, 2, 11, 8, + 72, 65, 2, 67, 2, 71, 4, 72, 0, 4, 64, 13, 6, + 64, 71, 6, 68, 74, 68, 84, 72, 6, 0, 7, 7, 7, + 29, 14, 4, 65, 8, 65, 69, 4, 96, 70, 0, 82, 65, + 74, 9, 3, 72, 14, 7, 4, 81, 9, 73, 75, 3, 88, + 11, 19, 13, 14, 17, 15, 8, 16, 16, 66, 4, 9, 3, + 1, 71, 64, 70, 68, 65, 68, 69, 66, 70, 79, 70, + 71, 78, 79, 81, 2, 5, 64, 65, 70, 73, 71, 71, + 79, 86, 83, 86, 100, 95, 107, 69, 69, 86, 65, + 71, 74, 77, 83, 88, 82, 84, 87, 78, 83, 91, 84, + 88, 1, 24, 18, 11, 6, 9, 2, 66, 64, 64, 6, 33, + 21, 15, 8, 18, 8, 7, 1, 10, 3, 41, 30, 23, 16, + 22, 5, 64, 67, 68, 70, 43, 22, 6, 2, 10, 65, 74, + 72, 5, 41, 28, 15, 8, 19, 5, 0, 65, 67, 62, 77, + 71, 65, 68, 70, 67, 2, 3, 0, 2, 6, 8, 74, 68, + 80, 73, 18, 75, 86, 71, 0, 67, 75, 77, 71, 76, + 82, 88, 91, 1, 2, 15, 64, 69, 3, 3, 4, 69, 65, + 0, 0, 77, 71, 77, 64, 9, 83, 65, 13, 69, 4, 64, + 4, 18, 68, 69, 4, 10, 78, 78, 99, 22, 25, 33, + 13, 9, 15, 8, 8, 10, 1, 5, 5, 72, 71, 74, 74, + 70, 79, 99, 75, 75, 74, 65, 70, 6, 12, 64, 8, + 15, 4, 2, 0, 65, 82, 75, 74, 91, 80, 87, 86, + 100, 97, 100, 101, 77, 76, 102, 69, 70, 79, 91, + 84, 85, 90, 84, 90, 92, 98, 101, 109, 110, 66, + 75, 89, 70, 8, 5, 13, 15, 17, 32, 21, 28, 29, + 45, 35, 32, 47, 44, 46, 16, 0, 78, 87, 101, 116, + 125, 126, 11, 44, 37, 36, 26, 34, 17, 12, 15, 5, + 74, 67, 8, 65, 21, 30, 65, 2, 12, 16, 5, 15, 28, + 4, 0, 31, 5, 78, 98, 113, 126, 126, 126, 126 }, + + { + + 33, + 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 84, 10, + 16, 52, 14, 29, 68, 15, 23, 64, 76, 64, 88, 104, + 0, 65, 125, 126, 124, 40, 4, 69, 15, 23, 64, 72, + 7, 16, 65, 1, 67, 71, 68, 82, 74, 92, 5, 69, 71, + 65, 78, 74, 88, 12, 1, 65, 68, 7, 3, 22, 0, 0, + 0, 1, 95, 97, 7, 70, 68, 18, 69, 89, 65, 28, 19, + 48, 44, 14, 16, 3, 20, 2, 0, 2, 76, 77, 80, 78, + 24, 1, 9, 72, 67, 71, 69, 74, 65, 73, 72, 82, + 18, 68, 3, 70, 80, 64, 72, 2, 5, 2, 2, 11, 8, + 72, 65, 2, 67, 2, 71, 4, 73, 0, 4, 65, 12, 5, + 65, 70, 6, 68, 75, 69, 84, 73, 6, 64, 7, 7, 7, + 30, 15, 4, 66, 8, 66, 70, 3, 97, 70, 0, 83, 65, + 75, 8, 2, 72, 15, 7, 4, 82, 8, 74, 75, 3, 89, + 11, 19, 13, 14, 17, 15, 8, 16, 15, 66, 4, 9, 3, + 1, 72, 64, 70, 68, 65, 68, 69, 67, 71, 79, 70, + 71, 79, 80, 81, 0, 3, 66, 67, 72, 75, 73, 73, + 81, 88, 85, 88, 103, 97, 108, 69, 70, 87, 66, + 72, 75, 78, 85, 89, 83, 86, 87, 79, 84, 91, 84, + 87, 1, 24, 18, 11, 6, 9, 2, 66, 64, 0, 7, 33, + 21, 15, 8, 18, 8, 7, 1, 12, 3, 41, 30, 23, 16, + 22, 5, 64, 67, 67, 70, 43, 21, 6, 2, 10, 65, 74, + 72, 5, 40, 27, 14, 7, 19, 5, 0, 65, 67, 62, 76, + 70, 64, 66, 69, 66, 3, 5, 1, 4, 7, 10, 73, 68, + 79, 72, 19, 74, 87, 71, 1, 67, 75, 78, 72, 77, + 83, 89, 92, 0, 2, 15, 64, 70, 2, 3, 4, 70, 66, + 0, 64, 78, 72, 77, 64, 9, 83, 66, 12, 70, 4, 65, + 3, 18, 69, 70, 4, 10, 79, 79, 101, 21, 25, 32, + 12, 7, 14, 6, 6, 8, 64, 2, 2, 75, 73, 76, 77, + 74, 82, 103, 77, 77, 76, 66, 72, 6, 13, 0, 9, + 17, 3, 0, 65, 66, 84, 77, 76, 93, 81, 89, 88, + 102, 98, 101, 102, 78, 76, 103, 71, 71, 81, 92, + 86, 87, 91, 86, 92, 93, 99, 102, 110, 110, 67, + 75, 90, 70, 8, 6, 14, 15, 18, 33, 21, 29, 30, + 46, 36, 33, 48, 45, 45, 14, 65, 80, 90, 104, + 119, 126, 126, 11, 44, 37, 36, 27, 34, 17, 13, + 15, 5, 73, 67, 9, 65, 22, 31, 65, 3, 13, 17, 5, + 15, 29, 4, 0, 29, 3, 80, 101, 116, 126, 126, + 126, 126 }, + + { + + 32, + 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 86, 8, 15, + 52, 14, 31, 68, 16, 24, 64, 76, 0, 89, 105, 0, + 67, 126, 126, 124, 43, 6, 69, 16, 24, 64, 72, 8, + 16, 65, 1, 67, 70, 68, 83, 74, 92, 5, 69, 70, + 65, 78, 74, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, + 0, 1, 95, 97, 8, 71, 68, 18, 68, 89, 0, 30, 20, + 50, 46, 16, 17, 4, 21, 3, 1, 4, 75, 77, 79, 77, + 24, 1, 9, 72, 67, 71, 68, 72, 65, 73, 72, 82, + 18, 68, 4, 69, 80, 64, 72, 3, 5, 2, 2, 11, 8, + 71, 65, 3, 67, 2, 71, 3, 73, 0, 3, 66, 12, 4, + 66, 69, 7, 68, 76, 69, 83, 73, 6, 64, 7, 7, 7, + 31, 15, 4, 66, 8, 66, 71, 3, 98, 70, 0, 83, 66, + 76, 8, 2, 73, 15, 7, 4, 83, 8, 75, 75, 3, 89, + 10, 19, 13, 14, 17, 15, 8, 16, 15, 66, 4, 9, 3, + 1, 72, 64, 70, 69, 65, 68, 70, 68, 71, 79, 71, + 71, 80, 81, 81, 64, 1, 67, 68, 74, 77, 75, 75, + 83, 90, 87, 90, 105, 98, 109, 69, 70, 87, 67, + 73, 76, 79, 86, 91, 84, 87, 88, 79, 84, 91, 84, + 87, 1, 24, 18, 11, 6, 9, 3, 65, 0, 1, 7, 33, 21, + 15, 8, 18, 9, 8, 2, 14, 3, 41, 30, 23, 16, 22, + 5, 64, 67, 66, 70, 44, 21, 5, 2, 10, 65, 74, 71, + 5, 40, 26, 13, 6, 19, 5, 0, 65, 66, 62, 75, 69, + 0, 65, 68, 65, 4, 6, 2, 5, 9, 12, 72, 67, 79, + 72, 20, 74, 87, 70, 2, 67, 76, 78, 72, 77, 84, + 90, 93, 64, 1, 15, 65, 70, 2, 3, 4, 71, 67, 0, + 64, 79, 72, 77, 64, 9, 83, 67, 12, 70, 4, 66, 2, + 18, 70, 71, 3, 9, 80, 80, 103, 20, 24, 32, 11, + 6, 12, 4, 4, 6, 67, 64, 0, 78, 75, 77, 80, 77, + 85, 107, 80, 80, 78, 67, 73, 6, 14, 0, 10, 19, + 1, 64, 67, 68, 86, 79, 77, 95, 82, 91, 89, 104, + 100, 102, 103, 78, 76, 104, 72, 73, 83, 94, 87, + 88, 93, 87, 93, 95, 100, 103, 111, 111, 67, 76, + 91, 69, 9, 6, 14, 16, 19, 34, 22, 30, 31, 48, + 37, 34, 49, 47, 45, 12, 67, 83, 92, 107, 122, + 126, 126, 11, 45, 38, 37, 27, 35, 17, 13, 16, 6, + 73, 67, 10, 64, 23, 32, 64, 4, 13, 17, 5, 16, + 30, 4, 0, 28, 1, 83, 104, 119, 126, 126, 126, + 126 }, + + { + + 31, + 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 87, 7, 14, + 52, 14, 33, 68, 16, 25, 64, 77, 0, 90, 106, 64, + 68, 126, 126, 125, 46, 7, 69, 16, 25, 64, 71, 9, + 17, 66, 2, 66, 69, 69, 83, 74, 92, 5, 68, 70, + 65, 78, 73, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, + 0, 2, 95, 97, 8, 71, 69, 18, 68, 88, 2, 32, 22, + 51, 48, 17, 18, 6, 22, 4, 1, 5, 75, 77, 79, 77, + 25, 1, 9, 71, 66, 70, 68, 71, 65, 74, 73, 83, + 18, 68, 4, 69, 80, 0, 72, 3, 5, 2, 3, 11, 7, 71, + 65, 3, 67, 2, 71, 2, 73, 0, 2, 67, 11, 4, 66, + 69, 7, 68, 76, 70, 83, 74, 6, 64, 7, 7, 7, 31, + 15, 4, 66, 9, 66, 72, 3, 98, 71, 0, 84, 66, 77, + 8, 2, 74, 15, 7, 4, 85, 8, 76, 75, 3, 90, 9, 19, + 12, 14, 17, 15, 8, 16, 15, 66, 3, 9, 2, 1, 72, + 65, 71, 69, 66, 69, 71, 69, 72, 79, 71, 70, 81, + 83, 81, 66, 64, 69, 70, 76, 79, 77, 77, 85, 92, + 88, 91, 107, 100, 110, 69, 70, 88, 68, 74, 77, + 81, 88, 92, 85, 88, 89, 80, 85, 91, 84, 86, 2, + 24, 18, 11, 7, 9, 3, 65, 0, 2, 8, 32, 21, 15, 8, + 19, 9, 9, 3, 16, 3, 42, 30, 23, 16, 23, 5, 64, + 66, 66, 70, 44, 21, 5, 2, 10, 64, 73, 70, 5, 39, + 26, 12, 6, 19, 5, 1, 64, 66, 62, 75, 68, 0, 64, + 67, 64, 6, 7, 3, 6, 10, 13, 72, 66, 79, 71, 22, + 74, 88, 70, 2, 67, 76, 79, 72, 78, 85, 91, 94, + 64, 1, 15, 65, 71, 1, 2, 4, 71, 67, 64, 64, 79, + 72, 78, 64, 9, 84, 67, 11, 71, 3, 67, 2, 19, 70, + 72, 3, 9, 80, 80, 104, 19, 23, 31, 10, 5, 11, 2, + 2, 4, 69, 66, 66, 81, 78, 78, 82, 80, 88, 111, + 83, 82, 80, 68, 74, 6, 15, 0, 12, 22, 64, 66, + 69, 70, 88, 81, 79, 97, 84, 92, 90, 105, 101, + 103, 104, 79, 77, 105, 73, 74, 84, 96, 89, 90, + 94, 89, 95, 96, 102, 105, 113, 112, 68, 77, 92, + 69, 9, 6, 15, 16, 19, 36, 23, 31, 32, 49, 39, + 35, 51, 48, 44, 11, 69, 85, 95, 109, 125, 126, + 126, 12, 45, 38, 37, 27, 36, 18, 13, 16, 6, 73, + 66, 10, 64, 24, 33, 64, 4, 14, 18, 5, 16, 31, 4, + 0, 27, 64, 85, 107, 123, 126, 126, 126, 126 }, + + { + + 30, + 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 89, 5, 12, + 52, 14, 36, 69, 17, 25, 64, 78, 0, 91, 107, 64, + 70, 126, 126, 125, 49, 8, 69, 17, 25, 64, 71, + 10, 17, 66, 2, 66, 69, 69, 84, 73, 92, 5, 68, + 69, 66, 78, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, + 0, 0, 2, 95, 97, 9, 72, 69, 18, 68, 88, 3, 34, + 23, 53, 50, 18, 19, 7, 24, 5, 2, 7, 74, 76, 78, + 76, 25, 1, 9, 71, 66, 70, 67, 69, 66, 74, 73, + 83, 18, 68, 4, 68, 80, 0, 72, 4, 5, 1, 3, 11, 7, + 71, 65, 3, 67, 2, 71, 2, 73, 0, 2, 68, 10, 3, + 67, 68, 8, 68, 77, 70, 82, 74, 6, 65, 7, 7, 7, + 32, 16, 4, 66, 9, 66, 73, 3, 99, 71, 0, 84, 67, + 78, 7, 2, 74, 16, 7, 4, 86, 7, 77, 75, 3, 90, 9, + 19, 12, 14, 17, 15, 8, 16, 15, 66, 3, 9, 2, 1, + 72, 65, 71, 70, 66, 69, 71, 70, 72, 79, 72, 70, + 82, 84, 81, 67, 66, 71, 72, 78, 81, 79, 79, 87, + 94, 90, 93, 110, 102, 111, 69, 71, 88, 69, 75, + 78, 82, 89, 94, 86, 89, 89, 80, 85, 91, 84, 86, + 2, 24, 18, 11, 7, 9, 3, 65, 1, 3, 8, 32, 21, 15, + 8, 19, 10, 10, 3, 18, 3, 42, 30, 23, 16, 23, 5, + 64, 66, 65, 70, 44, 20, 4, 2, 10, 64, 73, 70, 5, + 39, 25, 11, 5, 19, 5, 1, 64, 65, 62, 74, 67, 1, + 1, 66, 0, 7, 9, 4, 8, 12, 15, 71, 65, 78, 71, + 23, 73, 88, 70, 3, 67, 77, 79, 73, 79, 86, 92, + 95, 65, 0, 15, 66, 71, 1, 2, 4, 72, 68, 64, 65, + 80, 72, 78, 64, 9, 84, 68, 11, 72, 3, 68, 1, 19, + 71, 73, 2, 8, 81, 81, 106, 18, 23, 31, 9, 3, 9, + 0, 0, 2, 72, 69, 68, 84, 80, 80, 85, 84, 91, + 115, 85, 85, 82, 69, 75, 6, 16, 1, 13, 24, 65, + 68, 71, 71, 90, 83, 80, 99, 85, 94, 92, 107, + 103, 104, 105, 79, 77, 106, 75, 76, 86, 97, 91, + 92, 96, 90, 97, 98, 103, 106, 114, 112, 69, 77, + 93, 69, 10, 7, 15, 17, 20, 37, 24, 32, 33, 50, + 40, 36, 52, 49, 44, 9, 71, 88, 97, 112, 126, + 126, 126, 12, 46, 39, 38, 28, 37, 18, 14, 17, 7, + 72, 66, 11, 0, 25, 34, 64, 5, 14, 18, 5, 17, 32, + 4, 0, 25, 66, 88, 110, 126, 126, 126, 126, 126 }, + + { + + 28, + 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 90, 4, 11, + 52, 14, 38, 69, 18, 26, 64, 79, 0, 92, 109, 65, + 72, 126, 126, 126, 51, 9, 69, 18, 26, 64, 71, + 11, 17, 67, 2, 66, 68, 70, 84, 73, 93, 5, 68, + 69, 66, 79, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, + 0, 0, 3, 96, 97, 9, 73, 69, 18, 68, 88, 5, 35, + 25, 54, 51, 19, 20, 8, 25, 6, 3, 9, 74, 76, 78, + 75, 25, 1, 9, 70, 66, 69, 67, 68, 66, 75, 74, + 84, 18, 68, 4, 68, 80, 0, 72, 4, 4, 1, 3, 11, 6, + 71, 65, 3, 67, 1, 71, 1, 74, 0, 1, 70, 9, 2, 68, + 68, 8, 68, 78, 71, 82, 75, 5, 65, 7, 7, 7, 33, + 16, 4, 67, 9, 67, 74, 2, 100, 71, 0, 85, 67, 79, + 7, 1, 75, 16, 7, 4, 88, 7, 78, 75, 3, 91, 8, 18, + 12, 14, 17, 14, 7, 16, 14, 67, 2, 9, 2, 0, 73, + 66, 72, 70, 67, 70, 72, 71, 73, 79, 72, 70, 83, + 86, 81, 69, 68, 73, 74, 80, 84, 81, 81, 89, 96, + 92, 95, 112, 104, 112, 69, 71, 89, 70, 77, 80, + 84, 91, 95, 88, 91, 90, 81, 86, 91, 84, 85, 2, + 24, 18, 11, 7, 9, 3, 65, 1, 4, 9, 32, 21, 15, 8, + 19, 10, 10, 4, 19, 3, 42, 30, 23, 15, 23, 5, 64, + 66, 65, 70, 44, 20, 4, 2, 10, 64, 73, 69, 5, 38, + 24, 10, 4, 18, 5, 1, 64, 65, 62, 73, 66, 1, 2, + 65, 0, 8, 10, 5, 9, 13, 16, 71, 65, 78, 70, 24, + 73, 89, 70, 3, 67, 77, 80, 73, 80, 87, 94, 96, + 66, 0, 15, 66, 72, 0, 1, 3, 73, 69, 65, 65, 81, + 73, 79, 64, 9, 85, 69, 10, 73, 3, 69, 0, 19, 72, + 74, 2, 8, 82, 82, 108, 17, 22, 30, 7, 2, 8, 65, + 65, 64, 74, 72, 71, 87, 83, 81, 88, 87, 94, 119, + 88, 87, 84, 71, 77, 6, 16, 1, 14, 26, 67, 70, + 73, 73, 93, 85, 82, 101, 87, 96, 93, 109, 104, + 105, 106, 80, 78, 107, 76, 77, 88, 99, 93, 94, + 97, 92, 99, 99, 104, 108, 116, 113, 70, 78, 94, + 69, 10, 7, 16, 17, 20, 38, 24, 33, 34, 51, 41, + 37, 53, 50, 43, 7, 73, 90, 100, 115, 126, 126, + 126, 12, 46, 39, 38, 28, 37, 18, 14, 17, 7, 72, + 66, 11, 0, 26, 35, 64, 5, 15, 19, 5, 17, 32, 4, + 64, 24, 68, 90, 113, 126, 126, 126, 126, 126 }, + + { + + 27, + 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 91, 3, 10, + 52, 14, 40, 69, 19, 27, 64, 79, 1, 93, 110, 66, + 74, 126, 126, 126, 54, 11, 69, 19, 27, 64, 70, + 12, 18, 68, 2, 65, 67, 70, 84, 73, 93, 5, 68, + 68, 66, 79, 73, 88, 14, 2, 0, 67, 9, 3, 22, 0, + 0, 0, 4, 96, 97, 9, 74, 69, 18, 67, 88, 7, 37, + 27, 55, 53, 21, 21, 10, 26, 8, 4, 11, 74, 76, + 78, 74, 25, 1, 9, 69, 66, 68, 66, 67, 66, 75, + 74, 84, 18, 68, 5, 67, 79, 1, 72, 4, 4, 1, 3, + 11, 6, 70, 65, 4, 67, 1, 70, 0, 74, 0, 0, 71, 9, + 1, 69, 67, 8, 67, 79, 72, 82, 76, 5, 65, 8, 7, + 7, 34, 16, 4, 67, 10, 67, 74, 2, 101, 71, 0, 86, + 67, 80, 7, 1, 76, 16, 7, 4, 89, 7, 78, 75, 3, + 92, 7, 18, 12, 14, 17, 14, 7, 16, 14, 67, 2, 9, + 2, 0, 73, 66, 72, 70, 67, 70, 73, 71, 73, 79, + 72, 70, 84, 87, 81, 71, 69, 74, 75, 82, 86, 82, + 82, 91, 98, 93, 96, 114, 105, 113, 69, 71, 90, + 71, 78, 81, 85, 92, 96, 89, 92, 91, 82, 87, 91, + 83, 84, 3, 25, 18, 11, 7, 10, 4, 64, 2, 5, 10, + 32, 21, 15, 8, 20, 10, 11, 5, 21, 3, 42, 30, 23, + 15, 24, 5, 64, 66, 64, 70, 45, 20, 4, 2, 11, 64, + 73, 68, 5, 38, 24, 10, 3, 18, 5, 1, 0, 64, 62, + 72, 65, 2, 3, 0, 1, 10, 11, 7, 10, 14, 18, 70, + 64, 78, 69, 26, 73, 90, 69, 4, 67, 77, 81, 73, + 80, 88, 95, 97, 66, 0, 15, 66, 72, 64, 1, 3, 74, + 69, 65, 65, 82, 73, 79, 0, 10, 85, 69, 9, 73, 3, + 69, 0, 19, 73, 75, 2, 8, 83, 82, 109, 17, 21, + 29, 6, 1, 7, 67, 67, 66, 76, 74, 74, 89, 85, 82, + 91, 90, 97, 123, 91, 89, 85, 72, 78, 6, 17, 1, + 15, 28, 69, 71, 75, 75, 95, 86, 83, 103, 88, 97, + 94, 110, 105, 106, 106, 80, 78, 108, 77, 78, 89, + 101, 94, 95, 98, 93, 100, 100, 105, 109, 117, + 114, 70, 79, 94, 68, 10, 7, 17, 18, 21, 39, 25, + 34, 35, 53, 42, 38, 55, 52, 42, 6, 75, 92, 103, + 118, 126, 126, 126, 13, 46, 39, 39, 28, 38, 19, + 14, 18, 8, 72, 65, 12, 0, 27, 37, 0, 6, 16, 20, + 5, 18, 33, 4, 64, 23, 70, 92, 115, 126, 126, + 126, 126, 126 }, + + { + + 26, + 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 93, 1, 8, + 52, 14, 43, 70, 20, 27, 64, 80, 1, 94, 111, 66, + 76, 126, 126, 126, 57, 12, 69, 20, 27, 64, 70, + 13, 18, 68, 2, 65, 67, 70, 85, 72, 93, 5, 68, + 67, 67, 79, 73, 88, 15, 3, 0, 66, 10, 3, 22, 0, + 0, 0, 4, 96, 97, 10, 75, 69, 18, 67, 88, 8, 39, + 28, 57, 55, 22, 22, 11, 28, 9, 5, 13, 73, 75, + 77, 73, 25, 1, 9, 69, 66, 68, 66, 65, 67, 75, + 74, 84, 18, 68, 5, 67, 79, 1, 72, 5, 4, 0, 3, + 11, 6, 70, 65, 4, 67, 1, 70, 0, 74, 0, 0, 72, 8, + 0, 70, 66, 9, 67, 80, 72, 81, 76, 5, 66, 8, 7, + 7, 35, 17, 4, 67, 10, 67, 75, 2, 102, 71, 0, 86, + 68, 81, 6, 1, 76, 17, 7, 4, 90, 6, 79, 75, 3, + 92, 7, 18, 12, 14, 17, 14, 7, 16, 14, 67, 2, 9, + 2, 0, 73, 66, 72, 71, 67, 70, 73, 72, 74, 79, + 73, 70, 85, 88, 81, 72, 71, 76, 77, 84, 88, 84, + 84, 93, 100, 95, 98, 117, 107, 114, 69, 72, 90, + 72, 79, 82, 86, 94, 98, 90, 93, 91, 82, 87, 91, + 83, 84, 3, 25, 18, 11, 7, 10, 4, 64, 2, 6, 10, + 32, 21, 15, 8, 20, 11, 12, 5, 23, 3, 42, 30, 23, + 15, 24, 5, 64, 66, 0, 70, 45, 19, 3, 2, 11, 64, + 73, 68, 5, 37, 23, 9, 2, 18, 5, 1, 0, 64, 62, + 71, 64, 3, 5, 1, 2, 11, 13, 8, 12, 16, 20, 69, + 0, 77, 69, 27, 72, 90, 69, 5, 67, 78, 81, 74, + 81, 89, 96, 98, 67, 64, 15, 67, 73, 64, 1, 3, + 75, 70, 65, 66, 83, 73, 79, 0, 10, 85, 70, 9, + 74, 3, 70, 64, 19, 74, 76, 1, 7, 84, 83, 111, + 16, 21, 29, 5, 64, 5, 69, 69, 68, 79, 77, 76, + 92, 87, 84, 94, 94, 100, 126, 93, 92, 87, 73, + 79, 6, 18, 2, 16, 30, 70, 73, 77, 76, 97, 88, + 85, 105, 89, 99, 96, 112, 107, 107, 107, 81, 78, + 109, 79, 80, 91, 102, 96, 97, 100, 95, 102, 102, + 106, 110, 118, 114, 71, 79, 95, 68, 11, 8, 17, + 18, 22, 40, 26, 35, 36, 54, 43, 39, 56, 53, 42, + 4, 77, 95, 105, 121, 126, 126, 126, 13, 47, 40, + 39, 29, 39, 19, 15, 18, 8, 71, 65, 13, 1, 28, + 38, 0, 7, 16, 20, 5, 18, 34, 4, 64, 21, 72, 95, + 118, 126, 126, 126, 126, 126 }, + + { + + 25, + 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 94, 0, 7, + 52, 14, 45, 70, 20, 28, 64, 81, 1, 95, 112, 67, + 77, 126, 126, 126, 60, 13, 69, 20, 28, 64, 69, + 14, 19, 69, 3, 64, 66, 71, 85, 72, 93, 5, 67, + 67, 67, 79, 72, 88, 15, 3, 0, 66, 10, 3, 22, 0, + 0, 0, 5, 96, 97, 10, 75, 70, 18, 67, 87, 10, 41, + 30, 58, 57, 23, 23, 13, 29, 10, 5, 14, 73, 75, + 77, 73, 26, 1, 9, 68, 65, 67, 65, 64, 67, 76, + 75, 85, 18, 68, 5, 66, 79, 2, 72, 5, 4, 0, 4, + 11, 5, 70, 65, 4, 67, 1, 70, 64, 74, 0, 64, 73, + 7, 0, 70, 66, 9, 67, 80, 73, 81, 77, 5, 66, 8, + 7, 7, 35, 17, 4, 67, 11, 67, 76, 2, 102, 72, 0, + 87, 68, 82, 6, 1, 77, 17, 7, 4, 92, 6, 80, 75, + 3, 93, 6, 18, 11, 14, 17, 14, 7, 16, 14, 67, 1, + 9, 1, 0, 73, 67, 73, 71, 68, 71, 74, 73, 74, 79, + 73, 69, 86, 90, 81, 74, 73, 78, 79, 86, 90, 86, + 86, 95, 102, 96, 99, 119, 109, 115, 69, 72, 91, + 73, 80, 83, 88, 95, 99, 91, 94, 92, 83, 88, 91, + 83, 83, 4, 25, 18, 11, 8, 10, 4, 64, 3, 7, 11, + 31, 21, 15, 8, 21, 11, 13, 6, 25, 3, 43, 30, 23, + 15, 25, 5, 64, 65, 0, 70, 45, 19, 3, 2, 11, 0, + 72, 67, 5, 37, 23, 8, 2, 18, 5, 2, 1, 0, 62, 71, + 0, 3, 6, 2, 3, 13, 14, 9, 13, 17, 21, 69, 1, 77, + 68, 29, 72, 91, 69, 5, 67, 78, 82, 74, 82, 90, + 97, 99, 67, 64, 15, 67, 73, 65, 0, 3, 75, 70, + 66, 66, 83, 73, 80, 0, 10, 86, 70, 8, 75, 2, 71, + 64, 20, 74, 77, 1, 7, 84, 83, 112, 15, 20, 28, + 4, 65, 4, 71, 71, 70, 81, 79, 79, 95, 90, 85, + 96, 97, 103, 126, 96, 94, 89, 74, 80, 6, 19, 2, + 18, 33, 72, 75, 79, 78, 99, 90, 86, 107, 91, + 100, 97, 113, 108, 108, 108, 81, 79, 110, 80, + 81, 92, 104, 98, 99, 101, 96, 104, 103, 108, + 112, 120, 115, 72, 80, 96, 68, 11, 8, 18, 19, + 22, 42, 27, 36, 37, 55, 45, 40, 58, 54, 41, 3, + 79, 97, 108, 123, 126, 126, 126, 14, 47, 40, 40, + 29, 40, 20, 15, 19, 9, 71, 64, 13, 1, 29, 39, 0, + 7, 17, 21, 5, 19, 35, 4, 64, 20, 74, 97, 121, + 126, 126, 126, 126, 126 }, + + { + + 23, + 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 96, 65, 6, + 52, 14, 47, 70, 21, 29, 64, 82, 1, 96, 113, 67, + 79, 126, 126, 126, 62, 14, 69, 21, 29, 64, 69, + 15, 19, 69, 3, 64, 65, 71, 86, 72, 93, 5, 67, + 66, 67, 80, 72, 88, 16, 3, 0, 66, 11, 3, 22, 0, + 0, 0, 5, 97, 97, 11, 76, 70, 18, 67, 87, 12, 42, + 31, 60, 58, 24, 24, 14, 30, 11, 6, 16, 72, 75, + 76, 72, 26, 1, 9, 68, 65, 67, 65, 1, 67, 76, 75, + 85, 18, 68, 5, 66, 79, 2, 72, 6, 4, 0, 4, 11, 5, + 70, 65, 4, 67, 1, 70, 65, 75, 0, 65, 74, 6, 64, + 71, 65, 10, 67, 81, 73, 80, 77, 5, 66, 8, 7, 7, + 36, 17, 4, 68, 11, 68, 77, 1, 103, 72, 0, 87, + 69, 83, 6, 0, 78, 17, 7, 4, 93, 6, 81, 75, 3, + 93, 5, 18, 11, 14, 17, 14, 7, 16, 13, 67, 1, 9, + 1, 0, 74, 67, 73, 72, 68, 71, 75, 74, 75, 79, + 74, 69, 87, 91, 81, 75, 75, 80, 81, 88, 92, 88, + 88, 97, 104, 98, 101, 121, 111, 116, 69, 72, 91, + 74, 81, 84, 89, 97, 101, 92, 96, 93, 83, 88, 91, + 83, 83, 4, 25, 18, 11, 8, 10, 4, 64, 3, 8, 11, + 31, 21, 15, 8, 21, 12, 13, 7, 27, 3, 43, 30, 23, + 15, 25, 5, 64, 65, 1, 70, 45, 19, 2, 2, 11, 0, + 72, 66, 5, 36, 22, 7, 1, 18, 5, 2, 1, 0, 62, 70, + 1, 4, 7, 3, 4, 14, 15, 10, 14, 19, 23, 68, 1, + 77, 68, 30, 72, 91, 69, 6, 67, 79, 82, 74, 83, + 91, 98, 100, 68, 65, 15, 68, 74, 65, 0, 3, 76, + 71, 66, 66, 84, 74, 80, 0, 10, 86, 71, 8, 76, 2, + 72, 65, 20, 75, 78, 0, 6, 85, 84, 114, 14, 19, + 28, 3, 66, 2, 73, 73, 72, 84, 82, 81, 98, 92, + 86, 99, 100, 106, 126, 99, 97, 91, 75, 82, 6, + 20, 2, 19, 35, 74, 77, 81, 80, 101, 92, 88, 109, + 92, 102, 98, 115, 110, 109, 109, 82, 79, 111, + 81, 83, 94, 106, 100, 101, 103, 98, 106, 105, + 109, 113, 121, 116, 73, 81, 97, 68, 12, 8, 18, + 19, 23, 43, 27, 37, 38, 56, 46, 41, 59, 55, 41, + 1, 81, 100, 110, 126, 126, 126, 126, 14, 48, 41, + 40, 29, 40, 20, 15, 19, 9, 71, 64, 14, 2, 30, + 40, 0, 8, 17, 21, 5, 19, 36, 4, 64, 19, 76, 100, + 124, 126, 126, 126, 126, 126 }, + + { + + 22, + 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 66, 4, + 52, 14, 50, 71, 22, 29, 64, 82, 2, 97, 114, 68, + 81, 126, 126, 126, 62, 16, 69, 22, 29, 64, 69, + 16, 19, 70, 3, 64, 65, 71, 86, 71, 93, 5, 67, + 65, 68, 80, 72, 88, 16, 4, 1, 65, 11, 3, 22, 0, + 0, 0, 6, 97, 97, 11, 77, 70, 18, 66, 87, 13, 44, + 33, 61, 60, 26, 25, 15, 32, 12, 7, 18, 72, 74, + 76, 71, 26, 1, 9, 67, 65, 66, 64, 2, 68, 76, 75, + 85, 18, 68, 6, 65, 79, 2, 72, 6, 4, 64, 4, 11, + 5, 69, 65, 5, 67, 1, 70, 65, 75, 0, 65, 75, 6, + 65, 72, 64, 10, 67, 82, 74, 80, 78, 5, 67, 8, 7, + 7, 37, 18, 4, 68, 11, 68, 78, 1, 104, 72, 0, 88, + 69, 84, 5, 0, 78, 18, 7, 4, 94, 5, 82, 75, 3, + 94, 5, 18, 11, 14, 17, 14, 7, 16, 13, 67, 1, 9, + 1, 0, 74, 67, 73, 72, 68, 71, 75, 75, 75, 79, + 74, 69, 88, 92, 81, 77, 77, 81, 82, 90, 94, 90, + 90, 99, 106, 100, 103, 124, 112, 117, 69, 73, + 92, 75, 82, 85, 90, 98, 102, 93, 97, 93, 84, 89, + 91, 83, 82, 4, 25, 18, 11, 8, 10, 5, 0, 4, 9, + 12, 31, 21, 15, 8, 21, 12, 14, 7, 29, 3, 43, 30, + 23, 15, 25, 5, 64, 65, 2, 70, 46, 18, 2, 2, 11, + 0, 72, 66, 5, 36, 21, 6, 0, 18, 5, 2, 1, 1, 62, + 69, 2, 5, 9, 4, 5, 15, 17, 11, 16, 20, 25, 67, + 2, 76, 67, 31, 71, 92, 68, 7, 67, 79, 83, 75, + 83, 92, 99, 101, 69, 65, 15, 68, 74, 66, 0, 3, + 77, 72, 66, 67, 85, 74, 80, 0, 10, 86, 72, 7, + 76, 2, 73, 66, 20, 76, 79, 0, 6, 86, 85, 116, + 13, 19, 27, 2, 68, 1, 75, 75, 74, 86, 85, 84, + 101, 94, 88, 102, 104, 109, 126, 101, 99, 93, + 76, 83, 6, 21, 3, 20, 37, 75, 78, 83, 81, 103, + 94, 89, 111, 93, 104, 100, 117, 111, 110, 110, + 82, 79, 112, 83, 84, 96, 107, 101, 102, 104, 99, + 107, 106, 110, 114, 122, 116, 73, 81, 98, 67, + 12, 9, 19, 20, 24, 44, 28, 38, 39, 58, 47, 42, + 60, 57, 40, 64, 83, 102, 113, 126, 126, 126, + 126, 14, 48, 41, 41, 30, 41, 20, 16, 20, 10, 70, + 64, 15, 2, 31, 41, 1, 9, 18, 22, 5, 20, 37, 4, + 64, 17, 78, 102, 126, 126, 126, 126, 126, 126 }, + + { + + 21, + 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 68, 3, + 52, 14, 52, 71, 23, 30, 64, 83, 2, 98, 115, 68, + 83, 126, 126, 126, 62, 17, 69, 23, 30, 64, 68, + 17, 20, 70, 3, 0, 64, 72, 87, 71, 93, 5, 67, 65, + 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, 0, + 0, 6, 97, 97, 12, 78, 70, 18, 66, 87, 15, 46, + 34, 62, 62, 27, 26, 17, 33, 13, 8, 20, 71, 74, + 75, 70, 26, 1, 9, 67, 65, 66, 64, 4, 68, 77, 76, + 86, 18, 68, 6, 65, 79, 3, 72, 7, 4, 64, 4, 11, + 4, 69, 65, 5, 67, 1, 70, 66, 75, 0, 66, 76, 5, + 66, 73, 64, 11, 67, 83, 74, 79, 78, 5, 67, 8, 7, + 7, 38, 18, 4, 68, 12, 68, 79, 1, 105, 72, 0, 88, + 70, 85, 5, 0, 79, 18, 7, 4, 96, 5, 83, 75, 3, + 94, 4, 18, 11, 14, 17, 14, 7, 16, 13, 67, 0, 9, + 1, 0, 74, 68, 74, 73, 69, 72, 76, 76, 76, 79, + 75, 69, 89, 94, 81, 78, 79, 83, 84, 92, 96, 92, + 92, 101, 108, 101, 104, 126, 114, 118, 69, 73, + 92, 76, 83, 86, 92, 100, 104, 94, 98, 94, 84, + 89, 91, 83, 82, 5, 25, 18, 11, 8, 10, 5, 0, 4, + 10, 12, 31, 21, 15, 8, 22, 13, 15, 8, 31, 3, 43, + 30, 23, 15, 26, 5, 64, 65, 2, 70, 46, 18, 1, 2, + 11, 0, 72, 65, 5, 35, 21, 5, 64, 18, 5, 2, 2, 1, + 62, 68, 3, 5, 10, 5, 6, 17, 18, 12, 17, 22, 26, + 67, 3, 76, 67, 33, 71, 92, 68, 7, 67, 80, 83, + 75, 84, 93, 100, 102, 69, 66, 15, 69, 75, 66, + 64, 3, 78, 72, 67, 67, 86, 74, 81, 0, 10, 87, + 72, 7, 77, 2, 74, 66, 20, 77, 80, 64, 5, 87, 85, + 117, 12, 18, 27, 1, 69, 64, 77, 77, 76, 89, 87, + 86, 104, 97, 89, 105, 107, 112, 126, 104, 102, + 95, 77, 84, 6, 22, 3, 21, 39, 77, 80, 85, 83, + 105, 96, 91, 113, 95, 105, 101, 118, 113, 111, + 111, 83, 80, 113, 84, 86, 97, 109, 103, 104, + 106, 101, 109, 108, 111, 116, 124, 117, 74, 82, + 99, 67, 13, 9, 19, 20, 24, 45, 29, 39, 40, 59, + 48, 43, 62, 58, 40, 65, 85, 105, 115, 126, 126, + 126, 126, 15, 49, 42, 41, 30, 42, 21, 16, 20, + 10, 70, 0, 15, 3, 32, 42, 1, 9, 18, 22, 5, 20, + 38, 4, 64, 16, 80, 105, 126, 126, 126, 126, 126, + 126 }, + + { + + 20, + 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 100, 69, + 2, 52, 14, 54, 71, 24, 31, 64, 84, 2, 99, 116, + 69, 85, 126, 126, 126, 62, 18, 69, 24, 31, 64, + 68, 18, 20, 71, 3, 0, 0, 72, 87, 71, 93, 5, 67, + 64, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, + 0, 0, 7, 97, 97, 12, 79, 70, 18, 66, 87, 17, 48, + 36, 62, 62, 28, 27, 18, 34, 14, 9, 22, 71, 74, + 75, 69, 26, 1, 9, 66, 65, 65, 0, 5, 68, 77, 76, + 86, 18, 68, 6, 64, 79, 3, 72, 7, 4, 64, 4, 11, + 4, 69, 65, 5, 67, 1, 70, 67, 75, 0, 67, 77, 4, + 67, 74, 0, 11, 67, 84, 75, 79, 79, 5, 67, 8, 7, + 7, 39, 18, 4, 68, 12, 68, 80, 1, 106, 72, 0, 89, + 70, 86, 5, 0, 80, 18, 7, 4, 97, 5, 84, 75, 3, + 95, 3, 18, 11, 14, 17, 14, 7, 16, 13, 67, 0, 9, + 1, 0, 74, 68, 74, 73, 69, 72, 77, 77, 76, 79, + 75, 69, 90, 95, 81, 80, 81, 85, 86, 94, 98, 94, + 94, 103, 110, 103, 106, 126, 116, 119, 69, 73, + 93, 77, 84, 87, 93, 101, 105, 95, 99, 95, 85, + 90, 91, 83, 81, 5, 25, 18, 11, 8, 10, 5, 0, 5, + 11, 13, 31, 21, 15, 8, 22, 13, 16, 9, 33, 3, 43, + 30, 23, 15, 26, 5, 64, 65, 3, 70, 46, 18, 1, 2, + 11, 0, 72, 64, 5, 35, 20, 4, 65, 18, 5, 2, 2, 2, + 62, 67, 4, 6, 11, 6, 7, 18, 19, 13, 18, 23, 28, + 66, 4, 76, 66, 34, 71, 93, 68, 8, 67, 80, 84, + 75, 85, 94, 101, 103, 70, 66, 15, 69, 75, 67, + 64, 3, 79, 73, 67, 67, 87, 74, 81, 0, 10, 87, + 73, 6, 78, 2, 75, 67, 20, 78, 81, 64, 5, 88, 86, + 119, 11, 17, 26, 0, 70, 65, 79, 79, 78, 91, 90, + 89, 107, 99, 90, 108, 110, 115, 126, 107, 104, + 97, 78, 85, 6, 23, 3, 22, 41, 79, 82, 87, 85, + 107, 98, 92, 115, 96, 107, 102, 120, 114, 112, + 112, 83, 80, 114, 85, 87, 99, 111, 105, 106, + 107, 102, 111, 109, 112, 117, 125, 118, 75, 83, + 100, 67, 13, 9, 20, 21, 25, 46, 30, 40, 41, 60, + 49, 44, 62, 59, 39, 67, 87, 107, 118, 126, 126, + 126, 126, 15, 49, 42, 42, 30, 43, 21, 16, 21, + 11, 70, 0, 16, 3, 33, 43, 1, 10, 19, 23, 5, 21, + 39, 4, 64, 15, 82, 107, 126, 126, 126, 126, 126, + 126 }, + + { + + 18, + 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 102, 71, + 0, 51, 14, 56, 72, 24, 31, 65, 85, 2, 101, 118, + 70, 87, 126, 126, 126, 62, 19, 70, 24, 31, 65, + 68, 19, 20, 72, 3, 0, 0, 73, 88, 71, 94, 5, 67, + 64, 69, 81, 72, 88, 17, 4, 1, 65, 12, 2, 22, 0, + 0, 0, 7, 98, 97, 12, 80, 71, 18, 66, 87, 18, 49, + 37, 62, 62, 29, 28, 19, 35, 15, 9, 23, 71, 74, + 75, 69, 26, 1, 9, 66, 65, 65, 0, 6, 69, 78, 77, + 87, 18, 68, 6, 64, 79, 3, 72, 7, 3, 65, 4, 10, + 3, 69, 66, 5, 67, 0, 70, 68, 76, 64, 68, 79, 3, + 68, 75, 0, 11, 67, 85, 76, 79, 80, 4, 68, 8, 7, + 7, 39, 18, 4, 69, 12, 69, 81, 0, 107, 73, 64, + 90, 71, 87, 4, 64, 81, 18, 7, 4, 99, 4, 85, 75, + 3, 96, 2, 17, 10, 14, 17, 13, 6, 16, 12, 68, 64, + 9, 0, 64, 75, 69, 75, 74, 70, 73, 78, 78, 77, + 79, 76, 69, 91, 97, 81, 82, 83, 87, 88, 96, 101, + 96, 96, 105, 112, 105, 108, 126, 118, 121, 70, + 74, 94, 78, 86, 89, 95, 103, 107, 97, 101, 96, + 86, 91, 91, 83, 81, 5, 25, 18, 11, 8, 10, 5, 0, + 5, 12, 13, 30, 21, 15, 8, 22, 13, 16, 9, 34, 2, + 43, 30, 22, 14, 26, 5, 64, 65, 3, 70, 46, 17, 0, + 1, 11, 0, 72, 64, 5, 34, 19, 3, 66, 17, 5, 2, 2, + 2, 62, 67, 5, 6, 12, 7, 7, 19, 20, 14, 19, 24, + 29, 66, 4, 76, 66, 35, 71, 94, 68, 8, 67, 81, + 85, 76, 86, 95, 103, 105, 71, 67, 15, 70, 76, + 68, 65, 2, 80, 74, 68, 68, 88, 75, 82, 0, 10, + 88, 74, 5, 79, 1, 76, 68, 20, 79, 83, 65, 4, 89, + 87, 121, 10, 16, 25, 65, 72, 67, 81, 81, 81, 94, + 93, 92, 110, 102, 92, 111, 114, 118, 126, 110, + 107, 99, 80, 87, 6, 23, 3, 23, 43, 81, 84, 89, + 87, 110, 100, 94, 118, 98, 109, 104, 122, 116, + 113, 113, 84, 81, 116, 87, 89, 101, 113, 107, + 108, 109, 104, 113, 111, 114, 119, 126, 119, 76, + 84, 101, 67, 13, 9, 20, 21, 25, 47, 30, 41, 41, + 61, 50, 45, 62, 60, 38, 69, 90, 110, 121, 126, + 126, 126, 126, 15, 49, 42, 42, 30, 43, 21, 16, + 21, 11, 70, 0, 16, 3, 34, 44, 1, 10, 19, 23, 5, + 21, 39, 4, 65, 13, 85, 110, 126, 126, 126, 126, + 126, 126 }, + + { + + 17, + 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 103, 72, + 64, 51, 14, 59, 72, 25, 32, 65, 85, 3, 102, 119, + 70, 88, 126, 126, 126, 62, 21, 70, 25, 32, 65, + 67, 21, 21, 72, 4, 1, 1, 73, 88, 70, 94, 5, 66, + 0, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, + 0, 0, 8, 98, 97, 13, 80, 71, 18, 65, 86, 20, 51, + 39, 62, 62, 31, 29, 21, 37, 17, 10, 25, 70, 73, + 74, 68, 27, 2, 10, 65, 64, 64, 1, 8, 69, 78, 77, + 87, 19, 68, 7, 0, 78, 4, 71, 8, 3, 65, 5, 10, 3, + 68, 66, 6, 67, 0, 69, 68, 76, 64, 68, 80, 3, 68, + 75, 1, 12, 66, 85, 76, 78, 80, 4, 68, 9, 7, 7, + 40, 19, 5, 69, 13, 69, 81, 0, 107, 73, 64, 90, + 71, 88, 4, 64, 81, 19, 8, 4, 100, 4, 85, 74, 3, + 96, 2, 17, 10, 14, 17, 13, 6, 16, 12, 68, 64, 9, + 0, 64, 75, 69, 75, 74, 70, 73, 78, 78, 77, 78, + 76, 68, 91, 98, 80, 83, 84, 88, 89, 98, 103, 97, + 97, 107, 113, 106, 109, 126, 119, 122, 70, 74, + 94, 79, 87, 90, 96, 104, 108, 98, 102, 96, 86, + 91, 90, 82, 80, 6, 26, 18, 11, 9, 11, 6, 1, 6, + 14, 14, 30, 21, 15, 8, 23, 14, 17, 10, 36, 2, + 44, 31, 22, 14, 27, 5, 64, 64, 4, 70, 47, 17, 0, + 1, 12, 1, 71, 0, 5, 34, 19, 3, 66, 17, 5, 3, 3, + 3, 62, 66, 6, 7, 14, 9, 8, 21, 22, 16, 21, 26, + 31, 65, 5, 75, 65, 37, 70, 94, 67, 9, 66, 81, + 85, 76, 86, 95, 104, 106, 71, 67, 16, 70, 76, + 68, 65, 2, 80, 74, 68, 68, 88, 75, 82, 1, 11, + 88, 74, 5, 79, 1, 76, 68, 21, 79, 84, 65, 4, 89, + 87, 122, 10, 16, 25, 66, 73, 68, 83, 83, 83, 96, + 95, 94, 112, 104, 93, 113, 117, 121, 126, 112, + 109, 100, 81, 88, 6, 24, 4, 25, 46, 82, 85, 90, + 88, 112, 101, 95, 120, 99, 110, 105, 123, 117, + 114, 113, 84, 81, 117, 88, 90, 102, 114, 108, + 109, 110, 105, 114, 112, 115, 120, 126, 119, 76, + 84, 101, 66, 14, 10, 21, 22, 26, 49, 31, 42, 42, + 62, 52, 46, 62, 62, 38, 70, 92, 112, 123, 126, + 126, 126, 126, 16, 50, 43, 43, 31, 44, 22, 17, + 22, 12, 69, 1, 17, 4, 36, 46, 2, 11, 20, 24, 6, + 22, 40, 4, 65, 12, 87, 112, 126, 126, 126, 126, + 126, 126 }, + + { + + 16, + 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 104, 73, + 65, 51, 14, 61, 72, 26, 33, 65, 86, 3, 103, 120, + 71, 90, 126, 126, 126, 62, 22, 70, 26, 33, 65, + 67, 22, 21, 73, 4, 1, 2, 73, 88, 70, 94, 5, 66, + 1, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, + 0, 0, 9, 98, 97, 13, 81, 71, 18, 65, 86, 22, 53, + 41, 62, 62, 32, 30, 22, 38, 18, 11, 27, 70, 73, + 74, 67, 27, 2, 10, 64, 64, 0, 1, 9, 69, 78, 77, + 87, 19, 68, 7, 0, 78, 4, 71, 8, 3, 65, 5, 10, 3, + 68, 66, 6, 67, 0, 69, 69, 76, 64, 69, 81, 2, 69, + 76, 2, 12, 66, 86, 77, 78, 81, 4, 68, 9, 7, 7, + 41, 19, 5, 69, 13, 69, 82, 0, 108, 73, 64, 91, + 71, 89, 4, 64, 82, 19, 8, 4, 101, 4, 86, 74, 3, + 97, 1, 17, 10, 14, 17, 13, 6, 16, 12, 68, 64, 9, + 0, 64, 75, 69, 75, 74, 70, 73, 79, 79, 78, 78, + 76, 68, 92, 99, 80, 85, 86, 90, 91, 100, 105, + 99, 99, 109, 115, 108, 111, 126, 121, 123, 70, + 74, 95, 80, 88, 91, 97, 106, 109, 99, 103, 97, + 87, 92, 90, 82, 79, 6, 26, 18, 11, 9, 11, 6, 1, + 6, 15, 15, 30, 21, 15, 8, 23, 14, 18, 11, 38, 2, + 44, 31, 22, 14, 27, 5, 64, 64, 5, 70, 47, 17, 0, + 1, 12, 1, 71, 1, 5, 33, 18, 2, 67, 17, 5, 3, 3, + 3, 62, 65, 7, 8, 15, 10, 9, 22, 23, 17, 22, 27, + 33, 64, 6, 75, 64, 38, 70, 95, 67, 10, 66, 81, + 86, 76, 87, 96, 105, 107, 72, 67, 16, 70, 77, + 69, 65, 2, 81, 75, 68, 68, 89, 75, 82, 1, 11, + 88, 75, 4, 80, 1, 77, 69, 21, 80, 85, 65, 4, 90, + 88, 124, 9, 15, 24, 67, 74, 69, 85, 85, 85, 98, + 98, 97, 115, 106, 94, 116, 120, 124, 126, 115, + 111, 102, 82, 89, 6, 25, 4, 26, 48, 84, 87, 92, + 90, 114, 103, 97, 122, 100, 112, 106, 125, 118, + 115, 114, 85, 81, 118, 89, 91, 104, 116, 110, + 111, 111, 107, 116, 113, 116, 121, 126, 120, 77, + 85, 102, 66, 14, 10, 22, 22, 27, 50, 32, 43, 43, + 62, 53, 47, 62, 62, 37, 72, 94, 114, 126, 126, + 126, 126, 126, 16, 50, 43, 43, 31, 45, 22, 17, + 22, 12, 69, 1, 18, 4, 37, 47, 2, 12, 21, 25, 6, + 22, 41, 4, 65, 11, 89, 114, 126, 126, 126, 126, + 126, 126 }, + + { + + 15, + 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 106, 75, + 66, 51, 14, 62, 72, 27, 34, 65, 87, 3, 104, 121, + 71, 92, 126, 126, 126, 62, 23, 70, 27, 34, 65, + 66, 23, 22, 73, 4, 2, 3, 74, 89, 70, 94, 5, 66, + 1, 69, 81, 71, 88, 19, 5, 2, 64, 14, 2, 22, 0, + 0, 0, 9, 98, 97, 14, 82, 71, 18, 65, 86, 24, 55, + 42, 62, 62, 33, 31, 24, 39, 19, 12, 29, 69, 73, + 73, 66, 27, 2, 10, 64, 64, 0, 2, 11, 69, 79, 78, + 88, 19, 68, 7, 1, 78, 5, 71, 9, 3, 65, 5, 10, 2, + 68, 66, 6, 67, 0, 69, 70, 76, 64, 70, 82, 1, 70, + 77, 2, 13, 66, 87, 77, 77, 81, 4, 68, 9, 7, 7, + 42, 19, 5, 69, 14, 69, 83, 0, 109, 73, 64, 91, + 72, 90, 4, 64, 83, 19, 8, 4, 103, 4, 87, 74, 3, + 97, 0, 17, 10, 14, 17, 13, 6, 16, 12, 68, 65, 9, + 0, 64, 75, 70, 76, 75, 71, 74, 80, 80, 78, 78, + 77, 68, 93, 101, 80, 86, 88, 92, 93, 102, 107, + 101, 101, 111, 117, 109, 112, 126, 123, 124, 70, + 74, 95, 81, 89, 92, 99, 107, 111, 100, 104, 98, + 87, 92, 90, 82, 79, 7, 26, 18, 11, 9, 11, 6, 1, + 7, 16, 15, 30, 21, 15, 8, 24, 15, 19, 12, 40, 2, + 44, 31, 22, 14, 28, 5, 64, 64, 5, 70, 47, 17, + 64, 1, 12, 1, 71, 2, 5, 33, 18, 1, 68, 17, 5, 3, + 4, 4, 62, 64, 8, 8, 16, 11, 10, 24, 24, 18, 23, + 29, 34, 64, 7, 75, 64, 40, 70, 95, 67, 10, 66, + 82, 86, 76, 88, 97, 106, 108, 72, 68, 16, 71, + 77, 69, 66, 2, 82, 75, 69, 68, 90, 75, 83, 1, + 11, 89, 75, 4, 81, 1, 78, 69, 21, 81, 86, 66, 3, + 91, 88, 125, 8, 14, 24, 68, 75, 71, 87, 87, 87, + 101, 100, 99, 118, 109, 95, 119, 123, 126, 126, + 118, 114, 104, 83, 90, 6, 26, 4, 27, 50, 86, 89, + 94, 92, 116, 105, 98, 124, 102, 113, 107, 126, + 120, 116, 115, 85, 82, 119, 90, 93, 105, 118, + 112, 113, 113, 108, 118, 115, 117, 123, 126, + 121, 78, 86, 103, 66, 15, 10, 22, 23, 27, 51, + 33, 44, 44, 62, 54, 48, 62, 62, 37, 73, 96, 117, + 126, 126, 126, 126, 126, 17, 51, 44, 44, 31, 46, + 23, 17, 23, 13, 69, 2, 18, 5, 38, 48, 2, 12, 21, + 25, 6, 23, 42, 4, 65, 10, 91, 117, 126, 126, + 126, 126, 126, 126 }, + + }, + + { + + { + + 62, + 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 38, 62, + 62, 54, 22, 118, 65, 71, 79, 11, 13, 70, 9, 29, + 41, 62, 61, 27, 69, 126, 101, 76, 71, 79, 11, + 69, 90, 11, 20, 69, 82, 96, 4, 75, 87, 100, 7, + 74, 85, 4, 81, 86, 95, 66, 77, 70, 86, 72, 2, + 22, 0, 0, 0, 83, 86, 97, 72, 22, 1, 48, 12, 80, + 126, 91, 96, 81, 98, 102, 97, 119, 99, 110, 102, + 126, 80, 89, 94, 92, 24, 65, 84, 126, 73, 104, + 91, 126, 8, 7, 8, 2, 10, 68, 74, 88, 103, 91, + 89, 92, 76, 87, 110, 105, 78, 112, 99, 126, 126, + 126, 126, 66, 78, 71, 72, 4, 8, 70, 75, 89, 119, + 75, 43, 41, 126, 9, 2, 5, 3, 2, 67, 84, 74, 65, + 11, 6, 2, 69, 70, 8, 71, 5, 2, 22, 38, 31, 20, + 16, 19, 12, 17, 25, 66, 25, 21, 29, 89, 18, 35, + 32, 62, 62, 48, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 53, 62, 62, 62, 62, 62, 62, 62, 56, 62, + 62, 62, 27, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 53, 45, 38, 22, 75, 72, 77, 28, 32, 28, + 33, 18, 21, 18, 37, 9, 66, 7, 73, 67, 116, 112, + 71, 2, 10, 66, 77, 80, 84, 87, 126, 101, 24, 10, + 2, 75, 77, 91, 107, 111, 122, 76, 19, 11, 6, 5, + 72, 69, 69, 74, 86, 66, 29, 31, 32, 11, 8, 67, + 73, 89, 11, 59, 55, 55, 44, 26, 2, 73, 70, 78, + 62, 126, 124, 110, 126, 124, 105, 121, 117, 102, + 117, 116, 122, 95, 100, 95, 111, 114, 89, 80, + 82, 85, 81, 72, 64, 67, 7, 69, 69, 69, 69, 67, + 77, 64, 2, 67, 64, 6, 65, 66, 1, 12, 66, 71, 75, + 70, 72, 3, 26, 16, 28, 26, 22, 22, 15, 22, 22, + 4, 13, 23, 66, 13, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 54, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 49, 37, 26, 8, 65, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 43, 33, + 19, 15, 14, 18, 41, 41, 42, 43, 35, 39, 29, 21, + 24, 13, 70, 9, 71, 83, 31, 14, 9, 85, 81, 77, + 81, 80, 73, 74, 83, 71, 67, 2, 66, 66, 4, 4, 62, + 62, 62, 62, 62, 60, 53, 36, 6, 71, 39, 27, 21, + 11, 6, 0, 65, 67, 82, 81, 76, 72, 78, 72, 68, + 70, 76, 66, 1, 6, 2, 3, 9, 5, 62, 62, 62, 62, + 62, 60, 53, 36, 6 }, + + { + + 62, + 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 37, + 61, 62, 55, 22, 116, 65, 70, 78, 11, 13, 69, + 9, 28, 40, 61, 58, 25, 70, 124, 100, 75, 70, + 78, 11, 69, 89, 11, 20, 68, 81, 95, 4, 75, 86, + 99, 7, 73, 84, 4, 80, 85, 94, 65, 76, 70, 85, + 71, 2, 22, 0, 0, 0, 82, 86, 97, 71, 22, 1, 48, + 12, 80, 124, 89, 94, 79, 95, 100, 95, 117, 97, + 108, 100, 124, 80, 88, 93, 91, 24, 65, 83, + 124, 72, 103, 90, 125, 8, 7, 8, 2, 11, 68, 73, + 87, 102, 90, 88, 91, 75, 86, 108, 103, 77, + 110, 97, 122, 122, 123, 124, 65, 77, 70, 71, + 4, 9, 69, 74, 88, 116, 74, 41, 40, 124, 9, 3, + 5, 4, 3, 66, 82, 73, 64, 11, 6, 2, 68, 69, 7, + 70, 5, 2, 22, 37, 31, 20, 16, 19, 12, 17, 24, + 65, 25, 21, 29, 89, 18, 35, 32, 62, 62, 47, + 62, 62, 62, 61, 62, 62, 62, 62, 62, 62, 52, + 62, 62, 62, 62, 62, 62, 62, 54, 62, 60, 62, + 26, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 61, 52, 44, 37, 21, 75, 72, 77, 28, 31, 27, + 32, 17, 20, 17, 36, 8, 66, 6, 73, 67, 115, + 110, 70, 3, 10, 65, 76, 79, 83, 86, 124, 99, + 25, 11, 3, 74, 76, 89, 105, 109, 120, 75, 20, + 12, 7, 6, 71, 68, 68, 73, 85, 66, 30, 31, 32, + 11, 9, 66, 73, 88, 11, 59, 55, 54, 43, 26, 3, + 72, 69, 77, 62, 124, 122, 108, 124, 122, 103, + 119, 115, 100, 115, 114, 119, 94, 99, 94, 109, + 112, 88, 79, 81, 84, 80, 71, 64, 67, 7, 69, + 69, 69, 68, 66, 76, 0, 2, 66, 0, 6, 64, 65, 1, + 12, 65, 70, 74, 69, 71, 3, 25, 16, 27, 26, 22, + 22, 15, 22, 22, 4, 13, 22, 66, 12, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 52, 62, 62, 62, 62, 62, 62, 62, 61, 62, 48, + 36, 25, 8, 65, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 42, 32, 18, 15, 14, 17, 40, + 40, 41, 41, 34, 38, 28, 20, 23, 12, 70, 8, 71, + 83, 30, 13, 8, 84, 80, 76, 80, 78, 71, 73, 82, + 70, 66, 3, 65, 65, 4, 4, 62, 62, 62, 62, 60, + 56, 49, 32, 4, 70, 39, 28, 22, 12, 7, 1, 64, + 66, 81, 80, 75, 71, 77, 71, 67, 69, 75, 65, 2, + 6, 3, 4, 9, 5, 62, 62, 62, 62, 60, 56, 49, 32, + 4 }, + + { + + 62, + 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 36, + 59, 61, 55, 22, 114, 65, 70, 77, 11, 12, 69, + 8, 26, 39, 58, 54, 22, 72, 121, 99, 75, 70, + 77, 11, 69, 88, 11, 19, 68, 81, 94, 4, 75, 86, + 99, 7, 73, 84, 4, 80, 85, 94, 65, 76, 70, 85, + 71, 2, 22, 0, 0, 0, 81, 86, 97, 71, 21, 1, 47, + 12, 80, 122, 88, 93, 77, 93, 99, 94, 115, 96, + 107, 99, 122, 80, 88, 93, 91, 24, 65, 82, 122, + 72, 102, 89, 123, 8, 7, 8, 1, 11, 68, 73, 86, + 101, 89, 87, 90, 75, 85, 107, 102, 76, 109, + 96, 117, 118, 120, 121, 65, 77, 70, 71, 4, 9, + 69, 74, 88, 114, 74, 39, 38, 121, 9, 3, 5, 4, + 3, 66, 80, 72, 64, 11, 6, 2, 67, 68, 6, 70, 5, + 2, 21, 36, 30, 20, 15, 19, 12, 17, 23, 65, 24, + 20, 28, 89, 18, 34, 31, 62, 62, 46, 60, 62, + 62, 59, 62, 62, 62, 62, 62, 62, 50, 62, 62, + 62, 62, 62, 62, 62, 52, 62, 58, 62, 24, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 50, + 42, 35, 19, 75, 72, 78, 27, 30, 26, 31, 16, + 19, 16, 34, 7, 66, 5, 74, 68, 114, 109, 69, 3, + 10, 65, 75, 78, 82, 85, 122, 98, 25, 11, 3, + 73, 75, 88, 103, 107, 118, 74, 21, 13, 8, 7, + 70, 68, 68, 73, 84, 66, 31, 31, 31, 11, 9, 66, + 73, 88, 11, 59, 54, 53, 42, 26, 3, 72, 69, 77, + 62, 123, 121, 107, 122, 120, 102, 117, 113, + 99, 113, 112, 117, 93, 98, 94, 108, 110, 88, + 79, 81, 83, 80, 71, 64, 67, 6, 69, 69, 69, 68, + 66, 75, 0, 2, 66, 0, 6, 64, 65, 1, 11, 65, 70, + 74, 69, 70, 2, 24, 16, 26, 25, 21, 21, 15, 21, + 21, 4, 13, 21, 66, 11, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 50, 62, 62, + 62, 62, 62, 62, 62, 59, 59, 46, 34, 24, 7, 66, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 40, 30, 16, 14, 13, 15, 39, 39, 39, 39, + 32, 36, 26, 19, 21, 11, 71, 7, 72, 84, 28, 12, + 7, 84, 80, 75, 80, 77, 70, 73, 81, 69, 65, 3, + 65, 64, 4, 4, 62, 62, 62, 62, 57, 52, 45, 28, + 1, 70, 39, 28, 22, 12, 8, 1, 64, 66, 81, 80, + 75, 71, 77, 70, 66, 69, 75, 65, 2, 6, 3, 5, 9, + 5, 62, 62, 62, 62, 57, 52, 45, 28, 1 }, + + { + + 62, + 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 34, 57, + 60, 55, 22, 112, 65, 69, 76, 11, 12, 69, 8, + 25, 38, 56, 51, 20, 73, 118, 98, 75, 69, 76, + 11, 70, 87, 11, 19, 68, 81, 94, 4, 75, 86, 99, + 7, 73, 83, 4, 80, 84, 94, 65, 76, 70, 85, 71, + 2, 22, 0, 0, 0, 81, 86, 97, 70, 20, 1, 46, 11, + 80, 119, 87, 92, 76, 91, 97, 92, 113, 94, 106, + 98, 120, 80, 88, 92, 91, 24, 65, 81, 120, 72, + 101, 89, 121, 8, 6, 7, 1, 11, 68, 72, 86, 100, + 88, 87, 89, 74, 84, 105, 100, 76, 108, 95, + 112, 113, 117, 118, 65, 77, 70, 70, 4, 9, 68, + 73, 87, 112, 74, 37, 36, 118, 9, 3, 5, 4, 3, + 65, 79, 71, 64, 11, 6, 2, 67, 67, 5, 70, 5, 1, + 21, 35, 30, 20, 15, 19, 12, 17, 22, 65, 23, + 19, 28, 89, 18, 34, 31, 62, 62, 45, 58, 62, + 62, 57, 62, 62, 62, 62, 62, 61, 48, 62, 62, + 62, 62, 62, 62, 60, 50, 62, 56, 62, 22, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 48, + 40, 34, 17, 75, 72, 78, 26, 29, 25, 30, 15, + 18, 15, 32, 6, 67, 4, 75, 68, 114, 107, 68, 4, + 10, 65, 74, 78, 82, 85, 120, 97, 25, 11, 4, + 72, 74, 87, 102, 106, 116, 73, 21, 13, 8, 7, + 69, 67, 68, 73, 84, 66, 31, 31, 30, 11, 9, 66, + 73, 87, 11, 58, 54, 52, 41, 26, 3, 72, 69, 77, + 62, 122, 119, 106, 121, 119, 101, 115, 111, + 98, 112, 110, 115, 93, 97, 93, 107, 108, 87, + 79, 81, 83, 79, 71, 64, 67, 6, 69, 69, 70, 67, + 65, 74, 0, 2, 65, 0, 6, 64, 65, 1, 11, 65, 70, + 74, 69, 70, 1, 23, 16, 25, 24, 20, 21, 15, 20, + 20, 4, 13, 20, 66, 10, 62, 62, 61, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 48, 62, 62, + 62, 62, 62, 62, 62, 57, 57, 44, 32, 22, 6, 67, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, + 60, 38, 28, 15, 13, 12, 14, 37, 37, 37, 37, + 31, 34, 24, 18, 20, 10, 72, 6, 73, 85, 27, 11, + 6, 84, 79, 75, 79, 76, 69, 73, 81, 69, 65, 3, + 64, 0, 4, 4, 62, 62, 62, 59, 54, 48, 41, 24, + 65, 70, 39, 28, 22, 12, 8, 2, 64, 66, 80, 80, + 75, 70, 76, 69, 65, 69, 74, 65, 2, 6, 3, 5, 9, + 5, 62, 62, 62, 59, 54, 48, 41, 24, 65 }, + + { + + 62, + 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 33, 55, + 59, 55, 21, 110, 65, 69, 75, 10, 11, 69, 7, + 23, 37, 53, 47, 17, 75, 115, 97, 75, 69, 75, + 10, 70, 86, 11, 18, 68, 80, 93, 4, 75, 86, 99, + 7, 73, 83, 4, 80, 84, 93, 65, 76, 70, 85, 70, + 2, 22, 0, 0, 0, 80, 87, 97, 70, 19, 1, 45, 11, + 80, 117, 86, 91, 74, 89, 96, 91, 112, 93, 104, + 97, 118, 80, 87, 92, 91, 24, 65, 80, 118, 72, + 101, 88, 119, 8, 6, 7, 0, 11, 68, 72, 85, 99, + 87, 86, 88, 74, 84, 104, 99, 75, 107, 94, 107, + 109, 114, 115, 65, 76, 70, 70, 4, 9, 68, 73, + 87, 110, 74, 35, 34, 116, 9, 4, 5, 4, 3, 65, + 77, 70, 0, 10, 6, 2, 66, 67, 4, 70, 5, 1, 20, + 34, 29, 19, 14, 19, 12, 17, 21, 65, 22, 18, + 27, 89, 17, 33, 30, 62, 62, 44, 56, 62, 62, + 55, 62, 62, 62, 62, 62, 59, 46, 59, 62, 62, + 62, 62, 62, 57, 48, 62, 54, 62, 21, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 60, 55, 46, 38, + 32, 15, 75, 72, 79, 25, 28, 24, 28, 14, 16, + 14, 31, 5, 67, 3, 75, 69, 113, 106, 67, 4, 10, + 64, 74, 77, 81, 84, 118, 95, 25, 12, 4, 72, + 73, 86, 100, 104, 115, 73, 22, 14, 9, 8, 68, + 67, 68, 72, 83, 66, 32, 31, 30, 10, 9, 66, 73, + 87, 11, 58, 53, 51, 40, 26, 3, 71, 69, 77, 62, + 120, 118, 105, 119, 117, 100, 114, 110, 97, + 110, 109, 113, 92, 96, 93, 106, 107, 87, 79, + 81, 82, 79, 71, 65, 67, 5, 69, 69, 70, 67, 65, + 73, 0, 2, 65, 0, 6, 64, 65, 1, 10, 65, 70, 74, + 69, 69, 0, 22, 16, 24, 24, 19, 20, 15, 19, 19, + 4, 13, 19, 66, 9, 62, 62, 60, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 46, 62, 62, 62, + 62, 62, 62, 62, 54, 54, 42, 30, 21, 5, 67, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 57, + 36, 26, 13, 12, 12, 12, 36, 36, 36, 35, 29, + 32, 23, 17, 18, 9, 73, 4, 74, 85, 25, 9, 4, + 83, 79, 74, 79, 75, 68, 73, 80, 68, 64, 3, 64, + 1, 4, 4, 62, 62, 62, 56, 50, 44, 36, 20, 68, + 69, 39, 28, 22, 12, 9, 2, 64, 66, 80, 80, 75, + 70, 76, 69, 64, 69, 74, 64, 3, 6, 3, 6, 9, 5, + 62, 62, 62, 56, 50, 44, 36, 20, 68 }, + + { + + 62, + 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 32, 53, + 58, 55, 21, 108, 65, 69, 74, 10, 11, 69, 6, + 21, 36, 51, 44, 15, 77, 112, 96, 74, 69, 74, + 10, 70, 85, 11, 18, 68, 80, 92, 4, 75, 86, 99, + 7, 73, 83, 4, 80, 83, 93, 65, 76, 70, 85, 70, + 2, 22, 0, 0, 0, 80, 87, 97, 69, 18, 1, 44, 10, + 80, 114, 85, 90, 72, 87, 94, 89, 110, 91, 103, + 96, 115, 80, 87, 91, 90, 24, 65, 79, 116, 72, + 100, 88, 117, 8, 5, 6, 0, 11, 68, 71, 85, 98, + 86, 86, 87, 73, 83, 102, 97, 74, 105, 93, 102, + 105, 111, 112, 64, 76, 69, 69, 4, 9, 67, 73, + 86, 108, 74, 33, 32, 113, 9, 4, 5, 4, 3, 64, + 76, 69, 0, 10, 6, 2, 66, 66, 3, 69, 5, 0, 20, + 33, 29, 19, 14, 19, 12, 17, 20, 64, 21, 18, + 27, 89, 17, 32, 29, 62, 62, 43, 55, 62, 62, + 53, 62, 62, 62, 62, 61, 57, 44, 57, 62, 60, + 62, 62, 62, 55, 46, 62, 52, 62, 19, 62, 62, + 62, 62, 62, 62, 62, 62, 61, 58, 53, 44, 37, + 30, 13, 75, 72, 79, 24, 27, 23, 27, 13, 15, + 13, 29, 4, 68, 2, 76, 70, 112, 104, 66, 5, 10, + 64, 73, 77, 81, 83, 116, 94, 25, 12, 5, 71, + 72, 85, 99, 103, 113, 72, 23, 15, 10, 8, 67, + 66, 67, 72, 83, 66, 32, 31, 29, 10, 9, 66, 73, + 86, 11, 57, 52, 50, 39, 26, 3, 71, 69, 76, 62, + 119, 116, 103, 117, 116, 99, 112, 108, 96, + 108, 107, 111, 91, 95, 92, 105, 105, 87, 79, + 80, 82, 78, 71, 65, 67, 5, 69, 69, 71, 66, 65, + 72, 0, 2, 65, 0, 6, 64, 65, 1, 10, 65, 70, 74, + 69, 69, 64, 21, 16, 23, 23, 19, 19, 15, 19, + 18, 4, 13, 18, 66, 8, 62, 62, 59, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 44, 62, 62, + 62, 62, 62, 62, 61, 52, 52, 40, 29, 19, 5, 68, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 55, + 54, 34, 24, 12, 12, 11, 10, 35, 34, 34, 33, + 27, 30, 21, 16, 17, 8, 73, 3, 75, 86, 24, 8, + 3, 83, 79, 73, 78, 74, 67, 72, 79, 68, 64, 3, + 0, 2, 4, 4, 62, 62, 59, 53, 47, 40, 32, 16, + 71, 69, 39, 28, 22, 12, 9, 2, 0, 65, 79, 80, + 75, 69, 76, 68, 0, 69, 74, 64, 3, 6, 4, 6, 9, + 5, 62, 62, 59, 53, 47, 40, 32, 16, 71 }, + + { + + 62, + 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 30, 51, + 57, 55, 21, 107, 65, 68, 74, 10, 10, 68, 6, + 20, 34, 48, 40, 12, 78, 110, 95, 74, 68, 74, + 10, 71, 85, 11, 17, 68, 80, 92, 4, 75, 85, 98, + 7, 72, 82, 4, 79, 83, 93, 65, 76, 70, 85, 70, + 2, 22, 0, 0, 0, 79, 87, 97, 69, 18, 0, 44, 10, + 80, 112, 84, 89, 71, 84, 93, 88, 108, 90, 102, + 95, 113, 80, 87, 91, 90, 24, 65, 78, 113, 72, + 99, 87, 115, 7, 5, 6, 64, 12, 68, 71, 84, 98, + 86, 85, 86, 73, 82, 101, 96, 74, 104, 92, 97, + 100, 108, 109, 64, 76, 69, 69, 4, 9, 67, 72, + 86, 106, 73, 31, 30, 110, 9, 4, 5, 4, 4, 64, + 74, 68, 0, 10, 6, 2, 65, 65, 2, 69, 5, 0, 19, + 32, 28, 19, 13, 19, 12, 17, 18, 64, 20, 17, + 26, 89, 17, 32, 29, 62, 62, 42, 53, 62, 62, + 51, 62, 62, 62, 62, 57, 55, 43, 55, 62, 58, + 62, 62, 62, 52, 44, 62, 50, 62, 17, 62, 62, + 62, 62, 62, 62, 62, 62, 59, 56, 50, 42, 35, + 29, 12, 75, 72, 80, 23, 26, 22, 26, 12, 14, + 12, 27, 3, 68, 1, 77, 70, 112, 103, 65, 5, 10, + 64, 72, 76, 80, 83, 114, 93, 26, 12, 5, 70, + 71, 84, 97, 101, 111, 71, 23, 15, 10, 9, 66, + 66, 67, 72, 82, 66, 33, 31, 28, 10, 9, 66, 73, + 86, 10, 57, 52, 49, 38, 25, 3, 71, 69, 76, 62, + 118, 115, 102, 116, 114, 98, 110, 106, 95, + 107, 105, 109, 91, 94, 92, 104, 103, 86, 79, + 80, 81, 78, 71, 65, 67, 4, 69, 69, 71, 66, 64, + 71, 0, 2, 64, 1, 6, 0, 64, 1, 9, 65, 70, 74, + 69, 68, 65, 20, 16, 22, 22, 18, 19, 15, 18, + 18, 4, 12, 16, 67, 7, 62, 62, 58, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 42, 62, 62, + 62, 62, 62, 62, 58, 50, 49, 38, 27, 18, 4, 69, + 62, 62, 62, 62, 62, 62, 62, 62, 61, 58, 52, + 51, 32, 23, 10, 11, 10, 9, 33, 33, 32, 31, 26, + 28, 19, 15, 15, 7, 74, 2, 76, 87, 22, 7, 2, + 83, 78, 73, 78, 73, 66, 72, 79, 67, 0, 3, 0, + 3, 4, 4, 62, 62, 57, 50, 44, 36, 28, 12, 74, + 69, 39, 28, 22, 12, 10, 3, 0, 65, 79, 79, 74, + 69, 75, 67, 1, 68, 73, 64, 3, 6, 4, 7, 9, 5, + 62, 62, 57, 50, 44, 36, 28, 12, 74 }, + + { + + 62, + 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 29, 49, + 56, 55, 21, 105, 65, 68, 73, 9, 10, 68, 5, 18, + 33, 46, 37, 10, 80, 107, 94, 74, 68, 73, 9, + 71, 84, 11, 17, 68, 79, 91, 4, 75, 85, 98, 7, + 72, 82, 4, 79, 82, 92, 65, 76, 70, 85, 69, 2, + 22, 0, 0, 0, 79, 87, 97, 68, 17, 0, 43, 9, 80, + 109, 83, 88, 69, 82, 91, 86, 107, 88, 100, 94, + 111, 80, 86, 90, 90, 24, 65, 77, 111, 72, 98, + 87, 113, 7, 4, 5, 64, 12, 68, 70, 84, 97, 85, + 85, 85, 72, 81, 99, 94, 73, 103, 91, 92, 96, + 105, 106, 64, 75, 69, 68, 4, 9, 66, 72, 85, + 104, 73, 29, 28, 107, 9, 5, 5, 4, 4, 0, 73, + 67, 1, 9, 6, 2, 65, 65, 1, 69, 5, 64, 19, 31, + 28, 18, 13, 19, 12, 17, 17, 64, 19, 16, 26, + 89, 17, 31, 28, 60, 62, 41, 51, 62, 62, 49, + 62, 61, 62, 62, 54, 53, 41, 52, 62, 55, 62, + 62, 62, 49, 42, 62, 48, 62, 16, 62, 62, 62, + 62, 62, 62, 62, 62, 57, 53, 48, 40, 33, 27, + 10, 75, 72, 80, 22, 25, 21, 24, 11, 13, 11, + 26, 2, 69, 0, 77, 71, 111, 101, 64, 6, 10, 0, + 72, 76, 80, 82, 112, 91, 26, 13, 6, 70, 70, + 83, 96, 100, 109, 71, 24, 16, 11, 9, 65, 65, + 67, 71, 82, 66, 33, 31, 28, 9, 9, 66, 73, 85, + 10, 56, 51, 48, 37, 25, 3, 70, 69, 76, 62, + 116, 113, 101, 114, 113, 97, 109, 105, 94, + 105, 104, 107, 90, 93, 91, 103, 101, 86, 79, + 80, 81, 77, 71, 66, 67, 4, 69, 69, 72, 65, 64, + 70, 0, 2, 64, 1, 6, 0, 64, 1, 9, 65, 70, 74, + 69, 68, 66, 19, 16, 21, 22, 17, 18, 15, 17, + 17, 4, 12, 15, 67, 6, 61, 62, 57, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 40, 62, 62, + 62, 62, 62, 62, 56, 48, 47, 36, 25, 16, 3, 69, + 62, 62, 62, 62, 62, 62, 62, 62, 59, 56, 50, + 48, 30, 21, 9, 10, 10, 7, 32, 31, 31, 29, 24, + 26, 18, 14, 14, 6, 75, 0, 77, 87, 21, 5, 0, + 82, 78, 72, 77, 72, 65, 72, 78, 67, 0, 3, 1, + 4, 4, 4, 62, 62, 54, 47, 40, 32, 24, 8, 77, + 68, 39, 28, 22, 12, 10, 3, 0, 65, 78, 79, 74, + 68, 75, 66, 2, 68, 73, 0, 4, 6, 4, 7, 9, 5, + 62, 62, 54, 47, 40, 32, 24, 8, 77 }, + + { + + 62, + 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 27, 46, + 55, 55, 20, 103, 66, 68, 72, 9, 9, 68, 4, 16, + 32, 43, 33, 7, 82, 104, 93, 74, 68, 72, 9, 72, + 83, 11, 16, 68, 79, 91, 3, 76, 85, 98, 7, 72, + 82, 4, 79, 82, 92, 65, 76, 70, 85, 69, 2, 22, + 0, 0, 0, 78, 88, 97, 68, 16, 0, 42, 9, 81, + 107, 82, 87, 68, 80, 90, 85, 105, 87, 99, 93, + 109, 80, 86, 90, 90, 24, 65, 76, 109, 72, 98, + 86, 111, 7, 4, 5, 65, 12, 68, 70, 83, 96, 84, + 84, 85, 72, 81, 98, 93, 73, 102, 90, 88, 92, + 102, 104, 64, 75, 69, 68, 3, 9, 66, 72, 85, + 102, 73, 27, 26, 105, 9, 5, 5, 4, 4, 0, 71, + 67, 1, 9, 5, 2, 64, 64, 64, 69, 5, 64, 18, 29, + 27, 18, 12, 19, 12, 16, 16, 64, 18, 15, 25, + 89, 16, 30, 27, 58, 62, 39, 49, 62, 62, 46, + 62, 59, 62, 62, 50, 51, 39, 50, 62, 53, 62, + 62, 62, 46, 40, 62, 46, 62, 14, 62, 62, 62, + 62, 62, 62, 62, 60, 55, 51, 46, 38, 31, 25, 8, + 75, 73, 81, 21, 23, 20, 23, 10, 11, 9, 24, 1, + 69, 64, 78, 72, 111, 100, 0, 6, 10, 0, 71, 75, + 79, 82, 110, 90, 26, 13, 6, 69, 69, 82, 94, + 98, 108, 70, 24, 16, 11, 10, 64, 65, 67, 71, + 81, 67, 34, 31, 27, 9, 9, 66, 73, 85, 10, 56, + 50, 47, 36, 25, 3, 70, 69, 76, 62, 115, 112, + 100, 113, 111, 96, 107, 103, 93, 104, 102, + 105, 90, 93, 91, 102, 100, 86, 79, 80, 80, 77, + 71, 66, 67, 3, 69, 69, 72, 65, 64, 69, 0, 1, + 64, 1, 5, 0, 64, 1, 8, 65, 70, 74, 69, 67, 67, + 18, 16, 19, 21, 16, 17, 14, 16, 16, 4, 12, 14, + 67, 4, 60, 60, 56, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 60, 38, 62, 62, 62, 62, 62, 62, + 53, 45, 44, 34, 23, 15, 2, 70, 62, 62, 62, 62, + 62, 62, 62, 62, 56, 53, 47, 45, 28, 19, 7, 9, + 9, 5, 30, 30, 29, 27, 22, 24, 16, 12, 12, 4, + 76, 64, 78, 88, 19, 4, 64, 82, 78, 72, 77, 71, + 64, 72, 78, 66, 1, 3, 1, 4, 4, 3, 62, 60, 51, + 44, 37, 28, 19, 3, 80, 68, 39, 28, 22, 12, 11, + 3, 0, 65, 78, 79, 74, 68, 75, 66, 2, 68, 73, + 0, 4, 6, 4, 8, 9, 4, 62, 60, 51, 44, 37, 28, + 19, 3, 80 }, + + { + + 62, + 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 26, 44, + 54, 56, 20, 101, 66, 67, 71, 9, 8, 68, 4, 15, + 31, 41, 29, 4, 83, 101, 92, 73, 67, 71, 9, 72, + 82, 11, 16, 67, 79, 90, 3, 76, 85, 98, 7, 72, + 81, 4, 79, 82, 92, 65, 76, 70, 84, 69, 2, 22, + 0, 0, 0, 77, 88, 97, 68, 15, 0, 41, 9, 81, + 105, 80, 86, 66, 78, 88, 84, 103, 85, 98, 91, + 106, 80, 86, 90, 89, 24, 65, 75, 107, 71, 97, + 85, 109, 7, 4, 5, 65, 12, 68, 70, 82, 95, 83, + 83, 84, 71, 80, 97, 91, 72, 100, 89, 83, 87, + 98, 101, 0, 75, 68, 67, 3, 9, 66, 71, 84, 99, + 73, 25, 25, 102, 9, 5, 5, 4, 4, 1, 69, 66, 1, + 9, 5, 2, 0, 0, 65, 68, 5, 64, 17, 28, 26, 18, + 11, 19, 12, 16, 15, 0, 17, 15, 24, 89, 16, 30, + 27, 56, 62, 38, 48, 62, 62, 44, 60, 57, 62, + 62, 47, 49, 37, 48, 62, 51, 62, 62, 62, 44, + 38, 62, 44, 62, 12, 62, 62, 62, 62, 62, 62, + 60, 58, 53, 49, 44, 37, 30, 24, 6, 75, 73, 81, + 21, 22, 19, 22, 9, 10, 8, 22, 0, 69, 65, 79, + 72, 110, 99, 1, 6, 10, 0, 70, 74, 78, 81, 107, + 89, 26, 13, 6, 68, 68, 81, 92, 96, 106, 69, + 25, 17, 12, 11, 0, 65, 66, 71, 80, 67, 35, 31, + 26, 9, 10, 65, 73, 84, 10, 56, 50, 46, 35, 25, + 3, 70, 69, 75, 62, 114, 111, 98, 111, 109, 95, + 105, 101, 92, 102, 100, 103, 89, 92, 90, 101, + 98, 85, 78, 79, 79, 76, 71, 66, 67, 2, 69, 69, + 72, 65, 0, 68, 1, 1, 0, 1, 5, 0, 64, 1, 7, 65, + 69, 73, 69, 66, 67, 17, 16, 18, 20, 16, 17, + 14, 16, 15, 4, 12, 13, 67, 3, 59, 59, 56, 61, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 36, + 62, 62, 62, 62, 62, 62, 50, 43, 42, 33, 22, + 14, 2, 71, 62, 62, 62, 62, 62, 62, 62, 62, 54, + 51, 45, 43, 26, 17, 5, 9, 8, 4, 29, 29, 27, + 25, 21, 23, 14, 11, 10, 3, 76, 65, 78, 89, 17, + 3, 65, 82, 77, 71, 77, 70, 1, 71, 77, 65, 2, + 3, 2, 5, 4, 3, 62, 58, 49, 41, 34, 24, 15, 64, + 83, 68, 39, 28, 23, 13, 12, 4, 1, 64, 78, 79, + 74, 68, 74, 65, 3, 68, 72, 0, 4, 6, 5, 9, 9, + 4, 62, 58, 49, 41, 34, 24, 15, 64, 83 }, + + { + + 62, + 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 25, 42, + 53, 56, 20, 99, 66, 67, 70, 8, 8, 68, 3, 13, + 30, 38, 26, 2, 85, 98, 91, 73, 67, 70, 8, 72, + 81, 11, 15, 67, 78, 89, 3, 76, 85, 98, 7, 72, + 81, 4, 79, 81, 91, 65, 76, 70, 84, 68, 2, 22, + 0, 0, 0, 77, 88, 97, 67, 14, 0, 40, 8, 81, + 102, 79, 85, 64, 76, 87, 82, 102, 84, 96, 90, + 104, 80, 85, 89, 89, 24, 65, 74, 105, 71, 96, + 85, 107, 7, 3, 4, 66, 12, 68, 69, 82, 94, 82, + 83, 83, 71, 79, 95, 90, 71, 99, 88, 78, 83, + 95, 98, 0, 74, 68, 67, 3, 9, 65, 71, 84, 97, + 73, 23, 23, 99, 9, 6, 5, 4, 4, 1, 68, 65, 2, + 8, 5, 2, 0, 0, 66, 68, 5, 65, 17, 27, 26, 17, + 11, 19, 12, 16, 14, 0, 16, 14, 24, 89, 16, 29, + 26, 54, 62, 37, 46, 62, 62, 42, 57, 55, 62, + 62, 43, 47, 35, 45, 61, 48, 62, 62, 62, 41, + 36, 58, 42, 62, 11, 62, 62, 62, 62, 62, 60, + 58, 56, 51, 46, 42, 35, 28, 22, 4, 75, 73, 82, + 20, 21, 18, 20, 8, 9, 7, 21, 64, 70, 66, 79, + 73, 109, 97, 2, 7, 10, 1, 70, 74, 78, 80, 105, + 87, 26, 14, 7, 68, 67, 80, 91, 95, 104, 69, + 26, 18, 13, 11, 1, 64, 66, 70, 80, 67, 35, 31, + 26, 8, 10, 65, 73, 84, 10, 55, 49, 45, 34, 25, + 3, 69, 69, 75, 62, 112, 109, 97, 109, 108, 94, + 104, 100, 91, 100, 99, 101, 88, 91, 90, 100, + 96, 85, 78, 79, 79, 76, 71, 67, 67, 2, 69, 69, + 73, 64, 0, 67, 1, 1, 0, 1, 5, 0, 64, 1, 7, 65, + 69, 73, 69, 66, 68, 16, 16, 17, 20, 15, 16, + 14, 15, 14, 4, 12, 12, 67, 2, 58, 58, 55, 59, + 60, 62, 62, 62, 62, 62, 62, 62, 62, 55, 34, + 62, 62, 62, 62, 62, 62, 48, 41, 39, 31, 20, + 12, 1, 71, 62, 62, 62, 62, 62, 62, 62, 62, 52, + 48, 43, 40, 24, 15, 4, 8, 8, 2, 28, 27, 26, + 23, 19, 21, 13, 10, 9, 2, 77, 67, 79, 89, 16, + 1, 67, 81, 77, 70, 76, 69, 2, 71, 76, 65, 2, + 3, 2, 6, 4, 3, 62, 56, 46, 38, 30, 20, 11, 68, + 86, 67, 39, 28, 23, 13, 12, 4, 1, 64, 77, 79, + 74, 67, 74, 64, 4, 68, 72, 1, 5, 6, 5, 9, 9, + 4, 62, 56, 46, 38, 30, 20, 11, 68, 86 }, + + { + + 62, + 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 23, 40, + 52, 56, 20, 98, 66, 66, 70, 8, 7, 67, 3, 12, + 28, 36, 22, 64, 86, 96, 90, 73, 66, 70, 8, 73, + 81, 11, 15, 67, 78, 89, 3, 76, 84, 97, 7, 71, + 80, 4, 78, 81, 91, 65, 76, 70, 84, 68, 2, 22, + 0, 0, 0, 76, 88, 97, 67, 14, 64, 40, 8, 81, + 100, 78, 84, 0, 73, 85, 81, 100, 82, 95, 89, + 102, 80, 85, 89, 89, 24, 65, 73, 102, 71, 95, + 84, 105, 6, 3, 4, 66, 13, 68, 69, 81, 94, 82, + 82, 82, 70, 78, 94, 88, 71, 98, 87, 73, 78, + 92, 95, 0, 74, 68, 66, 3, 9, 65, 70, 83, 95, + 72, 21, 21, 96, 9, 6, 5, 4, 5, 2, 66, 64, 2, + 8, 5, 2, 1, 1, 67, 68, 5, 65, 16, 26, 25, 17, + 10, 19, 12, 16, 12, 0, 15, 13, 23, 89, 16, 29, + 26, 52, 62, 36, 44, 61, 62, 40, 55, 53, 62, + 62, 40, 45, 34, 43, 57, 46, 62, 62, 62, 38, + 34, 55, 40, 62, 9, 62, 62, 62, 62, 62, 58, 55, + 54, 49, 44, 39, 33, 26, 21, 3, 75, 73, 82, 19, + 20, 17, 19, 7, 8, 6, 19, 65, 70, 67, 80, 73, + 109, 96, 3, 7, 10, 1, 69, 73, 77, 80, 103, 86, + 27, 14, 7, 67, 66, 79, 89, 93, 102, 68, 26, + 18, 13, 12, 2, 64, 66, 70, 79, 67, 36, 31, 25, + 8, 10, 65, 73, 83, 9, 55, 49, 44, 33, 24, 3, + 69, 69, 75, 62, 111, 108, 96, 108, 106, 93, + 102, 98, 90, 99, 97, 99, 88, 90, 89, 99, 94, + 84, 78, 79, 78, 75, 71, 67, 67, 1, 69, 69, 73, + 64, 1, 66, 1, 1, 1, 2, 5, 1, 0, 1, 6, 65, 69, + 73, 69, 65, 69, 15, 16, 16, 19, 14, 16, 14, + 14, 14, 4, 11, 10, 68, 1, 56, 57, 54, 58, 58, + 62, 62, 62, 62, 62, 62, 62, 62, 52, 32, 62, + 62, 62, 62, 62, 62, 45, 39, 37, 29, 18, 11, 0, + 72, 62, 62, 62, 62, 62, 62, 60, 59, 49, 46, + 40, 37, 22, 14, 2, 7, 7, 1, 26, 26, 24, 21, + 18, 19, 11, 9, 7, 1, 78, 68, 80, 90, 14, 0, + 68, 81, 76, 70, 76, 68, 3, 71, 76, 64, 3, 3, + 3, 7, 4, 3, 62, 54, 44, 35, 27, 16, 7, 72, 89, + 67, 39, 28, 23, 13, 13, 5, 1, 64, 77, 78, 73, + 67, 73, 0, 5, 67, 71, 1, 5, 6, 5, 10, 9, 4, + 62, 54, 44, 35, 27, 16, 7, 72, 89 }, + + { + + 62, + 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 22, 38, + 51, 56, 19, 96, 66, 66, 69, 8, 7, 67, 2, 10, + 27, 33, 19, 66, 88, 93, 89, 73, 66, 69, 8, 73, + 80, 11, 14, 67, 78, 88, 3, 76, 84, 97, 7, 71, + 80, 4, 78, 80, 91, 65, 76, 70, 84, 68, 2, 22, + 0, 0, 0, 76, 89, 97, 66, 13, 64, 39, 7, 81, + 97, 77, 83, 2, 71, 84, 79, 98, 81, 94, 88, + 100, 80, 85, 88, 89, 24, 65, 72, 100, 71, 95, + 84, 103, 6, 2, 3, 67, 13, 68, 68, 81, 93, 81, + 82, 81, 70, 78, 92, 87, 70, 97, 86, 68, 74, + 89, 92, 0, 74, 68, 66, 3, 9, 64, 70, 83, 93, + 72, 19, 19, 94, 9, 6, 5, 4, 5, 2, 65, 0, 2, 8, + 5, 2, 1, 2, 68, 68, 5, 66, 16, 25, 25, 17, 10, + 19, 12, 16, 11, 0, 14, 12, 23, 89, 15, 28, 25, + 50, 62, 35, 42, 59, 60, 38, 52, 51, 62, 62, + 36, 43, 32, 41, 54, 43, 58, 62, 62, 35, 32, + 51, 38, 62, 7, 62, 62, 62, 62, 62, 56, 53, 52, + 47, 42, 37, 31, 24, 19, 1, 75, 73, 83, 18, 19, + 16, 18, 6, 6, 5, 17, 66, 71, 68, 81, 74, 108, + 94, 4, 8, 10, 1, 68, 73, 77, 79, 101, 85, 27, + 14, 8, 66, 65, 78, 88, 92, 101, 67, 27, 19, + 14, 12, 3, 0, 66, 70, 79, 67, 36, 31, 24, 8, + 10, 65, 73, 83, 9, 54, 48, 43, 32, 24, 3, 69, + 69, 75, 62, 110, 106, 95, 106, 105, 92, 100, + 96, 89, 97, 95, 97, 87, 89, 89, 98, 93, 84, + 78, 79, 78, 75, 71, 67, 67, 1, 69, 69, 74, 0, + 1, 65, 1, 1, 1, 2, 5, 1, 0, 1, 6, 65, 69, 73, + 69, 65, 70, 14, 16, 15, 18, 13, 15, 14, 13, + 13, 4, 11, 9, 68, 0, 55, 56, 53, 56, 56, 62, + 61, 62, 62, 62, 62, 62, 61, 50, 30, 62, 62, + 62, 62, 62, 59, 43, 36, 34, 27, 16, 9, 64, 73, + 62, 62, 62, 62, 62, 62, 57, 56, 47, 43, 38, + 34, 20, 12, 1, 6, 6, 64, 25, 24, 22, 19, 16, + 17, 9, 8, 6, 0, 79, 69, 81, 91, 13, 64, 69, + 81, 76, 69, 75, 67, 4, 71, 75, 64, 3, 3, 3, 8, + 4, 3, 61, 52, 41, 32, 24, 12, 2, 76, 92, 67, + 39, 28, 23, 13, 13, 5, 1, 64, 76, 78, 73, 66, + 73, 0, 6, 67, 71, 1, 5, 6, 5, 10, 9, 4, 61, + 52, 41, 32, 24, 12, 2, 76, 92 }, + + { + + 62, + 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 21, 36, + 50, 56, 19, 94, 66, 66, 68, 7, 6, 67, 1, 8, + 26, 31, 15, 69, 90, 90, 88, 72, 66, 68, 7, 73, + 79, 11, 14, 67, 77, 87, 3, 76, 84, 97, 7, 71, + 80, 4, 78, 80, 90, 65, 76, 70, 84, 67, 2, 22, + 0, 0, 0, 75, 89, 97, 66, 12, 64, 38, 7, 81, + 95, 76, 82, 4, 69, 82, 78, 97, 79, 92, 87, 97, + 80, 84, 88, 88, 24, 65, 71, 98, 71, 94, 83, + 101, 6, 2, 3, 67, 13, 68, 68, 80, 92, 80, 81, + 80, 69, 77, 91, 85, 69, 95, 85, 0, 70, 86, 89, + 1, 73, 67, 65, 3, 9, 64, 70, 82, 91, 72, 17, + 17, 91, 9, 7, 5, 4, 5, 3, 0, 1, 3, 7, 5, 2, 2, + 2, 69, 67, 5, 66, 15, 24, 24, 16, 9, 19, 12, + 16, 10, 1, 13, 12, 22, 89, 15, 27, 24, 48, 62, + 34, 41, 57, 58, 36, 50, 49, 62, 62, 33, 41, + 30, 38, 51, 41, 55, 62, 62, 33, 30, 48, 36, + 62, 6, 62, 62, 62, 61, 60, 54, 51, 50, 45, 39, + 35, 29, 23, 17, 64, 75, 73, 83, 17, 18, 15, + 16, 5, 5, 4, 16, 67, 71, 69, 81, 75, 107, 93, + 5, 8, 10, 2, 68, 72, 76, 78, 99, 83, 27, 15, + 8, 66, 64, 77, 86, 90, 99, 67, 28, 20, 15, 13, + 4, 0, 65, 69, 78, 67, 37, 31, 24, 7, 10, 65, + 73, 82, 9, 54, 47, 42, 31, 24, 3, 68, 69, 74, + 62, 108, 105, 93, 104, 103, 91, 99, 95, 88, + 95, 94, 95, 86, 88, 88, 97, 91, 84, 78, 78, + 77, 74, 71, 68, 67, 0, 69, 69, 74, 0, 1, 64, + 1, 1, 1, 2, 5, 1, 0, 1, 5, 65, 69, 73, 69, 64, + 71, 13, 16, 14, 18, 13, 14, 14, 13, 12, 4, 11, + 8, 68, 64, 54, 55, 52, 54, 54, 62, 59, 61, 62, + 59, 62, 62, 58, 47, 28, 62, 62, 62, 62, 59, + 56, 40, 34, 32, 25, 15, 8, 64, 73, 62, 62, 62, + 62, 59, 59, 55, 53, 45, 41, 36, 31, 18, 10, + 64, 6, 6, 66, 24, 23, 21, 17, 14, 15, 8, 7, 4, + 64, 79, 71, 82, 91, 11, 66, 71, 80, 76, 68, + 75, 66, 5, 70, 74, 0, 4, 3, 4, 9, 4, 3, 60, + 50, 38, 29, 20, 8, 65, 80, 95, 66, 39, 28, 23, + 13, 14, 5, 2, 0, 76, 78, 73, 66, 73, 1, 7, 67, + 71, 2, 6, 6, 6, 11, 9, 4, 60, 50, 38, 29, 20, + 8, 65, 80, 95 }, + + { + + 61, + 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 19, 34, + 49, 56, 19, 92, 66, 65, 67, 7, 6, 67, 1, 7, + 25, 28, 12, 71, 91, 87, 87, 72, 65, 67, 7, 74, + 78, 11, 13, 67, 77, 87, 3, 76, 84, 97, 7, 71, + 79, 4, 78, 79, 90, 65, 76, 70, 84, 67, 2, 22, + 0, 0, 0, 75, 89, 97, 65, 11, 64, 37, 6, 81, + 92, 75, 81, 5, 67, 81, 76, 95, 78, 91, 86, 95, + 80, 84, 87, 88, 24, 65, 70, 96, 71, 93, 83, + 99, 6, 1, 2, 68, 13, 68, 67, 80, 91, 79, 81, + 79, 69, 76, 89, 84, 69, 94, 84, 5, 65, 83, 86, + 1, 73, 67, 65, 3, 9, 0, 69, 82, 89, 72, 15, + 15, 88, 9, 7, 5, 4, 5, 3, 1, 2, 3, 7, 5, 2, 2, + 3, 70, 67, 5, 67, 15, 23, 24, 16, 9, 19, 12, + 16, 9, 1, 12, 11, 22, 89, 15, 27, 24, 46, 61, + 33, 39, 55, 55, 34, 47, 47, 62, 62, 29, 39, + 28, 36, 48, 38, 52, 61, 62, 30, 28, 44, 34, + 62, 4, 60, 62, 60, 58, 57, 52, 49, 48, 43, 37, + 33, 27, 21, 16, 66, 75, 73, 84, 16, 17, 14, + 15, 4, 4, 3, 14, 68, 72, 70, 82, 75, 107, 91, + 6, 9, 10, 2, 67, 72, 76, 78, 97, 82, 27, 15, + 9, 65, 0, 76, 85, 89, 97, 66, 28, 20, 15, 13, + 5, 1, 65, 69, 78, 67, 37, 31, 23, 7, 10, 65, + 73, 82, 9, 53, 47, 41, 30, 24, 3, 68, 69, 74, + 62, 107, 103, 92, 103, 102, 90, 97, 93, 87, + 94, 92, 93, 86, 87, 88, 96, 89, 83, 78, 78, + 77, 74, 71, 68, 67, 0, 69, 69, 75, 1, 2, 0, 1, + 1, 2, 2, 5, 1, 0, 1, 5, 65, 69, 73, 69, 64, + 72, 12, 16, 13, 17, 12, 14, 14, 12, 11, 4, 11, + 7, 68, 65, 53, 54, 51, 53, 52, 60, 57, 59, 59, + 57, 62, 60, 55, 45, 26, 62, 62, 62, 62, 55, + 53, 38, 32, 29, 23, 13, 6, 65, 74, 62, 62, 62, + 60, 56, 57, 52, 50, 42, 38, 33, 28, 16, 8, 65, + 5, 5, 67, 22, 21, 19, 15, 13, 13, 6, 6, 3, 65, + 80, 72, 83, 92, 10, 67, 72, 80, 75, 68, 74, + 65, 6, 70, 74, 0, 4, 3, 4, 10, 4, 3, 59, 48, + 36, 26, 17, 4, 69, 84, 98, 66, 39, 28, 23, 13, + 14, 6, 2, 0, 75, 78, 73, 65, 72, 2, 8, 67, 70, + 2, 6, 6, 6, 11, 9, 4, 59, 48, 36, 26, 17, 4, + 69, 84, 98 }, + + { + + 60, + 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 18, 32, + 48, 56, 19, 90, 66, 65, 66, 7, 5, 67, 0, 5, + 24, 26, 8, 74, 93, 84, 86, 72, 65, 66, 7, 74, + 77, 11, 13, 67, 77, 86, 3, 76, 84, 97, 7, 71, + 79, 4, 78, 79, 90, 65, 76, 70, 84, 67, 2, 22, + 0, 0, 0, 74, 89, 97, 65, 10, 64, 36, 6, 81, + 90, 74, 80, 7, 65, 79, 75, 93, 76, 90, 85, 93, + 80, 84, 87, 88, 24, 65, 69, 94, 71, 92, 82, + 97, 6, 1, 2, 68, 13, 68, 67, 79, 90, 78, 80, + 78, 68, 75, 88, 82, 68, 93, 83, 10, 2, 80, 83, + 1, 73, 67, 64, 3, 9, 0, 69, 81, 87, 72, 13, + 13, 85, 9, 7, 5, 4, 5, 4, 3, 3, 3, 7, 5, 2, 3, + 4, 71, 67, 5, 67, 14, 22, 23, 16, 8, 19, 12, + 16, 8, 1, 11, 10, 21, 89, 15, 26, 23, 44, 58, + 32, 37, 53, 53, 32, 45, 45, 62, 62, 26, 37, + 26, 34, 45, 36, 49, 57, 62, 27, 26, 41, 32, + 62, 2, 58, 62, 58, 56, 55, 50, 47, 46, 41, 35, + 31, 25, 19, 14, 68, 75, 73, 84, 15, 16, 13, + 14, 3, 3, 2, 12, 69, 72, 71, 83, 76, 106, 90, + 7, 9, 10, 2, 66, 71, 75, 77, 95, 81, 27, 15, + 9, 64, 1, 75, 83, 87, 95, 65, 29, 21, 16, 14, + 6, 1, 65, 69, 77, 67, 38, 31, 22, 7, 10, 65, + 73, 81, 9, 53, 46, 40, 29, 24, 3, 68, 69, 74, + 62, 106, 102, 91, 101, 100, 89, 95, 91, 86, + 92, 90, 91, 85, 86, 87, 95, 87, 83, 78, 78, + 76, 73, 71, 68, 67, 64, 69, 69, 75, 1, 2, 1, + 1, 1, 2, 2, 5, 1, 0, 1, 4, 65, 69, 73, 69, 0, + 73, 11, 16, 12, 16, 11, 13, 14, 11, 10, 4, 11, + 6, 68, 66, 52, 53, 50, 51, 50, 58, 55, 57, 57, + 54, 61, 57, 52, 42, 24, 62, 62, 62, 62, 52, + 50, 35, 30, 27, 21, 11, 5, 66, 75, 62, 62, 62, + 58, 53, 54, 50, 47, 40, 36, 31, 25, 14, 6, 67, + 4, 4, 69, 21, 20, 17, 13, 11, 11, 4, 5, 1, 66, + 81, 73, 84, 93, 8, 68, 73, 80, 75, 67, 74, 64, + 7, 70, 73, 1, 5, 3, 5, 11, 4, 3, 58, 46, 33, + 23, 14, 0, 73, 88, 101, 66, 39, 28, 23, 13, + 15, 6, 2, 0, 75, 78, 73, 65, 72, 3, 9, 67, 70, + 2, 6, 6, 6, 12, 9, 4, 58, 46, 33, 23, 14, 0, + 73, 88, 101 }, + + { + + 58, + 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 16, 29, + 47, 56, 18, 89, 67, 65, 66, 6, 4, 67, 64, 3, + 22, 23, 4, 77, 95, 82, 86, 72, 65, 66, 6, 75, + 77, 11, 12, 67, 77, 86, 2, 77, 84, 97, 6, 71, + 79, 4, 78, 79, 90, 65, 76, 71, 84, 67, 2, 22, + 0, 0, 0, 74, 90, 97, 65, 9, 65, 35, 5, 82, 88, + 73, 79, 8, 0, 78, 74, 92, 75, 89, 84, 91, 80, + 84, 87, 88, 24, 65, 69, 92, 71, 92, 82, 96, 5, + 0, 1, 69, 13, 68, 67, 79, 90, 78, 80, 78, 68, + 75, 87, 81, 68, 92, 82, 14, 6, 77, 81, 1, 73, + 67, 64, 2, 9, 0, 69, 81, 85, 72, 11, 11, 83, + 9, 7, 5, 4, 5, 4, 4, 3, 3, 6, 4, 2, 3, 4, 73, + 67, 5, 68, 13, 20, 22, 15, 7, 19, 12, 15, 6, + 1, 10, 9, 20, 89, 14, 25, 22, 41, 54, 30, 35, + 50, 50, 29, 42, 43, 55, 62, 22, 34, 24, 31, + 41, 33, 45, 52, 59, 24, 24, 37, 30, 62, 0, 55, + 59, 55, 53, 52, 47, 44, 43, 39, 32, 28, 23, + 17, 12, 70, 75, 74, 85, 14, 14, 11, 12, 1, 1, + 0, 10, 70, 73, 72, 84, 77, 106, 89, 7, 9, 10, + 2, 66, 71, 75, 77, 93, 80, 27, 15, 9, 64, 1, + 74, 82, 86, 94, 65, 29, 21, 16, 14, 7, 1, 65, + 69, 77, 68, 38, 30, 21, 6, 10, 65, 73, 81, 8, + 52, 45, 38, 28, 23, 3, 68, 69, 74, 62, 105, + 101, 90, 100, 99, 88, 94, 90, 85, 91, 89, 89, + 85, 86, 87, 94, 86, 83, 78, 78, 76, 73, 71, + 69, 68, 65, 69, 70, 76, 1, 2, 2, 1, 0, 2, 2, + 4, 1, 0, 1, 3, 65, 69, 73, 69, 0, 74, 10, 16, + 10, 15, 10, 12, 13, 10, 9, 4, 10, 4, 69, 68, + 50, 51, 49, 49, 48, 55, 52, 54, 54, 51, 58, + 54, 48, 39, 22, 62, 62, 61, 60, 48, 46, 32, + 27, 24, 19, 9, 3, 67, 76, 59, 60, 60, 55, 50, + 51, 47, 43, 37, 33, 28, 22, 12, 4, 69, 3, 3, + 71, 19, 18, 15, 10, 9, 9, 2, 3, 64, 68, 82, + 75, 85, 94, 6, 70, 75, 80, 75, 67, 74, 0, 8, + 70, 73, 1, 5, 3, 5, 11, 4, 2, 56, 44, 30, 19, + 10, 67, 78, 93, 104, 66, 39, 28, 23, 13, 15, + 6, 2, 0, 75, 78, 73, 65, 72, 3, 9, 67, 70, 2, + 6, 6, 6, 12, 8, 3, 56, 44, 30, 19, 10, 67, 78, + 93, 104 }, + + { + + 57, + 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 15, 27, + 46, 57, 18, 87, 67, 64, 65, 6, 4, 66, 64, 2, + 21, 21, 1, 79, 96, 79, 85, 71, 64, 65, 6, 75, + 76, 11, 12, 66, 76, 85, 2, 77, 83, 96, 6, 70, + 78, 4, 77, 78, 89, 64, 75, 71, 83, 66, 2, 22, + 0, 0, 0, 73, 90, 97, 64, 9, 65, 35, 5, 82, 85, + 71, 77, 10, 3, 76, 72, 90, 73, 87, 82, 88, 80, + 83, 86, 87, 24, 65, 68, 89, 70, 91, 81, 94, 5, + 0, 1, 69, 14, 68, 66, 78, 89, 77, 79, 77, 67, + 74, 85, 79, 67, 90, 80, 19, 11, 73, 78, 2, 72, + 66, 0, 2, 10, 1, 68, 80, 82, 71, 9, 10, 80, 9, + 8, 5, 5, 6, 5, 6, 4, 4, 6, 4, 2, 4, 5, 74, 66, + 5, 68, 13, 19, 22, 15, 7, 19, 12, 15, 5, 2, + 10, 9, 20, 89, 14, 25, 22, 39, 51, 29, 34, 48, + 48, 27, 40, 41, 49, 62, 19, 32, 23, 29, 38, + 31, 42, 48, 55, 22, 22, 34, 28, 62, 64, 53, + 57, 53, 51, 50, 45, 42, 41, 37, 30, 26, 22, + 16, 11, 71, 75, 74, 85, 14, 13, 10, 11, 0, 0, + 64, 9, 71, 73, 73, 84, 77, 105, 87, 8, 10, 10, + 3, 65, 70, 74, 76, 90, 78, 28, 16, 10, 0, 2, + 72, 80, 84, 92, 64, 30, 22, 17, 15, 8, 2, 64, + 68, 76, 68, 39, 30, 21, 6, 11, 64, 73, 80, 8, + 52, 45, 37, 27, 23, 4, 67, 68, 73, 62, 103, + 99, 88, 98, 97, 86, 92, 88, 83, 89, 87, 86, + 84, 85, 86, 92, 84, 82, 77, 77, 75, 72, 70, + 69, 68, 65, 69, 70, 76, 2, 3, 3, 2, 0, 3, 3, + 4, 2, 1, 1, 3, 64, 68, 72, 68, 1, 74, 9, 16, + 9, 15, 10, 12, 13, 10, 9, 4, 10, 3, 69, 69, + 49, 50, 49, 48, 47, 53, 50, 52, 52, 49, 56, + 52, 45, 37, 20, 61, 60, 57, 56, 45, 43, 30, + 25, 22, 18, 8, 2, 67, 76, 57, 58, 58, 53, 48, + 49, 45, 40, 35, 31, 26, 20, 11, 3, 70, 3, 3, + 72, 18, 17, 14, 8, 8, 8, 1, 2, 65, 69, 82, 76, + 85, 94, 5, 71, 76, 79, 74, 66, 73, 2, 10, 69, + 72, 2, 6, 4, 6, 12, 4, 2, 55, 42, 28, 16, 7, + 71, 82, 97, 106, 65, 39, 29, 24, 14, 16, 7, 3, + 1, 74, 77, 72, 64, 71, 4, 10, 66, 69, 3, 7, 6, + 7, 13, 8, 3, 55, 42, 28, 16, 7, 71, 82, 97, + 106 }, + + { + + 56, + 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 14, 25, + 45, 57, 18, 85, 67, 64, 64, 6, 3, 66, 65, 0, + 20, 18, 66, 82, 98, 76, 84, 71, 64, 64, 6, 75, + 75, 11, 11, 66, 76, 84, 2, 77, 83, 96, 6, 70, + 78, 4, 77, 78, 89, 64, 75, 71, 83, 66, 2, 22, + 0, 0, 0, 72, 90, 97, 64, 8, 65, 34, 5, 82, 83, + 70, 76, 12, 5, 75, 71, 88, 72, 86, 81, 86, 80, + 83, 86, 87, 24, 65, 67, 87, 70, 90, 80, 92, 5, + 0, 1, 70, 14, 68, 66, 77, 88, 76, 78, 76, 67, + 73, 84, 78, 66, 89, 79, 24, 15, 70, 75, 2, 72, + 66, 0, 2, 10, 1, 68, 80, 80, 71, 7, 8, 77, 9, + 8, 5, 5, 6, 5, 8, 5, 4, 6, 4, 2, 5, 6, 75, 66, + 5, 68, 12, 18, 21, 15, 6, 19, 12, 15, 4, 2, 9, + 8, 19, 89, 14, 24, 21, 37, 48, 28, 32, 46, 46, + 25, 38, 39, 43, 62, 15, 30, 21, 27, 35, 29, + 39, 44, 51, 19, 20, 31, 26, 62, 66, 51, 55, + 51, 49, 48, 43, 40, 39, 35, 28, 24, 20, 14, 9, + 73, 75, 74, 86, 13, 12, 9, 10, 64, 64, 65, 7, + 72, 73, 74, 85, 78, 104, 86, 9, 10, 10, 3, 64, + 69, 73, 75, 88, 77, 28, 16, 10, 1, 3, 71, 78, + 82, 90, 0, 31, 23, 18, 16, 9, 2, 64, 68, 75, + 68, 40, 30, 20, 6, 11, 64, 73, 80, 8, 52, 44, + 36, 26, 23, 4, 67, 68, 73, 62, 102, 98, 87, + 96, 95, 85, 90, 86, 82, 87, 85, 84, 83, 84, + 86, 91, 82, 82, 77, 77, 74, 72, 70, 69, 68, + 66, 69, 70, 76, 2, 3, 4, 2, 0, 3, 3, 4, 2, 1, + 1, 2, 64, 68, 72, 68, 2, 75, 8, 16, 8, 14, 9, + 11, 13, 9, 8, 4, 10, 2, 69, 70, 48, 49, 48, + 46, 45, 51, 48, 50, 50, 46, 53, 49, 42, 34, + 18, 57, 56, 53, 51, 42, 40, 27, 23, 19, 16, 6, + 1, 68, 77, 55, 56, 55, 51, 45, 46, 42, 37, 33, + 28, 24, 17, 9, 1, 72, 2, 2, 74, 17, 16, 12, 6, + 6, 6, 64, 1, 67, 70, 83, 77, 86, 95, 3, 72, + 77, 79, 74, 65, 73, 3, 11, 69, 71, 3, 7, 4, 6, + 13, 4, 2, 54, 40, 25, 13, 4, 75, 86, 101, 109, + 65, 39, 29, 24, 14, 17, 7, 3, 1, 74, 77, 72, + 64, 71, 5, 11, 66, 69, 3, 7, 6, 7, 14, 8, 3, + 54, 40, 25, 13, 4, 75, 86, 101, 109 }, + + { + + 55, + 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 12, 23, + 44, 57, 18, 83, 67, 0, 0, 6, 3, 66, 65, 64, + 19, 16, 69, 84, 99, 73, 83, 71, 0, 0, 6, 76, + 74, 11, 11, 66, 76, 84, 2, 77, 83, 96, 6, 70, + 77, 4, 77, 77, 89, 64, 75, 71, 83, 66, 2, 22, + 0, 0, 0, 72, 90, 97, 0, 7, 65, 33, 4, 82, 80, + 69, 75, 13, 7, 73, 69, 86, 70, 85, 80, 84, 80, + 83, 85, 87, 24, 65, 66, 85, 70, 89, 80, 90, 5, + 64, 0, 70, 14, 68, 65, 77, 87, 75, 78, 75, 66, + 72, 82, 76, 66, 88, 78, 29, 20, 67, 72, 2, 72, + 66, 1, 2, 10, 2, 67, 79, 78, 71, 5, 6, 74, 9, + 8, 5, 5, 6, 6, 9, 6, 4, 6, 4, 2, 5, 7, 76, 66, + 5, 69, 12, 17, 21, 15, 6, 19, 12, 15, 3, 2, 8, + 7, 19, 89, 14, 24, 21, 35, 45, 27, 30, 44, 43, + 23, 35, 37, 36, 62, 12, 28, 19, 25, 32, 26, + 36, 40, 47, 16, 18, 27, 24, 62, 68, 49, 53, + 49, 46, 45, 41, 38, 37, 33, 26, 22, 18, 12, 8, + 75, 75, 74, 86, 12, 11, 8, 9, 65, 65, 66, 5, + 73, 74, 75, 86, 78, 104, 84, 10, 11, 10, 3, 0, + 69, 73, 75, 86, 76, 28, 16, 11, 2, 4, 70, 77, + 81, 88, 1, 31, 23, 18, 16, 10, 3, 64, 68, 75, + 68, 40, 30, 19, 6, 11, 64, 73, 79, 8, 51, 44, + 35, 25, 23, 4, 67, 68, 73, 62, 101, 96, 86, + 95, 94, 84, 88, 84, 81, 86, 83, 82, 83, 83, + 85, 90, 80, 81, 77, 77, 74, 71, 70, 69, 68, + 66, 69, 70, 77, 3, 4, 5, 2, 0, 4, 3, 4, 2, 1, + 1, 2, 64, 68, 72, 68, 2, 76, 7, 16, 7, 13, 8, + 11, 13, 8, 7, 4, 10, 1, 69, 71, 47, 48, 47, + 45, 43, 49, 46, 48, 47, 44, 50, 46, 39, 32, + 16, 53, 52, 49, 46, 38, 37, 25, 21, 17, 14, 4, + 64, 69, 78, 53, 53, 53, 48, 42, 44, 40, 34, + 30, 26, 21, 14, 7, 64, 73, 1, 1, 75, 15, 14, + 10, 4, 5, 4, 66, 0, 68, 71, 84, 78, 87, 96, 2, + 73, 78, 79, 73, 65, 72, 4, 12, 69, 71, 3, 7, + 4, 7, 14, 4, 2, 53, 38, 23, 10, 1, 79, 90, + 105, 112, 65, 39, 29, 24, 14, 17, 8, 3, 1, 73, + 77, 72, 0, 70, 6, 12, 66, 68, 3, 7, 6, 7, 14, + 8, 3, 53, 38, 23, 10, 1, 79, 90, 105, 112 }, + + { + + 53, + 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 11, 21, + 43, 57, 17, 81, 67, 0, 1, 5, 2, 66, 66, 66, + 18, 13, 73, 87, 101, 70, 82, 71, 0, 1, 5, 76, + 73, 11, 10, 66, 75, 83, 2, 77, 83, 96, 6, 70, + 77, 4, 77, 77, 88, 64, 75, 71, 83, 65, 2, 22, + 0, 0, 0, 71, 91, 97, 0, 6, 65, 32, 4, 82, 78, + 68, 74, 15, 9, 72, 68, 85, 69, 83, 79, 82, 80, + 82, 85, 87, 24, 65, 65, 83, 70, 89, 79, 88, 5, + 64, 0, 71, 14, 68, 65, 76, 86, 74, 77, 74, 66, + 72, 81, 75, 65, 87, 77, 34, 24, 64, 69, 2, 71, + 66, 1, 2, 10, 2, 67, 79, 76, 71, 3, 4, 72, 9, + 9, 5, 5, 6, 6, 11, 7, 5, 5, 4, 2, 6, 7, 77, + 66, 5, 69, 11, 16, 20, 14, 5, 19, 12, 15, 2, + 2, 7, 6, 18, 89, 13, 23, 20, 33, 41, 26, 28, + 42, 41, 21, 33, 35, 30, 62, 8, 26, 17, 22, 29, + 24, 32, 35, 43, 13, 16, 24, 22, 62, 69, 47, + 51, 46, 44, 43, 39, 36, 35, 31, 23, 20, 16, + 10, 6, 77, 75, 74, 87, 11, 10, 7, 7, 66, 67, + 67, 4, 74, 74, 76, 86, 79, 103, 83, 11, 11, + 10, 4, 0, 68, 72, 74, 84, 74, 28, 17, 11, 2, + 5, 69, 75, 79, 87, 1, 32, 24, 19, 17, 11, 3, + 64, 67, 74, 68, 41, 30, 19, 5, 11, 64, 73, 79, + 8, 51, 43, 34, 24, 23, 4, 66, 68, 73, 62, 99, + 95, 85, 93, 92, 83, 87, 83, 80, 84, 82, 80, + 82, 82, 85, 89, 79, 81, 77, 77, 73, 71, 70, + 70, 68, 67, 69, 70, 77, 3, 4, 6, 2, 0, 4, 3, + 4, 2, 1, 1, 1, 64, 68, 72, 68, 3, 77, 6, 16, + 6, 13, 7, 10, 13, 7, 6, 4, 10, 0, 69, 72, 46, + 47, 46, 43, 41, 47, 44, 45, 45, 41, 47, 43, + 36, 29, 14, 48, 48, 45, 41, 35, 33, 22, 18, + 14, 12, 2, 65, 70, 78, 50, 51, 50, 46, 39, 41, + 37, 31, 28, 23, 19, 11, 5, 66, 75, 0, 1, 77, + 14, 13, 9, 2, 3, 2, 67, 64, 70, 72, 85, 80, + 88, 96, 0, 75, 80, 78, 73, 64, 72, 5, 13, 69, + 70, 4, 8, 4, 7, 15, 4, 2, 52, 36, 20, 7, 66, + 83, 95, 109, 115, 64, 39, 29, 24, 14, 18, 8, + 3, 1, 73, 77, 72, 0, 70, 6, 13, 66, 68, 4, 8, + 6, 7, 15, 8, 3, 52, 36, 20, 7, 66, 83, 95, + 109, 115 }, + + { + + 52, + 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 10, 19, + 42, 57, 17, 79, 67, 0, 2, 5, 2, 66, 67, 68, + 17, 11, 76, 89, 103, 67, 81, 70, 0, 2, 5, 76, + 72, 11, 10, 66, 75, 82, 2, 77, 83, 96, 6, 70, + 77, 4, 77, 76, 88, 64, 75, 71, 83, 65, 2, 22, + 0, 0, 0, 71, 91, 97, 1, 5, 65, 31, 3, 82, 75, + 67, 73, 17, 11, 70, 66, 83, 67, 82, 78, 79, + 80, 82, 84, 86, 24, 65, 64, 81, 70, 88, 79, + 86, 5, 65, 64, 71, 14, 68, 64, 76, 85, 73, 77, + 73, 65, 71, 79, 73, 64, 85, 76, 39, 28, 2, 66, + 3, 71, 65, 2, 2, 10, 3, 67, 78, 74, 71, 1, 2, + 69, 9, 9, 5, 5, 6, 7, 12, 8, 5, 5, 4, 2, 6, 8, + 78, 65, 5, 70, 11, 15, 20, 14, 5, 19, 12, 15, + 1, 3, 6, 6, 18, 89, 13, 22, 19, 31, 38, 25, + 27, 40, 39, 19, 30, 33, 24, 62, 5, 24, 15, 20, + 26, 21, 29, 31, 39, 11, 14, 20, 20, 62, 71, + 45, 49, 44, 42, 41, 37, 34, 33, 29, 21, 18, + 14, 9, 4, 79, 75, 74, 87, 10, 9, 6, 6, 67, 68, + 68, 2, 75, 75, 77, 87, 80, 102, 81, 12, 12, + 10, 4, 1, 68, 72, 73, 82, 73, 28, 17, 12, 3, + 6, 68, 74, 78, 85, 2, 33, 25, 20, 17, 12, 4, + 0, 67, 74, 68, 41, 30, 18, 5, 11, 64, 73, 78, + 8, 50, 42, 33, 23, 23, 4, 66, 68, 72, 62, 98, + 93, 83, 91, 91, 82, 85, 81, 79, 82, 80, 78, + 81, 81, 84, 88, 77, 81, 77, 76, 73, 70, 70, + 70, 68, 67, 69, 70, 78, 4, 4, 7, 2, 0, 4, 3, + 4, 2, 1, 1, 1, 64, 68, 72, 68, 3, 78, 5, 16, + 5, 12, 7, 9, 13, 7, 5, 4, 10, 64, 69, 73, 45, + 46, 45, 41, 39, 45, 42, 43, 42, 38, 44, 40, + 33, 27, 12, 44, 44, 41, 36, 32, 30, 20, 16, + 12, 10, 1, 67, 70, 79, 48, 48, 48, 44, 36, 38, + 35, 28, 26, 21, 17, 8, 3, 68, 76, 0, 0, 79, + 13, 11, 7, 0, 1, 0, 69, 65, 71, 73, 85, 81, + 89, 97, 64, 76, 81, 78, 73, 0, 71, 6, 14, 68, + 69, 4, 8, 4, 8, 16, 4, 2, 51, 34, 17, 4, 69, + 87, 99, 113, 118, 64, 39, 29, 24, 14, 18, 8, + 4, 2, 72, 77, 72, 1, 70, 7, 14, 66, 68, 4, 8, + 6, 8, 15, 8, 3, 51, 34, 17, 4, 69, 87, 99, + 113, 118 }, + + { + + 51, + 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 8, 17, + 41, 57, 17, 78, 67, 1, 2, 5, 1, 65, 67, 69, + 15, 8, 80, 92, 104, 65, 80, 70, 1, 2, 5, 77, + 72, 11, 9, 66, 75, 82, 2, 77, 82, 95, 6, 69, + 76, 4, 76, 76, 88, 64, 75, 71, 83, 65, 2, 22, + 0, 0, 0, 70, 91, 97, 1, 5, 66, 31, 3, 82, 73, + 66, 72, 18, 14, 69, 65, 81, 66, 81, 77, 77, + 80, 82, 84, 86, 24, 65, 0, 78, 70, 87, 78, 84, + 4, 65, 64, 72, 15, 68, 64, 75, 85, 73, 76, 72, + 65, 70, 78, 72, 64, 84, 75, 44, 33, 5, 0, 3, + 71, 65, 2, 2, 10, 3, 66, 78, 72, 70, 64, 0, + 66, 9, 9, 5, 5, 7, 7, 14, 9, 5, 5, 4, 2, 7, 9, + 79, 65, 5, 70, 10, 14, 19, 14, 4, 19, 12, 15, + 64, 3, 5, 5, 17, 89, 13, 22, 19, 29, 35, 24, + 25, 37, 36, 17, 28, 31, 17, 62, 1, 22, 14, 18, + 22, 19, 26, 27, 34, 8, 12, 17, 18, 62, 73, 43, + 47, 42, 39, 38, 35, 31, 31, 27, 19, 15, 12, 7, + 3, 80, 75, 74, 88, 9, 8, 5, 5, 68, 69, 69, 0, + 76, 75, 78, 88, 80, 102, 80, 13, 12, 10, 4, 2, + 67, 71, 73, 80, 72, 29, 17, 12, 4, 7, 67, 72, + 76, 83, 3, 33, 25, 20, 18, 13, 4, 0, 67, 73, + 68, 42, 30, 17, 5, 11, 64, 73, 78, 7, 50, 42, + 32, 22, 22, 4, 66, 68, 72, 62, 97, 92, 82, 90, + 89, 81, 83, 79, 78, 81, 78, 76, 81, 80, 84, + 87, 75, 80, 77, 76, 72, 70, 70, 70, 68, 68, + 69, 70, 78, 4, 5, 8, 2, 0, 5, 4, 4, 3, 2, 1, + 0, 64, 68, 72, 68, 4, 79, 4, 16, 4, 11, 6, 9, + 13, 6, 5, 4, 9, 66, 70, 74, 43, 45, 44, 40, + 37, 43, 40, 41, 40, 36, 41, 38, 30, 24, 10, + 40, 40, 37, 32, 28, 27, 17, 14, 9, 8, 64, 68, + 71, 80, 46, 46, 45, 41, 33, 36, 32, 25, 23, + 18, 14, 5, 1, 69, 78, 64, 64, 80, 11, 10, 5, + 65, 0, 65, 71, 66, 73, 74, 86, 82, 90, 98, 66, + 77, 82, 78, 72, 0, 71, 7, 15, 68, 69, 5, 9, 4, + 8, 17, 4, 2, 50, 32, 15, 1, 72, 91, 103, 117, + 121, 64, 39, 29, 24, 14, 19, 9, 4, 2, 72, 76, + 71, 1, 69, 8, 15, 65, 67, 4, 8, 6, 8, 16, 8, + 3, 50, 32, 15, 1, 72, 91, 103, 117, 121 }, + + { + + 50, + 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 7, 15, + 40, 57, 17, 76, 67, 1, 3, 4, 1, 65, 68, 71, + 14, 6, 83, 94, 106, 1, 79, 70, 1, 3, 4, 77, + 71, 11, 9, 66, 74, 81, 2, 77, 82, 95, 6, 69, + 76, 4, 76, 75, 87, 64, 75, 71, 83, 64, 2, 22, + 0, 0, 0, 70, 91, 97, 2, 4, 66, 30, 2, 82, 70, + 65, 71, 20, 16, 67, 0, 80, 64, 79, 76, 75, 80, + 81, 83, 86, 24, 65, 1, 76, 70, 86, 78, 82, 4, + 66, 65, 72, 15, 68, 0, 75, 84, 72, 76, 71, 64, + 69, 76, 70, 0, 83, 74, 49, 37, 8, 3, 3, 70, + 65, 3, 2, 10, 4, 66, 77, 70, 70, 66, 65, 0, 9, + 10, 5, 5, 7, 8, 15, 10, 6, 4, 4, 2, 7, 9, 80, + 65, 5, 71, 10, 13, 19, 13, 4, 19, 12, 15, 65, + 3, 4, 4, 17, 89, 13, 21, 18, 27, 32, 23, 23, + 35, 34, 15, 25, 29, 11, 62, 65, 20, 12, 15, + 19, 16, 23, 22, 30, 5, 10, 13, 16, 62, 74, 41, + 45, 40, 37, 36, 33, 29, 29, 25, 16, 13, 10, 5, + 1, 82, 75, 74, 88, 8, 7, 4, 3, 69, 70, 70, 64, + 77, 76, 79, 88, 81, 101, 78, 14, 13, 10, 5, 2, + 67, 71, 72, 78, 70, 29, 18, 13, 4, 8, 66, 71, + 75, 81, 3, 34, 26, 21, 18, 14, 5, 0, 66, 73, + 68, 42, 30, 17, 4, 11, 64, 73, 77, 7, 49, 41, + 31, 21, 22, 4, 65, 68, 72, 62, 95, 90, 81, 88, + 88, 80, 82, 78, 77, 79, 77, 74, 80, 79, 83, + 86, 73, 80, 77, 76, 72, 69, 70, 71, 68, 68, + 69, 70, 79, 5, 5, 9, 2, 0, 5, 4, 4, 3, 2, 1, + 0, 64, 68, 72, 68, 4, 80, 3, 16, 3, 11, 5, 8, + 13, 5, 4, 4, 9, 67, 70, 75, 42, 44, 43, 38, + 35, 41, 38, 38, 37, 33, 38, 35, 27, 22, 8, 35, + 36, 33, 27, 25, 24, 15, 12, 7, 6, 66, 70, 72, + 80, 43, 43, 43, 39, 30, 33, 30, 22, 21, 16, + 12, 2, 64, 71, 79, 65, 64, 82, 10, 8, 4, 67, + 65, 67, 72, 67, 74, 75, 87, 84, 91, 98, 67, + 79, 84, 77, 72, 1, 70, 8, 16, 68, 68, 5, 9, 4, + 9, 18, 4, 2, 49, 30, 12, 65, 76, 95, 107, 121, + 124, 0, 39, 29, 24, 14, 19, 9, 4, 2, 71, 76, + 71, 2, 69, 9, 16, 65, 67, 5, 9, 6, 8, 16, 8, + 3, 49, 30, 12, 65, 76, 95, 107, 121, 124 }, + + { + + 48, + 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 5, 12, + 39, 57, 16, 74, 68, 1, 4, 4, 0, 65, 69, 73, + 13, 3, 87, 97, 108, 4, 78, 70, 1, 4, 4, 78, + 70, 11, 8, 66, 74, 81, 1, 78, 82, 95, 6, 69, + 76, 4, 76, 75, 87, 64, 75, 71, 83, 64, 2, 22, + 0, 0, 0, 69, 92, 97, 2, 3, 66, 29, 2, 83, 68, + 64, 70, 21, 18, 66, 1, 78, 0, 78, 75, 73, 80, + 81, 83, 86, 24, 65, 2, 74, 70, 86, 77, 80, 4, + 66, 65, 73, 15, 68, 0, 74, 83, 71, 75, 71, 64, + 69, 75, 69, 0, 82, 73, 53, 41, 11, 5, 3, 70, + 65, 3, 1, 10, 4, 66, 77, 68, 70, 68, 67, 2, 9, + 10, 5, 5, 7, 8, 17, 10, 6, 4, 3, 2, 8, 10, 82, + 65, 5, 71, 9, 11, 18, 13, 3, 19, 12, 14, 66, + 3, 3, 3, 16, 89, 12, 20, 17, 25, 28, 21, 21, + 33, 31, 12, 23, 27, 4, 62, 69, 18, 10, 13, 16, + 14, 19, 18, 26, 2, 8, 10, 14, 62, 76, 39, 42, + 37, 34, 33, 30, 27, 26, 23, 14, 11, 8, 3, 64, + 84, 75, 75, 89, 7, 5, 3, 2, 70, 72, 72, 66, + 78, 76, 80, 89, 82, 101, 77, 15, 13, 10, 5, 3, + 66, 70, 72, 76, 69, 29, 18, 13, 5, 9, 65, 69, + 73, 80, 4, 34, 26, 21, 19, 15, 5, 0, 66, 72, + 69, 43, 30, 16, 4, 11, 64, 73, 77, 7, 49, 40, + 30, 20, 22, 4, 65, 68, 72, 62, 94, 89, 80, 87, + 86, 79, 80, 76, 76, 78, 75, 72, 80, 79, 83, + 85, 72, 80, 77, 76, 71, 69, 70, 71, 68, 69, + 69, 70, 79, 5, 5, 10, 2, 64, 5, 4, 3, 3, 2, 1, + 64, 64, 68, 72, 68, 5, 81, 2, 16, 1, 10, 4, 7, + 12, 4, 3, 4, 9, 68, 70, 77, 41, 42, 42, 36, + 33, 39, 36, 36, 35, 30, 35, 32, 24, 19, 6, 31, + 32, 28, 22, 21, 20, 12, 9, 4, 4, 68, 71, 73, + 81, 41, 41, 40, 36, 27, 30, 27, 19, 18, 13, 9, + 64, 66, 73, 81, 66, 65, 84, 8, 7, 2, 69, 67, + 69, 74, 69, 76, 77, 88, 85, 92, 99, 69, 80, + 85, 77, 72, 1, 70, 9, 17, 68, 68, 6, 10, 4, 9, + 18, 4, 1, 48, 28, 9, 68, 79, 99, 112, 126, + 126, 0, 39, 29, 24, 14, 20, 9, 4, 2, 71, 76, + 71, 2, 69, 9, 16, 65, 67, 5, 9, 6, 8, 17, 8, + 2, 48, 28, 9, 68, 79, 99, 112, 126, 126 }, + + { + + 47, + 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 4, 10, + 38, 58, 16, 72, 68, 2, 5, 4, 64, 65, 69, 74, + 12, 1, 91, 100, 109, 7, 77, 69, 2, 5, 4, 78, + 69, 11, 8, 65, 74, 80, 1, 78, 82, 95, 6, 69, + 75, 4, 76, 75, 87, 64, 75, 71, 82, 64, 2, 22, + 0, 0, 0, 68, 92, 97, 2, 2, 66, 28, 2, 83, 66, + 1, 69, 23, 20, 64, 2, 76, 2, 77, 73, 70, 80, + 81, 83, 85, 24, 65, 3, 72, 69, 85, 76, 78, 4, + 66, 65, 73, 15, 68, 0, 73, 82, 70, 74, 70, 0, + 68, 74, 67, 1, 80, 72, 58, 46, 15, 8, 4, 70, + 64, 4, 1, 10, 4, 65, 76, 65, 70, 70, 68, 5, 9, + 10, 5, 5, 7, 9, 19, 11, 6, 4, 3, 2, 9, 11, 83, + 64, 5, 71, 8, 10, 17, 13, 2, 19, 12, 14, 67, + 4, 2, 3, 15, 89, 12, 20, 17, 23, 25, 20, 20, + 31, 29, 10, 21, 25, 65, 62, 72, 16, 8, 11, 13, + 12, 16, 14, 22, 0, 6, 7, 12, 62, 78, 37, 40, + 35, 32, 31, 28, 25, 24, 21, 12, 9, 7, 2, 65, + 86, 75, 75, 89, 7, 4, 2, 1, 71, 73, 73, 68, + 79, 76, 81, 90, 82, 100, 76, 16, 13, 10, 5, 4, + 65, 69, 71, 73, 68, 29, 18, 13, 6, 10, 64, 67, + 71, 78, 5, 35, 27, 22, 20, 16, 5, 1, 66, 71, + 69, 44, 30, 15, 4, 12, 0, 73, 76, 7, 49, 40, + 29, 19, 22, 4, 65, 68, 71, 62, 93, 88, 78, 85, + 84, 78, 78, 74, 75, 76, 73, 70, 79, 78, 82, + 84, 70, 79, 76, 75, 70, 68, 70, 71, 68, 70, + 69, 70, 79, 5, 6, 11, 3, 64, 6, 4, 3, 3, 2, 1, + 65, 64, 67, 71, 68, 6, 81, 1, 16, 0, 9, 4, 7, + 12, 4, 2, 4, 9, 69, 70, 78, 40, 41, 42, 35, + 31, 37, 34, 34, 33, 28, 32, 29, 21, 16, 4, 27, + 28, 24, 17, 18, 17, 9, 7, 2, 3, 69, 72, 73, + 82, 39, 39, 38, 34, 25, 28, 25, 16, 16, 11, 7, + 66, 68, 75, 83, 66, 66, 85, 7, 6, 0, 71, 68, + 70, 76, 70, 78, 78, 88, 86, 92, 100, 71, 81, + 86, 77, 71, 2, 70, 10, 19, 67, 67, 7, 11, 4, + 10, 19, 4, 1, 47, 26, 7, 71, 82, 103, 116, + 126, 126, 0, 39, 29, 25, 15, 21, 10, 5, 3, 71, + 76, 71, 2, 68, 10, 17, 65, 66, 5, 9, 6, 9, 18, + 8, 2, 47, 26, 7, 71, 82, 103, 116, 126, 126 }, + + { + + 46, + 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 3, 8, 37, + 58, 16, 70, 68, 2, 6, 3, 64, 65, 70, 76, 11, + 65, 94, 102, 111, 10, 76, 69, 2, 6, 3, 78, 68, + 11, 7, 65, 73, 79, 1, 78, 82, 95, 6, 69, 75, + 4, 76, 74, 86, 64, 75, 71, 82, 0, 2, 22, 0, 0, + 0, 68, 92, 97, 3, 1, 66, 27, 1, 83, 0, 2, 68, + 25, 22, 0, 4, 75, 3, 75, 72, 68, 80, 80, 82, + 85, 24, 65, 4, 70, 69, 84, 76, 76, 4, 67, 66, + 74, 15, 68, 1, 73, 81, 69, 74, 69, 0, 67, 72, + 66, 2, 79, 71, 62, 50, 18, 11, 4, 69, 64, 4, + 1, 10, 5, 65, 76, 0, 70, 72, 70, 8, 9, 11, 5, + 5, 7, 9, 20, 12, 7, 3, 3, 2, 9, 11, 84, 64, 5, + 72, 8, 9, 17, 12, 2, 19, 12, 14, 68, 4, 1, 2, + 15, 89, 12, 19, 16, 21, 22, 19, 18, 29, 27, 8, + 18, 23, 71, 62, 76, 14, 6, 8, 10, 9, 13, 9, + 18, 66, 4, 3, 10, 62, 79, 35, 38, 33, 30, 29, + 26, 23, 22, 19, 9, 7, 5, 0, 67, 88, 75, 75, + 90, 6, 3, 1, 64, 72, 74, 74, 69, 80, 77, 82, + 90, 83, 99, 74, 17, 14, 10, 6, 4, 65, 69, 70, + 71, 66, 29, 19, 14, 6, 11, 0, 66, 70, 76, 5, + 36, 28, 23, 20, 17, 6, 1, 65, 71, 69, 44, 30, + 15, 3, 12, 0, 73, 76, 7, 48, 39, 28, 18, 22, + 4, 64, 68, 71, 62, 91, 86, 77, 83, 83, 77, 77, + 73, 74, 74, 72, 68, 78, 77, 82, 83, 68, 79, + 76, 75, 70, 68, 70, 72, 68, 70, 69, 70, 80, 6, + 6, 12, 3, 64, 6, 4, 3, 3, 2, 1, 65, 64, 67, + 71, 68, 6, 82, 0, 16, 64, 9, 3, 6, 12, 3, 1, + 4, 9, 70, 70, 79, 39, 40, 41, 33, 29, 35, 32, + 31, 30, 25, 29, 26, 18, 14, 2, 22, 24, 20, 12, + 15, 14, 7, 5, 64, 1, 71, 74, 74, 82, 36, 36, + 35, 32, 22, 25, 22, 13, 14, 8, 5, 69, 70, 77, + 84, 67, 66, 87, 6, 4, 64, 73, 70, 72, 77, 71, + 79, 79, 89, 88, 93, 100, 72, 83, 88, 76, 71, + 3, 69, 11, 20, 67, 66, 7, 11, 4, 10, 20, 4, 1, + 46, 24, 4, 74, 86, 107, 120, 126, 126, 1, 39, + 29, 25, 15, 21, 10, 5, 3, 70, 76, 71, 3, 68, + 11, 18, 65, 66, 6, 10, 6, 9, 18, 8, 2, 46, 24, + 4, 74, 86, 107, 120, 126, 126 }, + + { + + 45, + 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 1, 6, 36, + 58, 16, 69, 68, 3, 6, 3, 65, 64, 70, 77, 9, + 67, 98, 105, 112, 12, 75, 69, 3, 6, 3, 79, 68, + 11, 7, 65, 73, 79, 1, 78, 81, 94, 6, 68, 74, + 4, 75, 74, 86, 64, 75, 71, 82, 0, 2, 22, 0, 0, + 0, 67, 92, 97, 3, 1, 67, 27, 1, 83, 2, 3, 67, + 26, 25, 2, 5, 73, 5, 74, 71, 66, 80, 80, 82, + 85, 24, 65, 5, 67, 69, 83, 75, 74, 3, 67, 66, + 74, 16, 68, 1, 72, 81, 69, 73, 68, 1, 66, 71, + 64, 2, 78, 70, 62, 55, 21, 14, 4, 69, 64, 5, + 1, 10, 5, 64, 75, 2, 69, 74, 72, 11, 9, 11, 5, + 5, 8, 10, 22, 13, 7, 3, 3, 2, 10, 12, 85, 64, + 5, 72, 7, 8, 16, 12, 1, 19, 12, 14, 70, 4, 0, + 1, 14, 89, 12, 19, 16, 19, 19, 18, 16, 26, 24, + 6, 16, 21, 78, 62, 79, 12, 5, 6, 6, 7, 10, 5, + 13, 69, 2, 0, 8, 62, 81, 33, 36, 31, 27, 26, + 24, 20, 20, 17, 7, 4, 3, 65, 68, 89, 75, 75, + 90, 5, 2, 0, 65, 73, 75, 75, 71, 81, 77, 83, + 91, 83, 99, 73, 18, 14, 10, 6, 5, 64, 68, 70, + 69, 65, 30, 19, 14, 7, 12, 1, 64, 68, 74, 6, + 36, 28, 23, 21, 18, 6, 1, 65, 70, 69, 45, 30, + 14, 3, 12, 0, 73, 75, 6, 48, 39, 27, 17, 21, + 4, 64, 68, 71, 62, 90, 85, 76, 82, 81, 76, 75, + 71, 73, 73, 70, 66, 78, 76, 81, 82, 66, 78, + 76, 75, 69, 67, 70, 72, 68, 71, 69, 70, 80, 6, + 7, 13, 3, 64, 7, 5, 3, 4, 3, 1, 66, 64, 67, + 71, 68, 7, 83, 64, 16, 65, 8, 2, 6, 12, 2, 1, + 4, 8, 72, 71, 80, 37, 39, 40, 32, 27, 33, 30, + 29, 28, 23, 26, 24, 15, 11, 0, 18, 20, 16, 8, + 11, 11, 4, 3, 66, 64, 73, 75, 75, 83, 34, 34, + 33, 29, 19, 23, 20, 10, 11, 6, 2, 72, 72, 78, + 86, 68, 67, 88, 4, 3, 66, 75, 71, 74, 79, 72, + 81, 80, 90, 89, 94, 101, 74, 84, 89, 76, 70, + 3, 69, 12, 21, 67, 66, 8, 12, 4, 11, 21, 4, 1, + 45, 22, 2, 77, 89, 111, 124, 126, 126, 1, 39, + 29, 25, 15, 22, 11, 5, 3, 70, 75, 70, 3, 67, + 12, 19, 64, 65, 6, 10, 6, 9, 19, 8, 2, 45, 22, + 2, 77, 89, 111, 124, 126, 126 }, + + { + + 43, + 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 0, 4, 35, + 58, 15, 67, 68, 3, 7, 3, 65, 64, 71, 79, 8, + 70, 101, 107, 114, 15, 74, 69, 3, 7, 3, 79, + 67, 11, 6, 65, 73, 78, 1, 78, 81, 94, 6, 68, + 74, 4, 75, 73, 86, 64, 75, 71, 82, 0, 2, 22, + 0, 0, 0, 67, 93, 97, 4, 0, 67, 26, 0, 83, 5, + 4, 66, 28, 27, 3, 7, 71, 6, 73, 70, 64, 80, + 80, 81, 85, 24, 65, 6, 65, 69, 83, 75, 72, 3, + 68, 67, 75, 16, 68, 2, 72, 80, 68, 73, 67, 1, + 66, 69, 0, 3, 77, 69, 62, 59, 24, 17, 4, 69, + 64, 5, 1, 10, 6, 64, 75, 4, 69, 76, 74, 13, 9, + 11, 5, 5, 8, 10, 23, 14, 7, 3, 3, 2, 10, 13, + 86, 64, 5, 73, 7, 7, 16, 12, 1, 19, 12, 14, + 71, 4, 64, 0, 14, 89, 11, 18, 15, 17, 15, 17, + 14, 24, 22, 4, 13, 19, 84, 62, 83, 10, 3, 4, + 3, 4, 6, 1, 9, 72, 0, 67, 6, 62, 83, 31, 34, + 28, 25, 24, 22, 18, 18, 15, 5, 2, 1, 67, 70, + 91, 75, 75, 91, 4, 1, 64, 66, 74, 77, 76, 73, + 82, 78, 84, 92, 84, 98, 71, 19, 15, 10, 6, 6, + 64, 68, 69, 67, 64, 30, 19, 15, 8, 13, 2, 0, + 67, 73, 7, 37, 29, 24, 21, 19, 7, 1, 65, 70, + 69, 45, 30, 13, 3, 12, 0, 73, 75, 6, 47, 38, + 26, 16, 21, 4, 64, 68, 71, 62, 89, 83, 75, 80, + 80, 75, 73, 69, 72, 71, 68, 64, 77, 75, 81, + 81, 65, 78, 76, 75, 69, 67, 70, 72, 68, 71, + 69, 70, 81, 7, 7, 14, 3, 64, 7, 5, 3, 4, 3, 1, + 66, 64, 67, 71, 68, 7, 84, 65, 16, 66, 7, 1, + 5, 12, 1, 0, 4, 8, 73, 71, 81, 36, 38, 39, 30, + 25, 31, 28, 27, 25, 20, 23, 21, 12, 9, 65, 14, + 16, 12, 3, 8, 7, 2, 0, 69, 66, 75, 77, 76, 84, + 32, 31, 30, 27, 16, 20, 17, 7, 9, 3, 0, 75, + 74, 80, 87, 69, 68, 90, 3, 1, 68, 77, 73, 76, + 81, 73, 82, 81, 91, 90, 95, 102, 75, 85, 90, + 76, 70, 4, 68, 13, 22, 67, 65, 8, 12, 4, 11, + 22, 4, 1, 44, 20, 64, 80, 92, 115, 126, 126, + 126, 1, 39, 29, 25, 15, 22, 11, 5, 3, 69, 75, + 70, 4, 67, 12, 20, 64, 65, 6, 10, 6, 9, 19, 8, + 2, 44, 20, 64, 80, 92, 115, 126, 126, 126 }, + + { + + 42, + 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 64, 2, 34, + 58, 15, 65, 68, 3, 8, 2, 66, 64, 72, 81, 7, + 72, 105, 110, 116, 18, 73, 68, 3, 8, 2, 79, + 66, 11, 6, 65, 72, 77, 1, 78, 81, 94, 6, 68, + 74, 4, 75, 73, 85, 64, 75, 71, 82, 1, 2, 22, + 0, 0, 0, 66, 93, 97, 4, 64, 67, 25, 0, 83, 7, + 5, 65, 30, 29, 5, 8, 70, 8, 71, 69, 2, 80, 79, + 81, 84, 24, 65, 7, 0, 69, 82, 74, 70, 3, 68, + 67, 75, 16, 68, 2, 71, 79, 67, 72, 66, 2, 65, + 68, 2, 4, 75, 68, 62, 62, 27, 20, 5, 68, 0, 6, + 1, 10, 6, 64, 74, 6, 69, 78, 76, 16, 9, 12, 5, + 5, 8, 11, 25, 15, 8, 2, 3, 2, 11, 13, 87, 0, + 5, 73, 6, 6, 15, 11, 0, 19, 12, 14, 72, 5, 65, + 0, 13, 89, 11, 17, 14, 15, 12, 16, 13, 22, 20, + 2, 11, 17, 90, 62, 86, 8, 1, 1, 0, 2, 3, 67, + 5, 74, 65, 70, 4, 62, 84, 29, 32, 26, 23, 22, + 20, 16, 16, 13, 2, 0, 64, 68, 72, 93, 75, 75, + 91, 3, 0, 65, 68, 75, 78, 77, 74, 83, 78, 85, + 92, 85, 97, 70, 20, 15, 10, 7, 6, 0, 67, 68, + 65, 1, 30, 20, 15, 8, 14, 3, 2, 65, 71, 7, 38, + 30, 25, 22, 20, 7, 2, 64, 69, 69, 46, 30, 13, + 2, 12, 0, 73, 74, 6, 47, 37, 25, 15, 21, 4, 0, + 68, 70, 62, 87, 82, 73, 78, 78, 74, 72, 68, + 71, 69, 67, 1, 76, 74, 80, 80, 0, 78, 76, 74, + 68, 66, 70, 73, 68, 72, 69, 70, 81, 7, 7, 15, + 3, 64, 7, 5, 3, 4, 3, 1, 67, 64, 67, 71, 68, + 8, 85, 66, 16, 67, 7, 1, 4, 12, 1, 64, 4, 8, + 74, 71, 82, 35, 37, 38, 28, 23, 29, 26, 24, + 23, 17, 20, 18, 9, 6, 67, 9, 12, 8, 65, 5, 4, + 64, 65, 71, 68, 76, 78, 76, 84, 29, 29, 28, + 25, 13, 17, 15, 4, 7, 1, 65, 78, 76, 82, 89, + 69, 68, 92, 2, 0, 69, 79, 75, 78, 82, 74, 84, + 82, 91, 92, 96, 102, 77, 87, 92, 75, 70, 5, + 68, 14, 23, 66, 64, 9, 13, 4, 12, 23, 4, 1, + 43, 18, 67, 83, 96, 119, 126, 126, 126, 2, 39, + 29, 25, 15, 23, 11, 6, 4, 69, 75, 70, 4, 67, + 13, 21, 64, 65, 7, 11, 6, 10, 20, 8, 2, 43, + 18, 67, 83, 96, 119, 126, 126, 126 }, + + { + + 41, + 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 66, 0, + 33, 58, 15, 0, 68, 4, 9, 2, 66, 64, 72, 82, 6, + 75, 108, 112, 117, 21, 72, 68, 4, 9, 2, 80, + 65, 11, 5, 65, 72, 77, 1, 78, 81, 94, 6, 68, + 73, 4, 75, 72, 85, 64, 75, 71, 82, 1, 2, 22, + 0, 0, 0, 66, 93, 97, 5, 65, 67, 24, 64, 83, + 10, 6, 64, 31, 31, 6, 10, 68, 9, 70, 68, 4, + 80, 79, 80, 84, 24, 65, 8, 2, 69, 81, 74, 68, + 3, 69, 68, 76, 16, 68, 3, 71, 78, 66, 72, 65, + 2, 64, 66, 3, 4, 74, 67, 62, 62, 30, 23, 5, + 68, 0, 6, 1, 10, 7, 0, 74, 8, 69, 80, 78, 19, + 9, 12, 5, 5, 8, 11, 26, 16, 8, 2, 3, 2, 11, + 14, 88, 0, 5, 74, 6, 5, 15, 11, 0, 19, 12, 14, + 73, 5, 66, 64, 13, 89, 11, 17, 14, 13, 9, 15, + 11, 20, 17, 0, 8, 15, 97, 62, 90, 6, 64, 64, + 66, 64, 0, 71, 1, 77, 67, 74, 2, 62, 86, 27, + 30, 24, 20, 19, 18, 14, 14, 11, 0, 65, 66, 70, + 73, 95, 75, 75, 92, 2, 64, 66, 69, 76, 79, 78, + 76, 84, 79, 86, 93, 85, 97, 68, 21, 16, 10, 7, + 7, 0, 67, 68, 0, 2, 30, 20, 16, 9, 15, 4, 3, + 64, 69, 8, 38, 30, 25, 22, 21, 8, 2, 64, 69, + 69, 46, 30, 12, 2, 12, 0, 73, 74, 6, 46, 37, + 24, 14, 21, 4, 0, 68, 70, 62, 86, 80, 72, 77, + 77, 73, 70, 66, 70, 68, 65, 3, 76, 73, 80, 79, + 2, 77, 76, 74, 68, 66, 70, 73, 68, 72, 69, 70, + 82, 8, 8, 16, 3, 64, 8, 5, 3, 4, 3, 1, 67, 64, + 67, 71, 68, 8, 86, 67, 16, 68, 6, 0, 4, 12, 0, + 65, 4, 8, 75, 71, 83, 34, 36, 37, 27, 21, 27, + 24, 22, 20, 15, 17, 15, 6, 4, 69, 5, 8, 4, 70, + 1, 1, 66, 67, 74, 70, 78, 80, 77, 85, 27, 26, + 25, 22, 10, 15, 12, 1, 4, 65, 68, 81, 78, 84, + 90, 70, 69, 93, 0, 65, 71, 81, 76, 80, 84, 75, + 85, 83, 92, 93, 97, 103, 78, 88, 93, 75, 69, + 5, 67, 15, 24, 66, 64, 9, 13, 4, 12, 24, 4, 1, + 42, 16, 69, 86, 99, 123, 126, 126, 126, 2, 39, + 29, 25, 15, 23, 12, 6, 4, 68, 75, 70, 5, 66, + 14, 22, 64, 64, 7, 11, 6, 10, 20, 8, 2, 42, + 16, 69, 86, 99, 123, 126, 126, 126 }, + + { + + 40, + 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 67, 65, + 32, 58, 15, 2, 68, 4, 10, 2, 67, 64, 73, 84, + 5, 77, 112, 115, 119, 24, 71, 68, 4, 10, 2, + 80, 64, 11, 5, 65, 72, 76, 1, 78, 81, 94, 6, + 68, 73, 4, 75, 72, 85, 64, 75, 71, 82, 1, 2, + 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 23, 64, + 83, 12, 7, 0, 33, 33, 8, 11, 66, 11, 69, 67, + 6, 80, 79, 80, 84, 24, 65, 9, 4, 69, 80, 73, + 66, 3, 69, 68, 76, 16, 68, 3, 70, 77, 65, 71, + 64, 3, 0, 65, 5, 5, 73, 66, 62, 62, 33, 26, 5, + 68, 0, 7, 1, 10, 7, 0, 73, 10, 69, 82, 80, 22, + 9, 12, 5, 5, 8, 12, 28, 17, 8, 2, 3, 2, 12, + 15, 89, 0, 5, 74, 5, 4, 14, 11, 64, 19, 12, + 14, 74, 5, 67, 65, 12, 89, 11, 16, 13, 11, 6, + 14, 9, 18, 15, 65, 6, 13, 103, 62, 93, 4, 66, + 66, 69, 66, 66, 75, 66, 80, 69, 77, 0, 62, 88, + 25, 28, 22, 18, 17, 16, 12, 12, 9, 65, 67, 68, + 72, 75, 97, 75, 75, 92, 1, 65, 67, 70, 77, 80, + 79, 78, 85, 79, 87, 94, 86, 96, 67, 22, 16, + 10, 7, 8, 1, 66, 67, 2, 3, 30, 20, 16, 10, 16, + 5, 5, 1, 67, 9, 39, 31, 26, 23, 22, 8, 2, 64, + 68, 69, 47, 30, 11, 2, 12, 0, 73, 73, 6, 46, + 36, 23, 13, 21, 4, 0, 68, 70, 62, 85, 79, 71, + 75, 75, 72, 68, 64, 69, 66, 0, 5, 75, 72, 79, + 78, 4, 77, 76, 74, 67, 65, 70, 73, 68, 73, 69, + 70, 82, 8, 8, 17, 3, 64, 8, 5, 3, 4, 3, 1, 68, + 64, 67, 71, 68, 9, 87, 68, 16, 69, 5, 64, 3, + 12, 64, 66, 4, 8, 76, 71, 84, 33, 35, 36, 25, + 19, 25, 22, 20, 18, 12, 14, 12, 3, 1, 71, 1, + 4, 0, 75, 65, 65, 69, 69, 76, 72, 80, 81, 78, + 86, 25, 24, 23, 20, 7, 12, 10, 65, 2, 67, 70, + 84, 80, 86, 92, 71, 70, 95, 64, 66, 73, 83, + 78, 82, 86, 76, 87, 84, 93, 94, 98, 104, 80, + 89, 94, 75, 69, 6, 67, 16, 25, 66, 0, 10, 14, + 4, 13, 25, 4, 1, 41, 14, 72, 89, 102, 126, + 126, 126, 126, 2, 39, 29, 25, 15, 24, 12, 6, + 4, 68, 75, 70, 5, 66, 15, 23, 64, 64, 7, 11, + 6, 10, 21, 8, 2, 41, 14, 72, 89, 102, 126, + 126, 126, 126 }, + + { + + 38, + 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 69, 68, + 31, 58, 14, 3, 69, 4, 10, 1, 68, 64, 74, 86, + 3, 80, 116, 118, 121, 26, 71, 68, 4, 10, 1, + 81, 64, 11, 4, 65, 72, 76, 0, 79, 81, 94, 5, + 68, 73, 4, 75, 72, 85, 64, 75, 72, 82, 1, 2, + 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 22, 65, + 84, 14, 8, 1, 34, 35, 9, 12, 65, 12, 68, 66, + 8, 80, 79, 80, 84, 24, 65, 9, 6, 69, 80, 73, + 65, 2, 70, 69, 77, 16, 68, 3, 70, 77, 65, 71, + 64, 3, 0, 64, 6, 5, 72, 65, 62, 62, 36, 28, 5, + 68, 0, 7, 0, 10, 7, 0, 73, 12, 69, 84, 82, 24, + 9, 12, 5, 5, 8, 12, 29, 17, 8, 1, 2, 2, 12, + 15, 91, 0, 5, 75, 4, 2, 13, 10, 65, 19, 12, + 13, 76, 5, 68, 66, 11, 89, 10, 15, 12, 8, 2, + 12, 7, 15, 12, 68, 3, 11, 110, 62, 97, 1, 68, + 69, 73, 69, 70, 80, 71, 83, 71, 81, 65, 62, + 90, 22, 25, 19, 15, 14, 13, 9, 9, 7, 68, 70, + 70, 74, 77, 99, 75, 76, 93, 0, 67, 69, 72, 79, + 82, 81, 80, 86, 80, 88, 95, 87, 96, 66, 22, + 16, 10, 7, 8, 1, 66, 67, 4, 4, 30, 20, 16, 10, + 16, 6, 6, 2, 66, 9, 39, 31, 26, 23, 23, 8, 2, + 64, 68, 70, 47, 29, 10, 1, 12, 0, 73, 73, 5, + 45, 35, 21, 12, 20, 4, 0, 68, 70, 62, 84, 78, + 70, 74, 74, 71, 67, 0, 68, 65, 1, 7, 75, 72, + 79, 77, 5, 77, 76, 74, 67, 65, 70, 74, 69, 74, + 69, 71, 83, 8, 8, 18, 3, 65, 8, 5, 2, 4, 3, 1, + 69, 64, 67, 71, 68, 9, 88, 69, 16, 71, 4, 65, + 2, 11, 65, 67, 4, 7, 78, 72, 86, 31, 33, 35, + 23, 17, 22, 19, 17, 15, 9, 11, 9, 64, 65, 73, + 67, 0, 68, 80, 69, 69, 72, 72, 79, 74, 82, 83, + 79, 87, 22, 21, 20, 17, 4, 9, 7, 69, 64, 70, + 73, 87, 82, 88, 94, 72, 71, 97, 66, 68, 75, + 86, 80, 84, 88, 78, 89, 86, 94, 96, 99, 105, + 82, 91, 96, 75, 69, 6, 67, 17, 26, 66, 0, 10, + 14, 4, 13, 25, 4, 0, 39, 12, 75, 93, 106, 126, + 126, 126, 126, 2, 39, 29, 25, 15, 24, 12, 6, + 4, 68, 75, 70, 5, 66, 15, 23, 64, 64, 7, 11, + 6, 10, 21, 7, 1, 39, 12, 75, 93, 106, 126, + 126, 126, 126 }, + + { + + 37, + 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 70, 70, + 30, 59, 14, 5, 69, 5, 11, 1, 68, 0, 74, 87, 2, + 82, 119, 120, 122, 29, 70, 67, 5, 11, 1, 81, + 0, 11, 4, 64, 71, 75, 0, 79, 80, 93, 5, 67, + 72, 4, 74, 71, 84, 0, 74, 72, 81, 2, 2, 22, 0, + 0, 0, 64, 94, 97, 6, 67, 68, 22, 65, 84, 17, + 10, 3, 36, 38, 11, 14, 0, 14, 66, 64, 11, 80, + 78, 79, 83, 24, 65, 10, 9, 68, 79, 72, 0, 2, + 70, 69, 77, 17, 68, 4, 69, 76, 64, 70, 0, 4, + 1, 1, 8, 6, 70, 0, 62, 62, 40, 31, 6, 67, 1, + 8, 0, 11, 8, 1, 72, 15, 68, 86, 83, 27, 9, 13, + 5, 6, 9, 13, 31, 18, 9, 1, 2, 2, 13, 16, 92, + 1, 5, 75, 4, 1, 13, 10, 65, 19, 12, 13, 77, 6, + 68, 66, 11, 89, 10, 15, 12, 6, 64, 11, 6, 13, + 10, 70, 1, 9, 116, 62, 100, 64, 69, 71, 76, + 71, 73, 84, 75, 85, 73, 84, 67, 62, 91, 20, + 23, 17, 13, 12, 11, 7, 7, 5, 70, 72, 71, 75, + 78, 100, 75, 76, 93, 0, 68, 70, 73, 80, 83, + 82, 81, 87, 80, 89, 95, 87, 95, 64, 23, 17, + 10, 8, 9, 2, 65, 66, 7, 6, 31, 21, 17, 11, 17, + 8, 8, 4, 64, 10, 40, 32, 27, 24, 24, 9, 3, 0, + 67, 70, 48, 29, 10, 1, 13, 1, 73, 72, 5, 45, + 35, 20, 11, 20, 5, 1, 67, 69, 62, 82, 76, 68, + 72, 72, 69, 65, 2, 66, 0, 3, 10, 74, 71, 78, + 75, 7, 76, 75, 73, 66, 64, 69, 74, 69, 74, 69, + 71, 83, 9, 9, 19, 4, 65, 9, 6, 2, 5, 4, 1, 69, + 0, 66, 70, 67, 10, 88, 70, 16, 72, 4, 65, 2, + 11, 65, 67, 4, 7, 79, 72, 87, 30, 32, 35, 22, + 16, 20, 17, 15, 13, 7, 9, 7, 67, 67, 75, 71, + 66, 72, 84, 72, 72, 74, 74, 81, 75, 83, 84, + 79, 87, 20, 19, 18, 15, 2, 7, 5, 72, 66, 72, + 75, 89, 83, 89, 95, 72, 71, 98, 67, 69, 76, + 88, 81, 85, 89, 79, 90, 87, 94, 97, 99, 105, + 83, 92, 97, 74, 68, 7, 66, 19, 28, 65, 1, 11, + 15, 5, 14, 26, 4, 0, 38, 10, 77, 96, 109, 126, + 126, 126, 126, 3, 39, 30, 26, 16, 25, 13, 7, + 5, 67, 74, 69, 6, 65, 16, 24, 0, 0, 8, 12, 6, + 11, 22, 7, 1, 38, 10, 77, 96, 109, 126, 126, + 126, 126 }, + + { + + 36, + 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 71, 72, + 29, 59, 14, 7, 69, 5, 12, 1, 69, 0, 75, 89, 1, + 85, 123, 123, 124, 32, 69, 67, 5, 12, 1, 81, + 1, 11, 3, 64, 71, 74, 0, 79, 80, 93, 5, 67, + 72, 4, 74, 71, 84, 0, 74, 72, 81, 2, 2, 22, 0, + 0, 0, 0, 94, 97, 6, 68, 68, 21, 65, 84, 19, + 11, 4, 38, 40, 12, 15, 2, 15, 65, 0, 13, 80, + 78, 79, 83, 24, 65, 11, 11, 68, 78, 71, 2, 2, + 70, 69, 78, 17, 68, 4, 68, 75, 0, 69, 1, 4, 2, + 2, 9, 7, 69, 1, 62, 62, 43, 34, 6, 67, 1, 8, + 0, 11, 8, 1, 72, 17, 68, 88, 85, 30, 9, 13, 5, + 6, 9, 13, 33, 19, 9, 1, 2, 2, 14, 17, 93, 1, + 5, 75, 3, 0, 12, 10, 66, 19, 12, 13, 78, 6, + 69, 67, 10, 89, 10, 14, 11, 4, 67, 10, 4, 11, + 8, 72, 64, 7, 122, 62, 104, 66, 71, 73, 79, + 73, 76, 88, 79, 88, 75, 87, 69, 62, 93, 18, + 21, 15, 11, 10, 9, 5, 5, 3, 72, 74, 73, 77, + 80, 102, 75, 76, 94, 64, 69, 71, 74, 81, 84, + 83, 83, 88, 80, 90, 96, 88, 94, 0, 24, 17, 10, + 8, 10, 3, 64, 65, 9, 7, 31, 21, 17, 12, 18, 9, + 10, 6, 1, 11, 41, 33, 28, 25, 25, 9, 3, 0, 66, + 70, 49, 29, 9, 1, 13, 1, 73, 72, 5, 45, 34, + 19, 10, 20, 5, 1, 67, 69, 62, 81, 75, 67, 70, + 70, 68, 0, 4, 65, 2, 5, 12, 73, 70, 78, 74, 9, + 76, 75, 73, 65, 64, 69, 74, 69, 75, 69, 71, + 83, 9, 9, 20, 4, 65, 9, 6, 2, 5, 4, 1, 70, 0, + 66, 70, 67, 11, 89, 71, 16, 73, 3, 66, 1, 11, + 66, 68, 4, 7, 80, 72, 88, 29, 31, 34, 20, 14, + 18, 15, 13, 11, 4, 6, 4, 70, 70, 77, 75, 70, + 76, 89, 75, 75, 77, 76, 84, 77, 85, 85, 80, + 88, 18, 17, 15, 13, 64, 4, 2, 75, 68, 75, 77, + 92, 85, 91, 97, 73, 72, 100, 68, 70, 78, 90, + 83, 87, 91, 80, 92, 88, 95, 98, 100, 106, 85, + 93, 98, 74, 68, 8, 66, 20, 29, 65, 2, 12, 16, + 5, 14, 27, 4, 0, 37, 8, 80, 99, 112, 126, 126, + 126, 126, 3, 39, 30, 26, 16, 26, 13, 7, 5, 67, + 74, 69, 6, 65, 17, 25, 0, 0, 8, 12, 6, 11, 23, + 7, 1, 37, 8, 80, 99, 112, 126, 126, 126, 126 }, + + { + + 35, + 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 73, 74, + 28, 59, 14, 9, 69, 6, 13, 1, 69, 0, 75, 90, 0, + 87, 126, 125, 125, 35, 68, 67, 6, 13, 1, 82, + 2, 11, 3, 64, 71, 74, 0, 79, 80, 93, 5, 67, + 71, 4, 74, 70, 84, 0, 74, 72, 81, 2, 2, 22, 0, + 0, 0, 0, 94, 97, 7, 69, 68, 20, 66, 84, 22, + 12, 5, 39, 42, 14, 17, 4, 17, 64, 1, 15, 80, + 78, 78, 83, 24, 65, 12, 13, 68, 77, 71, 4, 2, + 71, 70, 78, 17, 68, 5, 68, 74, 1, 69, 2, 5, 3, + 4, 11, 7, 68, 2, 62, 62, 46, 37, 6, 67, 1, 9, + 0, 11, 9, 2, 71, 19, 68, 90, 87, 33, 9, 13, 5, + 6, 9, 14, 34, 20, 9, 1, 2, 2, 14, 18, 94, 1, + 5, 76, 3, 64, 12, 10, 66, 19, 12, 13, 79, 6, + 70, 68, 10, 89, 10, 14, 11, 2, 70, 9, 2, 9, 5, + 74, 67, 5, 126, 62, 107, 68, 73, 75, 82, 76, + 79, 92, 83, 91, 77, 91, 71, 62, 95, 16, 19, + 13, 8, 7, 7, 3, 3, 1, 74, 76, 75, 79, 81, 104, + 75, 76, 94, 65, 70, 72, 75, 82, 85, 84, 85, + 89, 81, 91, 97, 88, 94, 2, 25, 18, 10, 8, 11, + 3, 64, 65, 11, 8, 31, 21, 18, 13, 19, 10, 11, + 7, 3, 12, 41, 33, 28, 25, 26, 10, 3, 0, 66, + 70, 49, 29, 8, 1, 13, 1, 73, 71, 5, 44, 34, + 18, 9, 20, 5, 1, 67, 69, 62, 80, 73, 66, 69, + 69, 67, 2, 6, 64, 3, 7, 14, 73, 69, 77, 73, + 11, 75, 75, 73, 65, 0, 69, 74, 69, 75, 69, 71, + 84, 10, 10, 21, 4, 65, 10, 6, 2, 5, 4, 1, 70, + 0, 66, 70, 67, 11, 90, 72, 16, 74, 2, 67, 1, + 11, 67, 69, 4, 7, 81, 72, 89, 28, 30, 33, 19, + 12, 16, 13, 11, 8, 2, 3, 1, 73, 72, 79, 79, + 74, 80, 94, 79, 78, 79, 78, 86, 79, 87, 87, + 81, 89, 16, 14, 13, 10, 67, 2, 0, 78, 71, 77, + 80, 95, 87, 93, 98, 74, 73, 101, 70, 72, 80, + 92, 84, 89, 93, 81, 93, 89, 96, 99, 101, 107, + 86, 94, 99, 74, 67, 8, 65, 21, 30, 65, 2, 12, + 16, 5, 15, 28, 4, 0, 36, 6, 82, 102, 115, 126, + 126, 126, 126, 3, 39, 30, 26, 16, 26, 14, 7, + 5, 66, 74, 69, 7, 64, 18, 26, 0, 1, 8, 12, 6, + 11, 23, 7, 1, 36, 6, 82, 102, 115, 126, 126, + 126, 126 }, + + { + + 33, + 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 74, 76, + 27, 59, 13, 11, 69, 6, 14, 0, 70, 0, 76, 92, + 64, 90, 126, 126, 126, 38, 67, 67, 6, 14, 0, + 82, 3, 11, 2, 64, 70, 73, 0, 79, 80, 93, 5, + 67, 71, 4, 74, 70, 83, 0, 74, 72, 81, 3, 2, + 22, 0, 0, 0, 1, 95, 97, 7, 70, 68, 19, 66, 84, + 24, 13, 6, 41, 44, 15, 18, 5, 18, 1, 2, 17, + 80, 77, 78, 83, 24, 65, 13, 15, 68, 77, 70, 6, + 2, 71, 70, 79, 17, 68, 5, 67, 73, 2, 68, 3, 5, + 3, 5, 12, 8, 67, 3, 62, 62, 49, 40, 6, 66, 1, + 9, 0, 11, 9, 2, 71, 21, 68, 92, 89, 35, 9, 14, + 5, 6, 9, 14, 36, 21, 10, 0, 2, 2, 15, 18, 95, + 1, 5, 76, 2, 65, 11, 9, 67, 19, 12, 13, 80, 6, + 71, 69, 9, 89, 9, 13, 10, 0, 74, 8, 0, 7, 3, + 76, 69, 3, 126, 62, 111, 70, 75, 78, 85, 78, + 83, 97, 87, 94, 79, 94, 73, 62, 96, 14, 17, + 10, 6, 5, 5, 1, 1, 64, 77, 78, 77, 81, 83, + 106, 75, 76, 95, 66, 71, 73, 77, 83, 87, 85, + 86, 90, 81, 92, 97, 89, 93, 3, 26, 18, 10, 9, + 11, 4, 0, 64, 13, 10, 31, 22, 18, 13, 20, 11, + 13, 9, 4, 12, 42, 34, 29, 26, 27, 10, 3, 1, + 65, 70, 50, 29, 8, 0, 13, 1, 73, 71, 5, 44, + 33, 17, 8, 20, 5, 2, 67, 69, 62, 78, 72, 65, + 67, 67, 66, 3, 7, 0, 5, 8, 16, 72, 68, 77, 72, + 12, 75, 75, 73, 64, 0, 69, 75, 69, 76, 69, 71, + 84, 10, 10, 22, 4, 65, 10, 6, 2, 5, 4, 1, 71, + 0, 66, 70, 67, 12, 91, 73, 16, 75, 2, 68, 0, + 11, 68, 70, 4, 7, 82, 72, 90, 27, 29, 32, 17, + 10, 14, 11, 8, 6, 64, 0, 65, 76, 75, 81, 84, + 78, 84, 99, 82, 82, 82, 81, 89, 81, 89, 88, + 82, 89, 13, 12, 10, 8, 70, 64, 66, 81, 73, 80, + 82, 98, 89, 95, 100, 75, 73, 103, 71, 73, 81, + 94, 86, 91, 94, 82, 95, 90, 97, 101, 102, 107, + 88, 96, 101, 73, 67, 9, 65, 22, 31, 65, 3, 13, + 17, 5, 15, 29, 4, 0, 35, 4, 85, 105, 119, 126, + 126, 126, 126, 4, 39, 30, 26, 16, 27, 14, 7, + 5, 66, 74, 69, 7, 64, 18, 27, 0, 1, 9, 13, 6, + 11, 24, 7, 1, 35, 4, 85, 105, 119, 126, 126, + 126, 126 }, + + { + + 32, + 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 75, 78, + 26, 59, 13, 13, 69, 6, 15, 0, 70, 0, 77, 94, + 65, 92, 126, 126, 126, 41, 66, 66, 6, 15, 0, + 82, 4, 11, 2, 64, 70, 72, 0, 79, 80, 93, 5, + 67, 71, 4, 74, 69, 83, 0, 74, 72, 81, 3, 2, + 22, 0, 0, 0, 1, 95, 97, 8, 71, 68, 18, 67, 84, + 27, 14, 7, 43, 46, 17, 20, 7, 20, 2, 3, 20, + 80, 77, 77, 82, 24, 65, 14, 17, 68, 76, 70, 8, + 2, 72, 71, 79, 17, 68, 6, 67, 72, 3, 68, 4, 6, + 4, 7, 14, 9, 65, 4, 62, 62, 52, 43, 7, 66, 2, + 10, 0, 11, 10, 2, 70, 23, 68, 94, 91, 38, 9, + 14, 5, 6, 9, 15, 37, 22, 10, 0, 2, 2, 15, 19, + 96, 2, 5, 77, 2, 66, 11, 9, 67, 19, 12, 13, + 81, 7, 72, 69, 9, 89, 9, 12, 9, 65, 77, 7, 64, + 5, 1, 78, 72, 1, 126, 62, 114, 72, 77, 80, 88, + 81, 86, 101, 91, 96, 81, 98, 75, 62, 98, 12, + 15, 8, 4, 3, 3, 64, 64, 66, 79, 80, 79, 82, + 85, 108, 75, 76, 95, 67, 72, 74, 78, 84, 88, + 86, 88, 91, 82, 93, 98, 90, 92, 5, 27, 19, 10, + 9, 12, 4, 0, 0, 15, 11, 31, 22, 19, 14, 21, + 12, 14, 10, 6, 13, 43, 35, 30, 26, 28, 11, 4, + 1, 65, 70, 50, 29, 7, 0, 13, 1, 73, 70, 5, 43, + 32, 16, 7, 20, 5, 2, 67, 68, 62, 77, 70, 0, + 65, 66, 65, 5, 9, 1, 7, 10, 18, 71, 67, 76, + 71, 14, 75, 75, 72, 64, 1, 69, 75, 69, 76, 69, + 71, 85, 11, 10, 23, 4, 65, 10, 6, 2, 5, 4, 1, + 71, 0, 66, 70, 67, 12, 92, 74, 16, 76, 1, 68, + 64, 11, 68, 71, 4, 7, 83, 72, 91, 26, 28, 31, + 15, 8, 12, 9, 6, 3, 67, 66, 68, 79, 77, 83, + 88, 82, 88, 104, 85, 85, 84, 83, 91, 83, 90, + 90, 82, 90, 11, 9, 8, 6, 73, 67, 68, 84, 75, + 82, 84, 101, 91, 97, 101, 75, 74, 105, 72, 75, + 83, 96, 88, 93, 96, 83, 96, 91, 97, 102, 103, + 108, 89, 97, 102, 73, 67, 10, 64, 23, 32, 64, + 4, 13, 17, 5, 16, 30, 4, 0, 34, 2, 88, 108, + 122, 126, 126, 126, 126, 4, 39, 30, 26, 16, + 27, 14, 8, 6, 65, 74, 69, 8, 64, 19, 28, 0, 1, + 9, 13, 6, 12, 24, 7, 1, 34, 2, 88, 108, 122, + 126, 126, 126, 126 }, + + { + + 31, + 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 77, 80, + 25, 59, 13, 14, 69, 7, 15, 0, 71, 1, 77, 95, + 67, 95, 126, 126, 126, 43, 65, 66, 7, 15, 0, + 83, 4, 11, 1, 64, 70, 72, 0, 79, 79, 92, 5, + 66, 70, 4, 73, 69, 83, 0, 74, 72, 81, 3, 2, + 22, 0, 0, 0, 2, 95, 97, 8, 71, 69, 18, 67, 84, + 29, 15, 8, 44, 49, 18, 21, 9, 21, 3, 4, 22, + 80, 77, 77, 82, 24, 65, 15, 20, 68, 75, 69, + 10, 1, 72, 71, 80, 18, 68, 6, 66, 72, 3, 67, + 5, 6, 5, 8, 15, 9, 64, 5, 62, 62, 55, 46, 7, + 66, 2, 10, 0, 11, 10, 3, 70, 25, 67, 96, 93, + 41, 9, 14, 5, 6, 10, 15, 39, 23, 10, 0, 2, 2, + 16, 20, 97, 2, 5, 77, 1, 67, 10, 9, 68, 19, + 12, 13, 83, 7, 73, 70, 8, 89, 9, 12, 9, 67, + 80, 6, 66, 2, 65, 80, 74, 64, 126, 62, 118, + 74, 78, 82, 92, 83, 89, 105, 96, 99, 83, 101, + 77, 62, 100, 10, 13, 6, 1, 0, 1, 67, 66, 68, + 81, 83, 81, 84, 86, 109, 75, 76, 96, 68, 73, + 75, 79, 85, 89, 87, 90, 92, 82, 94, 99, 90, + 92, 6, 28, 19, 10, 9, 13, 5, 1, 0, 17, 12, 32, + 22, 19, 15, 22, 13, 16, 12, 8, 14, 43, 35, 30, + 27, 29, 11, 4, 1, 64, 70, 51, 29, 6, 0, 13, 1, + 73, 70, 4, 43, 32, 15, 6, 19, 5, 2, 67, 68, + 62, 76, 69, 1, 64, 64, 64, 7, 11, 2, 8, 12, + 20, 71, 66, 76, 70, 16, 74, 75, 72, 0, 1, 69, + 75, 69, 77, 69, 71, 85, 11, 11, 24, 4, 65, 11, + 7, 2, 6, 5, 1, 72, 0, 66, 70, 67, 13, 93, 75, + 16, 77, 0, 69, 64, 11, 69, 71, 4, 6, 85, 73, + 92, 24, 27, 30, 14, 6, 10, 7, 4, 1, 69, 69, + 70, 82, 80, 85, 92, 86, 92, 108, 89, 88, 87, + 85, 94, 85, 92, 91, 83, 91, 9, 7, 5, 3, 76, + 69, 71, 87, 78, 85, 87, 104, 93, 98, 103, 76, + 75, 106, 74, 76, 85, 98, 89, 95, 98, 84, 98, + 92, 98, 103, 104, 109, 91, 98, 103, 73, 66, + 10, 64, 24, 33, 64, 4, 14, 18, 5, 16, 31, 4, + 0, 33, 0, 90, 111, 125, 126, 126, 126, 126, 4, + 39, 30, 26, 16, 28, 15, 8, 6, 65, 73, 68, 8, + 0, 20, 29, 1, 2, 9, 13, 6, 12, 25, 7, 1, 33, + 0, 90, 111, 125, 126, 126, 126, 126 }, + + { + + 30, + 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 78, 82, + 24, 59, 13, 16, 69, 7, 16, 64, 71, 1, 78, 97, + 68, 97, 126, 126, 126, 46, 64, 66, 7, 16, 64, + 83, 5, 11, 1, 64, 69, 71, 0, 79, 79, 92, 5, + 66, 70, 4, 73, 68, 82, 0, 74, 72, 81, 4, 2, + 22, 0, 0, 0, 2, 95, 97, 9, 72, 69, 17, 68, 84, + 32, 16, 9, 46, 51, 20, 23, 10, 23, 5, 5, 24, + 80, 76, 76, 82, 24, 65, 16, 22, 68, 74, 69, + 12, 1, 73, 72, 80, 18, 68, 7, 66, 71, 4, 67, + 6, 7, 6, 10, 17, 10, 0, 6, 62, 62, 58, 49, 7, + 65, 2, 11, 0, 11, 11, 3, 69, 27, 67, 98, 95, + 44, 9, 15, 5, 6, 10, 16, 40, 24, 11, 64, 2, 2, + 16, 20, 98, 2, 5, 78, 1, 68, 10, 8, 68, 19, + 12, 13, 84, 7, 74, 71, 8, 89, 9, 11, 8, 69, + 83, 5, 68, 0, 67, 82, 77, 66, 126, 62, 121, + 76, 80, 85, 95, 86, 92, 110, 100, 102, 85, + 105, 79, 62, 101, 8, 11, 4, 64, 65, 64, 69, + 68, 70, 84, 85, 83, 86, 88, 111, 75, 76, 96, + 69, 74, 76, 81, 86, 90, 88, 91, 93, 83, 95, + 99, 91, 91, 8, 29, 20, 10, 10, 13, 5, 1, 1, + 19, 14, 32, 23, 20, 15, 23, 14, 17, 13, 10, + 14, 44, 36, 31, 27, 30, 12, 4, 2, 64, 70, 51, + 29, 6, 64, 13, 1, 73, 69, 4, 42, 31, 14, 5, + 19, 5, 3, 67, 68, 62, 74, 67, 2, 1, 0, 0, 8, + 12, 3, 10, 13, 22, 70, 65, 75, 69, 18, 74, 75, + 72, 0, 2, 69, 76, 69, 77, 69, 71, 86, 12, 11, + 25, 4, 65, 11, 7, 2, 6, 5, 1, 72, 0, 66, 70, + 67, 13, 94, 76, 16, 78, 0, 70, 65, 11, 70, 72, + 4, 6, 86, 73, 93, 23, 26, 29, 12, 4, 8, 5, 1, + 65, 72, 72, 73, 85, 82, 87, 97, 90, 96, 113, + 92, 91, 89, 87, 96, 87, 94, 93, 84, 91, 6, 4, + 3, 1, 79, 72, 73, 90, 80, 87, 89, 107, 95, + 100, 104, 77, 75, 108, 75, 78, 86, 100, 91, + 97, 99, 85, 99, 93, 99, 105, 105, 109, 92, + 100, 105, 72, 66, 11, 0, 25, 34, 64, 5, 14, + 18, 5, 17, 32, 4, 0, 32, 65, 93, 114, 126, + 126, 126, 126, 126, 5, 39, 30, 26, 16, 28, 15, + 8, 6, 64, 73, 68, 9, 0, 21, 30, 1, 2, 10, 14, + 6, 12, 25, 7, 1, 32, 65, 93, 114, 126, 126, + 126, 126, 126 }, + + { + + 28, + 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 80, 85, + 23, 59, 12, 18, 70, 7, 17, 64, 72, 1, 79, 99, + 69, 100, 126, 126, 126, 49, 0, 66, 7, 17, 64, + 84, 6, 11, 0, 64, 69, 71, 64, 80, 79, 92, 5, + 66, 70, 4, 73, 68, 82, 0, 74, 72, 81, 4, 2, + 22, 0, 0, 0, 3, 96, 97, 9, 73, 69, 16, 68, 85, + 34, 17, 10, 47, 53, 21, 24, 12, 24, 6, 6, 26, + 80, 76, 76, 82, 24, 65, 17, 24, 68, 74, 68, + 14, 1, 73, 72, 81, 18, 68, 7, 65, 70, 5, 66, + 6, 7, 6, 11, 18, 10, 1, 7, 62, 62, 61, 51, 7, + 65, 2, 11, 64, 11, 11, 3, 69, 29, 67, 100, 97, + 46, 9, 15, 5, 6, 10, 16, 42, 24, 11, 64, 1, 2, + 17, 21, 100, 2, 5, 78, 0, 70, 9, 8, 69, 19, + 12, 12, 85, 7, 75, 72, 7, 89, 8, 10, 7, 71, + 87, 3, 70, 65, 70, 85, 79, 68, 126, 62, 125, + 78, 82, 87, 98, 88, 96, 114, 104, 105, 87, + 108, 81, 62, 103, 6, 8, 1, 67, 68, 67, 71, 71, + 72, 86, 87, 85, 88, 90, 113, 75, 77, 97, 70, + 76, 77, 82, 87, 92, 90, 93, 94, 83, 96, 100, + 92, 91, 9, 30, 20, 10, 10, 14, 6, 2, 1, 21, + 15, 32, 23, 20, 16, 24, 15, 19, 15, 11, 15, + 44, 36, 31, 28, 31, 12, 4, 2, 0, 71, 52, 29, + 5, 64, 13, 1, 73, 69, 4, 42, 30, 13, 4, 19, 5, + 3, 67, 68, 62, 73, 66, 3, 2, 2, 1, 10, 14, 4, + 11, 15, 24, 70, 65, 75, 68, 19, 74, 75, 72, 1, + 2, 69, 76, 69, 78, 69, 71, 86, 12, 11, 26, 4, + 66, 11, 7, 1, 6, 5, 1, 73, 0, 66, 70, 67, 14, + 95, 77, 16, 80, 64, 71, 66, 10, 71, 73, 4, 6, + 87, 73, 95, 22, 24, 28, 10, 2, 6, 3, 64, 67, + 75, 75, 76, 88, 85, 89, 101, 94, 101, 118, 96, + 95, 92, 90, 99, 89, 96, 94, 85, 92, 4, 2, 0, + 65, 82, 75, 76, 93, 83, 90, 92, 110, 97, 102, + 106, 78, 76, 110, 77, 79, 88, 102, 93, 99, + 101, 87, 101, 95, 100, 106, 106, 110, 94, 101, + 106, 72, 66, 11, 0, 26, 35, 64, 5, 15, 19, 5, + 17, 32, 4, 64, 31, 67, 96, 117, 126, 126, 126, + 126, 126, 5, 39, 30, 26, 16, 29, 15, 8, 6, 64, + 73, 68, 9, 0, 21, 30, 1, 2, 10, 14, 6, 12, 26, + 7, 0, 31, 67, 96, 117, 126, 126, 126, 126, 126 }, + + { + + 27, + 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 81, 87, + 22, 60, 12, 20, 70, 8, 18, 64, 73, 1, 79, 100, + 70, 102, 126, 126, 126, 52, 1, 65, 8, 18, 64, + 84, 7, 11, 0, 0, 69, 70, 64, 80, 79, 92, 5, + 66, 69, 4, 73, 68, 82, 0, 74, 72, 80, 4, 2, + 22, 0, 0, 0, 4, 96, 97, 9, 74, 69, 15, 68, 85, + 36, 19, 11, 49, 55, 23, 25, 14, 26, 7, 8, 29, + 80, 76, 76, 81, 24, 65, 18, 26, 67, 73, 67, + 16, 1, 73, 72, 81, 18, 68, 7, 64, 69, 6, 65, + 7, 8, 7, 12, 20, 11, 3, 8, 62, 62, 62, 54, 8, + 65, 3, 12, 64, 11, 11, 4, 68, 32, 67, 102, 98, + 49, 9, 15, 5, 6, 10, 17, 44, 25, 11, 64, 1, 2, + 18, 22, 101, 3, 5, 78, 64, 71, 8, 8, 70, 19, + 12, 12, 86, 8, 76, 72, 6, 89, 8, 10, 7, 73, + 90, 2, 71, 67, 72, 87, 81, 70, 126, 62, 126, + 80, 84, 89, 101, 90, 99, 118, 108, 107, 89, + 111, 83, 62, 105, 4, 6, 64, 69, 70, 69, 73, + 73, 74, 88, 89, 86, 89, 91, 115, 75, 77, 97, + 70, 77, 78, 83, 88, 93, 91, 95, 95, 83, 97, + 101, 92, 90, 10, 31, 20, 10, 10, 15, 7, 3, 2, + 24, 16, 32, 23, 20, 17, 25, 16, 21, 17, 13, + 16, 45, 37, 32, 29, 32, 12, 5, 2, 1, 71, 53, + 29, 4, 64, 14, 2, 73, 68, 4, 42, 30, 12, 3, + 19, 5, 3, 67, 67, 62, 72, 65, 5, 4, 4, 2, 12, + 16, 5, 13, 17, 26, 69, 64, 74, 67, 21, 73, 74, + 71, 2, 3, 69, 76, 69, 79, 69, 71, 86, 12, 12, + 27, 5, 66, 12, 7, 1, 6, 5, 1, 74, 0, 65, 69, + 67, 15, 95, 78, 16, 81, 65, 71, 66, 10, 71, + 74, 4, 6, 88, 73, 96, 21, 23, 28, 9, 0, 4, 1, + 66, 69, 77, 78, 79, 91, 88, 91, 105, 98, 105, + 123, 99, 98, 95, 92, 101, 90, 97, 95, 85, 93, + 2, 0, 65, 67, 84, 77, 78, 96, 85, 92, 94, 112, + 99, 104, 108, 78, 77, 111, 78, 80, 90, 104, + 94, 100, 103, 88, 103, 96, 100, 107, 106, 111, + 96, 102, 107, 72, 65, 12, 0, 27, 37, 0, 6, 16, + 20, 5, 18, 33, 4, 64, 30, 69, 98, 120, 126, + 126, 126, 126, 126, 5, 39, 30, 27, 17, 30, 16, + 9, 7, 64, 73, 68, 9, 1, 22, 31, 1, 3, 10, 14, + 6, 13, 27, 7, 0, 30, 69, 98, 120, 126, 126, + 126, 126, 126 }, + + { + + 26, + 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 82, 89, + 21, 60, 12, 22, 70, 8, 19, 65, 73, 1, 80, 102, + 71, 105, 126, 126, 126, 55, 2, 65, 8, 19, 65, + 84, 8, 11, 64, 0, 68, 69, 64, 80, 79, 92, 5, + 66, 69, 4, 73, 67, 81, 0, 74, 72, 80, 5, 2, + 22, 0, 0, 0, 4, 96, 97, 10, 75, 69, 14, 69, + 85, 39, 20, 12, 51, 57, 24, 27, 15, 27, 9, 9, + 31, 80, 75, 75, 81, 24, 65, 19, 28, 67, 72, + 67, 18, 1, 74, 73, 82, 18, 68, 8, 64, 68, 7, + 65, 8, 8, 8, 14, 21, 12, 4, 9, 62, 62, 62, 57, + 8, 64, 3, 12, 64, 11, 12, 4, 68, 34, 67, 104, + 100, 52, 9, 16, 5, 6, 10, 17, 45, 26, 12, 65, + 1, 2, 18, 22, 102, 3, 5, 79, 64, 72, 8, 7, 70, + 19, 12, 12, 87, 8, 77, 73, 6, 89, 8, 9, 6, 75, + 93, 1, 73, 69, 74, 89, 84, 72, 126, 62, 126, + 82, 86, 92, 104, 93, 102, 123, 112, 110, 91, + 115, 85, 62, 106, 2, 4, 66, 71, 72, 71, 75, + 75, 76, 91, 91, 88, 91, 93, 117, 75, 77, 98, + 71, 78, 79, 85, 89, 94, 92, 96, 96, 84, 98, + 101, 93, 89, 12, 32, 21, 10, 11, 15, 7, 3, 3, + 26, 18, 32, 24, 21, 17, 26, 17, 22, 18, 15, + 16, 46, 38, 33, 29, 33, 13, 5, 3, 1, 71, 53, + 29, 4, 65, 14, 2, 73, 68, 4, 41, 29, 11, 2, + 19, 5, 4, 67, 67, 62, 70, 0, 6, 6, 5, 3, 13, + 17, 6, 15, 18, 28, 68, 0, 74, 66, 23, 73, 74, + 71, 2, 3, 69, 77, 69, 79, 69, 71, 87, 13, 12, + 28, 5, 66, 12, 7, 1, 6, 5, 1, 74, 0, 65, 69, + 67, 15, 96, 79, 16, 82, 65, 72, 67, 10, 72, + 75, 4, 6, 89, 73, 97, 20, 22, 27, 7, 65, 2, + 64, 69, 72, 80, 81, 82, 94, 90, 93, 110, 102, + 109, 126, 102, 101, 97, 94, 104, 92, 99, 97, + 86, 93, 64, 66, 68, 69, 87, 80, 81, 99, 87, + 95, 96, 115, 101, 106, 109, 79, 77, 113, 79, + 82, 91, 106, 96, 102, 104, 89, 104, 97, 101, + 109, 107, 111, 97, 104, 109, 71, 65, 13, 1, + 28, 38, 0, 7, 16, 20, 5, 18, 34, 4, 64, 29, + 71, 101, 123, 126, 126, 126, 126, 126, 6, 39, + 30, 27, 17, 30, 16, 9, 7, 0, 73, 68, 10, 1, + 23, 32, 1, 3, 11, 15, 6, 13, 27, 7, 0, 29, 71, + 101, 123, 126, 126, 126, 126, 126 }, + + { + + 25, + 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 84, 91, + 20, 60, 12, 23, 70, 9, 19, 65, 74, 2, 80, 103, + 73, 107, 126, 126, 126, 57, 3, 65, 9, 19, 65, + 85, 8, 11, 64, 0, 68, 69, 64, 80, 78, 91, 5, + 65, 68, 4, 72, 67, 81, 0, 74, 72, 80, 5, 2, + 22, 0, 0, 0, 5, 96, 97, 10, 75, 70, 14, 69, + 85, 41, 21, 13, 52, 60, 26, 28, 17, 29, 10, + 10, 33, 80, 75, 75, 81, 24, 65, 20, 31, 67, + 71, 66, 20, 0, 74, 73, 82, 19, 68, 8, 0, 68, + 7, 64, 9, 9, 9, 15, 23, 12, 5, 10, 62, 62, 62, + 60, 8, 64, 3, 13, 64, 11, 12, 5, 67, 36, 66, + 106, 102, 55, 9, 16, 5, 6, 11, 18, 47, 27, 12, + 65, 1, 2, 19, 23, 103, 3, 5, 79, 65, 73, 7, 7, + 71, 19, 12, 12, 89, 8, 78, 74, 5, 89, 8, 9, 6, + 77, 96, 0, 75, 72, 77, 91, 86, 74, 126, 62, + 126, 84, 87, 94, 108, 95, 105, 126, 117, 113, + 93, 118, 87, 62, 108, 0, 2, 68, 74, 75, 73, + 78, 77, 78, 93, 94, 90, 93, 94, 118, 75, 77, + 98, 72, 79, 80, 86, 90, 95, 93, 98, 97, 84, + 99, 102, 93, 89, 13, 33, 21, 10, 11, 16, 8, 4, + 3, 28, 19, 33, 24, 21, 18, 27, 18, 24, 20, 17, + 17, 46, 38, 33, 30, 34, 13, 5, 3, 2, 71, 54, + 29, 3, 65, 14, 2, 73, 67, 3, 41, 29, 10, 1, + 18, 5, 4, 67, 67, 62, 69, 1, 7, 7, 7, 4, 15, + 19, 7, 16, 20, 30, 68, 1, 73, 65, 25, 72, 74, + 71, 3, 4, 69, 77, 69, 80, 69, 71, 87, 13, 13, + 29, 5, 66, 13, 8, 1, 7, 6, 1, 75, 0, 65, 69, + 67, 16, 97, 80, 16, 83, 66, 73, 67, 10, 73, + 75, 4, 5, 91, 74, 98, 18, 21, 26, 6, 67, 0, + 66, 71, 74, 82, 84, 84, 97, 93, 95, 114, 106, + 113, 126, 106, 104, 100, 96, 106, 94, 101, 98, + 87, 94, 66, 68, 70, 72, 90, 82, 83, 102, 90, + 97, 99, 118, 103, 107, 111, 80, 78, 114, 81, + 83, 93, 108, 97, 104, 106, 90, 106, 98, 102, + 110, 108, 112, 99, 105, 110, 71, 64, 13, 1, + 29, 39, 0, 7, 17, 21, 5, 19, 35, 4, 64, 28, + 73, 103, 126, 126, 126, 126, 126, 126, 6, 39, + 30, 27, 17, 31, 17, 9, 7, 0, 72, 67, 10, 2, + 24, 33, 2, 4, 11, 15, 6, 13, 28, 7, 0, 28, 73, + 103, 126, 126, 126, 126, 126, 126 }, + + { + + 23, + 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 85, 93, + 19, 60, 11, 25, 70, 9, 20, 65, 74, 2, 81, 105, + 74, 110, 126, 126, 126, 60, 4, 65, 9, 20, 65, + 85, 9, 11, 65, 0, 68, 68, 64, 80, 78, 91, 5, + 65, 68, 4, 72, 66, 81, 0, 74, 72, 80, 5, 2, + 22, 0, 0, 0, 5, 97, 97, 11, 76, 70, 13, 70, + 85, 44, 22, 14, 54, 62, 27, 30, 19, 30, 11, + 11, 35, 80, 75, 74, 81, 24, 65, 21, 33, 67, + 71, 66, 22, 0, 75, 74, 83, 19, 68, 9, 0, 67, + 8, 64, 10, 9, 9, 17, 24, 13, 6, 11, 62, 62, + 62, 62, 8, 64, 3, 13, 64, 11, 13, 5, 67, 38, + 66, 108, 104, 57, 9, 16, 5, 6, 11, 18, 48, 28, + 12, 65, 1, 2, 19, 24, 104, 3, 5, 80, 65, 74, + 7, 7, 71, 19, 12, 12, 90, 8, 79, 75, 5, 89, 7, + 8, 5, 79, 100, 64, 77, 74, 79, 93, 89, 76, + 126, 62, 126, 86, 89, 96, 111, 98, 109, 126, + 121, 116, 95, 122, 89, 62, 110, 65, 0, 71, 76, + 77, 75, 80, 79, 80, 95, 96, 92, 95, 96, 120, + 75, 77, 99, 73, 80, 81, 87, 91, 97, 94, 100, + 98, 85, 100, 103, 94, 88, 15, 34, 22, 10, 11, + 17, 8, 4, 4, 30, 20, 33, 24, 22, 19, 28, 19, + 25, 21, 18, 18, 47, 39, 34, 30, 35, 14, 5, 3, + 2, 71, 54, 29, 2, 65, 14, 2, 73, 67, 3, 40, + 28, 9, 0, 18, 5, 4, 67, 67, 62, 68, 3, 8, 9, + 8, 5, 17, 21, 8, 18, 22, 32, 67, 2, 73, 64, + 26, 72, 74, 71, 3, 4, 69, 77, 69, 80, 69, 71, + 88, 14, 13, 30, 5, 66, 13, 8, 1, 7, 6, 1, 75, + 0, 65, 69, 67, 16, 98, 81, 16, 84, 67, 74, 68, + 10, 74, 76, 4, 5, 92, 74, 99, 17, 20, 25, 4, + 69, 65, 68, 73, 77, 85, 87, 87, 100, 95, 97, + 118, 110, 117, 126, 109, 108, 102, 99, 109, + 96, 103, 100, 88, 95, 68, 71, 73, 74, 93, 85, + 86, 105, 92, 100, 101, 121, 105, 109, 112, 81, + 79, 116, 82, 85, 95, 110, 99, 106, 108, 91, + 107, 99, 103, 111, 109, 113, 100, 106, 111, + 71, 64, 14, 2, 30, 40, 0, 8, 17, 21, 5, 19, + 36, 4, 64, 27, 75, 106, 126, 126, 126, 126, + 126, 126, 6, 39, 30, 27, 17, 31, 17, 9, 7, 1, + 72, 67, 11, 2, 24, 34, 2, 4, 11, 15, 6, 13, + 28, 7, 0, 27, 75, 106, 126, 126, 126, 126, + 126, 126 }, + + { + + 22, + 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 86, 95, + 18, 60, 11, 27, 70, 9, 21, 66, 75, 2, 82, 107, + 75, 112, 126, 126, 126, 62, 5, 64, 9, 21, 66, + 85, 10, 11, 65, 0, 67, 67, 64, 80, 78, 91, 5, + 65, 68, 4, 72, 66, 80, 0, 74, 72, 80, 6, 2, + 22, 0, 0, 0, 6, 97, 97, 11, 77, 70, 12, 70, + 85, 46, 23, 15, 56, 62, 29, 31, 20, 32, 13, + 12, 38, 80, 74, 74, 80, 24, 65, 22, 35, 67, + 70, 65, 24, 0, 75, 74, 83, 19, 68, 9, 1, 66, + 9, 0, 11, 10, 10, 18, 26, 14, 8, 12, 62, 62, + 62, 62, 9, 0, 4, 14, 64, 11, 13, 5, 66, 40, + 66, 110, 106, 60, 9, 17, 5, 6, 11, 19, 50, 29, + 13, 66, 1, 2, 20, 24, 105, 4, 5, 80, 66, 75, + 6, 6, 72, 19, 12, 12, 91, 9, 80, 75, 4, 89, 7, + 7, 4, 81, 103, 65, 78, 76, 81, 95, 91, 78, + 126, 62, 126, 88, 91, 99, 114, 100, 112, 126, + 125, 118, 97, 125, 91, 62, 111, 67, 65, 73, + 78, 79, 77, 82, 81, 82, 98, 98, 94, 96, 98, + 122, 75, 77, 99, 74, 81, 82, 89, 92, 98, 95, + 101, 99, 85, 101, 103, 95, 87, 16, 35, 22, 10, + 12, 17, 9, 5, 5, 32, 22, 33, 25, 22, 19, 29, + 20, 27, 23, 20, 18, 48, 40, 35, 31, 36, 14, 6, + 4, 3, 71, 55, 29, 2, 66, 14, 2, 73, 66, 3, 40, + 27, 8, 64, 18, 5, 5, 67, 66, 62, 66, 4, 10, + 11, 10, 6, 18, 22, 9, 20, 23, 34, 66, 3, 72, + 0, 28, 72, 74, 70, 4, 5, 69, 78, 69, 81, 69, + 71, 88, 14, 13, 31, 5, 66, 13, 8, 1, 7, 6, 1, + 76, 0, 65, 69, 67, 17, 99, 82, 16, 85, 67, 74, + 69, 10, 74, 77, 4, 5, 93, 74, 100, 16, 19, 24, + 2, 71, 67, 70, 76, 79, 88, 90, 90, 103, 98, + 99, 123, 114, 121, 126, 112, 111, 105, 101, + 111, 98, 104, 101, 88, 95, 71, 73, 75, 76, 96, + 88, 88, 108, 94, 102, 103, 124, 107, 111, 114, + 81, 79, 118, 83, 86, 96, 112, 101, 108, 109, + 92, 109, 100, 103, 113, 110, 113, 102, 108, + 113, 70, 64, 15, 2, 31, 41, 1, 9, 18, 22, 5, + 20, 37, 4, 64, 26, 77, 109, 126, 126, 126, + 126, 126, 126, 7, 39, 30, 27, 17, 32, 17, 10, + 8, 1, 72, 67, 11, 2, 25, 35, 2, 4, 12, 16, 6, + 14, 29, 7, 0, 26, 77, 109, 126, 126, 126, 126, + 126, 126 }, + + { + + 21, + 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 88, 97, + 17, 60, 11, 29, 70, 10, 22, 66, 75, 2, 82, + 108, 76, 115, 126, 126, 126, 62, 6, 64, 10, + 22, 66, 86, 11, 11, 66, 0, 67, 67, 64, 80, 78, + 91, 5, 65, 67, 4, 72, 65, 80, 0, 74, 72, 80, + 6, 2, 22, 0, 0, 0, 6, 97, 97, 12, 78, 70, 11, + 71, 85, 49, 24, 16, 57, 62, 30, 33, 22, 33, + 14, 13, 40, 80, 74, 73, 80, 24, 65, 23, 37, + 67, 69, 65, 26, 0, 76, 75, 84, 19, 68, 10, 1, + 65, 10, 0, 12, 10, 11, 20, 27, 14, 9, 13, 62, + 62, 62, 62, 9, 0, 4, 14, 64, 11, 14, 6, 66, + 42, 66, 112, 108, 62, 9, 17, 5, 6, 11, 19, 51, + 30, 13, 66, 1, 2, 20, 25, 106, 4, 5, 81, 66, + 76, 6, 6, 72, 19, 12, 12, 92, 9, 81, 76, 4, + 89, 7, 7, 4, 83, 106, 66, 80, 78, 84, 97, 94, + 80, 126, 62, 126, 90, 93, 101, 117, 103, 115, + 126, 126, 121, 99, 126, 93, 62, 113, 69, 67, + 75, 81, 82, 79, 84, 83, 84, 100, 100, 96, 98, + 99, 124, 75, 77, 100, 75, 82, 83, 90, 93, 99, + 96, 103, 100, 86, 102, 104, 95, 87, 18, 36, + 23, 10, 12, 18, 9, 5, 5, 34, 23, 33, 25, 23, + 20, 30, 21, 28, 24, 22, 19, 48, 40, 35, 31, + 37, 15, 6, 4, 3, 71, 55, 29, 1, 66, 14, 2, 73, + 66, 3, 39, 27, 7, 65, 18, 5, 5, 67, 66, 62, + 65, 6, 11, 12, 11, 7, 20, 24, 10, 21, 25, 36, + 66, 4, 72, 1, 30, 71, 74, 70, 4, 5, 69, 78, + 69, 81, 69, 71, 89, 15, 14, 32, 5, 66, 14, 8, + 1, 7, 6, 1, 76, 0, 65, 69, 67, 17, 100, 83, + 16, 86, 68, 75, 69, 10, 75, 78, 4, 5, 94, 74, + 101, 15, 18, 23, 1, 73, 69, 72, 78, 82, 90, + 93, 93, 106, 100, 101, 126, 118, 125, 126, + 116, 114, 107, 103, 114, 100, 106, 103, 89, + 96, 73, 76, 78, 79, 99, 90, 91, 111, 97, 105, + 106, 126, 109, 113, 115, 82, 80, 119, 85, 88, + 98, 114, 102, 110, 111, 93, 110, 101, 104, + 114, 111, 114, 103, 109, 114, 70, 0, 15, 3, + 32, 42, 1, 9, 18, 22, 5, 20, 38, 4, 64, 25, + 79, 111, 126, 126, 126, 126, 126, 126, 7, 39, + 30, 27, 17, 32, 18, 10, 8, 2, 72, 67, 12, 3, + 26, 36, 2, 5, 12, 16, 6, 14, 29, 7, 0, 25, 79, + 111, 126, 126, 126, 126, 126, 126 }, + + { + + 20, + 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 89, 99, + 16, 60, 11, 31, 70, 10, 23, 66, 76, 2, 83, + 110, 77, 117, 126, 126, 126, 62, 7, 64, 10, + 23, 66, 86, 12, 11, 66, 0, 67, 66, 64, 80, 78, + 91, 5, 65, 67, 4, 72, 65, 80, 0, 74, 72, 80, + 6, 2, 22, 0, 0, 0, 7, 97, 97, 12, 79, 70, 10, + 71, 85, 51, 25, 17, 59, 62, 32, 34, 24, 35, + 15, 14, 42, 80, 74, 73, 80, 24, 65, 24, 39, + 67, 68, 64, 28, 0, 76, 75, 84, 19, 68, 10, 2, + 64, 11, 1, 13, 11, 12, 21, 29, 15, 10, 14, 62, + 62, 62, 62, 9, 0, 4, 15, 64, 11, 14, 6, 65, + 44, 66, 114, 110, 62, 9, 17, 5, 6, 11, 20, 53, + 31, 13, 66, 1, 2, 21, 26, 107, 4, 5, 81, 67, + 77, 5, 6, 73, 19, 12, 12, 93, 9, 82, 77, 3, + 89, 7, 6, 3, 85, 109, 67, 82, 80, 86, 99, 96, + 82, 126, 62, 126, 92, 95, 103, 120, 105, 118, + 126, 126, 124, 101, 126, 95, 62, 115, 71, 69, + 77, 83, 84, 81, 86, 85, 86, 102, 102, 98, 100, + 101, 126, 75, 77, 100, 76, 83, 84, 91, 94, + 100, 97, 105, 101, 86, 103, 105, 96, 86, 19, + 37, 23, 10, 12, 19, 10, 6, 6, 36, 24, 33, 25, + 23, 21, 31, 22, 30, 26, 24, 20, 49, 41, 36, + 32, 38, 15, 6, 4, 4, 71, 56, 29, 0, 66, 14, 2, + 73, 65, 3, 39, 26, 6, 66, 18, 5, 5, 67, 66, + 62, 64, 7, 12, 14, 13, 8, 22, 26, 11, 23, 27, + 38, 65, 5, 71, 2, 32, 71, 74, 70, 5, 6, 69, + 78, 69, 82, 69, 71, 89, 15, 14, 33, 5, 66, 14, + 8, 1, 7, 6, 1, 77, 0, 65, 69, 67, 18, 101, 84, + 16, 87, 69, 76, 70, 10, 76, 79, 4, 5, 95, 74, + 102, 14, 17, 22, 64, 75, 71, 74, 80, 84, 93, + 96, 96, 109, 103, 103, 126, 122, 126, 126, + 119, 117, 110, 105, 116, 102, 108, 104, 90, + 97, 75, 78, 80, 81, 102, 93, 93, 114, 99, 107, + 108, 126, 111, 115, 117, 83, 81, 121, 86, 89, + 100, 116, 104, 112, 113, 94, 112, 102, 105, + 115, 112, 115, 105, 110, 115, 70, 0, 16, 3, + 33, 43, 1, 10, 19, 23, 5, 21, 39, 4, 64, 24, + 81, 114, 126, 126, 126, 126, 126, 126, 7, 39, + 30, 27, 17, 33, 18, 10, 8, 2, 72, 67, 12, 3, + 27, 37, 2, 5, 12, 16, 6, 14, 30, 7, 0, 24, 81, + 114, 126, 126, 126, 126, 126, 126 }, + + { + + 18, + 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 91, 102, + 15, 60, 10, 32, 71, 10, 23, 67, 77, 2, 84, + 112, 79, 120, 126, 126, 126, 62, 7, 64, 10, + 23, 67, 87, 12, 11, 67, 0, 67, 66, 65, 81, 78, + 91, 4, 65, 67, 4, 72, 65, 80, 0, 74, 73, 80, + 6, 2, 22, 0, 0, 0, 7, 98, 97, 12, 80, 71, 9, + 72, 86, 53, 26, 18, 60, 62, 33, 35, 25, 36, + 16, 15, 44, 80, 74, 73, 80, 24, 65, 24, 41, + 67, 68, 64, 29, 64, 77, 76, 85, 19, 68, 10, 2, + 64, 11, 1, 13, 11, 12, 22, 30, 15, 11, 15, 62, + 62, 62, 62, 9, 0, 4, 15, 65, 11, 14, 6, 65, + 46, 66, 116, 112, 62, 9, 17, 5, 6, 11, 20, 54, + 31, 13, 67, 0, 2, 21, 26, 109, 4, 5, 82, 68, + 79, 4, 5, 74, 19, 12, 11, 95, 9, 83, 78, 2, + 89, 6, 5, 2, 88, 113, 69, 84, 83, 89, 102, 99, + 84, 126, 62, 126, 95, 97, 106, 124, 108, 122, + 126, 126, 126, 103, 126, 97, 62, 117, 74, 72, + 80, 86, 87, 84, 89, 88, 88, 105, 105, 100, + 102, 103, 126, 75, 78, 101, 77, 85, 86, 93, + 96, 102, 99, 107, 102, 87, 104, 106, 97, 86, + 20, 37, 23, 10, 12, 19, 10, 6, 6, 38, 25, 33, + 25, 23, 21, 31, 23, 31, 27, 25, 20, 49, 41, + 36, 32, 39, 15, 6, 4, 4, 72, 56, 28, 64, 67, + 14, 2, 73, 65, 2, 38, 25, 4, 67, 17, 5, 5, 67, + 66, 62, 0, 8, 13, 15, 14, 9, 23, 27, 12, 24, + 28, 40, 65, 5, 71, 3, 33, 71, 74, 70, 5, 6, + 69, 79, 70, 83, 69, 72, 90, 15, 14, 34, 5, 67, + 14, 8, 0, 7, 6, 1, 78, 0, 65, 69, 67, 18, 102, + 85, 16, 89, 70, 77, 71, 9, 77, 80, 4, 4, 97, + 75, 104, 12, 15, 21, 66, 77, 74, 77, 83, 87, + 96, 99, 99, 113, 106, 105, 126, 126, 126, 126, + 123, 121, 113, 108, 119, 104, 110, 106, 91, + 98, 78, 81, 83, 84, 105, 96, 96, 118, 102, + 110, 111, 126, 113, 117, 119, 84, 82, 123, 88, + 91, 102, 119, 106, 114, 115, 96, 114, 104, + 106, 117, 113, 116, 107, 112, 117, 70, 0, 16, + 3, 34, 44, 1, 10, 19, 23, 5, 21, 39, 4, 65, + 22, 83, 117, 126, 126, 126, 126, 126, 126, 7, + 39, 30, 27, 17, 33, 18, 10, 8, 2, 72, 67, 12, + 3, 27, 37, 2, 5, 12, 16, 6, 14, 30, 6, 64, 22, + 83, 117, 126, 126, 126, 126, 126, 126 }, + + { + + 17, + 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 92, 104, + 14, 61, 10, 34, 71, 11, 24, 67, 77, 3, 84, + 113, 80, 122, 126, 126, 126, 62, 8, 0, 11, 24, + 67, 87, 13, 11, 67, 1, 66, 65, 65, 81, 77, 90, + 4, 64, 66, 4, 71, 64, 79, 1, 73, 73, 79, 7, 2, + 22, 0, 0, 0, 8, 98, 97, 13, 80, 71, 9, 72, 86, + 56, 28, 20, 62, 62, 35, 37, 27, 38, 18, 17, + 47, 80, 73, 72, 79, 24, 65, 25, 44, 66, 67, 0, + 31, 64, 77, 76, 85, 20, 68, 11, 3, 0, 12, 2, + 14, 12, 13, 24, 32, 16, 13, 17, 62, 62, 62, + 62, 10, 1, 5, 16, 65, 12, 15, 7, 64, 49, 65, + 118, 113, 62, 9, 18, 5, 7, 12, 21, 56, 32, 14, + 67, 0, 2, 22, 27, 110, 5, 5, 82, 68, 80, 4, 5, + 74, 19, 12, 11, 96, 10, 83, 78, 2, 89, 6, 5, + 2, 90, 116, 70, 85, 85, 91, 104, 101, 86, 126, + 62, 126, 97, 98, 108, 126, 110, 125, 126, 126, + 126, 105, 126, 99, 62, 118, 76, 74, 82, 88, + 89, 86, 91, 90, 90, 107, 107, 101, 103, 104, + 126, 75, 78, 101, 77, 86, 87, 94, 97, 103, + 100, 108, 103, 87, 105, 106, 97, 85, 22, 38, + 24, 10, 13, 20, 11, 7, 7, 41, 27, 34, 26, 24, + 22, 32, 25, 33, 29, 27, 21, 50, 42, 37, 33, + 40, 16, 7, 5, 5, 72, 57, 28, 64, 67, 15, 3, + 73, 64, 2, 38, 25, 3, 68, 17, 6, 6, 66, 65, + 62, 2, 10, 15, 17, 16, 11, 25, 29, 14, 26, 30, + 43, 64, 6, 70, 5, 35, 70, 73, 69, 6, 7, 68, + 79, 70, 83, 69, 72, 90, 16, 15, 35, 6, 67, 15, + 9, 0, 8, 7, 1, 78, 1, 64, 68, 66, 19, 102, 86, + 16, 90, 70, 77, 71, 9, 77, 80, 4, 4, 98, 75, + 105, 11, 14, 21, 67, 78, 76, 79, 85, 89, 98, + 101, 101, 116, 108, 107, 126, 126, 126, 126, + 126, 124, 115, 110, 121, 105, 111, 107, 91, + 98, 80, 83, 85, 86, 107, 98, 98, 121, 104, + 112, 113, 126, 114, 118, 120, 84, 82, 124, 89, + 92, 103, 121, 107, 115, 116, 97, 115, 105, + 106, 118, 113, 116, 108, 113, 118, 69, 1, 17, + 4, 36, 46, 2, 11, 20, 24, 6, 22, 40, 4, 65, + 21, 85, 119, 126, 126, 126, 126, 126, 126, 8, + 39, 31, 28, 18, 34, 19, 11, 9, 3, 71, 66, 13, + 4, 28, 38, 3, 6, 13, 17, 6, 15, 31, 6, 64, 21, + 85, 119, 126, 126, 126, 126, 126, 126 }, + + { + + 16, + 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 93, 106, + 13, 61, 10, 36, 71, 11, 25, 67, 78, 3, 85, + 115, 81, 125, 126, 126, 126, 62, 9, 0, 11, 25, + 67, 87, 14, 11, 68, 1, 66, 64, 65, 81, 77, 90, + 4, 64, 66, 4, 71, 64, 79, 1, 73, 73, 79, 7, 2, + 22, 0, 0, 0, 9, 98, 97, 13, 81, 71, 8, 72, 86, + 58, 29, 21, 62, 62, 36, 38, 29, 39, 19, 18, + 49, 80, 73, 72, 79, 24, 65, 26, 46, 66, 66, 1, + 33, 64, 77, 76, 86, 20, 68, 11, 4, 1, 13, 3, + 15, 12, 14, 25, 33, 17, 14, 18, 62, 62, 62, + 62, 10, 1, 5, 16, 65, 12, 15, 7, 64, 51, 65, + 120, 115, 62, 9, 18, 5, 7, 12, 21, 58, 33, 14, + 67, 0, 2, 23, 28, 111, 5, 5, 82, 69, 81, 3, 5, + 75, 19, 12, 11, 97, 10, 84, 79, 1, 89, 6, 4, + 1, 92, 119, 71, 87, 87, 93, 106, 103, 88, 126, + 62, 126, 99, 100, 110, 126, 112, 126, 126, + 126, 126, 107, 126, 101, 62, 120, 78, 76, 84, + 90, 91, 88, 93, 92, 92, 109, 109, 103, 105, + 106, 126, 75, 78, 102, 78, 87, 88, 95, 98, + 104, 101, 110, 104, 87, 106, 107, 98, 84, 23, + 39, 24, 10, 13, 21, 12, 8, 8, 43, 28, 34, 26, + 24, 23, 33, 26, 35, 31, 29, 22, 51, 43, 38, + 34, 41, 16, 7, 5, 6, 72, 58, 28, 65, 67, 15, + 3, 73, 64, 2, 38, 24, 2, 69, 17, 6, 6, 66, 65, + 62, 3, 11, 16, 19, 18, 12, 27, 31, 15, 28, 32, + 45, 0, 7, 70, 6, 37, 70, 73, 69, 7, 7, 68, 79, + 70, 84, 69, 72, 90, 16, 15, 36, 6, 67, 15, 9, + 0, 8, 7, 1, 79, 1, 64, 68, 66, 20, 103, 87, + 16, 91, 71, 78, 72, 9, 78, 81, 4, 4, 99, 75, + 106, 10, 13, 20, 69, 80, 78, 81, 87, 91, 101, + 104, 104, 119, 111, 109, 126, 126, 126, 126, + 126, 126, 118, 112, 124, 107, 113, 108, 92, + 99, 82, 85, 88, 88, 110, 101, 101, 124, 106, + 115, 115, 126, 116, 120, 122, 85, 83, 126, 90, + 93, 105, 123, 109, 117, 118, 98, 117, 106, + 107, 119, 114, 117, 110, 114, 119, 69, 1, 18, + 4, 37, 47, 2, 12, 21, 25, 6, 22, 41, 4, 65, + 20, 87, 122, 126, 126, 126, 126, 126, 126, 8, + 39, 31, 28, 18, 35, 19, 11, 9, 3, 71, 66, 13, + 4, 29, 39, 3, 6, 13, 17, 6, 15, 32, 6, 64, 20, + 87, 122, 126, 126, 126, 126, 126, 126 }, + + { + + 15, + 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 95, 108, + 12, 61, 10, 38, 71, 12, 26, 67, 78, 3, 85, + 116, 82, 126, 126, 126, 126, 62, 10, 0, 12, + 26, 67, 88, 15, 11, 68, 1, 66, 64, 65, 81, 77, + 90, 4, 64, 65, 4, 71, 0, 79, 1, 73, 73, 79, 7, + 2, 22, 0, 0, 0, 9, 98, 97, 14, 82, 71, 7, 73, + 86, 61, 30, 22, 62, 62, 38, 40, 31, 41, 20, + 19, 51, 80, 73, 71, 79, 24, 65, 27, 48, 66, + 65, 1, 35, 64, 78, 77, 86, 20, 68, 12, 4, 2, + 14, 3, 16, 13, 15, 27, 35, 17, 15, 19, 62, 62, + 62, 62, 10, 1, 5, 17, 65, 12, 16, 8, 0, 53, + 65, 122, 117, 62, 9, 18, 5, 7, 12, 22, 59, 34, + 14, 67, 0, 2, 23, 29, 112, 5, 5, 83, 69, 82, + 3, 5, 75, 19, 12, 11, 98, 10, 85, 80, 1, 89, + 6, 4, 1, 94, 122, 72, 89, 89, 96, 108, 106, + 90, 126, 62, 126, 101, 102, 112, 126, 115, + 126, 126, 126, 126, 109, 126, 103, 62, 122, + 80, 78, 86, 93, 94, 90, 95, 94, 94, 111, 111, + 105, 107, 107, 126, 75, 78, 102, 79, 88, 89, + 96, 99, 105, 102, 112, 105, 88, 107, 108, 98, + 84, 25, 40, 25, 10, 13, 22, 12, 8, 8, 45, 29, + 34, 26, 25, 24, 34, 27, 36, 32, 31, 23, 51, + 43, 38, 34, 42, 17, 7, 5, 6, 72, 58, 28, 66, + 67, 15, 3, 73, 0, 2, 37, 24, 1, 70, 17, 6, 6, + 66, 65, 62, 4, 13, 17, 20, 19, 13, 29, 33, 16, + 29, 34, 47, 0, 8, 69, 7, 39, 69, 73, 69, 7, 8, + 68, 79, 70, 84, 69, 72, 91, 17, 16, 37, 6, 67, + 16, 9, 0, 8, 7, 1, 79, 1, 64, 68, 66, 20, 104, + 88, 16, 92, 72, 79, 72, 9, 79, 82, 4, 4, 100, + 75, 107, 9, 12, 19, 70, 82, 80, 83, 89, 94, + 103, 107, 107, 122, 113, 111, 126, 126, 126, + 126, 126, 126, 120, 114, 126, 109, 115, 110, + 93, 100, 84, 88, 90, 91, 113, 103, 103, 126, + 109, 117, 118, 126, 118, 122, 123, 86, 84, + 126, 92, 95, 107, 125, 110, 119, 120, 99, 118, + 107, 108, 120, 115, 118, 111, 115, 120, 69, 2, + 18, 5, 38, 48, 2, 12, 21, 25, 6, 23, 42, 4, + 65, 19, 89, 124, 126, 126, 126, 126, 126, 126, + 8, 39, 31, 28, 18, 35, 20, 11, 9, 4, 71, 66, + 14, 5, 30, 40, 3, 7, 13, 17, 6, 15, 32, 6, 64, + 19, 89, 124, 126, 126, 126, 126, 126, 126 }, + + }, + + { + + { + + 62, + 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 47, 62, + 62, 12, 1, 99, 47, 85, 102, 6, 6, 73, 6, 23, 53, + 62, 62, 21, 97, 126, 117, 74, 85, 102, 6, 93, + 88, 19, 8, 89, 103, 116, 6, 5, 84, 96, 0, 85, + 106, 0, 75, 90, 101, 8, 79, 75, 97, 13, 3, 22, + 0, 0, 0, 83, 86, 97, 72, 22, 1, 29, 88, 126, + 126, 91, 95, 84, 86, 89, 91, 126, 76, 103, 90, + 126, 80, 76, 84, 78, 8, 2, 83, 126, 79, 104, 91, + 126, 65, 79, 72, 92, 7, 68, 71, 98, 86, 88, 82, + 72, 67, 72, 89, 69, 4, 66, 6, 71, 71, 5, 74, 19, + 69, 1, 12, 16, 21, 22, 10, 76, 78, 83, 11, 67, + 90, 67, 72, 75, 80, 83, 64, 32, 64, 94, 75, 0, + 74, 28, 36, 91, 65, 69, 77, 66, 1, 68, 81, 33, + 56, 40, 74, 66, 124, 26, 62, 62, 126, 24, 21, + 29, 34, 32, 26, 21, 23, 30, 20, 27, 16, 8, 5, 3, + 19, 19, 21, 15, 7, 11, 26, 14, 5, 15, 18, 69, + 30, 0, 62, 62, 62, 53, 62, 62, 62, 62, 46, 38, + 34, 30, 48, 43, 73, 29, 32, 19, 47, 27, 27, 35, + 42, 43, 51, 47, 21, 93, 7, 6, 25, 126, 115, 82, + 1, 10, 4, 85, 89, 94, 92, 126, 100, 6, 67, 71, + 77, 85, 88, 104, 98, 126, 82, 15, 2, 66, 70, 75, + 79, 83, 92, 108, 79, 69, 75, 5, 5, 78, 83, 81, + 99, 81, 25, 1, 5, 4, 73, 76, 86, 83, 87, 62, + 126, 126, 120, 126, 114, 117, 118, 117, 113, + 118, 120, 124, 94, 102, 99, 106, 126, 92, 6, 86, + 94, 91, 77, 71, 73, 64, 81, 64, 6, 67, 68, 67, + 68, 77, 64, 68, 78, 8, 4, 65, 9, 19, 3, 70, 76, + 86, 70, 64, 70, 8, 7, 69, 65, 74, 9, 9, 76, 82, + 77, 77, 21, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 52, 62, 62, 62, 62, 62, 62, + 48, 62, 62, 46, 25, 18, 9, 79, 62, 62, 62, 62, + 48, 48, 38, 41, 47, 45, 35, 22, 35, 16, 1, 32, + 37, 39, 40, 47, 33, 34, 22, 21, 3, 11, 3, 78, + 123, 10, 7, 2, 30, 13, 2, 78, 74, 72, 72, 75, + 71, 0, 70, 75, 72, 67, 10, 4, 11, 68, 62, 62, + 62, 62, 56, 51, 40, 25, 64, 71, 26, 19, 14, 7, + 4, 0, 67, 68, 79, 78, 74, 72, 72, 75, 71, 0, 70, + 75, 72, 67, 10, 4, 11, 68, 62, 62, 62, 62, 56, + 51, 40, 25, 64 }, + + { + + 62, + 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 46, + 62, 62, 13, 2, 97, 46, 84, 100, 6, 6, 71, 6, + 22, 52, 62, 60, 19, 97, 125, 115, 73, 84, 100, + 6, 92, 87, 20, 8, 88, 102, 114, 5, 4, 84, 96, + 0, 84, 105, 0, 75, 89, 100, 8, 78, 74, 96, 14, + 3, 22, 0, 0, 0, 82, 86, 97, 71, 22, 1, 29, 87, + 125, 124, 89, 94, 82, 84, 88, 89, 125, 75, + 101, 89, 124, 80, 76, 84, 78, 9, 2, 82, 124, + 78, 103, 90, 125, 65, 78, 72, 91, 8, 68, 70, + 97, 85, 87, 81, 71, 66, 71, 88, 68, 5, 66, 6, + 70, 70, 5, 73, 20, 68, 1, 13, 17, 22, 23, 11, + 76, 77, 82, 11, 67, 89, 67, 71, 74, 79, 81, 1, + 33, 1, 92, 75, 64, 73, 29, 37, 91, 65, 68, 77, + 65, 1, 67, 79, 33, 56, 41, 72, 67, 122, 25, + 62, 62, 125, 24, 21, 29, 34, 32, 26, 21, 23, + 30, 20, 27, 16, 8, 5, 3, 19, 19, 21, 15, 7, + 11, 26, 14, 4, 15, 18, 69, 29, 0, 62, 62, 62, + 52, 62, 62, 62, 62, 45, 37, 32, 29, 46, 42, + 74, 28, 31, 18, 46, 27, 27, 34, 41, 42, 50, + 46, 20, 93, 7, 6, 24, 125, 113, 80, 2, 10, 4, + 84, 88, 93, 91, 125, 98, 7, 66, 70, 76, 83, + 87, 102, 97, 124, 81, 16, 3, 65, 69, 74, 78, + 82, 91, 106, 78, 67, 74, 6, 5, 77, 82, 80, 98, + 80, 26, 2, 6, 5, 72, 75, 85, 82, 86, 62, 125, + 125, 118, 125, 112, 115, 116, 115, 111, 116, + 118, 121, 93, 101, 98, 105, 123, 91, 5, 85, + 93, 90, 76, 71, 72, 64, 80, 64, 6, 67, 68, 66, + 68, 77, 64, 68, 77, 8, 4, 65, 9, 19, 3, 70, + 75, 84, 70, 64, 69, 8, 7, 69, 65, 73, 9, 9, + 75, 81, 76, 76, 20, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 50, 62, 62, + 62, 62, 62, 62, 47, 60, 60, 45, 24, 17, 9, 79, + 62, 62, 62, 60, 46, 47, 37, 39, 46, 43, 34, + 20, 33, 15, 0, 31, 36, 37, 39, 46, 32, 33, 21, + 20, 2, 11, 3, 78, 122, 9, 6, 1, 29, 12, 1, 77, + 73, 71, 71, 73, 70, 1, 69, 73, 71, 66, 11, 5, + 12, 67, 62, 62, 62, 62, 54, 50, 38, 24, 65, + 70, 27, 20, 15, 8, 5, 1, 66, 67, 78, 77, 73, + 71, 71, 73, 70, 1, 69, 73, 71, 66, 11, 5, 12, + 67, 62, 62, 62, 62, 54, 50, 38, 24, 65 }, + + { + + 62, + 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 44, + 60, 62, 14, 2, 95, 44, 84, 99, 6, 6, 70, 5, + 21, 51, 60, 57, 17, 98, 123, 114, 73, 84, 99, + 6, 92, 86, 20, 8, 87, 101, 113, 4, 3, 84, 96, + 0, 84, 104, 0, 75, 89, 100, 8, 78, 74, 95, 14, + 3, 22, 0, 0, 0, 81, 86, 97, 71, 21, 1, 29, 86, + 124, 122, 88, 93, 80, 82, 87, 88, 123, 74, + 100, 88, 122, 81, 76, 84, 78, 9, 2, 81, 122, + 78, 102, 89, 123, 65, 78, 72, 91, 8, 68, 70, + 96, 85, 86, 81, 71, 66, 71, 87, 67, 5, 66, 6, + 70, 70, 5, 73, 20, 68, 1, 13, 17, 22, 23, 11, + 77, 76, 81, 10, 67, 89, 67, 70, 74, 79, 80, 2, + 34, 3, 90, 76, 65, 73, 29, 37, 92, 65, 68, 78, + 64, 1, 67, 78, 33, 56, 41, 71, 68, 121, 24, + 62, 62, 124, 24, 21, 29, 33, 31, 26, 21, 23, + 29, 19, 26, 16, 8, 5, 3, 18, 18, 20, 15, 7, + 11, 25, 13, 3, 14, 17, 69, 28, 64, 62, 62, 62, + 50, 60, 62, 62, 62, 44, 35, 30, 27, 44, 40, + 75, 27, 30, 16, 45, 26, 26, 33, 39, 40, 48, + 44, 18, 93, 6, 5, 22, 124, 112, 79, 3, 10, 4, + 83, 87, 92, 90, 123, 97, 8, 65, 69, 75, 82, + 86, 101, 96, 122, 80, 16, 3, 65, 69, 73, 77, + 81, 90, 105, 78, 66, 73, 6, 5, 76, 81, 80, 97, + 79, 26, 3, 6, 5, 71, 74, 84, 81, 85, 62, 124, + 123, 116, 123, 111, 114, 114, 113, 110, 114, + 116, 119, 92, 100, 97, 104, 120, 91, 4, 85, + 92, 89, 76, 71, 72, 64, 80, 64, 5, 67, 68, 65, + 68, 77, 64, 68, 77, 8, 4, 65, 8, 18, 3, 70, + 75, 83, 71, 64, 68, 7, 7, 69, 65, 73, 9, 9, + 75, 80, 76, 76, 18, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 48, 62, 62, + 62, 62, 62, 61, 45, 58, 58, 43, 23, 16, 8, 79, + 62, 62, 62, 58, 44, 45, 35, 37, 44, 41, 32, + 18, 31, 13, 64, 30, 35, 35, 37, 44, 30, 31, + 20, 19, 1, 10, 2, 78, 121, 8, 5, 64, 28, 11, + 0, 77, 73, 70, 70, 72, 69, 2, 69, 72, 70, 65, + 11, 6, 13, 66, 62, 62, 62, 60, 52, 48, 36, 22, + 66, 69, 27, 20, 16, 9, 6, 1, 65, 67, 77, 77, + 73, 70, 70, 72, 69, 2, 69, 72, 70, 65, 11, 6, + 13, 66, 62, 62, 62, 60, 52, 48, 36, 22, 66 }, + + { + + 62, + 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 42, 59, + 61, 14, 2, 93, 43, 84, 97, 6, 5, 69, 4, 20, + 50, 58, 53, 15, 99, 121, 112, 73, 84, 97, 6, + 91, 85, 21, 8, 86, 100, 112, 3, 2, 84, 97, 0, + 84, 103, 0, 76, 89, 100, 8, 78, 74, 94, 15, 3, + 22, 0, 0, 0, 81, 86, 97, 70, 20, 1, 28, 86, + 123, 120, 87, 92, 79, 81, 86, 87, 121, 73, 99, + 87, 120, 82, 76, 84, 78, 10, 2, 80, 120, 78, + 101, 88, 121, 65, 78, 72, 91, 9, 68, 69, 95, + 85, 85, 81, 71, 66, 70, 86, 67, 5, 66, 6, 70, + 70, 5, 73, 20, 68, 1, 14, 17, 23, 23, 12, 77, + 76, 80, 10, 67, 89, 67, 69, 74, 78, 79, 3, 35, + 4, 88, 76, 66, 72, 29, 37, 93, 65, 67, 78, 64, + 1, 67, 77, 33, 56, 41, 70, 69, 119, 23, 62, + 62, 122, 24, 21, 28, 32, 31, 25, 20, 23, 29, + 18, 25, 16, 8, 5, 2, 18, 17, 19, 14, 7, 11, + 24, 13, 2, 14, 16, 69, 27, 64, 62, 62, 61, 49, + 58, 62, 62, 62, 43, 33, 28, 26, 42, 38, 77, + 26, 29, 14, 44, 25, 25, 32, 38, 38, 46, 42, + 17, 93, 5, 4, 21, 122, 110, 77, 3, 10, 4, 82, + 86, 91, 89, 121, 96, 9, 64, 68, 75, 81, 85, + 99, 95, 120, 80, 17, 4, 64, 68, 72, 77, 81, + 89, 104, 78, 64, 72, 6, 5, 75, 81, 80, 96, 78, + 27, 4, 7, 5, 70, 74, 83, 81, 85, 62, 122, 122, + 115, 121, 110, 112, 113, 112, 108, 112, 114, + 117, 92, 99, 97, 103, 117, 91, 3, 85, 91, 88, + 76, 71, 72, 64, 79, 64, 4, 67, 68, 65, 68, 77, + 64, 68, 77, 7, 4, 65, 7, 17, 3, 70, 75, 82, + 72, 64, 67, 6, 7, 69, 65, 72, 9, 8, 74, 79, + 76, 76, 17, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 46, 62, 62, 62, 62, + 62, 59, 43, 56, 55, 41, 22, 15, 7, 79, 62, 62, + 62, 56, 42, 43, 34, 35, 42, 39, 30, 16, 29, + 11, 65, 29, 34, 33, 36, 42, 29, 29, 18, 17, 0, + 9, 1, 78, 120, 7, 3, 65, 27, 10, 64, 77, 72, + 70, 70, 71, 68, 3, 69, 71, 69, 64, 12, 7, 13, + 65, 62, 62, 62, 58, 50, 46, 34, 20, 67, 69, + 28, 21, 17, 9, 7, 2, 65, 66, 77, 77, 72, 70, + 70, 71, 68, 3, 69, 71, 69, 64, 12, 7, 13, 65, + 62, 62, 62, 58, 50, 46, 34, 20, 67 }, + + { + + 62, + 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 40, 57, + 60, 15, 2, 92, 41, 84, 96, 5, 5, 68, 3, 18, + 48, 56, 50, 12, 100, 119, 111, 73, 84, 96, 5, + 91, 84, 21, 7, 86, 99, 110, 2, 0, 85, 97, 0, + 83, 102, 64, 76, 89, 100, 8, 78, 74, 94, 15, + 3, 22, 0, 0, 0, 80, 87, 97, 70, 19, 1, 28, 85, + 122, 118, 86, 91, 77, 79, 86, 86, 119, 72, 98, + 86, 117, 82, 77, 84, 79, 10, 1, 79, 117, 77, + 101, 88, 119, 65, 78, 72, 91, 9, 68, 69, 94, + 85, 85, 80, 71, 66, 70, 85, 66, 5, 67, 5, 70, + 70, 5, 73, 20, 68, 1, 14, 17, 23, 23, 12, 78, + 75, 80, 9, 67, 88, 67, 68, 73, 78, 77, 5, 36, + 6, 86, 77, 67, 72, 30, 37, 94, 65, 67, 79, 0, + 1, 67, 76, 33, 56, 41, 68, 70, 118, 22, 62, + 62, 121, 23, 21, 28, 32, 30, 25, 20, 23, 28, + 17, 24, 15, 8, 5, 2, 17, 17, 18, 14, 6, 10, + 23, 12, 1, 13, 15, 69, 25, 65, 62, 62, 59, 47, + 57, 62, 62, 62, 42, 31, 25, 24, 40, 36, 78, + 24, 28, 13, 43, 24, 24, 30, 36, 36, 44, 41, + 15, 93, 4, 3, 19, 121, 109, 76, 4, 10, 4, 81, + 85, 90, 89, 119, 94, 10, 64, 68, 74, 79, 84, + 98, 94, 117, 79, 17, 4, 64, 68, 71, 76, 80, + 89, 103, 78, 0, 71, 6, 5, 74, 80, 80, 95, 77, + 27, 5, 7, 5, 69, 73, 82, 80, 84, 62, 121, 120, + 113, 120, 109, 111, 111, 110, 107, 111, 112, + 114, 91, 98, 96, 102, 114, 90, 2, 84, 90, 88, + 76, 71, 72, 65, 79, 65, 3, 67, 68, 64, 68, 77, + 64, 68, 76, 7, 3, 65, 6, 16, 2, 70, 75, 81, + 73, 65, 67, 6, 6, 69, 65, 72, 8, 8, 74, 79, + 76, 76, 15, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 44, 62, 62, 62, 62, + 62, 57, 41, 54, 53, 39, 20, 14, 6, 79, 62, 62, + 62, 54, 40, 41, 32, 33, 40, 37, 28, 14, 26, + 10, 67, 28, 33, 30, 34, 41, 27, 27, 17, 16, + 64, 8, 0, 78, 119, 5, 2, 67, 25, 9, 65, 77, + 72, 69, 69, 70, 68, 3, 68, 70, 68, 0, 12, 8, + 14, 65, 62, 62, 60, 56, 48, 44, 31, 18, 69, + 68, 28, 21, 17, 10, 7, 2, 64, 66, 76, 77, 72, + 69, 69, 70, 68, 3, 68, 70, 68, 0, 12, 8, 14, + 65, 62, 62, 60, 56, 48, 44, 31, 18, 69 }, + + { + + 62, + 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 38, 56, + 59, 16, 2, 90, 39, 83, 94, 5, 5, 67, 2, 17, + 47, 54, 47, 10, 100, 117, 110, 73, 83, 94, 5, + 91, 83, 21, 7, 85, 98, 109, 1, 64, 85, 97, 0, + 83, 101, 64, 76, 89, 100, 8, 77, 74, 93, 16, + 3, 22, 0, 0, 0, 80, 87, 97, 69, 18, 1, 27, 85, + 120, 115, 85, 90, 76, 78, 85, 85, 117, 71, 97, + 85, 115, 83, 77, 84, 79, 10, 1, 78, 115, 77, + 100, 87, 117, 65, 78, 72, 90, 9, 68, 68, 93, + 84, 84, 80, 71, 65, 69, 84, 66, 5, 67, 5, 69, + 70, 5, 73, 21, 68, 1, 15, 18, 23, 23, 12, 78, + 75, 79, 9, 67, 88, 67, 67, 73, 77, 76, 6, 37, + 7, 84, 77, 68, 71, 30, 37, 95, 65, 66, 79, 1, + 1, 67, 74, 33, 56, 41, 67, 71, 116, 21, 62, + 62, 120, 23, 21, 27, 31, 30, 25, 19, 23, 28, + 16, 23, 15, 8, 5, 2, 17, 16, 17, 13, 6, 10, + 22, 12, 0, 12, 15, 69, 24, 65, 62, 62, 58, 46, + 55, 62, 62, 62, 41, 29, 23, 23, 38, 34, 79, + 23, 27, 11, 42, 23, 23, 29, 35, 34, 42, 39, + 14, 93, 3, 2, 17, 119, 107, 75, 4, 10, 4, 80, + 84, 89, 88, 117, 93, 11, 0, 67, 73, 78, 83, + 96, 93, 115, 78, 18, 5, 0, 67, 70, 75, 80, 88, + 102, 77, 1, 70, 6, 5, 73, 80, 79, 94, 76, 27, + 6, 7, 5, 68, 72, 81, 80, 83, 62, 120, 119, + 112, 118, 108, 109, 110, 108, 105, 109, 110, + 112, 90, 97, 95, 101, 111, 90, 1, 84, 89, 87, + 76, 71, 72, 65, 78, 65, 2, 67, 68, 0, 68, 77, + 64, 68, 76, 6, 3, 65, 5, 15, 2, 70, 75, 80, + 73, 65, 66, 5, 6, 69, 65, 72, 8, 7, 74, 78, + 76, 76, 14, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 42, 62, 62, 62, 62, + 62, 55, 40, 52, 50, 37, 19, 13, 5, 79, 62, 62, + 62, 52, 38, 39, 31, 31, 38, 35, 26, 12, 24, 8, + 68, 27, 32, 28, 33, 39, 26, 25, 16, 15, 65, 7, + 64, 78, 118, 4, 1, 68, 24, 8, 66, 77, 71, 69, + 68, 69, 67, 4, 68, 69, 67, 1, 13, 9, 14, 64, + 62, 62, 58, 54, 46, 42, 29, 16, 70, 68, 29, + 22, 18, 11, 8, 3, 64, 66, 75, 77, 71, 69, 68, + 69, 67, 4, 68, 69, 67, 1, 13, 9, 14, 64, 62, + 62, 58, 54, 46, 42, 29, 16, 70 }, + + { + + 62, + 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 37, 54, + 58, 16, 3, 88, 38, 83, 93, 5, 4, 66, 1, 16, + 46, 53, 43, 8, 101, 115, 108, 73, 83, 93, 5, + 90, 82, 22, 7, 84, 97, 108, 64, 65, 85, 98, 0, + 83, 101, 64, 77, 88, 100, 7, 77, 74, 92, 16, + 3, 22, 0, 0, 0, 79, 87, 97, 69, 18, 0, 27, 84, + 119, 113, 84, 89, 74, 76, 84, 84, 115, 70, 96, + 85, 113, 84, 77, 84, 79, 11, 1, 77, 113, 77, + 99, 86, 115, 65, 78, 72, 90, 10, 69, 68, 93, + 84, 83, 80, 70, 65, 69, 83, 65, 5, 67, 5, 69, + 70, 5, 73, 21, 68, 1, 15, 18, 24, 24, 13, 79, + 74, 78, 8, 67, 88, 67, 66, 73, 77, 75, 7, 37, + 9, 83, 78, 69, 71, 30, 37, 95, 66, 66, 80, 1, + 0, 66, 73, 33, 56, 42, 66, 72, 115, 20, 62, + 62, 118, 23, 21, 27, 30, 29, 24, 19, 22, 27, + 16, 23, 15, 7, 5, 1, 16, 15, 16, 13, 6, 10, + 22, 11, 65, 12, 14, 69, 23, 66, 62, 62, 56, + 44, 53, 62, 62, 62, 39, 27, 21, 21, 36, 32, + 81, 22, 25, 9, 40, 22, 22, 28, 33, 32, 40, 37, + 12, 93, 2, 1, 16, 118, 106, 73, 5, 10, 4, 79, + 84, 89, 87, 116, 92, 12, 1, 66, 73, 77, 82, + 95, 92, 113, 78, 18, 5, 0, 67, 69, 75, 79, 87, + 101, 77, 3, 69, 6, 5, 73, 79, 79, 94, 76, 28, + 6, 8, 5, 67, 72, 81, 79, 83, 62, 118, 117, + 110, 116, 106, 108, 108, 107, 104, 107, 108, + 110, 90, 96, 95, 101, 108, 90, 0, 84, 89, 86, + 76, 71, 72, 65, 78, 65, 1, 67, 68, 0, 68, 77, + 64, 68, 76, 6, 3, 65, 4, 14, 2, 70, 75, 79, + 74, 65, 65, 4, 6, 69, 65, 71, 8, 7, 73, 77, + 76, 76, 12, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 40, 62, 62, 62, 62, + 62, 52, 38, 50, 48, 35, 18, 12, 4, 79, 62, 62, + 62, 50, 36, 38, 29, 29, 36, 32, 24, 10, 22, 6, + 69, 26, 30, 26, 31, 37, 24, 23, 14, 13, 66, 6, + 65, 79, 117, 3, 64, 70, 23, 6, 67, 76, 71, 68, + 68, 68, 66, 5, 68, 68, 66, 2, 13, 10, 15, 0, + 62, 62, 56, 52, 44, 40, 27, 14, 71, 67, 29, + 22, 19, 11, 9, 3, 0, 65, 75, 76, 71, 68, 68, + 68, 66, 5, 68, 68, 66, 2, 13, 10, 15, 0, 62, + 62, 56, 52, 44, 40, 27, 14, 71 }, + + { + + 62, + 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 35, 53, + 57, 17, 3, 87, 36, 83, 91, 4, 4, 65, 0, 15, + 45, 51, 40, 5, 102, 113, 107, 73, 83, 91, 4, + 90, 81, 22, 7, 84, 96, 106, 65, 66, 85, 98, 0, + 82, 100, 65, 77, 88, 100, 7, 77, 74, 91, 17, + 3, 22, 0, 0, 0, 79, 87, 97, 68, 17, 0, 26, 84, + 118, 111, 83, 88, 73, 75, 83, 83, 113, 69, 95, + 84, 110, 84, 78, 84, 80, 11, 1, 76, 110, 76, + 99, 86, 113, 65, 78, 72, 90, 10, 69, 67, 92, + 84, 82, 79, 70, 65, 68, 82, 65, 5, 68, 5, 69, + 70, 5, 73, 21, 68, 1, 16, 18, 24, 24, 13, 79, + 74, 78, 8, 67, 87, 67, 65, 72, 76, 73, 9, 38, + 10, 81, 78, 70, 70, 31, 37, 96, 66, 65, 80, 2, + 0, 66, 72, 33, 56, 42, 64, 73, 113, 19, 62, + 62, 117, 23, 21, 26, 30, 29, 24, 18, 22, 27, + 15, 22, 15, 7, 5, 1, 16, 15, 15, 12, 6, 10, + 21, 11, 66, 11, 13, 69, 22, 66, 62, 62, 54, + 43, 52, 62, 62, 62, 38, 25, 19, 20, 34, 30, + 82, 21, 24, 8, 39, 21, 21, 26, 32, 30, 38, 36, + 11, 93, 1, 0, 14, 116, 104, 72, 5, 10, 4, 78, + 83, 88, 87, 114, 90, 13, 2, 66, 72, 75, 81, + 93, 91, 110, 77, 19, 6, 1, 66, 68, 74, 79, 86, + 100, 77, 4, 68, 6, 5, 72, 79, 79, 93, 75, 28, + 7, 8, 5, 66, 71, 80, 79, 82, 62, 117, 116, + 109, 115, 105, 106, 107, 105, 102, 105, 106, + 107, 89, 95, 94, 100, 105, 89, 64, 83, 88, 85, + 76, 71, 72, 65, 77, 66, 0, 67, 68, 1, 68, 77, + 64, 68, 75, 5, 2, 65, 3, 13, 1, 70, 75, 78, + 75, 66, 64, 4, 5, 69, 65, 71, 7, 6, 73, 77, + 76, 76, 11, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 38, 62, 62, 62, 62, + 62, 50, 36, 48, 45, 33, 17, 11, 3, 79, 62, 61, + 62, 48, 34, 36, 28, 27, 34, 30, 22, 8, 20, 5, + 71, 25, 29, 24, 30, 36, 23, 21, 13, 12, 67, 5, + 66, 79, 116, 1, 65, 71, 21, 5, 68, 76, 70, 68, + 67, 67, 65, 5, 67, 67, 65, 3, 14, 11, 15, 0, + 62, 60, 54, 50, 42, 38, 24, 12, 72, 67, 30, + 23, 19, 12, 10, 4, 0, 65, 74, 76, 70, 68, 67, + 67, 65, 5, 67, 67, 65, 3, 14, 11, 15, 0, 62, + 60, 54, 50, 42, 38, 24, 12, 72 }, + + { + + 62, + 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 33, 51, + 56, 17, 3, 85, 34, 83, 90, 4, 3, 64, 64, 13, + 43, 49, 36, 3, 103, 111, 106, 73, 83, 90, 4, + 90, 81, 22, 6, 83, 95, 105, 66, 68, 86, 99, 0, + 82, 99, 65, 78, 88, 100, 7, 77, 74, 91, 17, 3, + 22, 0, 0, 0, 78, 88, 97, 68, 16, 0, 26, 83, + 117, 109, 82, 88, 71, 73, 83, 82, 111, 69, 94, + 83, 108, 85, 78, 85, 80, 11, 0, 76, 108, 76, + 98, 85, 112, 65, 78, 72, 90, 10, 69, 67, 91, + 84, 82, 79, 70, 65, 68, 81, 64, 5, 68, 4, 69, + 70, 4, 73, 21, 68, 1, 16, 18, 24, 24, 13, 80, + 73, 77, 7, 67, 87, 67, 64, 72, 76, 72, 10, 39, + 12, 79, 79, 71, 70, 31, 37, 97, 66, 65, 81, 2, + 0, 66, 71, 33, 56, 42, 0, 74, 112, 18, 59, 62, + 116, 22, 21, 26, 29, 28, 23, 18, 22, 26, 14, + 21, 14, 7, 4, 0, 15, 14, 14, 12, 5, 9, 20, 10, + 67, 10, 12, 69, 20, 67, 62, 62, 52, 41, 50, + 60, 62, 62, 37, 23, 16, 18, 31, 28, 84, 19, + 23, 6, 38, 20, 20, 25, 30, 28, 36, 34, 9, 93, + 0, 64, 12, 115, 103, 71, 6, 10, 4, 78, 82, 87, + 86, 112, 89, 13, 2, 65, 72, 74, 80, 92, 90, + 108, 77, 19, 6, 1, 66, 68, 74, 78, 86, 99, 77, + 5, 67, 6, 5, 71, 78, 79, 92, 74, 28, 8, 8, 5, + 65, 71, 79, 78, 82, 62, 116, 114, 107, 113, + 104, 105, 105, 104, 101, 104, 104, 105, 89, + 94, 94, 99, 102, 89, 65, 83, 87, 85, 76, 71, + 72, 66, 77, 66, 64, 67, 68, 1, 68, 77, 65, 68, + 75, 5, 2, 66, 2, 12, 1, 71, 75, 77, 76, 66, + 64, 3, 5, 69, 66, 71, 7, 6, 73, 76, 76, 76, 9, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 61, 36, 62, 62, 62, 62, 61, 48, 34, + 45, 43, 31, 15, 9, 2, 79, 61, 59, 62, 46, 31, + 34, 26, 24, 32, 28, 20, 6, 17, 3, 72, 23, 28, + 21, 28, 34, 21, 19, 11, 10, 68, 4, 67, 79, + 115, 0, 67, 73, 20, 4, 69, 76, 70, 67, 67, 66, + 65, 6, 67, 66, 65, 4, 14, 11, 16, 1, 61, 58, + 52, 48, 40, 36, 22, 10, 74, 66, 30, 23, 20, + 12, 10, 4, 1, 65, 74, 76, 70, 67, 67, 66, 65, + 6, 67, 66, 65, 4, 14, 11, 16, 1, 61, 58, 52, + 48, 40, 36, 22, 10, 74 }, + + { + + 62, + 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 31, 49, + 56, 18, 3, 83, 33, 82, 88, 4, 3, 0, 64, 12, + 42, 47, 33, 1, 103, 109, 104, 72, 82, 88, 4, + 89, 80, 23, 6, 82, 94, 104, 67, 69, 86, 99, 0, + 82, 98, 65, 78, 88, 100, 7, 76, 73, 90, 17, 3, + 22, 0, 0, 0, 77, 88, 97, 68, 15, 0, 26, 82, + 115, 106, 81, 87, 69, 71, 82, 81, 109, 68, 92, + 82, 106, 86, 78, 85, 80, 12, 0, 75, 106, 76, + 97, 84, 110, 65, 77, 72, 89, 11, 69, 66, 90, + 83, 81, 79, 70, 64, 67, 80, 0, 5, 68, 4, 68, + 69, 4, 73, 22, 68, 1, 16, 19, 25, 24, 14, 80, + 72, 76, 6, 67, 87, 67, 0, 72, 75, 71, 11, 40, + 14, 77, 80, 72, 69, 31, 38, 98, 66, 65, 81, 3, + 0, 66, 69, 33, 56, 42, 1, 75, 111, 17, 57, 62, + 114, 22, 21, 26, 28, 28, 23, 18, 22, 26, 13, + 20, 14, 7, 4, 0, 15, 13, 14, 12, 5, 9, 19, 9, + 68, 10, 12, 69, 19, 67, 62, 62, 51, 40, 48, + 58, 62, 62, 36, 21, 14, 17, 29, 27, 85, 18, + 22, 4, 37, 19, 19, 24, 28, 27, 34, 32, 8, 93, + 0, 65, 11, 113, 101, 69, 7, 10, 4, 77, 81, 86, + 85, 110, 88, 14, 3, 64, 71, 73, 79, 91, 89, + 106, 76, 20, 7, 2, 66, 67, 73, 77, 85, 97, 76, + 7, 66, 7, 5, 70, 77, 78, 91, 73, 29, 9, 9, 6, + 64, 70, 78, 77, 81, 62, 114, 112, 105, 111, + 103, 104, 103, 102, 99, 102, 102, 103, 88, 93, + 93, 98, 98, 89, 66, 83, 86, 84, 75, 71, 72, + 66, 77, 66, 65, 67, 68, 2, 68, 77, 65, 68, 75, + 5, 2, 66, 2, 11, 1, 71, 74, 75, 76, 66, 0, 2, + 5, 69, 66, 70, 7, 6, 72, 75, 75, 75, 7, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 58, 34, 62, 62, 62, 62, 58, 46, 33, 43, + 41, 30, 14, 8, 1, 79, 59, 57, 60, 44, 29, 32, + 25, 22, 30, 26, 18, 4, 15, 1, 73, 22, 27, 19, + 27, 32, 20, 17, 10, 9, 69, 3, 67, 79, 114, 64, + 68, 75, 19, 3, 70, 76, 69, 66, 66, 64, 64, 7, + 67, 65, 64, 5, 15, 12, 17, 2, 60, 57, 50, 46, + 38, 34, 20, 8, 75, 65, 30, 24, 21, 13, 11, 5, + 2, 64, 73, 76, 69, 66, 66, 64, 64, 7, 67, 65, + 64, 5, 15, 12, 17, 2, 60, 57, 50, 46, 38, 34, + 20, 8, 75 }, + + { + + 62, + 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 29, 48, + 55, 19, 3, 82, 31, 82, 87, 3, 3, 1, 65, 11, + 41, 45, 30, 65, 104, 107, 103, 72, 82, 87, 3, + 89, 79, 23, 6, 82, 93, 102, 68, 70, 86, 99, 0, + 81, 97, 66, 78, 88, 100, 7, 76, 73, 89, 18, 3, + 22, 0, 0, 0, 77, 88, 97, 67, 14, 0, 25, 82, + 114, 104, 80, 86, 68, 70, 81, 80, 107, 67, 91, + 81, 103, 86, 79, 85, 81, 12, 0, 74, 103, 75, + 97, 84, 108, 65, 77, 72, 89, 11, 69, 66, 89, + 83, 80, 78, 70, 64, 67, 79, 0, 5, 69, 4, 68, + 69, 4, 73, 22, 68, 1, 17, 19, 25, 24, 14, 81, + 72, 76, 6, 67, 86, 67, 1, 71, 75, 69, 13, 41, + 15, 75, 80, 73, 69, 32, 38, 99, 66, 64, 82, 4, + 0, 66, 68, 33, 56, 42, 3, 76, 109, 16, 54, 62, + 113, 22, 21, 25, 28, 27, 23, 17, 22, 25, 12, + 19, 14, 7, 4, 0, 14, 13, 13, 11, 5, 9, 18, 9, + 69, 9, 11, 69, 18, 68, 60, 62, 49, 38, 47, 56, + 62, 62, 35, 19, 12, 15, 27, 25, 86, 17, 21, 3, + 36, 18, 18, 22, 27, 25, 32, 31, 6, 93, 64, 66, + 9, 112, 100, 68, 7, 10, 4, 76, 80, 85, 85, + 108, 86, 15, 4, 64, 70, 71, 78, 89, 88, 103, + 75, 20, 7, 2, 65, 66, 72, 77, 84, 96, 76, 8, + 65, 7, 5, 69, 77, 78, 90, 72, 29, 10, 9, 6, 0, + 69, 77, 77, 80, 62, 113, 111, 104, 110, 102, + 102, 102, 100, 98, 100, 100, 100, 87, 92, 92, + 97, 95, 88, 67, 82, 85, 83, 75, 71, 72, 66, + 76, 67, 66, 67, 68, 3, 68, 77, 65, 68, 74, 4, + 1, 66, 1, 10, 0, 71, 74, 74, 77, 67, 1, 2, 4, + 69, 66, 70, 6, 5, 72, 75, 75, 75, 6, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 56, 32, 62, 62, 62, 62, 55, 44, 31, 41, 38, + 28, 13, 7, 0, 79, 57, 54, 57, 42, 27, 30, 23, + 20, 28, 24, 16, 2, 13, 0, 75, 21, 26, 17, 25, + 31, 18, 15, 9, 8, 70, 2, 68, 79, 113, 66, 69, + 76, 17, 2, 71, 76, 69, 66, 65, 0, 0, 7, 66, + 64, 0, 6, 15, 13, 17, 2, 60, 55, 48, 44, 36, + 32, 17, 6, 76, 65, 31, 24, 21, 14, 12, 5, 2, + 64, 72, 76, 69, 66, 65, 0, 0, 7, 66, 64, 0, 6, + 15, 13, 17, 2, 60, 55, 48, 44, 36, 32, 17, 6, + 76 }, + + { + + 62, + 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 28, 46, + 54, 19, 4, 80, 30, 82, 85, 3, 2, 2, 66, 10, + 40, 44, 26, 67, 105, 105, 101, 72, 82, 85, 3, + 88, 78, 24, 6, 81, 92, 101, 70, 71, 86, 100, + 0, 81, 97, 66, 79, 87, 100, 6, 76, 73, 88, 18, + 3, 22, 0, 0, 0, 76, 88, 97, 67, 14, 64, 25, + 81, 113, 102, 79, 85, 66, 68, 80, 79, 105, 66, + 90, 81, 101, 87, 79, 85, 81, 13, 0, 73, 101, + 75, 96, 83, 106, 65, 77, 72, 89, 12, 70, 65, + 89, 83, 79, 78, 69, 64, 66, 78, 1, 5, 69, 4, + 68, 69, 4, 73, 22, 68, 1, 17, 19, 26, 25, 15, + 81, 71, 75, 5, 67, 86, 67, 2, 71, 74, 68, 14, + 41, 17, 74, 81, 74, 68, 32, 38, 99, 67, 64, + 82, 4, 64, 65, 67, 33, 56, 43, 4, 77, 108, 15, + 51, 62, 111, 22, 21, 25, 27, 27, 22, 17, 21, + 25, 12, 19, 14, 6, 4, 64, 14, 12, 12, 11, 5, + 9, 18, 8, 71, 9, 10, 69, 17, 68, 57, 62, 47, + 37, 45, 54, 62, 61, 33, 17, 10, 14, 25, 23, + 88, 16, 19, 1, 34, 17, 17, 21, 25, 23, 30, 29, + 5, 93, 65, 67, 8, 110, 98, 66, 8, 10, 4, 75, + 80, 85, 84, 107, 85, 16, 5, 0, 70, 70, 77, 88, + 87, 101, 75, 21, 8, 3, 65, 65, 72, 76, 83, 95, + 76, 10, 64, 7, 5, 69, 76, 78, 90, 72, 30, 10, + 10, 6, 1, 69, 77, 76, 80, 62, 111, 109, 102, + 108, 100, 101, 100, 99, 96, 98, 98, 98, 87, + 91, 92, 97, 92, 88, 68, 82, 85, 82, 75, 71, + 72, 66, 76, 67, 67, 67, 68, 3, 68, 77, 65, 68, + 74, 4, 1, 66, 0, 9, 0, 71, 74, 73, 78, 67, 2, + 1, 4, 69, 66, 69, 6, 5, 71, 74, 75, 75, 4, 62, + 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 53, 30, 62, 62, 62, 62, 53, 41, 29, 39, + 36, 26, 12, 6, 64, 79, 55, 52, 55, 40, 25, 29, + 22, 18, 26, 21, 14, 0, 11, 65, 76, 20, 24, 15, + 24, 29, 17, 13, 7, 6, 71, 1, 69, 80, 112, 67, + 71, 78, 16, 0, 72, 75, 68, 65, 65, 1, 1, 8, + 66, 0, 1, 7, 16, 14, 18, 3, 59, 53, 46, 42, + 34, 30, 15, 4, 77, 64, 31, 25, 22, 14, 13, 6, + 3, 0, 72, 75, 68, 65, 65, 1, 1, 8, 66, 0, 1, + 7, 16, 14, 18, 3, 59, 53, 46, 42, 34, 30, 15, + 4, 77 }, + + { + + 62, + 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 26, 45, + 53, 20, 4, 78, 28, 82, 84, 3, 2, 3, 67, 8, 38, + 42, 23, 69, 106, 103, 100, 72, 82, 84, 3, 88, + 77, 24, 5, 80, 91, 100, 71, 73, 87, 100, 0, + 81, 96, 66, 79, 87, 100, 6, 76, 73, 88, 19, 3, + 22, 0, 0, 0, 76, 89, 97, 66, 13, 64, 24, 81, + 112, 100, 78, 84, 65, 67, 80, 78, 103, 65, 89, + 80, 99, 88, 79, 85, 81, 13, 64, 72, 99, 75, + 95, 82, 104, 65, 77, 72, 89, 12, 70, 65, 88, + 83, 79, 78, 69, 64, 66, 77, 1, 5, 69, 3, 68, + 69, 4, 73, 22, 68, 1, 18, 19, 26, 25, 15, 82, + 71, 74, 5, 67, 86, 67, 3, 71, 74, 67, 15, 42, + 18, 72, 81, 75, 68, 32, 38, 100, 67, 0, 83, 5, + 64, 65, 66, 33, 56, 43, 5, 78, 106, 14, 48, + 60, 110, 21, 21, 24, 26, 26, 22, 16, 21, 24, + 11, 18, 13, 6, 4, 64, 13, 11, 11, 10, 4, 8, + 17, 8, 72, 8, 9, 69, 15, 69, 55, 62, 45, 35, + 43, 52, 62, 58, 32, 15, 7, 12, 23, 21, 89, 14, + 18, 64, 33, 16, 16, 20, 24, 21, 28, 27, 3, 93, + 66, 68, 6, 109, 97, 65, 8, 10, 4, 74, 79, 84, + 83, 105, 84, 17, 5, 1, 69, 69, 76, 86, 86, 99, + 74, 21, 8, 3, 64, 64, 71, 76, 83, 94, 76, 11, + 0, 7, 5, 68, 76, 78, 89, 71, 30, 11, 10, 6, 2, + 68, 76, 76, 79, 62, 110, 108, 101, 106, 99, + 99, 99, 97, 95, 97, 96, 96, 86, 90, 91, 96, + 89, 88, 69, 82, 84, 82, 75, 71, 72, 67, 75, + 67, 68, 67, 68, 4, 68, 77, 65, 68, 74, 3, 1, + 66, 64, 8, 0, 71, 74, 72, 79, 67, 2, 0, 4, 69, + 66, 69, 6, 4, 71, 73, 75, 75, 3, 62, 60, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 50, + 28, 62, 62, 62, 62, 50, 39, 27, 37, 33, 24, + 10, 5, 65, 79, 52, 50, 53, 38, 23, 27, 20, 16, + 24, 19, 12, 65, 8, 67, 77, 19, 23, 12, 22, 27, + 15, 11, 6, 5, 72, 0, 70, 80, 111, 68, 72, 79, + 15, 64, 73, 75, 68, 65, 64, 2, 1, 9, 66, 1, 2, + 8, 16, 15, 18, 4, 59, 51, 44, 40, 32, 28, 13, + 2, 79, 64, 32, 25, 23, 15, 13, 6, 3, 0, 71, + 75, 68, 65, 64, 2, 1, 9, 66, 1, 2, 8, 16, 15, + 18, 4, 59, 51, 44, 40, 32, 28, 13, 2, 79 }, + + { + + 62, + 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 24, 43, + 52, 21, 4, 77, 26, 81, 82, 2, 2, 4, 68, 7, 37, + 40, 20, 72, 106, 101, 99, 72, 81, 82, 2, 88, + 76, 24, 5, 80, 90, 98, 72, 74, 87, 100, 0, 80, + 95, 67, 79, 87, 100, 6, 75, 73, 87, 19, 3, 22, + 0, 0, 0, 75, 89, 97, 66, 12, 64, 24, 80, 110, + 97, 77, 83, 0, 65, 79, 77, 101, 64, 88, 79, + 96, 88, 80, 85, 82, 13, 64, 71, 96, 74, 95, + 82, 102, 65, 77, 72, 88, 12, 70, 64, 87, 82, + 78, 77, 69, 0, 65, 76, 2, 5, 70, 3, 67, 69, 4, + 73, 23, 68, 1, 18, 20, 26, 25, 15, 82, 70, 74, + 4, 67, 85, 67, 4, 70, 73, 65, 17, 43, 20, 70, + 82, 76, 67, 33, 38, 101, 67, 0, 83, 6, 64, 65, + 64, 33, 56, 43, 7, 79, 105, 13, 46, 57, 109, + 21, 21, 24, 26, 26, 22, 16, 21, 24, 10, 17, + 13, 6, 4, 64, 13, 11, 10, 10, 4, 8, 16, 7, 73, + 7, 9, 69, 14, 69, 53, 62, 44, 34, 42, 50, 62, + 56, 31, 13, 5, 11, 21, 19, 90, 13, 17, 65, 32, + 15, 15, 18, 22, 19, 26, 26, 2, 93, 67, 69, 4, + 107, 95, 64, 9, 10, 4, 73, 78, 83, 83, 103, + 82, 18, 6, 1, 68, 67, 75, 85, 85, 96, 73, 22, + 9, 4, 64, 0, 70, 75, 82, 93, 75, 12, 1, 7, 5, + 67, 75, 77, 88, 70, 30, 12, 10, 6, 3, 67, 75, + 75, 78, 62, 109, 106, 99, 105, 98, 98, 97, 95, + 93, 95, 94, 93, 85, 89, 90, 95, 86, 87, 70, + 81, 83, 81, 75, 71, 72, 67, 75, 68, 69, 67, + 68, 5, 68, 77, 65, 68, 73, 3, 0, 66, 65, 7, + 64, 71, 74, 71, 79, 68, 3, 0, 3, 69, 66, 69, + 5, 4, 71, 73, 75, 75, 1, 62, 59, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 60, 48, 26, 62, + 62, 62, 62, 47, 37, 26, 35, 31, 22, 9, 4, 66, + 79, 50, 47, 50, 36, 21, 25, 19, 14, 22, 17, + 10, 67, 6, 68, 79, 18, 22, 10, 21, 26, 14, 9, + 5, 4, 73, 64, 71, 80, 110, 70, 73, 81, 13, 65, + 74, 75, 67, 64, 0, 3, 2, 9, 65, 2, 3, 9, 17, + 16, 19, 4, 58, 49, 42, 38, 30, 26, 10, 0, 80, + 0, 32, 26, 23, 16, 14, 7, 4, 0, 70, 75, 67, + 64, 0, 3, 2, 9, 65, 2, 3, 9, 17, 16, 19, 4, + 58, 49, 42, 38, 30, 26, 10, 0, 80 }, + + { + + 61, + 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 22, 42, + 51, 21, 4, 75, 25, 81, 81, 2, 1, 5, 69, 6, 36, + 38, 16, 74, 107, 99, 97, 72, 81, 81, 2, 87, + 75, 25, 5, 79, 89, 97, 73, 75, 87, 101, 0, 80, + 94, 67, 80, 87, 100, 6, 75, 73, 86, 20, 3, 22, + 0, 0, 0, 75, 89, 97, 65, 11, 64, 23, 80, 109, + 95, 76, 82, 1, 64, 78, 76, 99, 0, 87, 78, 94, + 89, 80, 85, 82, 14, 64, 70, 94, 74, 94, 81, + 100, 65, 77, 72, 88, 13, 70, 64, 86, 82, 77, + 77, 69, 0, 65, 75, 2, 5, 70, 3, 67, 69, 4, 73, + 23, 68, 1, 19, 20, 27, 25, 16, 83, 70, 73, 4, + 67, 85, 67, 5, 70, 73, 64, 18, 44, 21, 68, 82, + 77, 67, 33, 38, 102, 67, 1, 84, 6, 64, 65, 0, + 33, 56, 43, 8, 80, 103, 12, 43, 54, 107, 21, + 21, 23, 25, 25, 21, 15, 21, 23, 9, 16, 13, 6, + 4, 65, 12, 10, 9, 9, 4, 8, 15, 7, 74, 7, 8, + 69, 13, 70, 51, 60, 42, 32, 40, 48, 62, 53, + 30, 11, 3, 9, 19, 17, 92, 12, 16, 67, 31, 14, + 14, 17, 21, 17, 24, 24, 0, 93, 68, 70, 3, 106, + 94, 1, 9, 10, 4, 72, 77, 82, 82, 101, 81, 19, + 7, 2, 68, 66, 74, 83, 84, 94, 73, 22, 9, 4, 0, + 1, 70, 75, 81, 92, 75, 14, 2, 7, 5, 66, 75, + 77, 87, 69, 31, 13, 11, 6, 4, 67, 74, 75, 78, + 62, 107, 105, 98, 103, 97, 96, 96, 94, 92, 93, + 92, 91, 85, 88, 90, 94, 83, 87, 71, 81, 82, + 80, 75, 71, 72, 67, 74, 68, 70, 67, 68, 5, 68, + 77, 65, 68, 73, 2, 0, 66, 66, 6, 64, 71, 74, + 70, 80, 68, 4, 64, 3, 69, 66, 68, 5, 3, 70, + 72, 75, 75, 0, 62, 58, 61, 61, 61, 62, 62, 62, + 61, 62, 62, 62, 57, 45, 24, 62, 60, 59, 60, + 44, 35, 24, 33, 28, 20, 8, 3, 67, 79, 48, 45, + 48, 34, 19, 23, 17, 12, 20, 15, 8, 69, 4, 70, + 80, 17, 21, 8, 19, 24, 12, 7, 3, 2, 74, 65, + 72, 80, 109, 71, 75, 82, 12, 66, 75, 75, 67, + 64, 0, 4, 3, 10, 65, 3, 4, 10, 17, 17, 19, 5, + 58, 47, 40, 36, 28, 24, 8, 65, 81, 0, 33, 26, + 24, 16, 15, 7, 4, 1, 70, 75, 67, 64, 0, 4, 3, + 10, 65, 3, 4, 10, 17, 17, 19, 5, 58, 47, 40, + 36, 28, 24, 8, 65, 81 }, + + { + + 60, + 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 20, 40, + 50, 22, 4, 73, 23, 81, 79, 2, 1, 6, 70, 5, 35, + 36, 13, 76, 108, 97, 96, 72, 81, 79, 2, 87, + 74, 25, 5, 78, 88, 96, 74, 76, 87, 101, 0, 80, + 93, 67, 80, 87, 100, 6, 75, 73, 85, 20, 3, 22, + 0, 0, 0, 74, 89, 97, 65, 10, 64, 23, 79, 108, + 93, 75, 81, 3, 1, 77, 75, 97, 1, 86, 77, 92, + 90, 80, 85, 82, 14, 64, 69, 92, 74, 93, 80, + 98, 65, 77, 72, 88, 13, 70, 0, 85, 82, 76, 77, + 69, 0, 64, 74, 3, 5, 70, 3, 67, 69, 4, 73, 23, + 68, 1, 19, 20, 27, 25, 16, 83, 69, 72, 3, 67, + 85, 67, 6, 70, 72, 0, 19, 45, 23, 66, 83, 78, + 66, 33, 38, 103, 67, 1, 84, 7, 64, 65, 1, 33, + 56, 43, 9, 81, 102, 11, 40, 51, 106, 21, 21, + 23, 24, 25, 21, 15, 21, 23, 8, 15, 13, 6, 4, + 65, 12, 9, 8, 9, 4, 8, 14, 6, 75, 6, 7, 69, + 12, 70, 49, 58, 40, 31, 38, 46, 59, 51, 29, 9, + 1, 8, 17, 15, 93, 11, 15, 69, 30, 13, 13, 16, + 19, 15, 22, 22, 64, 93, 69, 71, 1, 104, 92, 2, + 10, 10, 4, 71, 76, 81, 81, 99, 80, 20, 8, 3, + 67, 65, 73, 82, 83, 92, 72, 23, 10, 5, 0, 2, + 69, 74, 80, 91, 75, 15, 3, 7, 5, 65, 74, 77, + 86, 68, 31, 14, 11, 6, 5, 66, 73, 74, 77, 62, + 106, 103, 96, 101, 96, 95, 94, 92, 90, 91, 90, + 89, 84, 87, 89, 93, 80, 87, 72, 81, 81, 79, + 75, 71, 72, 67, 74, 68, 71, 67, 68, 6, 68, 77, + 65, 68, 73, 2, 0, 66, 67, 5, 64, 71, 74, 69, + 81, 68, 5, 65, 3, 69, 66, 68, 5, 3, 70, 71, + 75, 75, 65, 61, 57, 60, 59, 59, 62, 62, 62, + 59, 60, 62, 61, 54, 42, 22, 61, 57, 55, 55, + 41, 33, 22, 31, 26, 18, 7, 2, 68, 79, 46, 43, + 46, 32, 17, 21, 16, 10, 18, 13, 6, 71, 2, 72, + 81, 16, 20, 6, 18, 22, 11, 5, 2, 1, 75, 66, + 73, 80, 108, 72, 76, 84, 11, 67, 76, 75, 66, + 0, 1, 5, 4, 11, 65, 4, 5, 11, 18, 18, 20, 6, + 57, 45, 38, 34, 26, 22, 6, 67, 82, 1, 33, 27, + 25, 17, 16, 8, 5, 1, 69, 75, 66, 0, 1, 5, 4, + 11, 65, 4, 5, 11, 18, 18, 20, 6, 57, 45, 38, + 34, 26, 22, 6, 67, 82 }, + + { + + 58, + 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 18, 38, + 49, 22, 4, 72, 21, 81, 78, 1, 0, 7, 71, 3, 33, + 34, 9, 79, 109, 95, 95, 72, 81, 78, 1, 87, 74, + 25, 4, 78, 88, 95, 76, 78, 88, 102, 64, 80, + 93, 68, 81, 87, 100, 5, 75, 73, 85, 20, 2, 22, + 0, 0, 0, 74, 90, 97, 65, 9, 65, 22, 79, 107, + 91, 74, 81, 4, 2, 77, 74, 96, 1, 85, 77, 90, + 91, 81, 86, 83, 14, 65, 69, 90, 74, 93, 80, + 97, 65, 77, 72, 88, 13, 71, 0, 85, 82, 76, 77, + 69, 0, 64, 73, 3, 5, 71, 2, 67, 69, 3, 73, 23, + 68, 1, 19, 20, 27, 25, 16, 84, 69, 72, 2, 67, + 85, 68, 6, 70, 72, 1, 20, 45, 24, 65, 84, 80, + 66, 33, 38, 104, 68, 1, 85, 7, 65, 65, 2, 33, + 55, 43, 10, 82, 101, 9, 37, 47, 105, 20, 21, + 22, 23, 24, 20, 14, 20, 22, 7, 14, 12, 5, 3, + 66, 11, 8, 7, 8, 3, 7, 13, 5, 77, 5, 6, 69, + 10, 71, 46, 55, 38, 29, 36, 43, 55, 48, 27, 7, + 65, 6, 14, 13, 95, 9, 13, 71, 28, 12, 12, 14, + 17, 13, 20, 20, 66, 93, 70, 72, 64, 103, 91, + 3, 10, 10, 4, 71, 76, 81, 81, 98, 79, 20, 8, + 3, 67, 64, 72, 81, 83, 90, 72, 23, 10, 5, 0, + 2, 69, 74, 80, 90, 75, 16, 4, 7, 4, 65, 74, + 77, 86, 68, 31, 14, 11, 6, 6, 66, 73, 74, 77, + 62, 105, 102, 95, 100, 95, 94, 93, 91, 89, 90, + 89, 87, 84, 87, 89, 93, 77, 87, 74, 81, 81, + 79, 75, 71, 72, 68, 74, 69, 72, 68, 68, 6, 69, + 77, 66, 68, 73, 1, 64, 67, 68, 4, 65, 72, 74, + 68, 82, 69, 5, 66, 2, 69, 67, 68, 4, 2, 70, + 71, 75, 75, 67, 59, 56, 58, 57, 56, 62, 62, + 62, 56, 57, 62, 58, 50, 39, 20, 57, 53, 51, + 49, 38, 30, 20, 28, 23, 16, 5, 0, 69, 79, 43, + 40, 43, 30, 14, 19, 14, 7, 16, 10, 4, 74, 64, + 74, 83, 14, 18, 3, 16, 20, 9, 3, 0, 64, 76, + 67, 74, 81, 107, 74, 78, 86, 9, 69, 78, 75, + 66, 0, 1, 6, 4, 11, 65, 5, 5, 12, 18, 18, 20, + 6, 56, 43, 36, 31, 23, 20, 3, 69, 84, 1, 33, + 27, 25, 17, 16, 8, 5, 1, 69, 75, 66, 0, 1, 6, + 4, 11, 65, 5, 5, 12, 18, 18, 20, 6, 56, 43, + 36, 31, 23, 20, 3, 69, 84 }, + + { + + 57, + 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 17, 37, + 49, 23, 5, 70, 20, 80, 76, 1, 0, 9, 71, 2, 32, + 33, 6, 81, 109, 93, 93, 71, 80, 76, 1, 86, 73, + 26, 4, 77, 87, 93, 77, 79, 88, 102, 64, 79, + 92, 68, 81, 86, 99, 5, 74, 72, 84, 21, 2, 22, + 0, 0, 0, 73, 90, 97, 64, 9, 65, 22, 78, 105, + 88, 72, 80, 6, 4, 76, 72, 94, 2, 83, 76, 87, + 91, 81, 86, 83, 15, 65, 68, 87, 73, 92, 79, + 95, 65, 76, 72, 87, 14, 71, 1, 84, 81, 75, 76, + 68, 1, 0, 72, 4, 6, 71, 2, 66, 68, 3, 72, 24, + 67, 1, 20, 21, 28, 26, 17, 84, 68, 71, 2, 67, + 84, 68, 7, 69, 71, 3, 22, 46, 26, 0, 84, 81, + 65, 34, 39, 104, 68, 2, 85, 8, 65, 64, 4, 33, + 55, 44, 12, 83, 99, 8, 35, 44, 103, 20, 21, + 22, 23, 24, 20, 14, 20, 22, 7, 14, 12, 5, 3, + 66, 11, 8, 7, 8, 3, 7, 13, 5, 78, 5, 6, 69, 9, + 71, 44, 53, 37, 28, 35, 41, 52, 46, 26, 6, 67, + 5, 12, 12, 96, 8, 12, 72, 27, 12, 12, 13, 16, + 12, 19, 19, 67, 93, 70, 72, 65, 101, 89, 5, + 11, 10, 4, 70, 75, 80, 80, 96, 77, 21, 9, 4, + 66, 1, 71, 79, 82, 87, 71, 24, 11, 6, 1, 3, + 68, 73, 79, 88, 74, 18, 5, 8, 4, 64, 73, 76, + 85, 67, 32, 15, 12, 7, 7, 65, 72, 73, 76, 62, + 103, 100, 93, 98, 93, 92, 91, 89, 87, 88, 87, + 84, 83, 86, 88, 92, 73, 86, 75, 80, 80, 78, + 74, 71, 71, 68, 73, 69, 72, 68, 68, 7, 69, 77, + 66, 68, 72, 1, 64, 67, 68, 4, 65, 72, 73, 66, + 82, 69, 6, 66, 2, 69, 67, 67, 4, 2, 69, 70, + 74, 74, 68, 58, 55, 57, 56, 54, 60, 60, 59, + 54, 55, 59, 56, 47, 37, 18, 54, 50, 48, 44, + 36, 28, 19, 26, 21, 15, 4, 64, 69, 79, 41, 38, + 41, 28, 12, 18, 13, 5, 15, 8, 3, 76, 66, 75, + 84, 13, 17, 1, 15, 19, 8, 2, 64, 65, 77, 67, + 74, 81, 106, 75, 79, 87, 8, 70, 79, 74, 65, 1, + 2, 8, 5, 12, 64, 7, 6, 13, 19, 19, 21, 7, 56, + 42, 35, 29, 21, 19, 1, 70, 85, 2, 34, 28, 26, + 18, 17, 9, 6, 2, 68, 74, 65, 1, 2, 8, 5, 12, + 64, 7, 6, 13, 19, 19, 21, 7, 56, 42, 35, 29, + 21, 19, 1, 70, 85 }, + + { + + 56, + 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 15, 35, + 48, 24, 5, 68, 18, 80, 75, 1, 0, 10, 72, 1, + 31, 31, 3, 83, 110, 91, 92, 71, 80, 75, 1, 86, + 72, 26, 4, 76, 86, 92, 78, 80, 88, 102, 64, + 79, 91, 68, 81, 86, 99, 5, 74, 72, 83, 21, 2, + 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 22, 77, + 104, 86, 71, 79, 8, 6, 75, 71, 92, 3, 82, 75, + 85, 92, 81, 86, 83, 15, 65, 67, 85, 73, 91, + 78, 93, 65, 76, 72, 87, 14, 71, 1, 83, 81, 74, + 76, 68, 1, 0, 71, 5, 6, 71, 2, 66, 68, 3, 72, + 24, 67, 1, 20, 21, 28, 26, 17, 85, 67, 70, 1, + 67, 84, 68, 8, 69, 71, 4, 23, 47, 28, 2, 85, + 82, 65, 34, 39, 105, 68, 2, 86, 9, 65, 64, 5, + 33, 55, 44, 13, 84, 98, 7, 32, 41, 102, 20, + 21, 22, 22, 23, 20, 14, 20, 21, 6, 13, 12, 5, + 3, 66, 10, 7, 6, 8, 3, 7, 12, 4, 79, 4, 5, 69, + 8, 72, 42, 51, 35, 26, 33, 39, 49, 44, 25, 4, + 69, 3, 10, 10, 97, 7, 11, 74, 26, 11, 11, 12, + 14, 10, 17, 17, 69, 93, 71, 73, 67, 100, 88, + 6, 12, 10, 4, 69, 74, 79, 79, 94, 76, 22, 10, + 5, 65, 2, 70, 78, 81, 85, 70, 24, 11, 6, 1, 4, + 67, 72, 78, 87, 74, 19, 6, 8, 4, 0, 72, 76, + 84, 66, 32, 16, 12, 7, 8, 64, 71, 72, 75, 62, + 102, 98, 91, 96, 92, 91, 89, 87, 86, 86, 85, + 82, 82, 85, 87, 91, 70, 86, 76, 80, 79, 77, + 74, 71, 71, 68, 73, 69, 73, 68, 68, 8, 69, 77, + 66, 68, 72, 1, 64, 67, 69, 3, 65, 72, 73, 65, + 83, 69, 7, 67, 2, 69, 67, 67, 4, 2, 69, 69, + 74, 74, 70, 57, 54, 56, 54, 52, 57, 57, 56, + 52, 52, 56, 53, 44, 34, 16, 50, 46, 44, 39, + 33, 26, 17, 24, 19, 13, 3, 65, 70, 79, 39, 36, + 39, 26, 10, 16, 11, 3, 13, 6, 1, 78, 68, 77, + 85, 12, 16, 64, 13, 17, 6, 0, 65, 66, 78, 68, + 75, 81, 105, 76, 80, 89, 7, 71, 80, 74, 65, 2, + 3, 9, 6, 13, 64, 8, 7, 14, 19, 20, 22, 8, 55, + 40, 33, 27, 19, 17, 64, 72, 86, 3, 34, 28, 27, + 19, 18, 9, 7, 2, 67, 74, 65, 2, 3, 9, 6, 13, + 64, 8, 7, 14, 19, 20, 22, 8, 55, 40, 33, 27, + 19, 17, 64, 72, 86 }, + + { + + 55, + 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 13, 34, + 47, 24, 5, 66, 17, 80, 73, 1, 64, 11, 73, 0, + 30, 29, 64, 85, 111, 89, 90, 71, 80, 73, 1, + 85, 71, 27, 4, 75, 85, 91, 79, 81, 88, 103, + 64, 79, 90, 68, 82, 86, 99, 5, 74, 72, 82, 22, + 2, 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 21, 77, + 103, 84, 70, 78, 9, 7, 74, 70, 90, 4, 81, 74, + 83, 93, 81, 86, 83, 16, 65, 66, 83, 73, 90, + 77, 91, 65, 76, 72, 87, 15, 71, 2, 82, 81, 73, + 76, 68, 1, 1, 70, 5, 6, 71, 2, 66, 68, 3, 72, + 24, 67, 1, 21, 21, 29, 26, 18, 85, 67, 69, 1, + 67, 84, 68, 9, 69, 70, 5, 24, 48, 29, 4, 85, + 83, 64, 34, 39, 106, 68, 3, 86, 9, 65, 64, 6, + 33, 55, 44, 14, 85, 96, 6, 29, 38, 100, 20, + 21, 21, 21, 23, 19, 13, 20, 21, 5, 12, 12, 5, + 3, 67, 10, 6, 5, 7, 3, 7, 11, 4, 80, 4, 4, 69, + 7, 72, 40, 49, 33, 25, 31, 37, 46, 41, 24, 2, + 71, 2, 8, 8, 99, 6, 10, 76, 25, 10, 10, 11, + 13, 8, 15, 15, 70, 93, 72, 74, 68, 98, 86, 8, + 12, 10, 4, 68, 73, 78, 78, 92, 75, 23, 11, 6, + 65, 3, 69, 76, 80, 83, 70, 25, 12, 7, 2, 5, + 67, 72, 77, 86, 74, 21, 7, 8, 4, 1, 72, 76, + 83, 65, 33, 17, 13, 7, 9, 64, 70, 72, 75, 62, + 100, 97, 90, 94, 91, 89, 88, 86, 84, 84, 83, + 80, 82, 84, 87, 90, 67, 86, 77, 80, 78, 76, + 74, 71, 71, 68, 72, 69, 74, 68, 68, 8, 69, 77, + 66, 68, 72, 0, 64, 67, 70, 2, 65, 72, 73, 64, + 84, 69, 8, 68, 2, 69, 67, 66, 4, 1, 68, 68, + 74, 74, 71, 56, 53, 55, 52, 50, 55, 55, 53, + 49, 49, 53, 50, 41, 31, 14, 46, 43, 40, 34, + 30, 24, 15, 22, 16, 11, 2, 66, 71, 79, 37, 34, + 37, 24, 8, 14, 10, 1, 11, 4, 64, 80, 70, 79, + 86, 11, 15, 66, 12, 15, 5, 65, 67, 68, 79, 69, + 76, 81, 104, 77, 82, 90, 6, 72, 81, 74, 64, 2, + 3, 10, 7, 14, 64, 9, 8, 15, 20, 21, 22, 9, 55, + 38, 31, 25, 17, 15, 66, 74, 87, 3, 35, 29, 28, + 19, 19, 10, 7, 3, 67, 74, 64, 2, 3, 10, 7, 14, + 64, 9, 8, 15, 20, 21, 22, 9, 55, 38, 31, 25, + 17, 15, 66, 74, 87 }, + + { + + 53, + 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 11, 32, + 46, 25, 5, 65, 15, 80, 72, 0, 64, 12, 74, 65, + 28, 27, 67, 88, 112, 87, 89, 71, 80, 72, 0, + 85, 70, 27, 3, 75, 84, 89, 80, 83, 89, 103, + 64, 78, 89, 69, 82, 86, 99, 5, 74, 72, 82, 22, + 2, 22, 0, 0, 0, 71, 91, 97, 0, 6, 65, 21, 76, + 102, 82, 69, 77, 11, 9, 74, 69, 88, 5, 80, 73, + 80, 93, 82, 86, 84, 16, 66, 65, 80, 72, 90, + 77, 89, 65, 76, 72, 87, 15, 71, 2, 81, 81, 73, + 75, 68, 1, 1, 69, 6, 6, 72, 1, 66, 68, 3, 72, + 24, 67, 1, 21, 21, 29, 26, 18, 86, 66, 69, 0, + 67, 83, 68, 10, 68, 70, 7, 26, 49, 31, 6, 86, + 84, 64, 35, 39, 107, 68, 3, 87, 10, 65, 64, 7, + 33, 55, 44, 16, 86, 95, 5, 26, 35, 99, 19, 21, + 21, 21, 22, 19, 13, 20, 20, 4, 11, 11, 5, 3, + 67, 9, 6, 4, 7, 2, 6, 10, 3, 81, 3, 3, 69, 5, + 73, 38, 47, 31, 23, 30, 35, 42, 39, 23, 0, 74, + 0, 6, 6, 100, 4, 9, 77, 24, 9, 9, 9, 11, 6, + 13, 14, 72, 93, 73, 75, 70, 97, 85, 9, 13, 10, + 4, 67, 72, 77, 78, 90, 73, 24, 11, 6, 64, 5, + 68, 75, 79, 80, 69, 25, 12, 7, 2, 6, 66, 71, + 77, 85, 74, 22, 8, 8, 4, 2, 71, 76, 82, 64, + 33, 18, 13, 7, 10, 0, 69, 71, 74, 62, 99, 95, + 88, 93, 90, 88, 86, 84, 83, 83, 81, 77, 81, + 83, 86, 89, 64, 85, 78, 79, 77, 76, 74, 71, + 71, 69, 72, 70, 75, 68, 68, 9, 69, 77, 66, 68, + 71, 0, 65, 67, 71, 1, 66, 72, 73, 0, 85, 70, + 8, 68, 1, 69, 67, 66, 3, 1, 68, 68, 74, 74, + 73, 55, 52, 54, 51, 47, 52, 52, 50, 47, 46, + 49, 47, 37, 29, 12, 42, 39, 36, 29, 27, 22, + 13, 20, 14, 9, 0, 67, 72, 79, 34, 31, 34, 22, + 6, 12, 8, 64, 9, 2, 66, 82, 73, 80, 88, 10, + 14, 69, 10, 14, 3, 67, 68, 69, 80, 70, 77, 81, + 103, 79, 83, 92, 4, 73, 82, 74, 64, 3, 4, 11, + 7, 14, 0, 10, 9, 16, 20, 22, 23, 9, 54, 36, + 29, 23, 15, 13, 69, 76, 89, 4, 35, 29, 28, 20, + 19, 10, 8, 3, 66, 74, 64, 3, 4, 11, 7, 14, 0, + 10, 9, 16, 20, 22, 23, 9, 54, 36, 29, 23, 15, + 13, 69, 76, 89 }, + + { + + 52, + 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 9, 31, + 45, 26, 5, 0, 13, 79, 70, 0, 64, 13, 75, 66, + 27, 25, 70, 90, 112, 85, 88, 71, 79, 70, 0, + 85, 69, 27, 3, 74, 83, 88, 81, 84, 89, 103, + 64, 78, 88, 69, 82, 86, 99, 5, 73, 72, 81, 23, + 2, 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 20, 76, + 100, 79, 68, 76, 12, 10, 73, 68, 86, 6, 79, + 72, 78, 94, 82, 86, 84, 16, 66, 64, 78, 72, + 89, 76, 87, 65, 76, 72, 86, 15, 71, 3, 80, 80, + 72, 75, 68, 2, 2, 68, 6, 6, 72, 1, 65, 68, 3, + 72, 25, 67, 1, 22, 22, 29, 26, 18, 86, 66, 68, + 0, 67, 83, 68, 11, 68, 69, 8, 27, 50, 32, 8, + 86, 85, 0, 35, 39, 108, 68, 4, 87, 11, 65, 64, + 9, 33, 55, 44, 17, 87, 93, 4, 24, 32, 98, 19, + 21, 20, 20, 22, 19, 12, 20, 20, 3, 10, 11, 5, + 3, 67, 9, 5, 3, 6, 2, 6, 9, 3, 82, 2, 3, 69, + 4, 73, 36, 45, 30, 22, 28, 33, 39, 36, 22, 65, + 76, 64, 4, 4, 101, 3, 8, 79, 23, 8, 8, 8, 10, + 4, 11, 12, 73, 93, 74, 76, 72, 95, 83, 10, 13, + 10, 4, 66, 71, 76, 77, 88, 72, 25, 12, 7, 0, + 6, 67, 73, 78, 78, 68, 26, 13, 8, 3, 7, 65, + 71, 76, 84, 73, 23, 9, 8, 4, 3, 71, 75, 81, 0, + 33, 19, 13, 7, 11, 1, 68, 71, 73, 62, 98, 94, + 87, 91, 89, 86, 85, 82, 81, 81, 79, 75, 80, + 82, 85, 88, 2, 85, 79, 79, 76, 75, 74, 71, 71, + 69, 71, 70, 76, 68, 68, 10, 69, 77, 66, 68, + 71, 64, 65, 67, 72, 0, 66, 72, 73, 1, 85, 70, + 9, 69, 1, 69, 67, 66, 3, 0, 68, 67, 74, 74, + 74, 54, 51, 53, 49, 45, 50, 49, 47, 44, 43, + 46, 44, 34, 26, 10, 38, 36, 32, 24, 24, 20, + 12, 18, 11, 7, 64, 68, 73, 79, 32, 29, 32, 20, + 4, 10, 7, 66, 7, 0, 68, 84, 75, 82, 89, 9, 13, + 71, 9, 12, 2, 69, 69, 70, 81, 71, 78, 81, 102, + 80, 84, 93, 3, 74, 83, 74, 0, 3, 5, 12, 8, 15, + 0, 11, 10, 17, 21, 23, 23, 10, 54, 34, 27, 21, + 13, 11, 71, 78, 90, 4, 36, 30, 29, 21, 20, 11, + 8, 3, 65, 74, 0, 3, 5, 12, 8, 15, 0, 11, 10, + 17, 21, 23, 23, 10, 54, 34, 27, 21, 13, 11, + 71, 78, 90 }, + + { + + 51, + 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 8, 29, + 44, 26, 6, 2, 12, 79, 69, 0, 65, 14, 76, 67, + 26, 24, 74, 92, 113, 83, 86, 71, 79, 69, 0, + 84, 68, 28, 3, 73, 82, 87, 83, 85, 89, 104, + 64, 78, 88, 69, 83, 85, 99, 4, 73, 72, 80, 23, + 2, 22, 0, 0, 0, 70, 91, 97, 1, 5, 66, 20, 75, + 99, 77, 67, 75, 14, 12, 72, 67, 84, 7, 78, 72, + 76, 95, 82, 86, 84, 17, 66, 0, 76, 72, 88, 75, + 85, 65, 76, 72, 86, 16, 72, 3, 80, 80, 71, 75, + 67, 2, 2, 67, 7, 6, 72, 1, 65, 68, 3, 72, 25, + 67, 1, 22, 22, 30, 27, 19, 87, 65, 67, 64, 67, + 83, 68, 12, 68, 69, 9, 28, 50, 34, 9, 87, 86, + 0, 35, 39, 108, 69, 4, 88, 11, 66, 0, 10, 33, + 55, 45, 18, 88, 92, 3, 21, 29, 96, 19, 21, 20, + 19, 21, 18, 12, 19, 19, 3, 10, 11, 4, 3, 68, + 8, 4, 2, 6, 2, 6, 9, 2, 84, 2, 2, 69, 3, 74, + 33, 43, 28, 20, 26, 31, 36, 34, 20, 67, 78, + 66, 2, 2, 103, 2, 6, 81, 21, 7, 7, 7, 8, 2, 9, + 10, 75, 93, 75, 77, 73, 94, 82, 12, 14, 10, 4, + 65, 71, 76, 76, 87, 71, 26, 13, 8, 0, 7, 66, + 72, 77, 76, 68, 26, 13, 8, 3, 8, 65, 70, 75, + 83, 73, 25, 10, 8, 4, 3, 70, 75, 81, 0, 34, + 19, 14, 7, 12, 1, 68, 70, 73, 62, 96, 92, 85, + 89, 87, 85, 83, 81, 80, 79, 77, 73, 80, 81, + 85, 88, 5, 85, 80, 79, 76, 74, 74, 71, 71, 69, + 71, 70, 77, 68, 68, 10, 69, 77, 66, 68, 71, + 64, 65, 67, 73, 64, 66, 72, 73, 2, 86, 70, 10, + 70, 1, 69, 67, 65, 3, 0, 67, 66, 74, 74, 76, + 53, 50, 52, 47, 43, 47, 47, 44, 42, 40, 43, + 41, 31, 23, 8, 35, 32, 28, 19, 22, 17, 10, 16, + 9, 5, 65, 69, 74, 79, 30, 27, 30, 18, 2, 9, 5, + 68, 5, 66, 70, 86, 77, 84, 90, 8, 11, 73, 7, + 10, 0, 71, 71, 72, 82, 72, 79, 82, 101, 81, + 86, 95, 2, 76, 84, 73, 0, 4, 5, 13, 9, 16, 0, + 12, 11, 18, 21, 24, 24, 11, 53, 32, 25, 19, + 11, 9, 73, 80, 91, 5, 36, 30, 30, 21, 21, 11, + 9, 4, 65, 73, 0, 4, 5, 13, 9, 16, 0, 12, 11, + 18, 21, 24, 24, 11, 53, 32, 25, 19, 11, 9, 73, + 80, 91 }, + + { + + 50, + 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 6, 28, + 43, 27, 6, 3, 10, 79, 67, 64, 65, 15, 77, 68, + 25, 22, 77, 95, 114, 81, 85, 71, 79, 67, 64, + 84, 67, 28, 3, 73, 81, 85, 84, 86, 89, 104, + 64, 77, 87, 70, 83, 85, 99, 4, 73, 72, 79, 24, + 2, 22, 0, 0, 0, 70, 91, 97, 2, 4, 66, 19, 75, + 98, 75, 66, 74, 15, 13, 71, 66, 82, 8, 77, 71, + 73, 95, 83, 86, 85, 17, 66, 1, 73, 71, 88, 75, + 83, 65, 76, 72, 86, 16, 72, 4, 79, 80, 70, 74, + 67, 2, 3, 66, 7, 6, 73, 1, 65, 68, 3, 72, 25, + 67, 1, 23, 22, 30, 27, 19, 87, 65, 67, 64, 67, + 82, 68, 13, 67, 68, 11, 30, 51, 35, 11, 87, + 87, 1, 36, 39, 109, 69, 5, 88, 12, 66, 0, 11, + 33, 55, 45, 20, 89, 90, 2, 18, 26, 95, 19, 21, + 19, 19, 21, 18, 11, 19, 19, 2, 9, 11, 4, 3, + 68, 8, 4, 1, 5, 2, 6, 8, 2, 85, 1, 1, 69, 2, + 74, 31, 41, 26, 19, 25, 29, 33, 31, 19, 69, + 80, 67, 0, 0, 104, 1, 5, 82, 20, 6, 6, 5, 7, + 0, 7, 9, 76, 93, 76, 78, 75, 92, 80, 13, 14, + 10, 4, 64, 70, 75, 76, 85, 69, 27, 14, 8, 1, + 9, 65, 70, 76, 73, 67, 27, 14, 9, 4, 9, 64, + 70, 74, 82, 73, 26, 11, 8, 4, 4, 70, 75, 80, + 1, 34, 20, 14, 7, 13, 2, 67, 70, 72, 62, 95, + 91, 84, 88, 86, 83, 82, 79, 78, 77, 75, 70, + 79, 80, 84, 87, 8, 84, 81, 78, 75, 73, 74, 71, + 71, 69, 70, 71, 78, 68, 68, 11, 69, 77, 66, + 68, 70, 65, 66, 67, 74, 65, 67, 72, 73, 3, 87, + 71, 11, 70, 0, 69, 67, 65, 2, 64, 67, 66, 74, + 74, 77, 52, 49, 51, 46, 40, 45, 44, 41, 39, + 37, 40, 38, 28, 21, 6, 31, 29, 24, 14, 19, 15, + 8, 14, 6, 3, 66, 70, 75, 79, 28, 24, 27, 16, + 0, 7, 4, 70, 3, 68, 72, 88, 79, 85, 92, 7, 10, + 75, 6, 9, 64, 73, 72, 73, 83, 73, 80, 82, 100, + 83, 87, 96, 0, 77, 85, 73, 1, 4, 6, 14, 10, + 16, 1, 13, 12, 19, 22, 25, 24, 11, 53, 30, 23, + 17, 9, 7, 76, 82, 92, 5, 37, 31, 30, 22, 22, + 12, 9, 4, 64, 73, 1, 4, 6, 14, 10, 16, 1, 13, + 12, 19, 22, 25, 24, 11, 53, 30, 23, 17, 9, 7, + 76, 82, 92 }, + + { + + 48, + 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 4, 26, + 42, 27, 6, 5, 8, 79, 66, 64, 66, 16, 78, 70, + 23, 20, 81, 97, 115, 79, 84, 71, 79, 66, 64, + 84, 67, 28, 2, 72, 80, 84, 85, 88, 90, 105, + 64, 77, 86, 70, 84, 85, 99, 4, 73, 72, 79, 24, + 2, 22, 0, 0, 0, 69, 92, 97, 2, 3, 66, 19, 74, + 97, 73, 65, 74, 17, 15, 71, 65, 80, 8, 76, 70, + 71, 96, 83, 87, 85, 17, 67, 1, 71, 71, 87, 74, + 82, 65, 76, 72, 86, 16, 72, 4, 78, 80, 70, 74, + 67, 2, 3, 65, 8, 6, 73, 0, 65, 68, 2, 72, 25, + 67, 1, 23, 22, 30, 27, 19, 88, 64, 66, 65, 67, + 82, 68, 14, 67, 68, 12, 31, 52, 37, 13, 88, + 88, 1, 36, 39, 110, 69, 5, 89, 12, 66, 0, 12, + 33, 55, 45, 21, 90, 89, 1, 15, 22, 94, 18, 21, + 19, 18, 20, 17, 11, 19, 18, 1, 8, 10, 4, 2, + 69, 7, 3, 0, 5, 1, 5, 7, 1, 86, 0, 0, 69, 0, + 75, 29, 39, 24, 17, 23, 26, 29, 29, 18, 71, + 83, 69, 66, 65, 106, 64, 4, 84, 19, 5, 5, 4, + 5, 65, 5, 7, 78, 93, 77, 79, 77, 91, 79, 14, + 15, 10, 4, 64, 69, 74, 75, 83, 68, 27, 14, 9, + 1, 10, 64, 69, 75, 71, 67, 27, 14, 9, 4, 9, + 64, 69, 74, 81, 73, 27, 12, 8, 4, 5, 69, 75, + 79, 2, 34, 21, 14, 7, 14, 2, 66, 69, 72, 62, + 94, 89, 82, 86, 85, 82, 80, 78, 77, 76, 73, + 68, 79, 79, 84, 86, 11, 84, 82, 78, 74, 73, + 74, 71, 71, 70, 70, 71, 79, 68, 68, 11, 69, + 77, 67, 68, 70, 65, 66, 68, 75, 66, 67, 73, + 73, 4, 88, 71, 11, 71, 0, 69, 68, 65, 2, 64, + 67, 65, 74, 74, 79, 51, 48, 50, 44, 38, 42, + 41, 38, 37, 34, 36, 35, 24, 18, 4, 27, 25, 20, + 9, 16, 13, 6, 11, 4, 1, 68, 72, 76, 79, 25, + 22, 25, 14, 66, 5, 2, 73, 1, 70, 74, 90, 82, + 87, 93, 5, 9, 78, 4, 7, 66, 75, 74, 75, 84, + 74, 81, 82, 99, 84, 89, 98, 64, 78, 86, 73, 1, + 5, 6, 15, 10, 17, 1, 14, 12, 20, 22, 25, 25, + 12, 52, 28, 21, 15, 7, 5, 78, 84, 94, 6, 37, + 31, 31, 22, 22, 12, 10, 4, 64, 73, 1, 5, 6, + 15, 10, 17, 1, 14, 12, 20, 22, 25, 25, 12, 52, + 28, 21, 15, 7, 5, 78, 84, 94 }, + + { + + 47, + 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 2, 24, + 42, 28, 6, 7, 7, 78, 64, 64, 66, 17, 78, 71, + 22, 18, 84, 99, 115, 77, 82, 70, 78, 64, 64, + 83, 66, 29, 2, 71, 79, 83, 86, 89, 90, 105, + 64, 77, 85, 70, 84, 85, 99, 4, 72, 71, 78, 24, + 2, 22, 0, 0, 0, 68, 92, 97, 2, 2, 66, 19, 73, + 95, 70, 64, 73, 19, 17, 70, 64, 78, 9, 74, 69, + 69, 97, 83, 87, 85, 18, 67, 2, 69, 71, 86, 73, + 80, 65, 75, 72, 85, 17, 72, 5, 77, 79, 69, 74, + 67, 3, 4, 64, 9, 6, 73, 0, 64, 67, 2, 72, 26, + 67, 1, 23, 23, 31, 27, 20, 88, 0, 65, 66, 67, + 82, 68, 15, 67, 67, 13, 32, 53, 39, 15, 89, + 89, 2, 36, 40, 111, 69, 5, 89, 13, 66, 0, 14, + 33, 55, 45, 22, 91, 88, 0, 13, 19, 92, 18, 21, + 19, 17, 20, 17, 11, 19, 18, 0, 7, 10, 4, 2, + 69, 7, 2, 0, 5, 1, 5, 6, 0, 87, 0, 0, 69, 64, + 75, 27, 37, 23, 16, 21, 24, 26, 27, 17, 73, + 85, 70, 68, 66, 107, 65, 3, 86, 18, 4, 4, 3, + 3, 66, 3, 5, 79, 93, 77, 80, 78, 89, 77, 16, + 16, 10, 4, 0, 68, 73, 74, 81, 67, 28, 15, 10, + 2, 11, 0, 68, 74, 69, 66, 28, 15, 10, 4, 10, + 0, 68, 73, 79, 72, 29, 13, 9, 4, 6, 68, 74, + 78, 3, 35, 22, 15, 8, 15, 3, 65, 68, 71, 62, + 92, 87, 80, 84, 84, 81, 78, 76, 75, 74, 71, + 66, 78, 78, 83, 85, 15, 84, 83, 78, 73, 72, + 73, 71, 71, 70, 70, 71, 80, 68, 68, 12, 69, + 77, 67, 68, 70, 65, 66, 68, 75, 67, 67, 73, + 72, 6, 88, 71, 12, 72, 0, 69, 68, 64, 2, 64, + 66, 64, 73, 73, 81, 50, 47, 49, 42, 36, 39, + 39, 35, 35, 32, 33, 33, 21, 15, 2, 23, 22, 17, + 4, 13, 11, 5, 9, 2, 0, 69, 73, 77, 79, 23, 20, + 23, 12, 68, 3, 1, 75, 64, 72, 76, 92, 84, 89, + 94, 4, 8, 80, 3, 5, 67, 77, 75, 76, 85, 75, + 81, 82, 98, 85, 90, 100, 65, 79, 87, 73, 2, 6, + 7, 17, 11, 18, 1, 15, 13, 21, 23, 26, 26, 13, + 51, 27, 19, 13, 5, 3, 80, 86, 95, 7, 37, 32, + 32, 23, 23, 13, 11, 5, 0, 73, 2, 6, 7, 17, 11, + 18, 1, 15, 13, 21, 23, 26, 26, 13, 51, 27, 19, + 13, 5, 3, 80, 86, 95 }, + + { + + 46, + 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 0, 23, + 41, 29, 6, 8, 5, 78, 0, 65, 66, 18, 79, 72, + 21, 16, 87, 102, 116, 75, 81, 70, 78, 0, 65, + 83, 65, 29, 2, 71, 78, 81, 87, 90, 90, 105, + 64, 76, 84, 71, 84, 85, 99, 4, 72, 71, 77, 25, + 2, 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 18, 73, + 94, 68, 0, 72, 20, 18, 69, 0, 76, 10, 73, 68, + 66, 97, 84, 87, 86, 18, 67, 3, 66, 70, 86, 73, + 78, 65, 75, 72, 85, 17, 72, 5, 76, 79, 68, 73, + 67, 3, 4, 0, 9, 6, 74, 0, 64, 67, 2, 72, 26, + 67, 1, 24, 23, 31, 27, 20, 89, 0, 65, 66, 67, + 81, 68, 16, 66, 67, 15, 34, 54, 40, 17, 89, + 90, 2, 37, 40, 112, 69, 6, 90, 14, 66, 0, 15, + 33, 55, 45, 24, 92, 86, 64, 10, 16, 91, 18, + 21, 18, 17, 19, 17, 10, 19, 17, 64, 6, 10, 4, + 2, 69, 6, 2, 64, 4, 1, 5, 5, 0, 88, 64, 64, + 69, 65, 76, 25, 35, 21, 14, 20, 22, 23, 24, + 16, 75, 87, 72, 70, 68, 108, 66, 2, 87, 17, 3, + 3, 1, 2, 68, 1, 4, 81, 93, 78, 81, 80, 88, 76, + 17, 16, 10, 4, 1, 67, 72, 74, 79, 65, 29, 16, + 10, 3, 13, 1, 66, 73, 66, 65, 28, 15, 10, 5, + 11, 1, 68, 72, 78, 72, 30, 14, 9, 4, 7, 68, + 74, 77, 4, 35, 23, 15, 8, 16, 4, 64, 68, 70, + 62, 91, 86, 79, 83, 83, 79, 77, 74, 74, 72, + 69, 0, 77, 77, 82, 84, 18, 83, 84, 77, 72, 71, + 73, 71, 71, 70, 69, 72, 81, 68, 68, 13, 69, + 77, 67, 68, 69, 66, 67, 68, 76, 68, 68, 73, + 72, 7, 89, 72, 13, 72, 64, 69, 68, 64, 1, 65, + 66, 64, 73, 73, 82, 49, 46, 48, 41, 33, 37, + 36, 32, 32, 29, 30, 30, 18, 13, 0, 19, 18, 13, + 64, 10, 9, 3, 7, 64, 65, 70, 74, 78, 79, 21, + 17, 20, 10, 70, 1, 64, 77, 66, 74, 78, 94, 86, + 90, 96, 3, 7, 82, 1, 4, 69, 79, 76, 77, 86, + 76, 82, 82, 97, 87, 91, 101, 67, 80, 88, 73, + 2, 6, 8, 18, 12, 18, 2, 16, 14, 22, 23, 27, + 26, 13, 51, 25, 17, 11, 3, 1, 83, 88, 96, 7, + 38, 32, 32, 24, 24, 13, 11, 5, 1, 73, 2, 6, 8, + 18, 12, 18, 2, 16, 14, 22, 23, 27, 26, 13, 51, + 25, 17, 11, 3, 1, 83, 88, 96 }, + + { + + 45, + 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 64, 21, + 40, 29, 7, 10, 4, 78, 2, 65, 67, 19, 80, 73, + 20, 15, 91, 104, 117, 73, 79, 70, 78, 2, 65, + 82, 64, 30, 2, 70, 77, 80, 89, 91, 90, 106, + 64, 76, 84, 71, 85, 84, 99, 3, 72, 71, 76, 25, + 2, 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 18, 72, + 93, 66, 1, 71, 22, 20, 68, 1, 74, 11, 72, 68, + 64, 98, 84, 87, 86, 19, 67, 4, 64, 70, 85, 72, + 76, 65, 75, 72, 85, 18, 73, 6, 76, 79, 67, 73, + 66, 3, 5, 1, 10, 6, 74, 0, 64, 67, 2, 72, 26, + 67, 1, 24, 23, 32, 28, 21, 89, 1, 64, 67, 67, + 81, 68, 17, 66, 66, 16, 35, 54, 42, 18, 90, + 91, 3, 37, 40, 112, 70, 6, 90, 14, 67, 1, 16, + 33, 55, 46, 25, 93, 85, 65, 7, 13, 89, 18, 21, + 18, 16, 19, 16, 10, 18, 17, 64, 6, 10, 3, 2, + 70, 6, 1, 65, 4, 1, 5, 5, 64, 90, 64, 65, 69, + 66, 76, 22, 33, 19, 13, 18, 20, 20, 22, 14, + 77, 89, 73, 72, 70, 110, 67, 0, 89, 15, 2, 2, + 0, 0, 70, 64, 2, 82, 93, 79, 82, 81, 86, 74, + 19, 17, 10, 4, 2, 67, 72, 73, 78, 64, 30, 17, + 11, 3, 14, 2, 65, 72, 64, 65, 29, 16, 11, 5, + 12, 1, 67, 71, 77, 72, 32, 15, 9, 4, 7, 67, + 74, 77, 4, 36, 23, 16, 8, 17, 4, 64, 67, 70, + 62, 89, 84, 77, 81, 81, 78, 75, 73, 72, 70, + 67, 2, 77, 76, 82, 84, 21, 83, 85, 77, 72, 70, + 73, 71, 71, 70, 69, 72, 82, 68, 68, 13, 69, + 77, 67, 68, 69, 66, 67, 68, 77, 69, 68, 73, + 72, 8, 90, 72, 14, 73, 64, 69, 68, 0, 1, 65, + 65, 0, 73, 73, 84, 48, 45, 47, 39, 31, 34, 34, + 29, 30, 26, 27, 27, 15, 10, 65, 16, 15, 9, 69, + 8, 6, 1, 5, 66, 67, 71, 75, 79, 79, 19, 15, + 18, 8, 72, 0, 65, 79, 68, 77, 80, 96, 88, 92, + 97, 2, 5, 84, 0, 2, 70, 81, 78, 79, 87, 77, + 83, 83, 96, 88, 93, 103, 68, 82, 89, 72, 3, 7, + 8, 19, 13, 19, 2, 17, 15, 23, 24, 28, 27, 14, + 50, 23, 15, 9, 1, 64, 85, 90, 97, 8, 38, 33, + 33, 24, 25, 14, 12, 6, 1, 72, 3, 7, 8, 19, 13, + 19, 2, 17, 15, 23, 24, 28, 27, 14, 50, 23, 15, + 9, 1, 64, 85, 90, 97 }, + + { + + 43, + 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 66, 20, + 39, 30, 7, 12, 2, 78, 3, 65, 67, 20, 81, 75, + 18, 13, 94, 106, 118, 71, 78, 70, 78, 3, 65, + 82, 0, 30, 1, 69, 76, 79, 90, 93, 91, 106, 64, + 76, 83, 71, 85, 84, 99, 3, 72, 71, 76, 26, 2, + 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 17, 72, 92, + 64, 2, 70, 23, 21, 68, 2, 72, 12, 71, 67, 1, + 99, 84, 87, 86, 19, 68, 5, 1, 70, 84, 71, 74, + 65, 75, 72, 85, 18, 73, 6, 75, 79, 67, 73, 66, + 3, 5, 2, 10, 6, 74, 64, 64, 67, 2, 72, 26, 67, + 1, 25, 23, 32, 28, 21, 90, 1, 0, 67, 67, 81, + 68, 18, 66, 66, 17, 36, 55, 43, 20, 90, 92, 3, + 37, 40, 113, 70, 7, 91, 15, 67, 1, 17, 33, 55, + 46, 26, 94, 83, 66, 4, 10, 88, 17, 21, 17, 15, + 18, 16, 9, 18, 16, 65, 5, 9, 3, 2, 70, 5, 0, + 66, 3, 0, 4, 4, 64, 91, 65, 66, 69, 68, 77, + 20, 31, 17, 11, 16, 18, 16, 19, 13, 79, 92, + 75, 74, 72, 111, 69, 64, 91, 14, 1, 1, 64, 64, + 72, 66, 0, 84, 93, 80, 83, 83, 85, 73, 20, 17, + 10, 4, 3, 66, 71, 72, 76, 0, 31, 17, 12, 4, + 15, 3, 0, 71, 1, 64, 29, 16, 11, 6, 13, 2, 67, + 71, 76, 72, 33, 16, 9, 4, 8, 67, 74, 76, 5, + 36, 24, 16, 8, 18, 5, 0, 67, 69, 62, 88, 83, + 76, 79, 80, 76, 74, 71, 71, 69, 65, 4, 76, 75, + 81, 83, 24, 83, 86, 77, 71, 70, 73, 71, 71, + 71, 68, 72, 83, 68, 68, 14, 69, 77, 67, 68, + 69, 67, 67, 68, 78, 70, 68, 73, 72, 9, 91, 72, + 14, 74, 64, 69, 68, 0, 1, 66, 65, 1, 73, 73, + 85, 47, 44, 46, 37, 29, 32, 31, 26, 27, 23, + 23, 24, 11, 7, 67, 12, 11, 5, 74, 5, 4, 64, 3, + 69, 69, 73, 76, 80, 79, 16, 13, 16, 6, 74, 65, + 67, 81, 70, 79, 82, 98, 91, 94, 98, 1, 4, 87, + 65, 0, 72, 83, 79, 80, 88, 78, 84, 83, 95, 89, + 94, 104, 69, 83, 90, 72, 3, 7, 9, 20, 13, 20, + 2, 18, 16, 24, 24, 29, 27, 15, 50, 21, 13, 7, + 64, 66, 87, 92, 99, 8, 39, 33, 34, 25, 25, 14, + 12, 6, 2, 72, 3, 7, 9, 20, 13, 20, 2, 18, 16, + 24, 24, 29, 27, 15, 50, 21, 13, 7, 64, 66, 87, + 92, 99 }, + + { + + 42, + 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 68, 18, + 38, 31, 7, 13, 0, 77, 5, 66, 67, 21, 82, 76, + 17, 11, 97, 109, 118, 69, 77, 70, 77, 5, 66, + 82, 1, 30, 1, 69, 75, 77, 91, 94, 91, 106, 64, + 75, 82, 72, 85, 84, 99, 3, 71, 71, 75, 26, 2, + 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 17, 71, + 90, 2, 3, 69, 25, 23, 67, 3, 70, 13, 70, 66, + 4, 99, 85, 87, 87, 19, 68, 6, 4, 69, 84, 71, + 72, 65, 75, 72, 84, 18, 73, 7, 74, 78, 66, 72, + 66, 4, 6, 3, 11, 6, 75, 64, 0, 67, 2, 72, 27, + 67, 1, 25, 24, 32, 28, 21, 90, 2, 0, 68, 67, + 80, 68, 19, 65, 65, 19, 38, 56, 45, 22, 91, + 93, 4, 38, 40, 114, 70, 7, 91, 16, 67, 1, 19, + 33, 55, 46, 28, 95, 82, 67, 2, 7, 87, 17, 21, + 17, 15, 18, 16, 9, 18, 16, 66, 4, 9, 3, 2, 70, + 5, 0, 67, 3, 0, 4, 3, 65, 92, 66, 66, 69, 69, + 77, 18, 29, 16, 10, 15, 16, 13, 17, 12, 81, + 94, 76, 76, 74, 112, 70, 65, 92, 13, 0, 0, 66, + 66, 74, 68, 64, 85, 93, 81, 84, 85, 83, 71, + 21, 18, 10, 4, 4, 65, 70, 72, 74, 2, 32, 18, + 12, 5, 17, 4, 1, 70, 4, 0, 30, 17, 12, 6, 14, + 3, 66, 70, 75, 71, 34, 17, 9, 4, 9, 66, 73, + 75, 6, 36, 25, 16, 8, 19, 6, 1, 66, 68, 62, + 87, 81, 74, 78, 79, 75, 72, 69, 69, 67, 0, 7, + 75, 74, 80, 82, 27, 82, 87, 76, 70, 69, 73, + 71, 71, 71, 68, 73, 84, 68, 68, 15, 69, 77, + 67, 68, 68, 67, 68, 68, 79, 71, 69, 73, 72, + 10, 91, 73, 15, 74, 65, 69, 68, 0, 0, 66, 65, + 1, 73, 73, 87, 46, 43, 45, 36, 26, 29, 28, 23, + 25, 20, 20, 21, 8, 5, 69, 8, 8, 1, 79, 2, 2, + 65, 1, 71, 71, 74, 77, 81, 79, 14, 10, 13, 4, + 76, 67, 68, 83, 72, 81, 84, 100, 93, 95, 100, + 0, 3, 89, 66, 64, 73, 85, 80, 81, 89, 79, 85, + 83, 94, 91, 95, 106, 71, 84, 91, 72, 4, 8, 10, + 21, 14, 20, 3, 19, 17, 25, 25, 30, 28, 15, 49, + 19, 11, 5, 66, 68, 90, 94, 100, 9, 39, 34, 34, + 26, 26, 15, 13, 6, 3, 72, 4, 8, 10, 21, 14, + 20, 3, 19, 17, 25, 25, 30, 28, 15, 49, 19, 11, + 5, 66, 68, 90, 94, 100 }, + + { + + 41, + 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 70, 17, + 37, 31, 7, 15, 64, 77, 6, 66, 68, 22, 83, 77, + 16, 9, 101, 111, 119, 67, 75, 70, 77, 6, 66, + 81, 2, 31, 1, 68, 74, 76, 92, 95, 91, 107, 64, + 75, 81, 72, 86, 84, 99, 3, 71, 71, 74, 27, 2, + 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 16, 71, + 89, 4, 4, 68, 26, 24, 66, 4, 68, 14, 69, 65, + 6, 100, 85, 87, 87, 20, 68, 7, 6, 69, 83, 70, + 70, 65, 75, 72, 84, 19, 73, 7, 73, 78, 65, 72, + 66, 4, 6, 4, 11, 6, 75, 64, 0, 67, 2, 72, 27, + 67, 1, 26, 24, 33, 28, 22, 91, 2, 1, 68, 67, + 80, 68, 20, 65, 65, 20, 39, 57, 46, 24, 91, + 94, 4, 38, 40, 115, 70, 8, 92, 16, 67, 1, 20, + 33, 55, 46, 29, 96, 80, 68, 64, 4, 85, 17, 21, + 16, 14, 17, 15, 8, 18, 15, 67, 3, 9, 3, 2, 71, + 4, 64, 68, 2, 0, 4, 2, 65, 93, 66, 67, 69, 70, + 78, 16, 27, 14, 8, 13, 14, 10, 14, 11, 83, 96, + 78, 78, 76, 114, 71, 66, 94, 12, 64, 64, 67, + 67, 76, 70, 66, 87, 93, 82, 85, 86, 82, 70, + 23, 18, 10, 4, 5, 64, 69, 71, 72, 3, 33, 19, + 13, 5, 18, 5, 3, 69, 6, 0, 30, 17, 12, 7, 15, + 3, 66, 69, 74, 71, 36, 18, 9, 4, 10, 66, 73, + 74, 7, 37, 26, 17, 8, 20, 6, 2, 66, 68, 62, + 85, 80, 73, 76, 78, 73, 71, 68, 68, 65, 2, 9, + 75, 73, 80, 81, 30, 82, 88, 76, 69, 68, 73, + 71, 71, 71, 67, 73, 85, 68, 68, 15, 69, 77, + 67, 68, 68, 68, 68, 68, 80, 72, 69, 73, 72, + 11, 92, 73, 16, 75, 65, 69, 68, 1, 0, 67, 64, + 2, 73, 73, 88, 45, 42, 44, 34, 24, 27, 26, 20, + 22, 17, 17, 18, 5, 2, 71, 4, 4, 66, 84, 64, 0, + 67, 64, 74, 73, 75, 78, 82, 79, 12, 8, 11, 2, + 78, 69, 70, 85, 74, 83, 86, 102, 95, 97, 101, + 64, 2, 91, 68, 66, 75, 87, 82, 83, 90, 80, 86, + 83, 93, 92, 97, 107, 72, 85, 92, 72, 4, 8, 10, + 22, 15, 21, 3, 20, 18, 26, 25, 31, 28, 16, 49, + 17, 9, 3, 68, 70, 92, 96, 101, 9, 40, 34, 35, + 26, 27, 15, 13, 7, 3, 72, 4, 8, 10, 22, 15, + 21, 3, 20, 18, 26, 25, 31, 28, 16, 49, 17, 9, + 3, 68, 70, 92, 96, 101 }, + + { + + 40, + 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 72, 15, + 36, 32, 7, 17, 66, 77, 8, 66, 68, 23, 84, 78, + 15, 7, 104, 113, 120, 65, 74, 70, 77, 8, 66, + 81, 3, 31, 1, 67, 73, 75, 93, 96, 91, 107, 64, + 75, 80, 72, 86, 84, 99, 3, 71, 71, 73, 27, 2, + 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 16, 70, + 88, 6, 5, 67, 28, 26, 65, 5, 66, 15, 68, 64, + 8, 101, 85, 87, 87, 20, 68, 8, 8, 69, 82, 69, + 68, 65, 75, 72, 84, 19, 73, 8, 72, 78, 64, 72, + 66, 4, 7, 5, 12, 6, 75, 64, 0, 67, 2, 72, 27, + 67, 1, 26, 24, 33, 28, 22, 91, 3, 2, 69, 67, + 80, 68, 21, 65, 64, 21, 40, 58, 48, 26, 92, + 95, 5, 38, 40, 116, 70, 8, 92, 17, 67, 1, 21, + 33, 55, 46, 30, 97, 79, 69, 67, 1, 84, 17, 21, + 16, 13, 17, 15, 8, 18, 15, 68, 2, 9, 3, 2, 71, + 4, 65, 69, 2, 0, 4, 1, 66, 94, 67, 68, 69, 71, + 78, 14, 25, 12, 7, 11, 12, 7, 12, 10, 85, 98, + 79, 80, 78, 115, 72, 67, 96, 11, 65, 65, 68, + 69, 78, 72, 68, 88, 93, 83, 86, 88, 80, 68, + 24, 19, 10, 4, 6, 0, 68, 70, 70, 4, 34, 20, + 14, 6, 19, 6, 4, 68, 8, 1, 31, 18, 13, 7, 16, + 4, 65, 68, 73, 71, 37, 19, 9, 4, 11, 65, 73, + 73, 8, 37, 27, 17, 8, 21, 7, 3, 65, 67, 62, + 84, 78, 71, 74, 77, 72, 69, 66, 66, 0, 4, 11, + 74, 72, 79, 80, 33, 82, 89, 76, 68, 67, 73, + 71, 71, 71, 67, 73, 86, 68, 68, 16, 69, 77, + 67, 68, 68, 68, 68, 68, 81, 73, 69, 73, 72, + 12, 93, 73, 17, 76, 65, 69, 68, 1, 0, 67, 64, + 3, 73, 73, 90, 44, 41, 43, 32, 22, 24, 23, 17, + 20, 14, 14, 15, 2, 64, 73, 0, 1, 70, 89, 67, + 65, 69, 66, 76, 75, 76, 79, 83, 79, 10, 6, 9, + 0, 80, 71, 71, 87, 76, 85, 88, 104, 97, 99, + 102, 65, 1, 93, 69, 68, 76, 89, 83, 84, 91, + 81, 87, 83, 92, 93, 98, 109, 73, 86, 93, 72, + 5, 9, 11, 23, 16, 22, 3, 21, 19, 27, 26, 32, + 29, 17, 48, 15, 7, 1, 70, 72, 94, 98, 102, 10, + 40, 35, 36, 27, 28, 16, 14, 7, 4, 72, 5, 9, + 11, 23, 16, 22, 3, 21, 19, 27, 26, 32, 29, 17, + 48, 15, 7, 1, 70, 72, 94, 98, 102 }, + + { + + 38, + 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 74, 13, + 35, 32, 7, 18, 68, 77, 9, 67, 69, 24, 85, 80, + 13, 5, 108, 116, 121, 0, 73, 70, 77, 9, 67, + 81, 3, 31, 0, 67, 73, 74, 95, 98, 92, 108, 65, + 75, 80, 73, 87, 84, 99, 2, 71, 71, 73, 27, 1, + 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 15, 70, + 87, 8, 6, 67, 29, 27, 65, 6, 65, 15, 67, 64, + 10, 102, 86, 88, 88, 20, 69, 8, 10, 69, 82, + 69, 67, 65, 75, 72, 84, 19, 74, 8, 72, 78, 64, + 72, 66, 4, 7, 6, 12, 6, 76, 65, 0, 67, 1, 72, + 27, 67, 1, 26, 24, 33, 28, 22, 92, 3, 2, 70, + 67, 80, 69, 21, 65, 64, 22, 41, 58, 49, 27, + 93, 97, 5, 38, 40, 117, 71, 8, 93, 17, 68, 1, + 22, 33, 54, 46, 31, 98, 78, 71, 70, 66, 83, + 16, 21, 15, 12, 16, 14, 7, 17, 14, 69, 1, 8, + 2, 1, 72, 3, 66, 70, 1, 64, 3, 0, 67, 96, 68, + 69, 69, 73, 79, 11, 22, 10, 5, 9, 9, 3, 9, 8, + 87, 101, 81, 83, 80, 117, 74, 69, 98, 9, 66, + 66, 70, 71, 80, 74, 70, 90, 93, 84, 87, 90, + 79, 67, 25, 19, 10, 4, 6, 0, 68, 70, 69, 5, + 34, 20, 14, 6, 20, 7, 5, 68, 10, 1, 31, 18, + 13, 7, 16, 4, 65, 68, 72, 71, 38, 20, 9, 3, + 11, 65, 73, 73, 8, 37, 27, 17, 8, 22, 7, 3, + 65, 67, 62, 83, 77, 70, 73, 76, 71, 68, 65, + 65, 1, 5, 13, 74, 72, 79, 80, 36, 82, 91, 76, + 68, 67, 73, 71, 71, 72, 67, 74, 87, 69, 68, + 16, 70, 77, 68, 68, 68, 69, 69, 69, 82, 74, + 70, 74, 72, 13, 94, 74, 17, 77, 66, 69, 69, 1, + 64, 68, 64, 3, 73, 73, 92, 42, 40, 41, 30, 19, + 21, 20, 14, 17, 11, 10, 12, 65, 67, 75, 67, + 66, 74, 95, 70, 68, 71, 69, 79, 77, 78, 81, + 84, 79, 7, 3, 6, 65, 83, 73, 73, 90, 78, 88, + 90, 107, 100, 101, 104, 67, 64, 96, 71, 70, + 78, 91, 85, 86, 92, 82, 88, 84, 91, 95, 100, + 111, 75, 88, 95, 72, 5, 9, 11, 24, 16, 22, 3, + 22, 19, 28, 26, 32, 29, 17, 47, 13, 5, 65, 73, + 74, 97, 100, 104, 10, 40, 35, 36, 27, 28, 16, + 14, 7, 4, 72, 5, 9, 11, 24, 16, 22, 3, 22, 19, + 28, 26, 32, 29, 17, 47, 13, 5, 65, 73, 74, 97, + 100, 104 }, + + { + + 37, + 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 75, 12, + 35, 33, 8, 20, 69, 76, 11, 67, 69, 26, 85, 81, + 12, 4, 111, 118, 121, 2, 71, 69, 76, 11, 67, + 80, 4, 32, 0, 66, 72, 72, 96, 99, 92, 108, 65, + 74, 79, 73, 87, 83, 98, 2, 70, 70, 72, 28, 1, + 22, 0, 0, 0, 64, 94, 97, 6, 67, 68, 15, 69, + 85, 11, 8, 66, 31, 29, 64, 8, 0, 16, 65, 0, + 13, 102, 86, 88, 88, 21, 69, 9, 13, 68, 81, + 68, 65, 65, 74, 72, 83, 20, 74, 9, 71, 77, 0, + 71, 65, 5, 8, 7, 13, 7, 76, 65, 1, 66, 1, 71, + 28, 66, 1, 27, 25, 34, 29, 23, 92, 4, 3, 70, + 67, 79, 69, 22, 64, 0, 24, 43, 59, 51, 29, 93, + 98, 6, 39, 41, 117, 71, 9, 93, 18, 68, 2, 24, + 33, 54, 47, 33, 99, 76, 72, 72, 69, 81, 16, + 21, 15, 12, 16, 14, 7, 17, 14, 69, 1, 8, 2, 1, + 72, 3, 66, 70, 1, 64, 3, 0, 67, 97, 68, 69, + 69, 74, 79, 9, 20, 9, 4, 8, 7, 0, 7, 7, 88, + 103, 82, 85, 81, 118, 75, 70, 99, 8, 66, 66, + 71, 72, 81, 75, 71, 91, 93, 84, 87, 91, 77, + 65, 27, 20, 10, 4, 7, 1, 67, 69, 67, 7, 35, + 21, 15, 7, 22, 8, 7, 67, 13, 2, 32, 19, 14, 8, + 17, 5, 64, 67, 70, 70, 40, 21, 10, 3, 12, 64, + 72, 72, 9, 38, 28, 18, 9, 23, 8, 4, 64, 66, + 62, 81, 75, 68, 71, 74, 69, 66, 0, 0, 3, 7, + 16, 73, 71, 78, 79, 40, 81, 92, 75, 67, 66, + 72, 71, 70, 72, 66, 74, 87, 69, 68, 17, 70, + 77, 68, 68, 67, 69, 69, 69, 82, 74, 70, 74, + 71, 15, 94, 74, 18, 77, 66, 69, 69, 2, 64, 68, + 0, 4, 72, 72, 93, 41, 39, 40, 29, 17, 19, 18, + 11, 15, 9, 7, 10, 68, 69, 77, 70, 69, 77, 100, + 72, 70, 72, 71, 81, 78, 79, 82, 84, 79, 5, 1, + 4, 67, 85, 74, 74, 92, 79, 90, 91, 109, 102, + 102, 105, 68, 65, 98, 72, 71, 79, 92, 86, 87, + 93, 82, 88, 84, 90, 96, 101, 112, 76, 89, 96, + 71, 6, 10, 12, 26, 17, 23, 4, 24, 20, 29, 27, + 33, 30, 18, 47, 12, 4, 67, 75, 75, 99, 101, + 105, 11, 41, 36, 37, 28, 29, 17, 15, 8, 5, 71, + 6, 10, 12, 26, 17, 23, 4, 24, 20, 29, 27, 33, + 30, 18, 47, 12, 4, 67, 75, 75, 99, 101, 105 }, + + { + + 36, + 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 77, 10, + 34, 34, 8, 22, 71, 76, 12, 67, 69, 27, 86, 82, + 11, 2, 114, 120, 122, 4, 70, 69, 76, 12, 67, + 80, 5, 32, 0, 65, 71, 71, 97, 100, 92, 108, + 65, 74, 78, 73, 87, 83, 98, 2, 70, 70, 71, 28, + 1, 22, 0, 0, 0, 0, 94, 97, 6, 68, 68, 15, 68, + 84, 13, 9, 65, 33, 31, 0, 9, 2, 17, 64, 1, 15, + 103, 86, 88, 88, 21, 69, 10, 15, 68, 80, 67, + 0, 65, 74, 72, 83, 20, 74, 9, 70, 77, 1, 71, + 65, 5, 8, 8, 14, 7, 76, 65, 1, 66, 1, 71, 28, + 66, 1, 27, 25, 34, 29, 23, 93, 5, 4, 71, 67, + 79, 69, 23, 64, 0, 25, 44, 60, 53, 31, 94, 99, + 6, 39, 41, 118, 71, 9, 94, 19, 68, 2, 25, 33, + 54, 47, 34, 100, 75, 73, 75, 72, 80, 16, 21, + 15, 11, 15, 14, 7, 17, 13, 70, 0, 8, 2, 1, 72, + 2, 67, 71, 1, 64, 3, 64, 68, 98, 69, 70, 69, + 75, 80, 7, 18, 7, 2, 6, 5, 66, 5, 6, 90, 105, + 84, 87, 83, 119, 76, 71, 101, 7, 67, 67, 72, + 74, 83, 77, 73, 93, 93, 85, 88, 93, 76, 64, + 28, 21, 10, 4, 8, 2, 66, 68, 65, 8, 36, 22, + 16, 8, 23, 9, 8, 66, 15, 3, 32, 19, 14, 8, 18, + 6, 0, 66, 69, 70, 41, 22, 10, 3, 13, 0, 72, + 71, 10, 38, 29, 18, 9, 24, 9, 5, 0, 65, 62, + 80, 73, 66, 69, 73, 68, 64, 2, 1, 5, 9, 18, + 72, 70, 77, 78, 43, 81, 93, 75, 66, 65, 72, + 71, 70, 72, 66, 74, 88, 69, 68, 18, 70, 77, + 68, 68, 67, 69, 69, 69, 83, 75, 70, 74, 71, + 16, 95, 74, 19, 78, 66, 69, 69, 2, 64, 68, 0, + 5, 72, 72, 95, 40, 38, 39, 27, 15, 16, 15, 8, + 13, 6, 4, 7, 71, 72, 79, 74, 73, 81, 105, 75, + 72, 74, 73, 83, 80, 80, 83, 85, 79, 3, 64, 2, + 69, 87, 76, 76, 94, 81, 92, 93, 111, 104, 104, + 106, 69, 66, 100, 74, 73, 81, 94, 87, 88, 94, + 83, 89, 84, 89, 97, 102, 114, 77, 90, 97, 71, + 6, 11, 13, 27, 18, 24, 4, 25, 21, 30, 27, 34, + 31, 19, 46, 10, 2, 69, 77, 77, 101, 103, 106, + 12, 41, 36, 38, 29, 30, 17, 16, 8, 6, 71, 6, + 11, 13, 27, 18, 24, 4, 25, 21, 30, 27, 34, 31, + 19, 46, 10, 2, 69, 77, 77, 101, 103, 106 }, + + { + + 35, + 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 79, 9, + 33, 34, 8, 24, 72, 76, 14, 67, 70, 28, 87, 83, + 10, 0, 118, 122, 123, 6, 68, 69, 76, 14, 67, + 79, 6, 33, 0, 64, 70, 70, 98, 101, 92, 109, + 65, 74, 77, 73, 88, 83, 98, 2, 70, 70, 70, 29, + 1, 22, 0, 0, 0, 0, 94, 97, 7, 69, 68, 14, 68, + 83, 15, 10, 64, 34, 32, 1, 10, 4, 18, 0, 2, + 17, 104, 86, 88, 88, 22, 69, 11, 17, 68, 79, + 66, 2, 65, 74, 72, 83, 21, 74, 10, 69, 77, 2, + 71, 65, 5, 9, 9, 14, 7, 76, 65, 1, 66, 1, 71, + 28, 66, 1, 28, 25, 35, 29, 24, 93, 5, 5, 71, + 67, 79, 69, 24, 64, 1, 26, 45, 61, 54, 33, 94, + 100, 7, 39, 41, 119, 71, 10, 94, 19, 68, 2, + 26, 33, 54, 47, 35, 101, 73, 74, 78, 75, 78, + 16, 21, 14, 10, 15, 13, 6, 17, 13, 71, 64, 8, + 2, 1, 73, 2, 68, 72, 0, 64, 3, 65, 68, 99, 69, + 71, 69, 76, 80, 5, 16, 5, 1, 4, 3, 69, 2, 5, + 92, 107, 85, 89, 85, 121, 77, 72, 103, 6, 68, + 68, 73, 75, 85, 79, 75, 94, 93, 86, 89, 94, + 74, 1, 30, 21, 10, 4, 9, 3, 65, 67, 0, 9, 37, + 23, 17, 8, 24, 10, 10, 65, 17, 3, 33, 20, 15, + 9, 19, 6, 0, 65, 68, 70, 43, 23, 10, 3, 14, 0, + 72, 70, 11, 39, 30, 19, 9, 25, 9, 6, 0, 65, + 62, 78, 72, 65, 67, 72, 66, 0, 3, 3, 7, 11, + 20, 72, 69, 77, 77, 46, 81, 94, 75, 65, 64, + 72, 71, 70, 72, 65, 74, 89, 69, 68, 18, 70, + 77, 68, 68, 67, 70, 69, 69, 84, 76, 70, 74, + 71, 17, 96, 74, 20, 79, 66, 69, 69, 3, 64, 69, + 1, 6, 72, 72, 96, 39, 37, 38, 25, 13, 14, 13, + 5, 10, 3, 1, 4, 74, 75, 81, 78, 76, 85, 110, + 78, 74, 76, 75, 86, 82, 81, 84, 86, 79, 1, 66, + 0, 71, 89, 78, 77, 96, 83, 94, 95, 113, 106, + 106, 107, 70, 67, 102, 75, 75, 82, 96, 89, 90, + 95, 84, 90, 84, 88, 98, 104, 115, 78, 91, 98, + 71, 7, 11, 13, 28, 19, 25, 4, 26, 22, 31, 28, + 35, 31, 20, 46, 8, 0, 71, 79, 79, 103, 105, + 107, 12, 42, 37, 39, 29, 31, 18, 16, 9, 6, 71, + 7, 11, 13, 28, 19, 25, 4, 26, 22, 31, 28, 35, + 31, 20, 46, 8, 0, 71, 79, 79, 103, 105, 107 }, + + { + + 33, + 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 81, 7, + 32, 35, 8, 25, 74, 76, 15, 68, 70, 29, 88, 85, + 8, 65, 121, 125, 124, 8, 67, 69, 76, 15, 68, + 79, 7, 33, 64, 64, 69, 68, 99, 103, 93, 109, + 65, 73, 76, 74, 88, 83, 98, 2, 70, 70, 70, 29, + 1, 22, 0, 0, 0, 1, 95, 97, 7, 70, 68, 14, 67, + 82, 17, 11, 0, 36, 34, 1, 11, 6, 19, 1, 3, 20, + 104, 87, 88, 89, 22, 70, 12, 20, 67, 79, 66, + 4, 65, 74, 72, 83, 21, 74, 10, 68, 77, 2, 70, + 65, 5, 9, 10, 15, 7, 77, 66, 1, 66, 1, 71, 28, + 66, 1, 28, 25, 35, 29, 24, 94, 6, 5, 72, 67, + 78, 69, 25, 0, 1, 28, 47, 62, 56, 35, 95, 101, + 7, 40, 41, 120, 71, 10, 95, 20, 68, 2, 27, 33, + 54, 47, 37, 102, 72, 75, 81, 78, 77, 15, 21, + 14, 10, 14, 13, 6, 17, 12, 72, 65, 7, 2, 1, + 73, 1, 68, 73, 0, 65, 2, 66, 69, 100, 70, 72, + 69, 78, 81, 3, 14, 3, 64, 3, 1, 73, 0, 4, 94, + 110, 87, 91, 87, 122, 79, 73, 104, 5, 69, 69, + 75, 77, 87, 81, 76, 96, 93, 87, 90, 96, 73, 2, + 31, 22, 10, 4, 10, 4, 64, 67, 2, 11, 38, 23, + 17, 9, 26, 11, 11, 64, 20, 4, 33, 20, 15, 9, + 20, 7, 1, 65, 67, 70, 44, 24, 10, 3, 15, 1, + 72, 69, 12, 39, 31, 19, 9, 26, 10, 7, 1, 64, + 62, 77, 70, 0, 66, 71, 65, 2, 5, 4, 8, 13, 23, + 71, 68, 76, 76, 49, 80, 95, 74, 64, 64, 72, + 71, 70, 73, 65, 75, 90, 69, 68, 19, 70, 77, + 68, 68, 66, 70, 70, 69, 85, 77, 71, 74, 71, + 18, 97, 75, 20, 79, 67, 69, 69, 3, 65, 69, 1, + 6, 72, 72, 98, 38, 36, 37, 24, 10, 11, 10, 2, + 8, 0, 66, 1, 78, 77, 83, 82, 80, 89, 115, 81, + 76, 78, 77, 88, 84, 83, 85, 87, 79, 65, 69, + 66, 73, 91, 80, 79, 98, 85, 96, 97, 115, 109, + 107, 109, 71, 68, 105, 77, 76, 84, 98, 90, 91, + 96, 85, 91, 84, 87, 100, 105, 117, 80, 92, 99, + 71, 7, 12, 14, 29, 19, 25, 5, 27, 23, 32, 28, + 36, 32, 20, 45, 6, 65, 73, 81, 81, 106, 107, + 109, 13, 42, 37, 39, 30, 31, 18, 17, 9, 7, 71, + 7, 12, 14, 29, 19, 25, 5, 27, 23, 32, 28, 36, + 32, 20, 45, 6, 65, 73, 81, 81, 106, 107, 109 }, + + { + + 32, + 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 83, 6, + 31, 36, 8, 27, 76, 75, 17, 68, 70, 30, 89, 86, + 7, 67, 124, 126, 124, 10, 66, 69, 75, 17, 68, + 79, 8, 33, 64, 0, 68, 67, 100, 104, 93, 109, + 65, 73, 75, 74, 88, 83, 98, 2, 69, 70, 69, 30, + 1, 22, 0, 0, 0, 1, 95, 97, 8, 71, 68, 13, 67, + 80, 20, 12, 1, 37, 35, 2, 12, 8, 20, 2, 4, 22, + 105, 87, 88, 89, 22, 70, 13, 22, 67, 78, 65, + 6, 65, 74, 72, 82, 21, 74, 11, 67, 76, 3, 70, + 65, 6, 10, 11, 15, 7, 77, 66, 2, 66, 1, 71, + 29, 66, 1, 29, 26, 35, 29, 24, 94, 6, 6, 72, + 67, 78, 69, 26, 0, 2, 29, 48, 62, 57, 37, 95, + 102, 8, 40, 41, 121, 71, 11, 95, 21, 68, 2, + 29, 33, 54, 47, 38, 103, 70, 76, 83, 81, 76, + 15, 21, 13, 9, 14, 13, 5, 17, 12, 73, 66, 7, + 2, 1, 73, 1, 69, 74, 64, 65, 2, 67, 69, 101, + 71, 72, 69, 79, 81, 1, 12, 2, 65, 1, 64, 76, + 66, 3, 96, 112, 88, 93, 89, 123, 80, 74, 106, + 4, 70, 70, 76, 78, 89, 83, 78, 97, 93, 88, 91, + 98, 71, 4, 32, 22, 10, 4, 11, 5, 0, 66, 4, 12, + 39, 24, 18, 10, 27, 12, 13, 0, 22, 5, 34, 21, + 16, 10, 21, 8, 1, 64, 66, 69, 45, 25, 10, 3, + 16, 1, 71, 68, 13, 39, 32, 19, 9, 27, 11, 8, + 1, 0, 62, 76, 69, 1, 64, 70, 0, 3, 7, 6, 10, + 15, 25, 70, 67, 75, 75, 52, 80, 96, 74, 0, 0, + 72, 71, 70, 73, 64, 75, 91, 69, 68, 20, 70, + 77, 68, 68, 66, 71, 70, 69, 86, 78, 71, 74, + 71, 19, 97, 75, 21, 80, 67, 69, 69, 3, 65, 70, + 1, 7, 72, 72, 99, 37, 35, 36, 22, 8, 9, 7, 64, + 5, 66, 69, 65, 81, 80, 85, 86, 83, 93, 120, + 84, 78, 79, 79, 91, 86, 84, 86, 88, 79, 67, + 71, 68, 75, 93, 82, 80, 100, 87, 98, 99, 117, + 111, 109, 110, 72, 69, 107, 78, 78, 85, 100, + 91, 92, 97, 86, 92, 84, 86, 101, 106, 118, 81, + 93, 100, 71, 8, 12, 15, 30, 20, 26, 5, 28, 24, + 33, 29, 37, 32, 21, 45, 4, 67, 75, 83, 83, + 108, 109, 110, 13, 43, 38, 40, 31, 32, 19, 17, + 9, 8, 71, 8, 12, 15, 30, 20, 26, 5, 28, 24, + 33, 29, 37, 32, 21, 45, 4, 67, 75, 83, 83, + 108, 109, 110 }, + + { + + 31, + 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 84, 4, + 30, 36, 9, 29, 77, 75, 18, 68, 71, 31, 90, 87, + 6, 68, 126, 126, 125, 12, 64, 69, 75, 18, 68, + 78, 9, 34, 64, 1, 67, 66, 102, 105, 93, 110, + 65, 73, 75, 74, 89, 82, 98, 1, 69, 70, 68, 30, + 1, 22, 0, 0, 0, 2, 95, 97, 8, 71, 69, 13, 66, + 79, 22, 13, 2, 39, 37, 3, 13, 10, 21, 3, 4, + 24, 106, 87, 88, 89, 23, 70, 14, 24, 67, 77, + 64, 8, 65, 74, 72, 82, 22, 75, 11, 67, 76, 4, + 70, 64, 6, 10, 12, 16, 7, 77, 66, 2, 66, 1, + 71, 29, 66, 1, 29, 26, 36, 30, 25, 95, 7, 7, + 73, 67, 78, 69, 27, 0, 2, 30, 49, 62, 59, 38, + 96, 103, 8, 40, 41, 121, 72, 11, 96, 21, 69, + 3, 30, 33, 54, 48, 39, 104, 69, 77, 86, 84, + 74, 15, 21, 13, 8, 13, 12, 5, 16, 11, 73, 66, + 7, 1, 1, 74, 0, 70, 75, 64, 65, 2, 67, 70, + 103, 71, 73, 69, 80, 82, 65, 10, 0, 67, 64, + 66, 79, 68, 1, 98, 114, 90, 95, 91, 125, 81, + 76, 108, 2, 71, 71, 77, 80, 91, 85, 80, 99, + 93, 89, 92, 99, 70, 5, 34, 23, 10, 4, 12, 5, + 0, 65, 5, 13, 40, 25, 19, 10, 28, 13, 14, 1, + 24, 5, 34, 21, 16, 10, 22, 8, 2, 0, 65, 69, + 47, 26, 10, 3, 16, 2, 71, 68, 13, 40, 32, 20, + 9, 28, 11, 8, 2, 0, 62, 74, 67, 3, 1, 68, 1, + 5, 8, 7, 12, 17, 27, 70, 66, 75, 75, 55, 80, + 97, 74, 0, 1, 72, 71, 70, 73, 64, 75, 92, 69, + 68, 20, 70, 77, 68, 68, 66, 71, 70, 69, 87, + 79, 71, 74, 71, 20, 98, 75, 22, 81, 67, 69, + 69, 4, 65, 70, 2, 8, 72, 72, 101, 36, 34, 35, + 20, 6, 6, 5, 67, 3, 69, 72, 68, 84, 83, 87, + 89, 87, 97, 125, 86, 81, 81, 81, 93, 88, 85, + 87, 89, 79, 69, 73, 70, 77, 95, 83, 82, 102, + 89, 101, 101, 119, 113, 111, 111, 73, 71, 109, + 80, 80, 87, 102, 93, 94, 98, 87, 93, 85, 85, + 102, 108, 120, 82, 95, 101, 70, 8, 13, 15, 31, + 21, 27, 5, 29, 25, 34, 29, 38, 33, 22, 44, 2, + 69, 77, 85, 85, 110, 111, 111, 14, 43, 38, 41, + 31, 33, 19, 18, 10, 8, 70, 8, 13, 15, 31, 21, + 27, 5, 29, 25, 34, 29, 38, 33, 22, 44, 2, 69, + 77, 85, 85, 110, 111, 111 }, + + { + + 30, + 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 86, 3, + 29, 37, 9, 30, 79, 75, 20, 69, 71, 32, 91, 88, + 5, 70, 126, 126, 126, 14, 0, 69, 75, 20, 69, + 78, 10, 34, 64, 1, 66, 64, 103, 106, 93, 110, + 65, 72, 74, 75, 89, 82, 98, 1, 69, 70, 67, 31, + 1, 22, 0, 0, 0, 2, 95, 97, 9, 72, 69, 12, 66, + 78, 24, 14, 3, 40, 38, 4, 14, 12, 22, 4, 5, + 27, 106, 88, 88, 90, 23, 70, 15, 27, 66, 77, + 64, 10, 65, 74, 72, 82, 22, 75, 12, 66, 76, 5, + 69, 64, 6, 11, 13, 16, 7, 78, 66, 2, 66, 1, + 71, 29, 66, 1, 30, 26, 36, 30, 25, 95, 7, 7, + 73, 67, 77, 69, 28, 1, 3, 32, 51, 62, 60, 40, + 96, 104, 9, 41, 41, 122, 72, 12, 96, 22, 69, + 3, 31, 33, 54, 48, 41, 105, 67, 78, 89, 87, + 73, 15, 21, 12, 8, 13, 12, 4, 16, 11, 74, 67, + 7, 1, 1, 74, 0, 70, 76, 65, 65, 2, 68, 70, + 104, 72, 74, 69, 81, 82, 67, 8, 65, 68, 65, + 68, 82, 71, 0, 100, 116, 91, 97, 93, 126, 82, + 77, 109, 1, 72, 72, 79, 81, 93, 87, 81, 100, + 93, 90, 93, 101, 68, 7, 35, 23, 10, 4, 13, 6, + 1, 65, 7, 15, 41, 26, 19, 11, 30, 14, 16, 2, + 27, 6, 35, 22, 17, 11, 23, 9, 2, 1, 64, 69, + 48, 27, 10, 3, 17, 2, 71, 67, 14, 40, 33, 20, + 9, 29, 12, 9, 2, 1, 62, 73, 66, 4, 2, 67, 3, + 6, 10, 9, 14, 19, 30, 69, 65, 74, 74, 58, 79, + 98, 73, 1, 2, 72, 71, 70, 73, 0, 76, 93, 69, + 68, 21, 70, 77, 68, 68, 65, 72, 71, 69, 88, + 80, 72, 74, 71, 21, 99, 76, 23, 81, 68, 69, + 69, 4, 66, 71, 2, 8, 72, 72, 102, 35, 33, 34, + 19, 3, 4, 2, 70, 0, 72, 75, 71, 87, 85, 89, + 93, 90, 101, 126, 89, 83, 83, 83, 96, 90, 86, + 88, 90, 79, 71, 76, 73, 79, 97, 85, 83, 104, + 91, 103, 103, 121, 115, 112, 113, 74, 72, 111, + 81, 81, 88, 104, 94, 95, 99, 88, 94, 85, 84, + 104, 109, 121, 84, 96, 102, 70, 9, 13, 16, 32, + 22, 27, 6, 30, 26, 35, 30, 39, 33, 22, 44, 0, + 71, 79, 87, 87, 113, 113, 112, 14, 44, 39, 41, + 32, 34, 20, 18, 10, 9, 70, 9, 13, 16, 32, 22, + 27, 6, 30, 26, 35, 30, 39, 33, 22, 44, 0, 71, + 79, 87, 87, 113, 113, 112 }, + + { + + 28, + 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 88, 1, + 28, 37, 9, 32, 81, 75, 21, 69, 72, 33, 92, 90, + 3, 72, 126, 126, 126, 16, 1, 69, 75, 21, 69, + 78, 10, 34, 65, 2, 65, 0, 104, 108, 94, 111, + 65, 72, 73, 75, 90, 82, 98, 1, 69, 70, 67, 31, + 1, 22, 0, 0, 0, 3, 96, 97, 9, 73, 69, 12, 65, + 77, 26, 15, 3, 42, 40, 4, 15, 14, 22, 5, 6, + 29, 107, 88, 89, 90, 23, 71, 15, 29, 66, 76, + 0, 11, 65, 74, 72, 82, 22, 75, 12, 65, 76, 5, + 69, 64, 6, 11, 14, 17, 7, 78, 67, 2, 66, 0, + 71, 29, 66, 1, 30, 26, 36, 30, 25, 96, 8, 8, + 74, 67, 77, 69, 29, 1, 3, 33, 52, 62, 62, 42, + 97, 105, 9, 41, 41, 123, 72, 12, 97, 22, 69, + 3, 32, 33, 54, 48, 42, 106, 66, 79, 92, 91, + 72, 14, 21, 12, 7, 12, 11, 4, 16, 10, 75, 68, + 6, 1, 0, 75, 64, 71, 77, 65, 66, 1, 69, 71, + 105, 73, 75, 69, 83, 83, 69, 6, 67, 70, 67, + 71, 86, 73, 64, 102, 119, 93, 100, 95, 126, + 84, 78, 111, 0, 73, 73, 80, 83, 95, 89, 83, + 102, 93, 91, 94, 103, 67, 8, 36, 24, 10, 4, + 13, 7, 2, 64, 9, 16, 41, 26, 20, 11, 31, 15, + 17, 3, 29, 6, 35, 22, 17, 11, 23, 9, 3, 1, 0, + 69, 49, 28, 10, 3, 18, 3, 71, 66, 15, 40, 34, + 20, 9, 30, 12, 10, 3, 1, 62, 72, 64, 6, 4, 66, + 4, 8, 11, 10, 15, 21, 32, 69, 64, 74, 73, 61, + 79, 99, 73, 2, 2, 72, 71, 70, 74, 0, 76, 94, + 69, 68, 21, 70, 77, 69, 68, 65, 72, 71, 70, + 89, 81, 72, 75, 71, 22, 100, 76, 23, 82, 68, + 69, 70, 4, 66, 71, 2, 9, 72, 72, 104, 34, 32, + 33, 17, 1, 1, 64, 73, 65, 75, 79, 74, 91, 88, + 91, 97, 94, 105, 126, 92, 85, 85, 86, 98, 92, + 88, 90, 91, 79, 74, 78, 75, 81, 100, 87, 85, + 107, 93, 105, 105, 123, 118, 114, 114, 76, 73, + 114, 83, 83, 90, 106, 96, 97, 100, 89, 95, 85, + 83, 105, 111, 123, 85, 97, 103, 70, 9, 14, 16, + 33, 22, 28, 6, 31, 26, 36, 30, 39, 34, 23, 43, + 65, 73, 81, 89, 89, 115, 115, 114, 15, 44, 39, + 42, 32, 34, 20, 19, 10, 9, 70, 9, 14, 16, 33, + 22, 28, 6, 31, 26, 36, 30, 39, 34, 23, 43, 65, + 73, 81, 89, 89, 115, 115, 114 }, + + { + + 27, + 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 90, 64, + 28, 38, 9, 34, 82, 74, 23, 69, 72, 34, 92, 91, + 2, 74, 126, 126, 126, 18, 3, 68, 74, 23, 69, + 77, 11, 35, 65, 3, 64, 1, 105, 109, 94, 111, + 65, 72, 72, 75, 90, 82, 98, 1, 68, 69, 66, 31, + 1, 22, 0, 0, 0, 4, 96, 97, 9, 74, 69, 12, 64, + 75, 29, 16, 4, 44, 42, 5, 16, 16, 23, 7, 7, + 31, 108, 88, 89, 90, 24, 71, 16, 31, 66, 75, + 1, 13, 65, 73, 72, 81, 23, 75, 13, 64, 75, 6, + 69, 64, 7, 12, 15, 18, 7, 78, 67, 3, 65, 0, + 71, 30, 66, 1, 30, 27, 37, 30, 26, 96, 9, 9, + 75, 67, 77, 69, 30, 1, 4, 34, 53, 62, 62, 44, + 98, 106, 10, 41, 42, 124, 72, 12, 97, 23, 69, + 3, 34, 33, 54, 48, 43, 107, 65, 80, 94, 94, + 70, 14, 21, 12, 6, 12, 11, 4, 16, 10, 76, 69, + 6, 1, 0, 75, 64, 72, 77, 65, 66, 1, 70, 72, + 106, 73, 75, 69, 84, 83, 71, 4, 68, 71, 69, + 73, 89, 75, 65, 104, 121, 94, 102, 96, 126, + 85, 79, 113, 64, 74, 74, 81, 85, 96, 91, 85, + 103, 93, 91, 95, 104, 65, 10, 38, 25, 10, 4, + 14, 8, 3, 0, 11, 17, 42, 27, 21, 12, 32, 16, + 18, 4, 31, 7, 36, 23, 18, 11, 24, 10, 4, 2, 2, + 68, 51, 29, 11, 3, 19, 4, 70, 65, 16, 41, 35, + 21, 10, 31, 13, 11, 4, 2, 62, 70, 1, 8, 6, 65, + 5, 10, 13, 12, 17, 23, 34, 68, 0, 73, 72, 62, + 79, 100, 73, 3, 3, 71, 71, 70, 74, 0, 76, 95, + 69, 68, 22, 70, 77, 69, 68, 65, 72, 71, 70, + 89, 82, 72, 75, 70, 24, 100, 76, 24, 83, 68, + 69, 70, 5, 66, 71, 3, 10, 71, 71, 106, 33, 31, + 32, 15, 64, 65, 66, 76, 67, 77, 82, 76, 94, + 91, 93, 101, 97, 108, 126, 95, 87, 86, 88, + 100, 93, 89, 91, 92, 79, 76, 80, 77, 83, 102, + 89, 86, 109, 95, 107, 107, 125, 120, 116, 115, + 77, 74, 116, 84, 85, 91, 108, 97, 98, 101, 90, + 95, 85, 82, 106, 112, 125, 86, 98, 104, 70, + 10, 15, 17, 35, 23, 29, 6, 32, 27, 37, 31, 40, + 35, 24, 42, 66, 75, 83, 91, 91, 117, 117, 115, + 16, 44, 40, 43, 33, 35, 21, 20, 11, 10, 70, + 10, 15, 17, 35, 23, 29, 6, 32, 27, 37, 31, 40, + 35, 24, 42, 66, 75, 83, 91, 91, 117, 117, 115 }, + + { + + 26, + 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 92, 65, + 27, 39, 9, 35, 84, 74, 24, 70, 72, 35, 93, 92, + 1, 76, 126, 126, 126, 20, 4, 68, 74, 24, 70, + 77, 12, 35, 65, 3, 0, 3, 106, 110, 94, 111, + 65, 71, 71, 76, 90, 82, 98, 1, 68, 69, 65, 32, + 1, 22, 0, 0, 0, 4, 96, 97, 10, 75, 69, 11, 64, + 74, 31, 17, 5, 45, 43, 6, 17, 18, 24, 8, 8, + 34, 108, 89, 89, 91, 24, 71, 17, 34, 65, 75, + 1, 15, 65, 73, 72, 81, 23, 75, 13, 0, 75, 7, + 68, 64, 7, 12, 16, 18, 7, 79, 67, 3, 65, 0, + 71, 30, 66, 1, 31, 27, 37, 30, 26, 97, 9, 9, + 75, 67, 76, 69, 31, 2, 4, 36, 55, 62, 62, 46, + 98, 107, 10, 42, 42, 125, 72, 13, 98, 24, 69, + 3, 35, 33, 54, 48, 45, 108, 0, 81, 97, 97, 69, + 14, 21, 11, 6, 11, 11, 3, 16, 9, 77, 70, 6, 1, + 0, 75, 65, 72, 78, 66, 66, 1, 71, 72, 107, 74, + 76, 69, 85, 84, 73, 2, 70, 73, 70, 75, 92, 78, + 66, 106, 123, 96, 104, 98, 126, 86, 80, 114, + 65, 75, 75, 83, 86, 98, 93, 86, 105, 93, 92, + 96, 106, 64, 11, 39, 25, 10, 4, 15, 9, 4, 0, + 13, 19, 43, 28, 21, 13, 34, 17, 20, 5, 34, 8, + 36, 23, 18, 12, 25, 11, 4, 3, 3, 68, 52, 30, + 11, 3, 20, 4, 70, 64, 17, 41, 36, 21, 10, 32, + 14, 12, 4, 3, 62, 69, 2, 9, 7, 64, 7, 11, 15, + 13, 19, 25, 37, 67, 1, 72, 71, 62, 78, 101, + 72, 4, 4, 71, 71, 70, 74, 1, 77, 96, 69, 68, + 23, 70, 77, 69, 68, 64, 73, 72, 70, 90, 83, + 73, 75, 70, 25, 101, 77, 25, 83, 69, 69, 70, + 5, 67, 72, 3, 10, 71, 71, 107, 32, 30, 31, 14, + 67, 67, 69, 79, 70, 80, 85, 79, 97, 93, 95, + 105, 101, 112, 126, 98, 89, 88, 90, 103, 95, + 90, 92, 93, 79, 78, 83, 80, 85, 104, 91, 88, + 111, 97, 109, 109, 126, 122, 117, 117, 78, 75, + 118, 86, 86, 93, 110, 98, 99, 102, 91, 96, 85, + 81, 108, 113, 126, 88, 99, 105, 70, 10, 15, + 18, 36, 24, 29, 7, 33, 28, 38, 31, 41, 35, 24, + 42, 68, 77, 85, 93, 93, 120, 119, 116, 16, 45, + 40, 43, 34, 36, 21, 20, 11, 11, 70, 10, 15, + 18, 36, 24, 29, 7, 33, 28, 38, 31, 41, 35, 24, + 42, 68, 77, 85, 93, 93, 120, 119, 116 }, + + { + + 25, + 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 93, 67, + 26, 39, 10, 37, 85, 74, 26, 70, 73, 36, 94, + 93, 0, 77, 126, 126, 126, 22, 6, 68, 74, 26, + 70, 76, 13, 36, 65, 4, 1, 4, 108, 111, 94, + 112, 65, 71, 71, 76, 91, 81, 98, 0, 68, 69, + 64, 32, 1, 22, 0, 0, 0, 5, 96, 97, 10, 75, 70, + 11, 0, 73, 33, 18, 6, 47, 45, 7, 18, 20, 25, + 9, 8, 36, 109, 89, 89, 91, 25, 71, 18, 36, 65, + 74, 2, 17, 65, 73, 72, 81, 24, 76, 14, 0, 75, + 8, 68, 0, 7, 13, 17, 19, 7, 79, 67, 3, 65, 0, + 71, 30, 66, 1, 31, 27, 38, 31, 27, 97, 10, 10, + 76, 67, 76, 69, 32, 2, 5, 37, 56, 62, 62, 47, + 99, 108, 11, 42, 42, 125, 73, 13, 98, 24, 70, + 4, 36, 33, 54, 49, 46, 109, 1, 82, 100, 100, + 67, 14, 21, 11, 5, 11, 10, 3, 15, 9, 77, 70, + 6, 0, 0, 76, 65, 73, 79, 66, 66, 1, 71, 73, + 109, 74, 77, 69, 86, 84, 76, 0, 72, 74, 72, + 77, 95, 80, 68, 108, 125, 97, 106, 100, 126, + 87, 82, 116, 67, 76, 76, 84, 88, 100, 95, 88, + 106, 93, 93, 97, 107, 1, 13, 41, 26, 10, 4, + 16, 9, 4, 1, 14, 20, 44, 29, 22, 13, 35, 18, + 21, 6, 36, 8, 37, 24, 19, 12, 26, 11, 5, 4, 4, + 68, 54, 31, 11, 3, 20, 5, 70, 64, 17, 42, 36, + 22, 10, 33, 14, 12, 5, 3, 62, 67, 4, 11, 9, 1, + 8, 13, 16, 15, 21, 27, 39, 67, 2, 72, 71, 62, + 78, 102, 72, 4, 5, 71, 71, 70, 74, 1, 77, 97, + 69, 68, 23, 70, 77, 69, 68, 64, 73, 72, 70, + 91, 84, 73, 75, 70, 26, 102, 77, 26, 84, 69, + 69, 70, 6, 67, 72, 4, 11, 71, 71, 109, 31, 29, + 30, 12, 69, 70, 71, 82, 72, 83, 88, 82, 100, + 96, 97, 108, 104, 116, 126, 100, 92, 90, 92, + 105, 97, 91, 93, 94, 79, 80, 85, 82, 87, 106, + 92, 89, 113, 99, 112, 111, 126, 124, 119, 118, + 79, 77, 120, 87, 88, 94, 112, 100, 101, 103, + 92, 97, 86, 80, 109, 115, 126, 89, 101, 106, + 69, 11, 16, 18, 37, 25, 30, 7, 34, 29, 39, 32, + 42, 36, 25, 41, 70, 79, 87, 95, 95, 122, 121, + 117, 17, 45, 41, 44, 34, 37, 22, 21, 12, 11, + 69, 11, 16, 18, 37, 25, 30, 7, 34, 29, 39, 32, + 42, 36, 25, 41, 70, 79, 87, 95, 95, 122, 121, + 117 }, + + { + + 23, + 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 95, 68, + 25, 40, 10, 39, 87, 74, 27, 70, 73, 37, 95, + 95, 65, 79, 126, 126, 126, 24, 7, 68, 74, 27, + 70, 76, 14, 36, 66, 5, 2, 5, 109, 113, 95, + 112, 65, 71, 70, 76, 91, 81, 98, 0, 68, 69, + 64, 33, 1, 22, 0, 0, 0, 5, 97, 97, 11, 76, 70, + 10, 0, 72, 35, 19, 7, 48, 46, 7, 19, 22, 26, + 10, 9, 38, 110, 89, 89, 91, 25, 72, 19, 38, + 65, 73, 3, 19, 65, 73, 72, 81, 24, 76, 14, 1, + 75, 8, 68, 0, 7, 13, 18, 19, 7, 79, 68, 3, 65, + 0, 71, 30, 66, 1, 32, 27, 38, 31, 27, 98, 10, + 11, 76, 67, 76, 69, 33, 2, 5, 38, 57, 62, 62, + 49, 99, 109, 11, 42, 42, 126, 73, 14, 99, 25, + 70, 4, 37, 33, 54, 49, 47, 110, 3, 83, 103, + 103, 66, 13, 21, 10, 4, 10, 10, 2, 15, 8, 78, + 71, 5, 0, 0, 76, 66, 74, 80, 67, 67, 0, 72, + 73, 110, 75, 78, 69, 88, 85, 78, 65, 74, 76, + 74, 79, 99, 83, 69, 110, 126, 99, 108, 102, + 126, 89, 83, 118, 68, 77, 77, 85, 89, 102, 97, + 90, 108, 93, 94, 98, 109, 2, 14, 42, 26, 10, + 4, 17, 10, 5, 2, 16, 21, 45, 29, 23, 14, 36, + 19, 23, 7, 38, 9, 37, 24, 19, 13, 27, 12, 5, + 4, 5, 68, 55, 32, 11, 3, 21, 5, 70, 0, 18, 42, + 37, 22, 10, 34, 15, 13, 5, 4, 62, 66, 5, 12, + 11, 2, 10, 14, 18, 16, 22, 29, 41, 66, 3, 71, + 70, 62, 78, 103, 72, 5, 5, 71, 71, 70, 75, 2, + 77, 98, 69, 68, 24, 70, 77, 69, 68, 64, 74, + 72, 70, 92, 85, 73, 75, 70, 27, 103, 77, 26, + 85, 69, 69, 70, 6, 67, 73, 4, 12, 71, 71, 110, + 30, 28, 29, 10, 71, 72, 74, 85, 75, 86, 92, + 85, 104, 99, 99, 112, 108, 120, 126, 103, 94, + 92, 94, 108, 99, 93, 94, 95, 79, 83, 87, 84, + 89, 108, 94, 91, 115, 101, 114, 113, 126, 126, + 121, 119, 80, 78, 123, 89, 90, 96, 114, 101, + 102, 104, 93, 98, 86, 79, 110, 116, 126, 90, + 102, 107, 69, 11, 16, 19, 38, 25, 31, 7, 35, + 30, 40, 32, 43, 36, 26, 41, 72, 81, 89, 97, + 97, 124, 123, 119, 17, 46, 41, 45, 35, 37, 22, + 21, 12, 12, 69, 11, 16, 19, 38, 25, 31, 7, 35, + 30, 40, 32, 43, 36, 26, 41, 72, 81, 89, 97, + 97, 124, 123, 119 }, + + { + + 22, + 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 70, + 24, 41, 10, 40, 89, 73, 29, 71, 73, 38, 96, + 96, 66, 81, 126, 126, 126, 26, 8, 68, 73, 29, + 71, 76, 15, 36, 66, 5, 3, 7, 110, 114, 95, + 112, 65, 70, 69, 77, 91, 81, 98, 0, 67, 69, 0, + 33, 1, 22, 0, 0, 0, 6, 97, 97, 11, 77, 70, 10, + 1, 70, 38, 20, 8, 50, 48, 8, 20, 24, 27, 11, + 10, 41, 110, 90, 89, 92, 25, 72, 20, 41, 64, + 73, 3, 21, 65, 73, 72, 80, 24, 76, 15, 2, 74, + 9, 67, 0, 8, 14, 19, 20, 7, 80, 68, 4, 65, 0, + 71, 31, 66, 1, 32, 28, 38, 31, 27, 98, 11, 11, + 77, 67, 75, 69, 34, 3, 6, 40, 59, 62, 62, 51, + 100, 110, 12, 43, 42, 126, 73, 14, 99, 26, 70, + 4, 39, 33, 54, 49, 49, 111, 4, 84, 105, 106, + 65, 13, 21, 10, 4, 10, 10, 2, 15, 8, 79, 72, + 5, 0, 0, 76, 66, 74, 81, 67, 67, 0, 73, 74, + 111, 76, 78, 69, 89, 85, 80, 67, 75, 77, 75, + 81, 102, 85, 70, 112, 126, 100, 110, 104, 126, + 90, 84, 119, 69, 78, 78, 87, 91, 104, 99, 91, + 109, 93, 95, 99, 111, 4, 16, 43, 27, 10, 4, + 18, 11, 6, 2, 18, 23, 46, 30, 23, 15, 38, 20, + 24, 8, 41, 10, 38, 25, 20, 13, 28, 13, 6, 5, + 6, 67, 56, 33, 11, 3, 22, 6, 69, 1, 19, 42, + 38, 22, 10, 35, 16, 14, 6, 5, 62, 65, 7, 14, + 12, 3, 11, 16, 20, 18, 24, 31, 44, 65, 4, 70, + 69, 62, 77, 104, 71, 6, 6, 71, 71, 70, 75, 2, + 78, 99, 69, 68, 25, 70, 77, 69, 68, 0, 74, 73, + 70, 93, 86, 74, 75, 70, 28, 103, 78, 27, 85, + 70, 69, 70, 6, 68, 73, 4, 12, 71, 71, 112, 29, + 27, 28, 9, 74, 75, 77, 88, 77, 89, 95, 88, + 107, 101, 101, 116, 111, 124, 126, 106, 96, + 93, 96, 110, 101, 94, 95, 96, 79, 85, 90, 87, + 91, 110, 96, 92, 117, 103, 116, 115, 126, 126, + 122, 121, 81, 79, 125, 90, 91, 97, 116, 102, + 103, 105, 94, 99, 86, 78, 112, 117, 126, 92, + 103, 108, 69, 12, 17, 20, 39, 26, 31, 8, 36, + 31, 41, 33, 44, 37, 26, 40, 74, 83, 91, 99, + 99, 126, 125, 120, 18, 46, 42, 45, 36, 38, 23, + 22, 12, 13, 69, 12, 17, 20, 39, 26, 31, 8, 36, + 31, 41, 33, 44, 37, 26, 40, 74, 83, 91, 99, + 99, 126, 125, 120 }, + + { + + 21, + 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 71, + 23, 41, 10, 42, 90, 73, 30, 71, 74, 39, 97, + 97, 67, 83, 126, 126, 126, 28, 10, 68, 73, 30, + 71, 75, 16, 37, 66, 6, 4, 8, 111, 115, 95, + 113, 65, 70, 68, 77, 92, 81, 98, 0, 67, 69, 1, + 34, 1, 22, 0, 0, 0, 6, 97, 97, 12, 78, 70, 9, + 1, 69, 40, 21, 9, 51, 49, 9, 21, 26, 28, 12, + 11, 43, 111, 90, 89, 92, 26, 72, 21, 43, 64, + 72, 4, 23, 65, 73, 72, 80, 25, 76, 15, 3, 74, + 10, 67, 0, 8, 14, 20, 20, 7, 80, 68, 4, 65, 0, + 71, 31, 66, 1, 33, 28, 39, 31, 28, 99, 11, 12, + 77, 67, 75, 69, 35, 3, 6, 41, 60, 62, 62, 53, + 100, 111, 12, 43, 42, 126, 73, 15, 100, 26, + 70, 4, 40, 33, 54, 49, 50, 112, 6, 85, 108, + 109, 0, 13, 21, 9, 3, 9, 9, 1, 15, 7, 80, 73, + 5, 0, 0, 77, 67, 75, 82, 68, 67, 0, 74, 74, + 112, 76, 79, 69, 90, 86, 82, 69, 77, 79, 77, + 83, 105, 88, 71, 114, 126, 102, 112, 106, 126, + 91, 85, 121, 70, 79, 79, 88, 92, 106, 101, 93, + 111, 93, 96, 100, 112, 5, 17, 45, 27, 10, 4, + 19, 12, 7, 3, 20, 24, 47, 31, 24, 15, 39, 21, + 26, 9, 43, 10, 38, 25, 20, 14, 29, 13, 6, 6, + 7, 67, 58, 34, 11, 3, 23, 6, 69, 2, 20, 43, + 39, 23, 10, 36, 16, 15, 6, 5, 62, 0, 8, 15, + 14, 4, 13, 17, 21, 19, 26, 33, 46, 65, 5, 70, + 68, 62, 77, 105, 71, 7, 7, 71, 71, 70, 75, 3, + 78, 100, 69, 68, 25, 70, 77, 69, 68, 0, 75, + 73, 70, 94, 87, 74, 75, 70, 29, 104, 78, 28, + 86, 70, 69, 70, 7, 68, 74, 5, 13, 71, 71, 113, + 28, 26, 27, 7, 76, 77, 79, 91, 80, 92, 98, 91, + 110, 104, 103, 120, 115, 126, 126, 109, 98, + 95, 98, 113, 103, 95, 96, 97, 79, 87, 92, 89, + 93, 112, 98, 94, 119, 105, 118, 117, 126, 126, + 124, 122, 82, 80, 126, 92, 93, 99, 118, 104, + 105, 106, 95, 100, 86, 77, 113, 119, 126, 93, + 104, 109, 69, 12, 17, 20, 40, 27, 32, 8, 37, + 32, 42, 33, 45, 37, 27, 40, 76, 85, 93, 101, + 101, 126, 126, 121, 18, 47, 42, 46, 36, 39, + 23, 22, 13, 13, 69, 12, 17, 20, 40, 27, 32, 8, + 37, 32, 42, 33, 45, 37, 27, 40, 76, 85, 93, + 101, 101, 126, 126, 121 }, + + { + + 20, + 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 101, 73, + 22, 42, 10, 44, 92, 73, 32, 71, 74, 40, 98, + 98, 68, 85, 126, 126, 126, 30, 11, 68, 73, 32, + 71, 75, 17, 37, 66, 7, 5, 9, 112, 116, 95, + 113, 65, 70, 67, 77, 92, 81, 98, 0, 67, 69, 2, + 34, 1, 22, 0, 0, 0, 7, 97, 97, 12, 79, 70, 9, + 2, 68, 42, 22, 10, 53, 51, 10, 22, 28, 29, 13, + 12, 45, 112, 90, 89, 92, 26, 72, 22, 45, 64, + 71, 5, 25, 65, 73, 72, 80, 25, 76, 16, 4, 74, + 11, 67, 0, 8, 15, 21, 21, 7, 80, 68, 4, 65, 0, + 71, 31, 66, 1, 33, 28, 39, 31, 28, 99, 12, 13, + 78, 67, 75, 69, 36, 3, 7, 42, 61, 62, 62, 55, + 101, 112, 13, 43, 42, 126, 73, 15, 100, 27, + 70, 4, 41, 33, 54, 49, 51, 113, 7, 86, 111, + 112, 1, 13, 21, 9, 2, 9, 9, 1, 15, 7, 81, 74, + 5, 0, 0, 77, 67, 76, 83, 68, 67, 0, 75, 75, + 113, 77, 80, 69, 91, 86, 84, 71, 79, 80, 79, + 85, 108, 90, 72, 116, 126, 103, 114, 108, 126, + 92, 86, 123, 71, 80, 80, 89, 94, 108, 103, 95, + 112, 93, 97, 101, 114, 7, 19, 46, 28, 10, 4, + 20, 13, 8, 4, 22, 25, 48, 32, 25, 16, 40, 22, + 27, 10, 45, 11, 39, 26, 21, 14, 30, 14, 7, 7, + 8, 67, 59, 35, 11, 3, 24, 7, 69, 3, 21, 43, + 40, 23, 10, 37, 17, 16, 7, 6, 62, 1, 10, 17, + 16, 5, 14, 19, 23, 21, 28, 35, 48, 64, 6, 69, + 67, 62, 77, 106, 71, 8, 8, 71, 71, 70, 75, 3, + 78, 101, 69, 68, 26, 70, 77, 69, 68, 0, 75, + 73, 70, 95, 88, 74, 75, 70, 30, 105, 78, 29, + 87, 70, 69, 70, 7, 68, 74, 5, 14, 71, 71, 115, + 27, 25, 26, 5, 78, 80, 82, 94, 82, 95, 101, + 94, 113, 107, 105, 124, 118, 126, 126, 112, + 100, 97, 100, 115, 105, 96, 97, 98, 79, 89, + 94, 91, 95, 114, 100, 95, 121, 107, 120, 119, + 126, 126, 126, 123, 83, 81, 126, 93, 95, 100, + 120, 105, 106, 107, 96, 101, 86, 76, 114, 120, + 126, 94, 105, 110, 69, 13, 18, 21, 41, 28, 33, + 8, 38, 33, 43, 34, 46, 38, 28, 39, 78, 87, 95, + 103, 103, 126, 126, 122, 19, 47, 43, 47, 37, + 40, 24, 23, 13, 14, 69, 13, 18, 21, 41, 28, + 33, 8, 38, 33, 43, 34, 46, 38, 28, 39, 78, 87, + 95, 103, 103, 126, 126, 122 }, + + { + + 18, + 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 103, 75, + 21, 42, 10, 45, 94, 73, 33, 72, 75, 41, 99, + 100, 70, 87, 126, 126, 126, 32, 12, 68, 73, + 33, 72, 75, 17, 37, 67, 7, 5, 10, 114, 118, + 96, 114, 66, 70, 67, 78, 93, 81, 98, 64, 67, + 69, 2, 34, 0, 22, 0, 0, 0, 7, 98, 97, 12, 80, + 71, 8, 2, 67, 44, 23, 10, 54, 52, 10, 23, 29, + 29, 14, 12, 47, 113, 91, 90, 93, 26, 73, 22, + 47, 64, 71, 5, 26, 65, 73, 72, 80, 25, 77, 16, + 4, 74, 11, 67, 0, 8, 15, 22, 21, 7, 81, 69, 4, + 65, 64, 71, 31, 66, 1, 33, 28, 39, 31, 28, + 100, 12, 13, 79, 67, 75, 70, 36, 3, 7, 43, 62, + 62, 62, 56, 102, 114, 13, 43, 42, 126, 74, 15, + 101, 27, 71, 4, 42, 33, 53, 49, 52, 114, 8, + 88, 114, 116, 2, 12, 21, 8, 1, 8, 8, 0, 14, 6, + 82, 75, 4, 64, 64, 78, 68, 77, 84, 69, 68, 64, + 76, 76, 115, 78, 81, 69, 93, 87, 87, 74, 81, + 82, 81, 88, 112, 93, 74, 118, 126, 105, 117, + 110, 126, 94, 88, 125, 73, 81, 81, 91, 96, + 110, 105, 97, 114, 93, 98, 102, 116, 8, 20, + 47, 28, 10, 4, 20, 13, 8, 4, 23, 26, 48, 32, + 25, 16, 41, 23, 28, 10, 47, 11, 39, 26, 21, + 14, 30, 14, 7, 7, 9, 67, 60, 36, 11, 2, 24, 7, + 69, 3, 21, 43, 40, 23, 10, 38, 17, 16, 7, 6, + 62, 2, 11, 18, 17, 6, 15, 20, 24, 22, 29, 36, + 50, 64, 6, 69, 67, 62, 77, 108, 71, 8, 8, 71, + 71, 70, 76, 3, 79, 102, 70, 68, 26, 71, 77, + 70, 68, 0, 76, 74, 71, 96, 89, 75, 76, 70, 31, + 106, 79, 29, 88, 71, 69, 71, 7, 69, 75, 5, 14, + 71, 71, 117, 25, 24, 24, 3, 81, 83, 85, 97, + 85, 98, 105, 97, 117, 110, 107, 126, 122, 126, + 126, 115, 103, 99, 103, 118, 107, 98, 99, 99, + 79, 92, 97, 94, 97, 117, 102, 97, 124, 109, + 123, 121, 126, 126, 126, 125, 85, 83, 126, 95, + 97, 102, 122, 107, 108, 108, 97, 102, 87, 75, + 116, 122, 126, 96, 107, 112, 69, 13, 18, 21, + 42, 28, 33, 8, 39, 33, 44, 34, 46, 38, 28, 38, + 80, 89, 98, 106, 105, 126, 126, 124, 19, 47, + 43, 47, 37, 40, 24, 23, 13, 14, 69, 13, 18, + 21, 42, 28, 33, 8, 39, 33, 44, 34, 46, 38, 28, + 38, 80, 89, 98, 106, 105, 126, 126, 124 }, + + { + + 17, + 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 104, 76, + 21, 43, 11, 47, 95, 72, 35, 72, 75, 43, 99, + 101, 71, 88, 126, 126, 126, 34, 14, 67, 72, + 35, 72, 74, 18, 38, 67, 8, 6, 12, 115, 119, + 96, 114, 66, 69, 66, 78, 93, 80, 97, 64, 66, + 68, 3, 35, 0, 22, 0, 0, 0, 8, 98, 97, 13, 80, + 71, 8, 3, 65, 47, 25, 11, 56, 54, 11, 25, 31, + 30, 16, 13, 50, 113, 91, 90, 93, 27, 73, 23, + 50, 0, 70, 6, 28, 65, 72, 72, 79, 26, 77, 17, + 5, 73, 12, 66, 1, 9, 16, 23, 22, 8, 81, 69, 5, + 64, 64, 70, 32, 65, 1, 34, 29, 40, 32, 29, + 100, 13, 14, 79, 67, 74, 70, 37, 4, 8, 45, 62, + 62, 62, 58, 102, 115, 14, 44, 43, 126, 74, 16, + 101, 28, 71, 5, 44, 33, 53, 50, 54, 115, 10, + 89, 116, 119, 4, 12, 21, 8, 1, 8, 8, 0, 14, 6, + 82, 75, 4, 64, 64, 78, 68, 77, 84, 69, 68, 64, + 76, 76, 116, 78, 81, 69, 94, 87, 89, 76, 82, + 83, 82, 90, 115, 95, 75, 119, 126, 106, 119, + 111, 126, 95, 89, 126, 74, 81, 81, 92, 97, + 111, 106, 98, 115, 93, 98, 102, 117, 10, 22, + 49, 29, 10, 4, 21, 14, 9, 5, 25, 28, 49, 33, + 26, 17, 43, 24, 30, 11, 50, 12, 40, 27, 22, + 15, 31, 15, 8, 8, 11, 66, 62, 37, 12, 2, 25, + 8, 68, 4, 22, 44, 41, 24, 11, 39, 18, 17, 8, + 7, 62, 4, 13, 20, 19, 8, 17, 22, 26, 24, 31, + 38, 53, 0, 7, 68, 66, 62, 76, 109, 70, 9, 9, + 70, 71, 69, 76, 4, 79, 102, 70, 68, 27, 71, + 77, 70, 68, 1, 76, 74, 71, 96, 89, 75, 76, 69, + 33, 106, 79, 30, 88, 71, 69, 71, 8, 69, 75, 6, + 15, 70, 70, 118, 24, 23, 23, 2, 83, 85, 87, + 100, 87, 100, 108, 99, 120, 112, 109, 126, + 125, 126, 126, 117, 105, 100, 105, 120, 108, + 99, 100, 99, 79, 94, 99, 96, 99, 119, 103, 98, + 126, 110, 125, 122, 126, 126, 126, 126, 86, + 84, 126, 96, 98, 103, 123, 108, 109, 109, 97, + 102, 87, 74, 117, 123, 126, 97, 108, 113, 68, + 14, 19, 22, 44, 29, 34, 9, 41, 34, 45, 35, 47, + 39, 29, 38, 81, 90, 100, 108, 106, 126, 126, + 125, 20, 48, 44, 48, 38, 41, 25, 24, 14, 15, + 68, 14, 19, 22, 44, 29, 34, 9, 41, 34, 45, 35, + 47, 39, 29, 38, 81, 90, 100, 108, 106, 126, + 126, 125 }, + + { + + 16, + 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 106, 78, + 20, 44, 11, 49, 97, 72, 36, 72, 75, 44, 100, + 102, 72, 90, 126, 126, 126, 36, 15, 67, 72, + 36, 72, 74, 19, 38, 67, 9, 7, 13, 116, 120, + 96, 114, 66, 69, 65, 78, 93, 80, 97, 64, 66, + 68, 4, 35, 0, 22, 0, 0, 0, 9, 98, 97, 13, 81, + 71, 8, 4, 64, 49, 26, 12, 58, 56, 12, 26, 33, + 31, 17, 14, 52, 114, 91, 90, 93, 27, 73, 24, + 52, 0, 69, 7, 30, 65, 72, 72, 79, 26, 77, 17, + 6, 73, 13, 66, 1, 9, 16, 24, 23, 8, 81, 69, 5, + 64, 64, 70, 32, 65, 1, 34, 29, 40, 32, 29, + 101, 14, 15, 80, 67, 74, 70, 38, 4, 8, 46, 62, + 62, 62, 60, 103, 116, 14, 44, 43, 126, 74, 16, + 102, 29, 71, 5, 45, 33, 53, 50, 55, 116, 11, + 90, 119, 122, 5, 12, 21, 8, 0, 7, 8, 0, 14, 5, + 83, 76, 4, 64, 64, 78, 69, 78, 85, 69, 68, 64, + 77, 77, 117, 79, 82, 69, 95, 88, 91, 78, 84, + 85, 84, 92, 118, 97, 76, 121, 126, 108, 121, + 113, 126, 96, 90, 126, 75, 82, 82, 93, 99, + 113, 108, 100, 117, 93, 99, 103, 119, 11, 23, + 50, 30, 10, 4, 22, 15, 10, 6, 27, 29, 50, 34, + 27, 18, 44, 25, 31, 12, 52, 13, 40, 27, 22, + 15, 32, 16, 9, 9, 12, 66, 62, 38, 12, 2, 26, + 9, 68, 5, 23, 44, 42, 24, 11, 40, 19, 18, 9, + 8, 62, 5, 15, 22, 21, 9, 18, 24, 28, 25, 33, + 40, 55, 1, 8, 67, 65, 62, 76, 110, 70, 10, 10, + 70, 71, 69, 76, 4, 79, 103, 70, 68, 28, 71, + 77, 70, 68, 1, 76, 74, 71, 97, 90, 75, 76, 69, + 34, 107, 79, 31, 89, 71, 69, 71, 8, 69, 75, 6, + 16, 70, 70, 120, 23, 22, 22, 0, 85, 88, 90, + 103, 89, 103, 111, 102, 123, 115, 111, 126, + 126, 126, 126, 120, 107, 102, 107, 122, 110, + 100, 101, 100, 79, 96, 101, 98, 101, 121, 105, + 100, 126, 112, 126, 124, 126, 126, 126, 126, + 87, 85, 126, 98, 100, 105, 125, 109, 110, 110, + 98, 103, 87, 73, 118, 124, 126, 98, 109, 114, + 68, 14, 20, 23, 45, 30, 35, 9, 42, 35, 46, 35, + 48, 40, 30, 37, 83, 92, 102, 110, 108, 126, + 126, 126, 21, 48, 44, 49, 39, 42, 25, 25, 14, + 16, 68, 14, 20, 23, 45, 30, 35, 9, 42, 35, 46, + 35, 48, 40, 30, 37, 83, 92, 102, 110, 108, + 126, 126, 126 }, + + { + + 15, + 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 108, 79, + 19, 44, 11, 51, 98, 72, 38, 72, 76, 45, 101, + 103, 73, 92, 126, 126, 126, 38, 17, 67, 72, + 38, 72, 73, 20, 39, 67, 10, 8, 14, 117, 121, + 96, 115, 66, 69, 64, 78, 94, 80, 97, 64, 66, + 68, 5, 36, 0, 22, 0, 0, 0, 9, 98, 97, 14, 82, + 71, 7, 4, 0, 51, 27, 13, 59, 57, 13, 27, 35, + 32, 18, 15, 54, 115, 91, 90, 93, 28, 73, 25, + 54, 0, 68, 8, 32, 65, 72, 72, 79, 27, 77, 18, + 7, 73, 14, 66, 1, 9, 17, 25, 23, 8, 81, 69, 5, + 64, 64, 70, 32, 65, 1, 35, 29, 41, 32, 30, + 101, 14, 16, 80, 67, 74, 70, 39, 4, 9, 47, 62, + 62, 62, 62, 103, 117, 15, 44, 43, 126, 74, 17, + 102, 29, 71, 5, 46, 33, 53, 50, 56, 117, 13, + 91, 122, 125, 7, 12, 21, 7, 64, 7, 7, 64, 14, + 5, 84, 77, 4, 64, 64, 79, 69, 79, 86, 70, 68, + 64, 78, 77, 118, 79, 83, 69, 96, 88, 93, 80, + 86, 86, 86, 94, 121, 100, 77, 123, 126, 109, + 123, 115, 126, 97, 91, 126, 76, 83, 83, 94, + 100, 115, 110, 102, 118, 93, 100, 104, 120, + 13, 25, 52, 30, 10, 4, 23, 16, 11, 7, 29, 30, + 51, 35, 28, 18, 45, 26, 33, 13, 54, 13, 41, + 28, 23, 16, 33, 16, 9, 10, 13, 66, 62, 39, 12, + 2, 27, 9, 68, 6, 24, 45, 43, 25, 11, 41, 19, + 19, 9, 8, 62, 7, 16, 23, 23, 10, 20, 25, 29, + 27, 35, 42, 57, 1, 9, 67, 64, 62, 76, 111, 70, + 11, 11, 70, 71, 69, 76, 5, 79, 104, 70, 68, + 28, 71, 77, 70, 68, 1, 77, 74, 71, 98, 91, 75, + 76, 69, 35, 108, 79, 32, 90, 71, 69, 71, 9, + 69, 76, 7, 17, 70, 70, 121, 22, 21, 21, 65, + 87, 90, 92, 106, 92, 106, 114, 105, 126, 118, + 113, 126, 126, 126, 126, 123, 109, 104, 109, + 125, 112, 101, 102, 101, 79, 98, 103, 100, + 103, 123, 107, 101, 126, 114, 126, 126, 126, + 126, 126, 126, 88, 86, 126, 99, 102, 106, 126, + 111, 112, 111, 99, 104, 87, 72, 119, 126, 126, + 99, 110, 115, 68, 15, 20, 23, 46, 31, 36, 9, + 43, 36, 47, 36, 49, 40, 31, 37, 85, 94, 104, + 112, 110, 126, 126, 126, 21, 49, 45, 50, 39, + 43, 26, 25, 15, 16, 68, 15, 20, 23, 46, 31, + 36, 9, 43, 36, 47, 36, 49, 40, 31, 37, 85, 94, + 104, 112, 110, 126, 126, 126 }, + + }, + + { + + { + + 62, + 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 30, 61, + 62, 54, 14, 118, 6, 78, 65, 1, 14, 73, 13, 64, + 20, 62, 67, 90, 104, 126, 104, 67, 78, 65, 1, + 86, 95, 2, 18, 69, 81, 96, 8, 67, 86, 88, 5, 76, + 94, 9, 69, 81, 88, 67, 74, 74, 80, 72, 5, 22, 0, + 0, 0, 83, 86, 97, 72, 22, 1, 52, 8, 69, 126, + 102, 82, 74, 107, 126, 126, 126, 95, 126, 114, + 126, 123, 115, 122, 115, 0, 68, 84, 104, 70, 93, + 90, 126, 74, 97, 91, 126, 7, 82, 76, 125, 93, + 87, 77, 71, 0, 68, 84, 1, 65, 2, 7, 66, 64, 2, + 78, 13, 11, 28, 19, 25, 18, 17, 19, 46, 12, 13, + 44, 30, 1, 108, 100, 101, 91, 94, 88, 84, 86, + 83, 87, 94, 70, 72, 74, 4, 102, 100, 95, 75, 72, + 75, 71, 17, 69, 1, 65, 26, 72, 6, 9, 1, 72, 62, + 54, 38, 45, 54, 44, 26, 45, 34, 30, 33, 18, 5, + 1, 2, 25, 18, 24, 21, 19, 18, 22, 14, 29, 21, 8, + 12, 17, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 46, 62, 60, 41, 62, 62, 62, + 62, 60, 58, 62, 47, 41, 15, 26, 3, 68, 97, 71, + 21, 13, 9, 1, 5, 0, 72, 74, 91, 67, 36, 24, 19, + 17, 64, 68, 78, 77, 86, 92, 8, 3, 1, 65, 73, 76, + 80, 88, 110, 97, 84, 79, 73, 74, 86, 96, 97, + 117, 78, 30, 15, 10, 1, 71, 79, 86, 90, 97, 62, + 93, 84, 79, 66, 71, 1, 3, 4, 75, 1, 5, 66, 79, + 71, 68, 19, 1, 27, 23, 36, 34, 19, 27, 31, 21, + 15, 1, 17, 64, 104, 97, 96, 88, 85, 85, 85, 88, + 66, 77, 76, 76, 5, 76, 83, 99, 95, 95, 76, 74, + 70, 75, 68, 65, 73, 1, 1, 68, 75, 8, 64, 70, 57, + 44, 47, 49, 50, 52, 48, 47, 40, 40, 43, 37, 19, + 23, 16, 46, 42, 41, 36, 34, 28, 13, 6, 0, 77, + 82, 94, 69, 109, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 61, 50, 28, 5, 62, 62, 33, 62, 62, + 62, 60, 62, 58, 52, 58, 51, 52, 34, 37, 24, 66, + 42, 32, 13, 120, 112, 114, 85, 92, 89, 71, 81, + 80, 68, 70, 7, 68, 13, 74, 62, 62, 62, 62, 60, + 57, 29, 9, 82, 75, 40, 29, 20, 9, 8, 2, 64, 68, + 92, 106, 97, 90, 90, 88, 73, 79, 86, 73, 70, 69, + 66, 64, 5, 4, 62, 62, 62, 62, 60, 54, 43, 27, 67 }, + + { + + 62, + 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 29, + 60, 62, 54, 14, 115, 6, 77, 64, 1, 14, 72, 12, + 65, 20, 62, 68, 91, 104, 124, 102, 67, 77, 64, + 1, 85, 93, 3, 18, 68, 80, 95, 8, 67, 85, 88, + 5, 75, 93, 9, 69, 80, 88, 66, 73, 73, 79, 71, + 5, 22, 0, 0, 0, 82, 86, 97, 71, 22, 1, 52, 8, + 69, 125, 101, 82, 73, 105, 125, 125, 125, 93, + 125, 112, 125, 121, 114, 121, 114, 1, 67, 83, + 103, 69, 92, 89, 125, 73, 96, 90, 125, 8, 81, + 75, 123, 92, 86, 76, 70, 1, 67, 83, 2, 64, 2, + 7, 65, 64, 2, 77, 13, 11, 28, 19, 25, 18, 17, + 19, 45, 12, 13, 43, 29, 1, 107, 99, 100, 90, + 93, 87, 83, 85, 82, 86, 92, 70, 72, 73, 3, + 101, 99, 95, 74, 72, 74, 70, 17, 68, 1, 65, + 25, 71, 6, 8, 1, 72, 62, 54, 38, 45, 54, 44, + 26, 45, 34, 29, 33, 18, 5, 1, 2, 25, 18, 24, + 21, 19, 17, 22, 14, 28, 20, 8, 11, 16, 89, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 60, 44, 62, 59, 40, 62, 62, 62, 62, 58, + 56, 61, 45, 39, 15, 25, 2, 68, 97, 70, 22, 14, + 10, 2, 5, 0, 71, 73, 90, 66, 37, 25, 20, 17, + 0, 67, 77, 76, 85, 91, 9, 4, 2, 64, 72, 75, + 79, 87, 108, 96, 82, 78, 72, 73, 85, 95, 96, + 115, 77, 31, 16, 11, 2, 70, 78, 85, 89, 96, + 62, 92, 83, 78, 66, 70, 1, 4, 5, 74, 2, 6, 65, + 78, 71, 68, 19, 2, 27, 23, 35, 34, 19, 26, 30, + 21, 15, 1, 16, 64, 103, 96, 95, 87, 84, 84, + 84, 87, 66, 76, 75, 75, 5, 75, 82, 98, 94, 95, + 76, 73, 70, 74, 68, 65, 72, 1, 1, 67, 74, 8, + 64, 70, 57, 44, 47, 49, 49, 52, 48, 47, 40, + 40, 43, 37, 19, 22, 15, 45, 41, 40, 35, 33, + 27, 13, 6, 0, 76, 81, 93, 69, 108, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 61, 59, 48, 27, 5, + 62, 62, 32, 62, 62, 62, 58, 62, 56, 50, 56, + 49, 50, 33, 35, 23, 67, 41, 31, 12, 118, 110, + 112, 84, 91, 88, 69, 80, 79, 68, 69, 9, 66, + 15, 73, 62, 62, 62, 62, 58, 55, 27, 7, 83, 74, + 41, 29, 20, 9, 9, 2, 64, 68, 91, 105, 96, 89, + 89, 86, 72, 78, 85, 72, 69, 68, 65, 0, 6, 4, + 62, 62, 62, 62, 59, 53, 41, 26, 67 }, + + { + + 62, + 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 28, + 59, 61, 54, 14, 113, 6, 76, 0, 1, 13, 72, 11, + 66, 19, 60, 70, 92, 105, 121, 101, 67, 76, 0, + 1, 85, 92, 3, 17, 68, 80, 94, 8, 67, 85, 88, + 5, 75, 92, 9, 69, 80, 88, 66, 73, 73, 79, 71, + 5, 22, 0, 0, 0, 81, 86, 97, 71, 21, 1, 52, 8, + 69, 124, 100, 82, 73, 104, 123, 123, 124, 92, + 123, 111, 123, 120, 113, 120, 113, 2, 67, 82, + 102, 69, 92, 88, 123, 73, 96, 90, 124, 8, 81, + 75, 122, 92, 85, 76, 70, 1, 67, 82, 2, 64, 1, + 7, 65, 64, 2, 77, 13, 11, 27, 19, 24, 18, 17, + 19, 43, 12, 13, 41, 28, 0, 106, 98, 99, 89, + 92, 86, 82, 84, 82, 85, 91, 70, 72, 73, 2, + 101, 98, 95, 74, 72, 73, 70, 16, 67, 1, 65, + 24, 70, 5, 7, 1, 73, 60, 53, 37, 44, 53, 43, + 25, 44, 34, 28, 32, 18, 5, 1, 2, 24, 17, 23, + 20, 18, 16, 21, 13, 26, 19, 7, 10, 15, 89, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 58, 41, 62, 57, 38, 62, 62, 62, 62, 56, + 54, 58, 43, 37, 14, 23, 1, 69, 97, 70, 22, 14, + 10, 2, 5, 0, 71, 73, 89, 66, 37, 25, 20, 17, + 1, 67, 76, 76, 84, 90, 10, 5, 2, 64, 71, 75, + 79, 86, 107, 95, 81, 77, 72, 73, 84, 94, 95, + 114, 77, 31, 16, 11, 2, 69, 77, 84, 88, 95, + 62, 92, 83, 78, 66, 70, 1, 4, 5, 74, 2, 6, 64, + 78, 71, 68, 18, 2, 26, 22, 34, 33, 19, 25, 29, + 21, 15, 0, 15, 65, 102, 95, 94, 87, 84, 84, + 83, 86, 66, 76, 75, 75, 4, 75, 82, 98, 93, 95, + 76, 73, 70, 73, 68, 65, 71, 1, 1, 67, 73, 7, + 64, 71, 56, 44, 47, 48, 48, 51, 47, 46, 39, + 39, 42, 36, 18, 21, 14, 43, 40, 38, 33, 32, + 26, 12, 5, 0, 76, 81, 93, 70, 107, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 59, 57, 46, 26, 4, + 62, 60, 31, 62, 62, 62, 56, 60, 54, 48, 54, + 47, 48, 31, 33, 21, 68, 39, 29, 10, 117, 109, + 111, 83, 90, 87, 67, 79, 78, 68, 68, 10, 65, + 16, 72, 62, 62, 62, 62, 55, 52, 24, 5, 84, 74, + 41, 29, 20, 9, 9, 2, 64, 68, 90, 104, 95, 88, + 88, 85, 71, 77, 84, 71, 68, 67, 65, 1, 6, 4, + 62, 62, 62, 61, 57, 51, 39, 24, 68 }, + + { + + 62, + 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 26, 57, + 60, 54, 14, 111, 6, 75, 1, 1, 12, 72, 10, 67, + 19, 58, 71, 93, 105, 118, 100, 67, 75, 1, 1, + 84, 91, 4, 17, 68, 79, 93, 7, 68, 85, 88, 5, + 75, 92, 9, 69, 80, 88, 65, 73, 73, 79, 70, 5, + 22, 0, 0, 0, 81, 86, 97, 70, 20, 1, 52, 8, 69, + 123, 99, 82, 72, 103, 121, 121, 122, 91, 121, + 110, 121, 119, 112, 119, 112, 3, 67, 81, 101, + 69, 91, 88, 121, 73, 95, 89, 123, 8, 81, 74, + 120, 91, 84, 76, 70, 1, 67, 81, 3, 0, 1, 7, + 65, 64, 2, 77, 13, 10, 27, 19, 23, 18, 17, 19, + 41, 12, 12, 39, 27, 64, 105, 97, 98, 88, 91, + 86, 81, 84, 81, 84, 90, 70, 72, 73, 1, 100, + 97, 95, 74, 72, 72, 70, 15, 66, 1, 65, 23, 69, + 5, 6, 1, 74, 59, 52, 37, 43, 52, 42, 25, 43, + 33, 27, 31, 18, 5, 1, 1, 23, 16, 22, 19, 17, + 15, 20, 13, 24, 18, 7, 9, 14, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 55, + 39, 62, 55, 37, 62, 61, 62, 59, 54, 51, 56, + 41, 34, 13, 21, 0, 70, 97, 70, 23, 14, 10, 2, + 5, 0, 71, 73, 89, 66, 37, 25, 20, 17, 2, 66, + 76, 75, 84, 89, 11, 5, 3, 64, 70, 74, 78, 86, + 106, 94, 80, 76, 71, 73, 83, 93, 94, 113, 76, + 31, 16, 11, 2, 68, 77, 83, 87, 94, 62, 91, 82, + 77, 66, 70, 1, 4, 5, 74, 2, 6, 64, 78, 71, 68, + 18, 3, 25, 21, 33, 32, 19, 24, 28, 21, 15, 0, + 14, 65, 101, 94, 93, 86, 83, 83, 83, 85, 66, + 76, 75, 74, 4, 75, 82, 97, 92, 95, 76, 73, 70, + 72, 68, 65, 70, 1, 1, 67, 72, 6, 64, 72, 55, + 43, 46, 47, 47, 50, 46, 45, 38, 38, 41, 35, + 17, 20, 13, 42, 39, 37, 31, 30, 25, 11, 5, 64, + 76, 81, 93, 70, 106, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 57, 54, 44, 24, 3, 61, 59, 29, + 62, 62, 60, 54, 58, 52, 46, 52, 45, 45, 29, + 31, 19, 69, 37, 27, 9, 116, 108, 110, 82, 89, + 86, 66, 78, 77, 68, 67, 12, 0, 18, 71, 62, 62, + 62, 62, 52, 49, 21, 3, 85, 74, 41, 29, 20, 9, + 9, 2, 64, 68, 90, 103, 94, 87, 87, 84, 71, 77, + 83, 71, 68, 67, 65, 1, 6, 4, 62, 62, 62, 59, + 55, 49, 37, 22, 69 }, + + { + + 62, + 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 25, 56, + 58, 54, 14, 108, 5, 74, 1, 1, 11, 72, 9, 68, + 18, 56, 73, 94, 106, 115, 99, 67, 74, 1, 1, + 84, 90, 4, 16, 68, 79, 93, 7, 68, 84, 88, 5, + 75, 91, 8, 70, 80, 88, 65, 72, 73, 78, 70, 5, + 22, 0, 0, 0, 80, 87, 97, 70, 19, 1, 52, 8, 69, + 122, 98, 82, 72, 101, 120, 119, 121, 90, 120, + 108, 119, 118, 112, 118, 112, 3, 67, 80, 100, + 69, 91, 87, 119, 73, 95, 89, 122, 8, 80, 74, + 119, 91, 84, 76, 69, 1, 67, 81, 3, 0, 0, 6, + 65, 64, 2, 77, 13, 10, 26, 19, 23, 18, 17, 18, + 39, 12, 12, 37, 26, 65, 104, 96, 97, 87, 91, + 85, 80, 83, 81, 83, 89, 70, 72, 72, 0, 100, + 96, 95, 74, 72, 72, 70, 14, 65, 1, 65, 21, 68, + 4, 5, 1, 75, 57, 51, 36, 42, 51, 41, 24, 42, + 33, 25, 30, 17, 5, 1, 1, 22, 16, 21, 19, 16, + 14, 19, 12, 22, 17, 6, 8, 13, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 53, + 36, 62, 54, 35, 62, 59, 62, 57, 51, 49, 53, + 39, 32, 12, 20, 65, 71, 97, 70, 23, 15, 10, 2, + 5, 0, 71, 73, 88, 65, 38, 25, 20, 17, 3, 66, + 75, 75, 83, 89, 12, 6, 3, 64, 70, 74, 78, 85, + 105, 94, 79, 76, 71, 73, 82, 92, 94, 112, 76, + 32, 16, 11, 2, 67, 76, 83, 86, 93, 62, 91, 82, + 77, 66, 70, 1, 4, 5, 73, 2, 6, 0, 78, 71, 68, + 17, 3, 24, 20, 32, 31, 19, 22, 27, 20, 15, 64, + 13, 66, 101, 94, 92, 86, 83, 83, 82, 84, 67, + 76, 75, 74, 3, 75, 82, 97, 91, 95, 76, 72, 70, + 72, 68, 65, 69, 1, 0, 67, 71, 6, 65, 73, 54, + 43, 46, 46, 46, 49, 45, 44, 37, 37, 40, 34, + 16, 19, 12, 40, 37, 35, 29, 29, 24, 10, 4, 64, + 76, 81, 93, 71, 106, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 60, 55, 52, 42, 23, 2, 59, 57, 28, + 62, 62, 58, 52, 55, 50, 44, 50, 43, 43, 27, + 29, 17, 70, 35, 25, 7, 115, 107, 109, 82, 88, + 85, 64, 77, 76, 68, 66, 13, 1, 19, 71, 62, 62, + 62, 62, 49, 46, 18, 1, 86, 74, 41, 29, 20, 9, + 9, 2, 64, 68, 89, 102, 93, 86, 87, 83, 70, 76, + 82, 70, 67, 66, 64, 2, 7, 4, 62, 62, 62, 57, + 53, 47, 35, 20, 70 }, + + { + + 62, + 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 23, 54, + 57, 54, 14, 106, 5, 73, 2, 1, 11, 71, 8, 69, + 18, 54, 75, 95, 106, 112, 97, 67, 73, 2, 1, + 84, 89, 4, 16, 68, 79, 92, 7, 69, 84, 88, 5, + 75, 90, 8, 70, 80, 88, 64, 72, 72, 78, 69, 5, + 22, 0, 0, 0, 80, 87, 97, 69, 18, 1, 52, 8, 69, + 121, 97, 82, 71, 100, 118, 117, 119, 89, 118, + 107, 117, 117, 111, 117, 111, 4, 67, 79, 99, + 69, 90, 86, 117, 73, 95, 88, 120, 9, 80, 73, + 118, 90, 83, 76, 69, 2, 66, 80, 4, 1, 0, 6, + 65, 64, 2, 77, 13, 9, 25, 19, 22, 18, 17, 18, + 37, 12, 11, 36, 25, 66, 103, 95, 96, 86, 90, + 84, 79, 82, 80, 82, 88, 70, 72, 72, 64, 99, + 95, 95, 73, 72, 71, 70, 13, 64, 1, 65, 20, 67, + 4, 4, 1, 75, 56, 50, 36, 41, 50, 40, 23, 42, + 33, 24, 29, 17, 5, 1, 0, 22, 15, 20, 18, 15, + 13, 19, 11, 20, 16, 5, 7, 12, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 51, + 34, 60, 52, 33, 62, 57, 60, 55, 49, 47, 50, + 37, 29, 11, 18, 66, 71, 97, 70, 23, 15, 10, 2, + 5, 0, 71, 73, 88, 65, 38, 25, 20, 17, 4, 65, + 74, 75, 82, 88, 13, 7, 3, 0, 69, 73, 77, 85, + 104, 93, 77, 75, 71, 72, 81, 91, 93, 111, 75, + 32, 17, 11, 2, 66, 75, 82, 85, 92, 62, 91, 82, + 76, 66, 70, 1, 4, 5, 73, 2, 7, 0, 78, 71, 68, + 16, 4, 23, 19, 31, 31, 19, 21, 26, 20, 15, 65, + 12, 66, 100, 93, 91, 85, 82, 82, 82, 83, 67, + 76, 75, 74, 2, 75, 82, 96, 90, 95, 76, 72, 70, + 71, 68, 65, 68, 1, 0, 67, 70, 5, 65, 73, 53, + 43, 45, 46, 45, 48, 44, 43, 37, 36, 39, 33, + 15, 18, 11, 39, 36, 34, 27, 28, 23, 9, 3, 65, + 76, 80, 93, 71, 105, 62, 62, 62, 62, 62, 62, + 62, 62, 60, 58, 53, 50, 40, 21, 1, 57, 55, 27, + 61, 62, 56, 50, 53, 48, 42, 48, 41, 40, 25, + 27, 15, 71, 33, 23, 6, 114, 105, 108, 81, 87, + 84, 1, 76, 75, 68, 65, 15, 3, 21, 70, 62, 62, + 62, 62, 47, 43, 16, 64, 87, 74, 41, 29, 20, 9, + 9, 2, 64, 68, 89, 101, 92, 85, 86, 82, 69, 76, + 81, 69, 66, 65, 64, 2, 7, 4, 62, 62, 62, 56, + 51, 45, 33, 18, 71 }, + + { + + 62, + 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 22, 53, + 56, 54, 14, 104, 5, 73, 3, 1, 10, 71, 7, 70, + 17, 53, 76, 96, 107, 109, 96, 67, 73, 3, 1, + 83, 88, 5, 15, 67, 78, 91, 6, 69, 84, 88, 5, + 74, 90, 8, 70, 79, 88, 64, 72, 72, 78, 69, 5, + 22, 0, 0, 0, 79, 87, 97, 69, 18, 0, 52, 8, 69, + 120, 97, 82, 71, 99, 116, 115, 118, 88, 116, + 106, 115, 116, 110, 116, 110, 5, 67, 78, 99, + 68, 90, 86, 115, 73, 94, 88, 119, 9, 80, 73, + 116, 90, 82, 75, 69, 2, 66, 79, 4, 1, 64, 6, + 65, 64, 2, 77, 13, 9, 25, 19, 21, 18, 17, 18, + 35, 12, 11, 34, 24, 67, 103, 94, 96, 86, 89, + 84, 78, 82, 80, 82, 86, 70, 72, 72, 65, 99, + 94, 95, 73, 72, 70, 69, 12, 64, 1, 65, 19, 66, + 3, 3, 1, 76, 54, 49, 35, 41, 49, 40, 23, 41, + 32, 23, 28, 17, 5, 1, 0, 21, 14, 19, 17, 15, + 12, 18, 11, 18, 15, 5, 6, 11, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 54, 48, + 31, 58, 50, 32, 62, 54, 57, 52, 47, 44, 48, + 34, 27, 10, 16, 67, 72, 97, 69, 24, 15, 11, 2, + 5, 0, 71, 73, 87, 65, 38, 26, 20, 17, 5, 65, + 74, 74, 82, 87, 14, 7, 4, 0, 68, 73, 77, 84, + 103, 92, 76, 74, 70, 72, 81, 91, 92, 109, 75, + 32, 17, 11, 3, 66, 75, 81, 85, 91, 62, 90, 81, + 76, 66, 70, 1, 4, 5, 73, 3, 7, 1, 78, 71, 69, + 16, 4, 22, 18, 30, 30, 19, 20, 25, 20, 15, 65, + 11, 67, 99, 92, 90, 85, 82, 82, 81, 83, 67, + 75, 74, 73, 2, 75, 82, 96, 89, 95, 76, 72, 70, + 70, 68, 65, 67, 0, 0, 67, 70, 4, 65, 74, 52, + 42, 45, 45, 44, 48, 44, 42, 36, 36, 38, 32, + 14, 17, 10, 37, 35, 32, 25, 26, 21, 8, 3, 65, + 76, 80, 92, 72, 104, 62, 62, 62, 62, 62, 62, + 62, 62, 58, 55, 51, 47, 38, 20, 1, 56, 54, 25, + 59, 62, 54, 48, 51, 46, 40, 45, 39, 38, 23, + 25, 14, 73, 31, 21, 4, 113, 104, 107, 80, 86, + 83, 2, 75, 74, 68, 64, 16, 4, 22, 69, 62, 62, + 62, 59, 44, 41, 13, 66, 89, 73, 41, 29, 20, 9, + 9, 2, 64, 68, 88, 100, 92, 84, 85, 81, 69, 75, + 80, 69, 66, 65, 64, 3, 7, 4, 62, 62, 61, 54, + 50, 44, 30, 17, 72 }, + + { + + 62, + 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 20, 51, + 54, 54, 14, 101, 4, 72, 3, 1, 9, 71, 6, 71, + 17, 51, 78, 97, 107, 106, 95, 67, 72, 3, 1, + 83, 87, 5, 15, 67, 78, 91, 6, 70, 83, 88, 5, + 74, 89, 7, 70, 79, 88, 0, 71, 72, 77, 68, 5, + 22, 0, 0, 0, 79, 87, 97, 68, 17, 0, 52, 8, 69, + 119, 96, 82, 70, 97, 115, 113, 116, 87, 115, + 104, 113, 115, 109, 115, 110, 6, 67, 77, 98, + 68, 89, 85, 113, 73, 94, 87, 118, 9, 79, 72, + 115, 89, 82, 75, 68, 2, 66, 78, 5, 2, 64, 5, + 65, 64, 2, 77, 13, 8, 24, 19, 21, 18, 17, 17, + 33, 12, 10, 32, 23, 68, 102, 93, 95, 85, 88, + 83, 77, 81, 79, 81, 85, 70, 72, 71, 66, 98, + 93, 95, 73, 72, 70, 69, 11, 0, 1, 65, 17, 65, + 3, 2, 1, 77, 53, 48, 35, 40, 48, 39, 22, 40, + 32, 22, 27, 17, 5, 1, 64, 20, 14, 18, 17, 14, + 11, 17, 10, 16, 14, 4, 5, 10, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 60, 61, 52, 46, + 29, 56, 49, 30, 62, 52, 55, 50, 44, 42, 45, + 32, 24, 9, 15, 69, 73, 97, 69, 24, 16, 11, 2, + 5, 0, 71, 73, 87, 64, 39, 26, 20, 17, 6, 64, + 73, 74, 81, 86, 15, 8, 4, 0, 67, 72, 76, 84, + 102, 92, 75, 74, 70, 72, 80, 90, 92, 108, 74, + 33, 17, 11, 3, 65, 74, 80, 84, 90, 62, 90, 81, + 75, 66, 70, 1, 4, 5, 72, 3, 7, 1, 78, 71, 69, + 15, 5, 21, 17, 29, 29, 19, 19, 24, 19, 15, 66, + 10, 67, 98, 92, 89, 84, 81, 81, 81, 82, 67, + 75, 74, 73, 1, 75, 82, 95, 88, 95, 76, 71, 70, + 70, 68, 65, 66, 0, 0, 67, 69, 4, 66, 75, 51, + 42, 44, 44, 43, 47, 43, 41, 35, 35, 37, 31, + 13, 16, 9, 36, 33, 31, 23, 25, 20, 7, 2, 66, + 76, 80, 92, 72, 103, 62, 62, 62, 62, 62, 62, + 62, 61, 56, 53, 49, 45, 36, 18, 0, 54, 52, 24, + 57, 62, 52, 46, 49, 44, 38, 43, 37, 35, 21, + 23, 12, 74, 29, 19, 3, 112, 103, 106, 80, 85, + 82, 4, 74, 73, 68, 0, 18, 6, 24, 69, 62, 62, + 61, 56, 41, 38, 10, 68, 90, 73, 41, 29, 20, 9, + 9, 2, 64, 68, 88, 99, 91, 83, 84, 80, 68, 75, + 79, 68, 65, 64, 0, 3, 8, 4, 62, 62, 59, 52, + 48, 42, 28, 15, 73 }, + + { + + 62, + 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 19, 50, + 53, 54, 14, 99, 4, 71, 4, 1, 8, 71, 5, 73, 16, + 49, 80, 98, 108, 104, 94, 67, 71, 4, 1, 83, + 86, 5, 14, 67, 78, 90, 5, 70, 83, 89, 5, 74, + 89, 7, 71, 79, 88, 0, 71, 72, 77, 68, 5, 22, + 0, 0, 0, 78, 88, 97, 68, 16, 0, 52, 8, 69, + 118, 95, 82, 70, 96, 113, 111, 115, 86, 113, + 103, 112, 114, 109, 114, 109, 6, 67, 76, 97, + 68, 89, 85, 112, 73, 94, 87, 117, 9, 79, 72, + 114, 89, 81, 75, 68, 2, 66, 78, 5, 2, 65, 5, + 65, 64, 2, 77, 13, 8, 23, 19, 20, 18, 17, 17, + 31, 12, 10, 30, 22, 69, 101, 92, 94, 84, 88, + 83, 76, 81, 79, 80, 84, 70, 72, 71, 68, 98, + 92, 95, 73, 73, 69, 69, 10, 1, 1, 65, 16, 64, + 2, 1, 1, 78, 51, 47, 34, 39, 47, 38, 21, 39, + 31, 20, 26, 16, 5, 1, 64, 19, 13, 17, 16, 13, + 10, 16, 9, 14, 12, 3, 4, 9, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 61, 58, 58, 49, 43, + 26, 54, 47, 28, 61, 50, 52, 47, 42, 39, 42, + 30, 22, 8, 13, 70, 74, 98, 69, 24, 16, 11, 2, + 5, 0, 71, 73, 86, 64, 39, 26, 20, 17, 7, 64, + 73, 74, 81, 86, 16, 8, 4, 0, 67, 72, 76, 83, + 101, 91, 74, 73, 70, 72, 79, 89, 91, 107, 74, + 33, 17, 11, 3, 64, 74, 80, 83, 90, 62, 90, 81, + 75, 66, 70, 1, 4, 5, 72, 3, 7, 2, 78, 71, 69, + 14, 5, 20, 16, 28, 28, 19, 17, 22, 19, 15, 67, + 9, 68, 98, 91, 88, 84, 81, 81, 80, 81, 68, 75, + 74, 73, 0, 75, 82, 95, 88, 96, 76, 71, 70, 69, + 68, 65, 66, 0, 64, 67, 68, 3, 66, 76, 50, 41, + 44, 43, 41, 46, 42, 40, 34, 34, 36, 30, 12, + 15, 8, 34, 32, 29, 21, 23, 19, 6, 1, 66, 76, + 80, 92, 73, 103, 62, 62, 62, 62, 62, 62, 61, + 58, 54, 51, 47, 42, 34, 17, 64, 52, 50, 22, + 55, 61, 49, 43, 46, 41, 36, 41, 34, 33, 19, + 20, 10, 75, 27, 17, 1, 111, 102, 105, 79, 84, + 82, 5, 73, 73, 68, 0, 19, 7, 25, 68, 62, 62, + 58, 53, 38, 35, 7, 70, 91, 73, 41, 29, 20, 9, + 9, 2, 64, 68, 87, 99, 90, 82, 84, 79, 68, 74, + 79, 68, 65, 64, 0, 4, 8, 3, 62, 62, 57, 50, + 46, 40, 26, 13, 74 }, + + { + + 62, + 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 18, 49, + 52, 54, 14, 97, 4, 70, 5, 1, 8, 70, 4, 74, 15, + 47, 81, 99, 109, 101, 92, 67, 70, 5, 1, 82, + 85, 6, 13, 67, 77, 89, 5, 70, 83, 89, 5, 74, + 88, 7, 71, 79, 88, 0, 71, 71, 77, 68, 5, 22, + 0, 0, 0, 77, 88, 97, 68, 15, 0, 52, 8, 69, + 117, 94, 82, 70, 95, 111, 109, 113, 84, 111, + 102, 110, 113, 108, 113, 108, 7, 66, 75, 96, + 68, 88, 84, 110, 73, 93, 87, 115, 10, 79, 72, + 112, 89, 80, 75, 68, 3, 65, 77, 5, 2, 65, 5, + 64, 64, 2, 76, 13, 8, 23, 19, 19, 18, 17, 17, + 29, 12, 10, 29, 21, 69, 100, 91, 93, 83, 87, + 82, 75, 80, 79, 79, 83, 70, 72, 71, 69, 97, + 91, 95, 72, 73, 68, 69, 9, 2, 1, 65, 15, 0, 1, + 0, 1, 78, 50, 46, 34, 38, 46, 37, 21, 39, 31, + 19, 25, 16, 5, 1, 64, 19, 12, 16, 15, 12, 9, + 16, 9, 13, 11, 3, 3, 8, 89, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 59, 56, 56, 46, 41, 23, + 53, 45, 27, 59, 48, 50, 45, 40, 37, 40, 28, + 20, 8, 11, 71, 74, 98, 69, 25, 16, 11, 3, 5, + 0, 70, 73, 85, 64, 39, 26, 21, 17, 8, 0, 72, + 73, 80, 85, 17, 9, 5, 1, 66, 71, 76, 82, 100, + 90, 72, 72, 69, 71, 78, 88, 90, 106, 73, 33, + 18, 12, 3, 0, 73, 79, 82, 89, 62, 89, 80, 74, + 66, 70, 1, 5, 6, 72, 3, 8, 3, 78, 71, 69, 14, + 5, 19, 16, 27, 28, 19, 16, 21, 19, 15, 67, 8, + 69, 97, 90, 87, 84, 80, 81, 79, 80, 68, 75, + 74, 72, 0, 75, 82, 95, 87, 96, 76, 71, 70, 68, + 68, 65, 65, 0, 64, 67, 67, 2, 66, 76, 49, 41, + 44, 43, 40, 45, 41, 39, 34, 33, 35, 30, 12, + 14, 7, 33, 31, 27, 19, 22, 18, 6, 1, 66, 75, + 79, 92, 74, 102, 62, 62, 62, 62, 62, 62, 59, + 56, 52, 49, 45, 40, 32, 16, 65, 50, 49, 21, + 53, 59, 47, 41, 44, 39, 34, 39, 32, 31, 18, + 18, 8, 76, 25, 15, 64, 110, 100, 103, 78, 83, + 81, 7, 72, 72, 68, 1, 21, 8, 27, 67, 62, 62, + 56, 50, 36, 32, 5, 72, 92, 73, 41, 29, 20, 9, + 10, 2, 64, 68, 86, 98, 89, 81, 83, 77, 67, 73, + 78, 67, 64, 0, 0, 5, 8, 3, 62, 61, 56, 49, 44, + 38, 24, 11, 74 }, + + { + + 62, + 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 16, 47, + 50, 54, 14, 94, 3, 69, 5, 1, 7, 70, 3, 75, 15, + 45, 83, 100, 109, 98, 91, 67, 69, 5, 1, 82, + 84, 6, 13, 67, 77, 89, 5, 71, 82, 89, 5, 74, + 87, 6, 71, 79, 88, 1, 70, 71, 76, 67, 5, 22, + 0, 0, 0, 77, 88, 97, 67, 14, 0, 52, 8, 69, + 116, 93, 82, 69, 93, 110, 107, 112, 83, 110, + 100, 108, 112, 107, 112, 108, 8, 66, 74, 95, + 68, 88, 83, 108, 73, 93, 86, 114, 10, 78, 71, + 111, 88, 80, 75, 67, 3, 65, 76, 6, 3, 66, 4, + 64, 64, 2, 76, 13, 7, 22, 19, 19, 18, 17, 16, + 27, 12, 9, 27, 20, 70, 99, 90, 92, 82, 86, 81, + 74, 79, 78, 78, 82, 70, 72, 70, 70, 97, 90, + 95, 72, 73, 68, 69, 8, 3, 1, 65, 13, 1, 1, 64, + 1, 79, 48, 45, 33, 37, 45, 36, 20, 38, 31, 18, + 24, 16, 5, 1, 65, 18, 12, 15, 15, 11, 8, 15, + 8, 11, 10, 2, 2, 7, 89, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 57, 54, 53, 44, 39, 21, 51, + 44, 25, 56, 46, 48, 43, 37, 35, 37, 26, 17, 7, + 10, 73, 75, 98, 69, 25, 17, 11, 3, 5, 0, 70, + 73, 85, 0, 40, 26, 21, 17, 9, 0, 71, 73, 79, + 84, 18, 10, 5, 1, 65, 71, 75, 82, 99, 90, 71, + 72, 69, 71, 77, 87, 90, 105, 73, 34, 18, 12, + 3, 1, 72, 78, 81, 88, 62, 89, 80, 74, 66, 70, + 1, 5, 6, 71, 3, 8, 3, 78, 71, 69, 13, 6, 18, + 15, 26, 27, 19, 15, 20, 18, 15, 68, 7, 69, 96, + 90, 86, 83, 80, 80, 79, 79, 68, 75, 74, 72, + 64, 75, 82, 94, 86, 96, 76, 70, 70, 68, 68, + 65, 64, 0, 64, 67, 66, 2, 67, 77, 48, 41, 43, + 42, 39, 44, 40, 38, 33, 32, 34, 29, 11, 13, 6, + 31, 29, 26, 17, 21, 17, 5, 0, 67, 75, 79, 92, + 74, 101, 62, 62, 62, 62, 62, 60, 57, 53, 50, + 47, 43, 38, 30, 14, 66, 48, 47, 20, 51, 57, + 45, 39, 42, 37, 32, 37, 30, 28, 16, 16, 6, 77, + 23, 13, 65, 109, 99, 102, 78, 82, 80, 9, 71, + 71, 68, 2, 22, 10, 28, 67, 62, 60, 53, 47, 33, + 29, 2, 74, 93, 73, 41, 29, 20, 9, 10, 2, 64, + 68, 86, 97, 88, 80, 82, 76, 66, 73, 77, 66, 0, + 1, 1, 5, 9, 3, 60, 59, 54, 47, 42, 36, 22, 9, + 75 }, + + { + + 62, + 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 15, 46, + 49, 54, 14, 92, 3, 69, 6, 1, 6, 70, 2, 76, 14, + 44, 84, 101, 110, 95, 90, 67, 69, 6, 1, 81, + 83, 7, 12, 66, 76, 88, 4, 71, 82, 89, 5, 73, + 87, 6, 71, 78, 88, 1, 70, 71, 76, 67, 5, 22, + 0, 0, 0, 76, 88, 97, 67, 14, 64, 52, 8, 69, + 115, 93, 82, 69, 92, 108, 105, 110, 82, 108, + 99, 106, 111, 106, 111, 107, 9, 66, 73, 95, + 67, 87, 83, 106, 73, 92, 86, 113, 10, 78, 71, + 109, 88, 79, 74, 67, 3, 65, 75, 6, 3, 66, 4, + 64, 64, 2, 76, 13, 7, 22, 19, 18, 18, 17, 16, + 25, 12, 9, 25, 19, 71, 99, 89, 92, 82, 85, 81, + 73, 79, 78, 78, 80, 70, 72, 70, 71, 96, 89, + 95, 72, 73, 67, 68, 7, 3, 1, 65, 12, 2, 0, 65, + 1, 80, 47, 44, 33, 37, 44, 36, 20, 37, 30, 17, + 23, 16, 5, 1, 65, 17, 11, 14, 14, 11, 7, 14, + 8, 9, 9, 2, 1, 6, 89, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 54, 52, 51, 41, 36, 18, 49, 42, + 24, 54, 43, 45, 40, 35, 32, 35, 23, 15, 6, 8, + 74, 76, 98, 68, 26, 17, 12, 3, 5, 0, 70, 73, + 84, 0, 40, 27, 21, 17, 10, 1, 71, 72, 79, 83, + 19, 10, 6, 1, 64, 70, 75, 81, 98, 89, 70, 71, + 68, 71, 77, 87, 89, 103, 72, 34, 18, 12, 4, 1, + 72, 77, 81, 87, 62, 88, 79, 73, 66, 70, 1, 5, + 6, 71, 4, 8, 4, 78, 71, 70, 13, 6, 17, 14, 25, + 26, 19, 14, 19, 18, 15, 68, 6, 70, 95, 89, 85, + 83, 79, 80, 78, 79, 68, 74, 73, 71, 64, 75, + 82, 94, 85, 96, 76, 70, 70, 67, 68, 65, 0, 64, + 64, 67, 66, 1, 67, 78, 47, 40, 43, 41, 38, 44, + 40, 37, 32, 32, 33, 28, 10, 12, 5, 30, 28, 24, + 15, 19, 15, 4, 0, 67, 75, 79, 91, 75, 100, 62, + 62, 62, 62, 62, 58, 55, 51, 48, 44, 41, 35, + 28, 13, 66, 47, 46, 18, 49, 54, 43, 37, 40, + 35, 30, 34, 28, 26, 14, 14, 5, 79, 21, 11, 67, + 108, 98, 101, 77, 81, 79, 10, 70, 70, 68, 3, + 24, 11, 30, 66, 61, 59, 51, 44, 30, 27, 64, + 76, 95, 72, 41, 29, 20, 9, 10, 2, 64, 68, 85, + 96, 88, 79, 81, 75, 66, 72, 76, 66, 0, 1, 1, + 6, 9, 3, 59, 58, 52, 45, 41, 35, 19, 8, 76 }, + + { + + 62, + 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 13, 44, + 48, 54, 14, 90, 3, 68, 7, 1, 5, 70, 1, 77, 14, + 42, 86, 102, 110, 92, 89, 67, 68, 7, 1, 81, + 82, 7, 12, 66, 76, 87, 4, 72, 82, 89, 5, 73, + 86, 6, 72, 78, 88, 2, 70, 71, 76, 66, 5, 22, + 0, 0, 0, 76, 89, 97, 66, 13, 64, 52, 8, 69, + 114, 92, 82, 68, 91, 106, 103, 109, 81, 106, + 98, 104, 110, 106, 110, 106, 9, 66, 72, 94, + 67, 87, 82, 104, 73, 92, 85, 112, 10, 78, 70, + 108, 87, 78, 74, 67, 3, 65, 75, 7, 4, 67, 4, + 64, 64, 2, 76, 13, 6, 21, 19, 17, 18, 17, 16, + 23, 12, 8, 23, 18, 72, 98, 88, 91, 81, 85, 80, + 72, 78, 77, 77, 79, 70, 72, 70, 72, 96, 88, + 95, 72, 73, 66, 68, 6, 4, 1, 65, 11, 3, 0, 66, + 1, 81, 45, 43, 32, 36, 43, 35, 19, 36, 30, 15, + 22, 15, 5, 1, 66, 16, 10, 13, 13, 10, 6, 13, + 7, 7, 8, 1, 0, 5, 89, 62, 62, 61, 62, 62, 62, + 62, 62, 61, 52, 50, 48, 39, 34, 16, 47, 40, + 22, 52, 41, 43, 38, 33, 30, 32, 21, 12, 5, 6, + 75, 77, 98, 68, 26, 17, 12, 3, 5, 0, 70, 73, + 84, 0, 40, 27, 21, 17, 11, 1, 70, 72, 78, 83, + 20, 11, 6, 1, 64, 70, 74, 81, 97, 88, 69, 70, + 68, 71, 76, 86, 88, 102, 72, 34, 18, 12, 4, 2, + 71, 77, 80, 86, 62, 88, 79, 73, 66, 70, 1, 5, + 6, 71, 4, 8, 4, 78, 71, 70, 12, 7, 16, 13, 24, + 25, 19, 12, 18, 18, 15, 69, 5, 70, 95, 88, 84, + 82, 79, 79, 78, 78, 69, 74, 73, 71, 65, 75, + 82, 93, 84, 96, 76, 70, 70, 66, 68, 65, 1, 64, + 65, 67, 65, 0, 67, 79, 46, 40, 42, 40, 37, 43, + 39, 36, 31, 31, 32, 27, 9, 11, 4, 28, 27, 23, + 13, 18, 14, 3, 64, 68, 75, 79, 91, 75, 100, + 62, 62, 62, 62, 62, 56, 53, 48, 46, 42, 39, + 33, 26, 11, 67, 45, 44, 17, 47, 52, 41, 35, + 37, 33, 28, 32, 26, 23, 12, 12, 3, 80, 19, 9, + 68, 107, 97, 100, 76, 80, 78, 12, 69, 69, 68, + 4, 25, 13, 31, 65, 59, 57, 48, 41, 27, 24, 67, + 78, 96, 72, 41, 29, 20, 9, 10, 2, 64, 68, 85, + 95, 87, 78, 81, 74, 65, 72, 75, 65, 1, 2, 1, + 6, 9, 3, 58, 56, 50, 43, 39, 33, 17, 6, 77 }, + + { + + 62, + 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 12, 43, + 46, 54, 14, 87, 2, 67, 7, 1, 5, 69, 0, 78, 13, + 40, 88, 103, 111, 89, 87, 67, 67, 7, 1, 81, + 81, 7, 11, 66, 76, 87, 4, 72, 81, 89, 5, 73, + 85, 5, 72, 78, 88, 2, 69, 70, 75, 66, 5, 22, + 0, 0, 0, 75, 89, 97, 66, 12, 64, 52, 8, 69, + 113, 91, 82, 68, 89, 105, 101, 107, 80, 105, + 96, 102, 109, 105, 109, 106, 10, 66, 71, 93, + 67, 86, 81, 102, 73, 92, 85, 110, 11, 77, 70, + 107, 87, 78, 74, 66, 4, 64, 74, 7, 4, 67, 3, + 64, 64, 2, 76, 13, 6, 20, 19, 17, 18, 17, 15, + 21, 12, 8, 22, 17, 73, 97, 87, 90, 80, 84, 79, + 71, 77, 77, 76, 78, 70, 72, 69, 73, 95, 87, + 95, 71, 73, 66, 68, 5, 5, 1, 65, 9, 4, 64, 67, + 1, 81, 44, 42, 32, 35, 42, 34, 18, 36, 30, 14, + 21, 15, 5, 1, 66, 16, 10, 12, 13, 9, 5, 13, 6, + 5, 7, 0, 64, 4, 89, 61, 62, 59, 62, 61, 60, + 60, 60, 59, 50, 48, 46, 36, 32, 13, 45, 39, + 20, 49, 39, 41, 36, 30, 28, 29, 19, 10, 4, 5, + 77, 77, 98, 68, 26, 18, 12, 3, 5, 0, 70, 73, + 83, 1, 41, 27, 21, 17, 12, 2, 69, 72, 77, 82, + 21, 12, 6, 2, 0, 69, 74, 80, 96, 88, 67, 70, + 68, 70, 75, 85, 88, 101, 71, 35, 19, 12, 4, 3, + 70, 76, 79, 85, 62, 88, 79, 72, 66, 70, 1, 5, + 6, 70, 4, 9, 5, 78, 71, 70, 11, 7, 15, 12, 23, + 25, 19, 11, 17, 17, 15, 70, 4, 71, 94, 88, 83, + 82, 78, 79, 77, 77, 69, 74, 73, 71, 66, 75, + 82, 93, 83, 96, 76, 69, 70, 66, 68, 65, 2, 64, + 65, 67, 64, 0, 68, 79, 45, 40, 42, 40, 36, 42, + 38, 35, 31, 30, 31, 26, 8, 10, 3, 27, 25, 21, + 11, 17, 13, 2, 65, 68, 75, 78, 91, 76, 99, 62, + 62, 62, 62, 60, 54, 51, 46, 44, 40, 37, 31, + 24, 10, 68, 43, 42, 16, 45, 50, 39, 33, 35, + 31, 26, 30, 24, 21, 10, 10, 1, 81, 17, 7, 70, + 106, 95, 99, 76, 79, 77, 14, 68, 68, 68, 5, + 27, 14, 33, 65, 58, 55, 46, 38, 25, 21, 69, + 80, 97, 72, 41, 29, 20, 9, 10, 2, 64, 68, 84, + 94, 86, 77, 80, 73, 64, 71, 74, 64, 2, 3, 2, + 7, 10, 3, 56, 55, 49, 42, 37, 31, 15, 4, 78 }, + + { + + 61, + 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 10, 41, + 45, 54, 14, 85, 2, 66, 8, 1, 4, 69, 64, 79, + 13, 38, 89, 104, 111, 86, 86, 67, 66, 8, 1, + 80, 80, 8, 11, 66, 75, 86, 3, 73, 81, 89, 5, + 73, 85, 5, 72, 78, 88, 3, 69, 70, 75, 65, 5, + 22, 0, 0, 0, 75, 89, 97, 65, 11, 64, 52, 8, + 69, 112, 90, 82, 67, 88, 103, 99, 106, 79, + 103, 95, 100, 108, 104, 108, 105, 11, 66, 70, + 92, 67, 86, 81, 100, 73, 91, 84, 109, 11, 77, + 69, 105, 86, 77, 74, 66, 4, 64, 73, 8, 5, 68, + 3, 64, 64, 2, 76, 13, 5, 20, 19, 16, 18, 17, + 15, 19, 12, 7, 20, 16, 74, 96, 86, 89, 79, 83, + 79, 70, 77, 76, 75, 77, 70, 72, 69, 74, 95, + 86, 95, 71, 73, 65, 68, 4, 6, 1, 65, 8, 5, 64, + 68, 1, 82, 42, 41, 31, 34, 41, 33, 18, 35, 29, + 13, 20, 15, 5, 1, 67, 15, 9, 11, 12, 8, 4, 12, + 6, 3, 6, 0, 65, 3, 89, 60, 61, 58, 62, 59, 58, + 58, 58, 56, 47, 46, 43, 34, 29, 11, 43, 37, + 19, 47, 37, 38, 33, 28, 25, 27, 17, 7, 3, 3, + 78, 78, 98, 68, 27, 18, 12, 3, 5, 0, 70, 73, + 83, 1, 41, 27, 21, 17, 13, 2, 69, 71, 77, 81, + 22, 12, 7, 2, 1, 69, 73, 80, 95, 87, 66, 69, + 67, 70, 74, 84, 87, 100, 71, 35, 19, 12, 4, 4, + 70, 75, 78, 84, 62, 87, 78, 72, 66, 70, 1, 5, + 6, 70, 4, 9, 5, 78, 71, 70, 11, 8, 14, 11, 22, + 24, 19, 10, 16, 17, 15, 70, 3, 71, 93, 87, 82, + 81, 78, 78, 77, 76, 69, 74, 73, 70, 66, 75, + 82, 92, 82, 96, 76, 69, 70, 65, 68, 65, 3, 64, + 65, 67, 0, 64, 68, 80, 44, 39, 41, 39, 35, 41, + 37, 34, 30, 29, 30, 25, 7, 9, 2, 25, 24, 20, + 9, 15, 12, 1, 65, 69, 75, 78, 91, 76, 98, 62, + 62, 61, 61, 57, 52, 49, 43, 42, 38, 35, 28, + 22, 8, 69, 41, 41, 14, 43, 48, 37, 31, 33, 29, + 24, 28, 22, 18, 8, 8, 64, 82, 15, 5, 71, 105, + 94, 98, 75, 78, 76, 15, 67, 67, 68, 6, 28, 16, + 34, 64, 56, 54, 43, 35, 22, 18, 72, 82, 98, + 72, 41, 29, 20, 9, 10, 2, 64, 68, 84, 93, 85, + 76, 79, 72, 64, 71, 73, 64, 2, 3, 2, 7, 10, 3, + 55, 53, 47, 40, 35, 29, 13, 2, 79 }, + + { + + 60, + 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 9, 40, + 44, 54, 14, 83, 2, 65, 9, 1, 3, 69, 65, 80, + 12, 36, 91, 105, 112, 83, 85, 67, 65, 9, 1, + 80, 79, 8, 10, 66, 75, 85, 3, 73, 81, 89, 5, + 73, 84, 5, 72, 78, 88, 3, 69, 70, 75, 65, 5, + 22, 0, 0, 0, 74, 89, 97, 65, 10, 64, 52, 8, + 69, 111, 89, 82, 67, 87, 101, 97, 104, 78, + 101, 94, 98, 107, 103, 107, 104, 12, 66, 69, + 91, 67, 85, 80, 98, 73, 91, 84, 108, 11, 77, + 69, 104, 86, 76, 74, 66, 4, 64, 72, 8, 5, 68, + 3, 64, 64, 2, 76, 13, 5, 19, 19, 15, 18, 17, + 15, 17, 12, 7, 18, 15, 75, 95, 85, 88, 78, 82, + 78, 69, 76, 76, 74, 76, 70, 72, 69, 75, 94, + 85, 95, 71, 73, 64, 68, 3, 7, 1, 65, 7, 6, 65, + 69, 1, 83, 41, 40, 31, 33, 40, 32, 17, 34, 29, + 12, 19, 15, 5, 1, 67, 14, 8, 10, 11, 7, 3, 11, + 5, 1, 5, 64, 66, 2, 89, 58, 60, 56, 60, 57, + 56, 56, 56, 54, 45, 44, 41, 31, 27, 8, 41, 35, + 17, 45, 35, 36, 31, 26, 23, 24, 15, 5, 2, 1, + 79, 79, 98, 68, 27, 18, 12, 3, 5, 0, 70, 73, + 82, 1, 41, 27, 21, 17, 14, 3, 68, 71, 76, 80, + 23, 13, 7, 2, 2, 68, 73, 79, 94, 86, 65, 68, + 67, 70, 73, 83, 86, 99, 70, 35, 19, 12, 4, 5, + 69, 74, 77, 83, 62, 87, 78, 71, 66, 70, 1, 5, + 6, 70, 4, 9, 6, 78, 71, 70, 10, 8, 13, 10, 21, + 23, 19, 9, 15, 17, 15, 71, 2, 72, 92, 86, 81, + 81, 77, 78, 76, 75, 69, 74, 73, 70, 67, 75, + 82, 92, 81, 96, 76, 69, 70, 64, 68, 65, 4, 64, + 65, 67, 1, 65, 68, 81, 43, 39, 41, 38, 34, 40, + 36, 33, 29, 28, 29, 24, 6, 8, 1, 24, 23, 18, + 7, 14, 11, 0, 66, 69, 75, 78, 91, 77, 97, 62, + 62, 59, 59, 54, 50, 47, 41, 40, 36, 33, 26, + 20, 7, 70, 39, 39, 13, 41, 46, 35, 29, 31, 27, + 22, 26, 20, 16, 6, 6, 66, 83, 13, 3, 73, 104, + 93, 97, 74, 77, 75, 17, 66, 66, 68, 7, 30, 17, + 36, 0, 55, 52, 41, 32, 19, 15, 75, 84, 99, 72, + 41, 29, 20, 9, 10, 2, 64, 68, 83, 92, 84, 75, + 78, 71, 0, 70, 72, 0, 3, 4, 2, 8, 10, 3, 54, + 52, 45, 38, 33, 27, 11, 0, 80 }, + + { + + 58, + 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 7, 38, + 42, 53, 14, 81, 1, 65, 9, 0, 2, 69, 67, 82, + 11, 34, 93, 106, 113, 81, 84, 68, 65, 9, 0, + 80, 78, 8, 9, 66, 75, 85, 2, 74, 81, 90, 5, + 73, 84, 4, 73, 78, 88, 3, 69, 70, 75, 65, 4, + 22, 0, 0, 0, 74, 90, 97, 65, 9, 65, 52, 7, 69, + 110, 89, 82, 67, 86, 100, 96, 103, 77, 100, + 93, 97, 106, 103, 106, 104, 12, 66, 69, 91, + 67, 85, 80, 97, 73, 91, 84, 107, 11, 77, 69, + 103, 86, 76, 74, 66, 4, 64, 72, 8, 5, 69, 2, + 64, 65, 2, 76, 12, 4, 18, 19, 14, 17, 17, 14, + 15, 11, 6, 16, 14, 76, 95, 85, 88, 78, 82, 78, + 68, 76, 76, 74, 75, 71, 72, 69, 77, 94, 85, + 95, 71, 74, 64, 68, 2, 7, 1, 65, 5, 6, 66, 70, + 1, 84, 39, 39, 30, 32, 39, 31, 16, 33, 28, 10, + 18, 14, 4, 1, 68, 13, 7, 9, 10, 6, 2, 10, 4, + 64, 3, 65, 68, 0, 89, 56, 58, 54, 58, 55, 53, + 53, 53, 51, 42, 41, 38, 28, 24, 5, 39, 33, 15, + 42, 32, 33, 28, 23, 20, 21, 12, 2, 1, 64, 81, + 80, 99, 68, 27, 18, 12, 3, 5, 64, 70, 73, 82, + 1, 41, 27, 21, 17, 15, 3, 68, 71, 76, 80, 23, + 13, 7, 2, 2, 68, 73, 79, 93, 86, 64, 68, 67, + 70, 73, 83, 86, 98, 70, 35, 19, 12, 4, 5, 69, + 74, 77, 83, 62, 87, 78, 71, 66, 70, 1, 5, 6, + 70, 4, 9, 6, 78, 71, 71, 9, 8, 12, 9, 20, 22, + 18, 7, 13, 16, 14, 72, 0, 73, 92, 86, 80, 81, + 77, 78, 76, 75, 70, 74, 73, 70, 68, 75, 82, + 92, 81, 97, 76, 69, 70, 64, 69, 65, 4, 65, 66, + 67, 1, 66, 69, 82, 42, 38, 40, 37, 32, 39, 35, + 32, 28, 27, 28, 23, 5, 6, 64, 22, 21, 16, 5, + 12, 9, 64, 67, 70, 75, 78, 91, 78, 97, 62, 61, + 57, 56, 51, 47, 44, 38, 37, 33, 30, 23, 17, 5, + 71, 37, 37, 11, 39, 43, 32, 26, 28, 24, 20, + 23, 17, 13, 4, 3, 68, 85, 11, 1, 75, 103, 92, + 96, 74, 77, 75, 18, 66, 66, 68, 7, 31, 18, 37, + 0, 53, 50, 38, 28, 16, 12, 78, 87, 101, 72, + 41, 28, 19, 9, 10, 2, 65, 68, 83, 92, 84, 75, + 78, 70, 0, 70, 72, 0, 3, 4, 2, 8, 10, 2, 52, + 50, 43, 36, 31, 25, 8, 65, 81 }, + + { + + 57, + 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 6, 37, + 41, 53, 14, 78, 1, 64, 10, 0, 2, 68, 68, 83, + 11, 33, 94, 107, 113, 78, 82, 68, 64, 10, 0, + 79, 76, 9, 9, 65, 74, 84, 2, 74, 80, 90, 5, + 72, 83, 4, 73, 77, 88, 4, 68, 69, 74, 64, 4, + 22, 0, 0, 0, 73, 90, 97, 64, 9, 65, 52, 7, 69, + 108, 88, 82, 66, 84, 98, 94, 101, 75, 98, 91, + 95, 104, 102, 105, 103, 13, 65, 68, 90, 66, + 84, 79, 95, 72, 90, 83, 105, 12, 76, 68, 101, + 85, 75, 73, 65, 5, 0, 71, 9, 6, 69, 2, 0, 65, + 2, 75, 12, 4, 18, 19, 14, 17, 17, 14, 14, 11, + 6, 15, 13, 76, 94, 84, 87, 77, 81, 77, 67, 75, + 75, 73, 73, 71, 72, 68, 78, 93, 84, 95, 70, + 74, 0, 67, 2, 8, 1, 65, 4, 7, 66, 71, 1, 84, + 38, 39, 30, 32, 39, 31, 16, 33, 28, 9, 18, 14, + 4, 1, 68, 13, 7, 9, 10, 6, 1, 10, 4, 65, 2, + 65, 69, 64, 89, 55, 57, 53, 57, 54, 51, 51, + 51, 49, 40, 39, 36, 26, 22, 3, 38, 32, 14, 40, + 30, 31, 26, 21, 18, 19, 10, 0, 1, 65, 82, 80, + 99, 67, 28, 19, 13, 4, 5, 64, 69, 72, 81, 2, + 42, 28, 22, 17, 16, 4, 67, 70, 75, 79, 24, 14, + 8, 3, 3, 67, 72, 78, 91, 85, 1, 67, 66, 69, + 72, 82, 85, 96, 69, 36, 20, 13, 5, 6, 68, 73, + 76, 82, 62, 86, 77, 70, 66, 69, 1, 6, 7, 69, + 5, 10, 7, 77, 71, 71, 9, 9, 12, 9, 19, 22, 18, + 6, 12, 16, 14, 72, 64, 73, 91, 85, 79, 80, 76, + 77, 75, 74, 70, 73, 72, 69, 68, 74, 81, 91, + 80, 97, 76, 68, 70, 0, 69, 65, 5, 65, 66, 66, + 2, 66, 69, 82, 42, 38, 40, 37, 31, 39, 35, 32, + 28, 27, 28, 23, 5, 5, 65, 21, 20, 15, 4, 11, + 8, 64, 67, 70, 74, 77, 90, 78, 96, 60, 59, 55, + 54, 49, 45, 42, 36, 35, 31, 28, 21, 15, 4, 71, + 36, 36, 10, 38, 41, 30, 24, 26, 22, 18, 21, + 15, 11, 3, 1, 69, 86, 10, 0, 76, 101, 90, 94, + 73, 76, 74, 20, 65, 65, 68, 8, 33, 20, 39, 1, + 52, 49, 36, 25, 14, 10, 80, 89, 102, 71, 42, + 28, 19, 9, 11, 2, 65, 68, 82, 91, 83, 74, 77, + 68, 1, 69, 71, 1, 4, 5, 3, 9, 11, 2, 51, 49, + 42, 35, 30, 24, 6, 66, 81 }, + + { + + 56, + 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 5, 36, + 40, 53, 14, 76, 1, 0, 11, 0, 1, 68, 69, 84, + 10, 31, 96, 108, 114, 75, 81, 68, 0, 11, 0, + 79, 75, 9, 8, 65, 74, 83, 2, 74, 80, 90, 5, + 72, 82, 4, 73, 77, 88, 4, 68, 69, 74, 64, 4, + 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 52, 7, 69, + 107, 87, 82, 66, 83, 96, 92, 100, 74, 96, 90, + 93, 103, 101, 104, 102, 14, 65, 67, 89, 66, + 84, 78, 93, 72, 90, 83, 104, 12, 76, 68, 100, + 85, 74, 73, 65, 5, 0, 70, 9, 6, 70, 2, 0, 65, + 2, 75, 12, 4, 17, 19, 13, 17, 17, 14, 12, 11, + 6, 13, 12, 77, 93, 83, 86, 76, 80, 76, 66, 74, + 75, 72, 72, 71, 72, 68, 79, 93, 83, 95, 70, + 74, 1, 67, 1, 9, 1, 65, 3, 8, 67, 72, 1, 85, + 36, 38, 29, 31, 38, 30, 15, 32, 28, 8, 17, 14, + 4, 1, 68, 12, 6, 8, 9, 5, 0, 9, 3, 67, 1, 66, + 70, 65, 89, 53, 56, 51, 55, 52, 49, 49, 49, + 46, 38, 37, 33, 23, 20, 0, 36, 30, 12, 38, 28, + 29, 24, 19, 16, 16, 8, 65, 0, 67, 83, 81, 99, + 67, 28, 19, 13, 4, 5, 64, 69, 72, 80, 2, 42, + 28, 22, 17, 17, 4, 66, 70, 74, 78, 25, 15, 8, + 3, 4, 67, 72, 77, 90, 84, 2, 66, 66, 69, 71, + 81, 84, 95, 69, 36, 20, 13, 5, 7, 67, 72, 75, + 81, 62, 86, 77, 70, 66, 69, 1, 6, 7, 69, 5, + 10, 8, 77, 71, 71, 8, 9, 11, 8, 18, 21, 18, 5, + 11, 16, 14, 73, 65, 74, 90, 84, 78, 80, 76, + 77, 74, 73, 70, 73, 72, 69, 69, 74, 81, 91, + 79, 97, 76, 68, 70, 1, 69, 65, 6, 65, 66, 66, + 3, 67, 69, 83, 41, 38, 40, 36, 30, 38, 34, 31, + 27, 26, 27, 22, 4, 4, 66, 19, 19, 13, 2, 10, + 7, 65, 68, 70, 74, 77, 90, 79, 95, 58, 57, 53, + 52, 46, 43, 40, 33, 33, 29, 26, 19, 13, 3, 72, + 34, 34, 9, 36, 39, 28, 22, 24, 20, 16, 19, 13, + 9, 1, 64, 71, 87, 8, 65, 78, 100, 89, 93, 72, + 75, 73, 22, 64, 64, 68, 9, 34, 21, 40, 2, 51, + 47, 33, 22, 11, 7, 83, 91, 103, 71, 42, 28, + 19, 9, 11, 2, 65, 68, 81, 90, 82, 73, 76, 67, + 2, 68, 70, 2, 5, 6, 3, 10, 11, 2, 50, 47, 40, + 33, 28, 22, 4, 68, 82 }, + + { + + 55, + 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 3, 34, + 39, 53, 14, 74, 1, 1, 12, 0, 0, 68, 70, 85, + 10, 29, 97, 109, 114, 72, 80, 68, 1, 12, 0, + 78, 74, 10, 8, 65, 73, 82, 1, 75, 80, 90, 5, + 72, 82, 4, 73, 77, 88, 5, 68, 69, 74, 0, 4, + 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 52, 7, 69, + 106, 86, 82, 65, 82, 94, 90, 98, 73, 94, 89, + 91, 102, 100, 103, 101, 15, 65, 66, 88, 66, + 83, 78, 91, 72, 89, 82, 103, 12, 76, 67, 98, + 84, 73, 73, 65, 5, 0, 69, 10, 7, 70, 2, 0, 65, + 2, 75, 12, 3, 17, 19, 12, 17, 17, 14, 10, 11, + 5, 11, 11, 78, 92, 82, 85, 75, 79, 76, 65, 74, + 74, 71, 71, 71, 72, 68, 80, 92, 82, 95, 70, + 74, 2, 67, 0, 10, 1, 65, 2, 9, 67, 73, 1, 86, + 35, 37, 29, 30, 37, 29, 15, 31, 27, 7, 16, 14, + 4, 1, 69, 11, 5, 7, 8, 4, 64, 8, 3, 69, 0, 66, + 71, 66, 89, 52, 54, 50, 53, 50, 47, 47, 47, + 44, 35, 35, 31, 21, 17, 65, 34, 28, 11, 36, + 26, 26, 21, 17, 13, 14, 6, 68, 64, 69, 84, 82, + 99, 67, 29, 19, 13, 4, 5, 64, 69, 72, 80, 2, + 42, 28, 22, 17, 18, 5, 66, 69, 74, 77, 26, 15, + 9, 3, 5, 66, 71, 77, 89, 83, 3, 65, 65, 69, + 70, 80, 83, 94, 68, 36, 20, 13, 5, 8, 67, 71, + 74, 80, 62, 85, 76, 69, 66, 69, 1, 6, 7, 69, + 5, 10, 8, 77, 71, 71, 8, 10, 10, 7, 17, 20, + 18, 4, 10, 16, 14, 73, 66, 74, 89, 83, 77, 79, + 75, 76, 74, 72, 70, 73, 72, 68, 69, 74, 81, + 90, 78, 97, 76, 68, 70, 2, 69, 65, 7, 65, 66, + 66, 4, 68, 69, 84, 40, 37, 39, 35, 29, 37, 33, + 30, 26, 25, 26, 21, 3, 3, 67, 18, 18, 12, 0, + 8, 6, 66, 68, 71, 74, 77, 90, 79, 94, 56, 55, + 51, 50, 43, 41, 38, 31, 31, 27, 24, 16, 11, 1, + 73, 32, 33, 7, 34, 37, 26, 20, 22, 18, 14, 17, + 11, 6, 64, 66, 73, 88, 6, 67, 79, 99, 88, 92, + 71, 74, 72, 23, 0, 0, 68, 10, 36, 23, 42, 3, + 49, 46, 31, 19, 8, 4, 86, 93, 104, 71, 42, 28, + 19, 9, 11, 2, 65, 68, 81, 89, 81, 72, 75, 66, + 2, 68, 69, 2, 5, 6, 3, 10, 11, 2, 49, 46, 38, + 31, 26, 20, 2, 70, 83 }, + + { + + 53, + 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 2, 33, + 37, 53, 14, 71, 0, 2, 12, 0, 64, 68, 71, 86, + 9, 27, 99, 110, 115, 69, 79, 68, 2, 12, 0, 78, + 73, 10, 7, 65, 73, 82, 1, 75, 79, 90, 5, 72, + 81, 3, 74, 77, 88, 5, 67, 69, 73, 0, 4, 22, 0, + 0, 0, 71, 91, 97, 0, 6, 65, 52, 7, 69, 105, + 85, 82, 65, 80, 93, 88, 97, 72, 93, 87, 89, + 101, 100, 102, 101, 15, 65, 65, 87, 66, 83, + 77, 89, 72, 89, 82, 102, 12, 75, 67, 97, 84, + 73, 73, 64, 5, 0, 69, 10, 7, 71, 1, 0, 65, 2, + 75, 12, 3, 16, 19, 12, 17, 17, 13, 8, 11, 5, + 9, 10, 79, 91, 81, 84, 74, 79, 75, 64, 73, 74, + 70, 70, 71, 72, 67, 81, 92, 81, 95, 70, 74, 2, + 67, 64, 11, 1, 65, 0, 10, 68, 74, 1, 87, 33, + 36, 28, 29, 36, 28, 14, 30, 27, 5, 15, 13, 4, + 1, 69, 10, 5, 6, 8, 3, 65, 7, 2, 71, 64, 67, + 72, 67, 89, 50, 53, 48, 51, 48, 45, 44, 45, + 41, 33, 33, 28, 18, 15, 68, 32, 27, 9, 33, 24, + 24, 19, 14, 11, 11, 4, 70, 65, 70, 86, 83, 99, + 67, 29, 20, 13, 4, 5, 64, 69, 72, 79, 3, 43, + 28, 22, 17, 19, 5, 65, 69, 73, 77, 27, 16, 9, + 3, 5, 66, 71, 76, 88, 83, 4, 65, 65, 69, 69, + 79, 83, 93, 68, 37, 20, 13, 5, 9, 66, 71, 73, + 79, 62, 85, 76, 69, 66, 69, 1, 6, 7, 68, 5, + 10, 9, 77, 71, 71, 7, 10, 9, 6, 16, 19, 18, 2, + 9, 15, 14, 74, 67, 75, 89, 83, 76, 79, 75, 76, + 73, 71, 71, 73, 72, 68, 70, 74, 81, 90, 77, + 97, 76, 67, 70, 2, 69, 65, 8, 65, 67, 66, 5, + 68, 70, 85, 39, 37, 39, 34, 28, 36, 32, 29, + 25, 24, 25, 20, 2, 2, 68, 16, 16, 10, 65, 7, + 5, 67, 69, 71, 74, 77, 90, 80, 94, 53, 52, 49, + 47, 40, 39, 36, 28, 29, 25, 22, 14, 9, 0, 74, + 30, 31, 6, 32, 35, 24, 18, 19, 16, 12, 15, 9, + 4, 66, 68, 75, 89, 4, 69, 81, 98, 87, 91, 71, + 73, 71, 25, 1, 1, 68, 11, 37, 24, 43, 3, 48, + 44, 28, 16, 5, 1, 89, 95, 105, 71, 42, 28, 19, + 9, 11, 2, 65, 68, 80, 88, 80, 71, 75, 65, 3, + 67, 68, 3, 6, 7, 4, 11, 12, 2, 47, 44, 36, 29, + 24, 18, 0, 72, 84 }, + + { + + 52, + 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 0, 31, + 36, 53, 14, 69, 0, 3, 13, 0, 64, 67, 72, 87, + 9, 25, 101, 111, 115, 66, 77, 68, 3, 13, 0, + 78, 72, 10, 7, 65, 73, 81, 1, 76, 79, 90, 5, + 72, 80, 3, 74, 77, 88, 6, 67, 68, 73, 1, 4, + 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 52, 7, 69, + 104, 84, 82, 64, 79, 91, 86, 95, 71, 91, 86, + 87, 100, 99, 101, 100, 16, 65, 64, 86, 66, 82, + 76, 87, 72, 89, 81, 100, 13, 75, 66, 96, 83, + 72, 73, 64, 6, 1, 68, 11, 8, 71, 1, 0, 65, 2, + 75, 12, 2, 15, 19, 11, 17, 17, 13, 6, 11, 4, + 8, 9, 80, 90, 80, 83, 73, 78, 74, 0, 72, 73, + 69, 69, 71, 72, 67, 82, 91, 80, 95, 69, 74, 3, + 67, 65, 12, 1, 65, 64, 11, 68, 75, 1, 87, 32, + 35, 28, 28, 35, 27, 13, 30, 27, 4, 14, 13, 4, + 1, 70, 10, 4, 5, 7, 2, 66, 7, 1, 73, 65, 68, + 73, 68, 89, 48, 52, 46, 49, 47, 43, 42, 43, + 39, 31, 31, 26, 16, 13, 70, 30, 25, 7, 31, 22, + 22, 17, 12, 9, 8, 2, 73, 66, 72, 87, 83, 99, + 67, 29, 20, 13, 4, 5, 64, 69, 72, 79, 3, 43, + 28, 22, 17, 20, 6, 64, 69, 72, 76, 28, 17, 9, + 4, 6, 65, 70, 76, 87, 82, 6, 64, 65, 68, 68, + 78, 82, 92, 67, 37, 21, 13, 5, 10, 65, 70, 72, + 78, 62, 85, 76, 68, 66, 69, 1, 6, 7, 68, 5, + 11, 9, 77, 71, 71, 6, 11, 8, 5, 15, 19, 18, 1, + 8, 15, 14, 75, 68, 75, 88, 82, 75, 78, 74, 75, + 73, 70, 71, 73, 72, 68, 71, 74, 81, 89, 76, + 97, 76, 67, 70, 3, 69, 65, 9, 65, 67, 66, 6, + 69, 70, 85, 38, 37, 38, 34, 27, 35, 31, 28, + 25, 23, 24, 19, 1, 1, 69, 15, 15, 9, 67, 6, 4, + 68, 70, 72, 74, 76, 90, 80, 93, 51, 50, 47, + 45, 38, 37, 34, 26, 27, 23, 20, 12, 7, 65, 75, + 28, 29, 5, 30, 33, 22, 16, 17, 14, 10, 13, 7, + 1, 68, 70, 77, 90, 2, 71, 82, 97, 85, 90, 70, + 72, 70, 27, 2, 2, 68, 12, 39, 26, 45, 4, 46, + 42, 26, 13, 3, 65, 91, 97, 106, 71, 42, 28, + 19, 9, 11, 2, 65, 68, 80, 87, 79, 70, 74, 64, + 4, 67, 67, 4, 7, 8, 4, 11, 12, 2, 46, 43, 35, + 28, 22, 16, 65, 74, 85 }, + + { + + 51, + 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 64, 30, + 35, 53, 14, 67, 0, 3, 14, 0, 65, 67, 73, 88, + 8, 24, 102, 112, 116, 0, 76, 68, 3, 14, 0, 77, + 71, 11, 6, 64, 72, 80, 0, 76, 79, 90, 5, 71, + 80, 3, 74, 76, 88, 6, 67, 68, 73, 1, 4, 22, 0, + 0, 0, 70, 91, 97, 1, 5, 66, 52, 7, 69, 103, + 84, 82, 64, 78, 89, 84, 94, 70, 89, 85, 85, + 99, 98, 100, 99, 17, 65, 0, 86, 65, 82, 76, + 85, 72, 88, 81, 99, 13, 75, 66, 94, 83, 71, + 72, 64, 6, 1, 67, 11, 8, 72, 1, 0, 65, 2, 75, + 12, 2, 15, 19, 10, 17, 17, 13, 4, 11, 4, 6, 8, + 81, 90, 79, 83, 73, 77, 74, 1, 72, 73, 69, 67, + 71, 72, 67, 83, 91, 79, 95, 69, 74, 4, 66, 66, + 12, 1, 65, 65, 12, 69, 76, 1, 88, 30, 34, 27, + 28, 34, 27, 13, 29, 26, 3, 13, 13, 4, 1, 70, + 9, 3, 4, 6, 2, 67, 6, 1, 75, 66, 68, 74, 69, + 89, 47, 50, 45, 47, 45, 41, 40, 41, 36, 28, + 29, 23, 13, 10, 73, 28, 23, 6, 29, 19, 19, 14, + 10, 6, 6, 64, 75, 67, 74, 88, 84, 99, 66, 30, + 20, 14, 4, 5, 64, 69, 72, 78, 3, 43, 29, 22, + 17, 21, 6, 64, 68, 72, 75, 29, 17, 10, 4, 7, + 65, 70, 75, 86, 81, 7, 0, 64, 68, 68, 78, 81, + 90, 67, 37, 21, 13, 6, 10, 65, 69, 72, 77, 62, + 84, 75, 68, 66, 69, 1, 6, 7, 68, 6, 11, 10, + 77, 71, 72, 6, 11, 7, 4, 14, 18, 18, 0, 7, 15, + 14, 75, 69, 76, 87, 81, 74, 78, 74, 75, 72, + 70, 71, 72, 71, 67, 71, 74, 81, 89, 75, 97, + 76, 67, 70, 4, 69, 65, 10, 66, 67, 66, 6, 70, + 70, 86, 37, 36, 38, 33, 26, 35, 31, 27, 24, + 23, 23, 18, 0, 0, 70, 13, 14, 7, 69, 4, 2, 69, + 70, 72, 74, 76, 89, 81, 92, 49, 48, 45, 43, + 35, 35, 32, 23, 25, 20, 18, 9, 5, 66, 75, 27, + 28, 3, 28, 30, 20, 14, 15, 12, 8, 10, 5, 64, + 70, 72, 78, 92, 0, 73, 84, 96, 84, 89, 69, 71, + 69, 28, 3, 3, 68, 13, 40, 27, 46, 5, 45, 41, + 23, 10, 0, 67, 94, 99, 108, 70, 42, 28, 19, 9, + 11, 2, 65, 68, 79, 86, 79, 69, 73, 0, 4, 66, + 66, 4, 7, 8, 4, 12, 12, 2, 45, 41, 33, 26, 21, + 15, 68, 75, 86 }, + + { + + 50, + 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 66, 28, + 33, 53, 14, 64, 64, 4, 14, 0, 66, 67, 74, 89, + 8, 22, 104, 113, 116, 3, 75, 68, 4, 14, 0, 77, + 70, 11, 6, 64, 72, 80, 0, 77, 78, 90, 5, 71, + 79, 2, 74, 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, + 0, 0, 70, 91, 97, 2, 4, 66, 52, 7, 69, 102, + 83, 82, 0, 76, 88, 82, 92, 69, 88, 83, 83, 98, + 97, 99, 99, 18, 65, 1, 85, 65, 81, 75, 83, 72, + 88, 80, 98, 13, 74, 65, 93, 82, 71, 72, 0, 6, + 1, 66, 12, 9, 72, 0, 0, 65, 2, 75, 12, 1, 14, + 19, 10, 17, 17, 12, 2, 11, 3, 4, 7, 82, 89, + 78, 82, 72, 76, 73, 2, 71, 72, 68, 66, 71, 72, + 66, 84, 90, 78, 95, 69, 74, 4, 66, 67, 13, 1, + 65, 67, 13, 69, 77, 1, 89, 29, 33, 27, 27, 33, + 26, 12, 28, 26, 2, 12, 13, 4, 1, 71, 8, 3, 3, + 6, 1, 68, 5, 0, 77, 67, 69, 75, 70, 89, 45, + 49, 43, 45, 43, 39, 37, 39, 34, 26, 27, 21, + 11, 8, 75, 26, 22, 4, 26, 17, 17, 12, 7, 4, 3, + 66, 78, 68, 75, 90, 85, 99, 66, 30, 21, 14, 4, + 5, 64, 69, 72, 78, 4, 44, 29, 22, 17, 22, 7, + 0, 68, 71, 74, 30, 18, 10, 4, 8, 64, 69, 75, + 85, 81, 8, 0, 64, 68, 67, 77, 81, 89, 66, 38, + 21, 13, 6, 11, 64, 68, 71, 76, 62, 84, 75, 67, + 66, 69, 1, 6, 7, 67, 6, 11, 10, 77, 71, 72, 5, + 12, 6, 3, 13, 17, 18, 64, 6, 14, 14, 76, 70, + 76, 86, 81, 73, 77, 73, 74, 72, 69, 71, 72, + 71, 67, 72, 74, 81, 88, 74, 97, 76, 66, 70, 4, + 69, 65, 11, 66, 67, 66, 7, 70, 71, 87, 36, 36, + 37, 32, 25, 34, 30, 26, 23, 22, 22, 17, 64, + 64, 71, 12, 12, 6, 71, 3, 1, 70, 71, 73, 74, + 76, 89, 81, 91, 47, 46, 43, 40, 32, 33, 30, + 21, 23, 18, 16, 7, 3, 68, 76, 25, 26, 2, 26, + 28, 18, 12, 13, 10, 6, 8, 3, 67, 72, 74, 80, + 93, 65, 75, 85, 95, 83, 88, 69, 70, 68, 30, 4, + 4, 68, 14, 42, 29, 48, 5, 43, 39, 21, 7, 66, + 70, 97, 101, 109, 70, 42, 28, 19, 9, 11, 2, + 65, 68, 79, 85, 78, 68, 72, 1, 5, 66, 65, 5, + 8, 9, 5, 12, 13, 2, 43, 40, 31, 24, 19, 13, + 70, 77, 87 }, + + { + + 48, + 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 67, 27, + 32, 53, 14, 1, 64, 5, 15, 0, 67, 67, 75, 91, + 7, 20, 106, 114, 117, 5, 74, 68, 5, 15, 0, 77, + 69, 11, 5, 64, 72, 79, 64, 77, 78, 91, 5, 71, + 79, 2, 75, 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, + 0, 0, 69, 92, 97, 2, 3, 66, 52, 7, 69, 101, + 82, 82, 0, 75, 86, 80, 91, 68, 86, 82, 82, 97, + 97, 98, 98, 18, 65, 2, 84, 65, 81, 75, 82, 72, + 88, 80, 97, 13, 74, 65, 92, 82, 70, 72, 0, 6, + 1, 66, 12, 9, 73, 0, 0, 65, 2, 75, 12, 1, 13, + 19, 9, 17, 17, 12, 0, 11, 3, 2, 6, 83, 88, 77, + 81, 71, 76, 73, 3, 71, 72, 67, 65, 71, 72, 66, + 86, 90, 77, 95, 69, 75, 5, 66, 68, 14, 1, 65, + 68, 14, 70, 78, 1, 90, 27, 32, 26, 26, 32, 25, + 11, 27, 25, 0, 11, 12, 4, 1, 71, 7, 2, 2, 5, + 0, 69, 4, 64, 79, 69, 70, 76, 71, 89, 43, 47, + 41, 43, 41, 37, 35, 37, 31, 23, 25, 18, 8, 5, + 78, 24, 20, 2, 24, 15, 14, 9, 5, 1, 0, 68, 80, + 69, 77, 91, 86, 100, 66, 30, 21, 14, 4, 5, 64, + 69, 72, 77, 4, 44, 29, 22, 17, 23, 7, 0, 68, + 71, 74, 31, 18, 10, 4, 8, 64, 69, 74, 84, 80, + 9, 1, 64, 68, 66, 76, 80, 88, 66, 38, 21, 13, + 6, 12, 64, 68, 70, 76, 62, 84, 75, 67, 66, 69, + 1, 6, 7, 67, 6, 11, 11, 77, 71, 72, 4, 12, 5, + 2, 12, 16, 18, 66, 4, 14, 14, 77, 71, 77, 86, + 80, 72, 77, 73, 74, 71, 68, 72, 72, 71, 67, + 73, 74, 81, 88, 74, 98, 76, 66, 70, 5, 69, 65, + 11, 66, 68, 66, 8, 71, 71, 88, 35, 35, 37, 31, + 23, 33, 29, 25, 22, 21, 21, 16, 65, 65, 72, + 10, 11, 4, 73, 1, 0, 71, 72, 73, 74, 76, 89, + 82, 91, 44, 43, 41, 38, 29, 30, 27, 18, 21, + 16, 14, 4, 1, 69, 77, 23, 24, 0, 24, 26, 15, + 9, 10, 7, 4, 6, 0, 69, 74, 77, 82, 94, 67, 77, + 87, 94, 82, 87, 68, 69, 68, 31, 5, 4, 68, 14, + 43, 30, 49, 6, 42, 37, 18, 4, 69, 73, 100, + 103, 110, 70, 42, 28, 19, 9, 11, 2, 65, 68, + 78, 85, 77, 67, 72, 2, 5, 65, 65, 5, 8, 9, 5, + 13, 13, 1, 42, 38, 29, 22, 17, 11, 72, 79, 88 }, + + { + + 47, + 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 68, 26, + 31, 53, 14, 3, 64, 6, 16, 0, 67, 66, 76, 92, + 6, 18, 107, 115, 118, 8, 72, 68, 6, 16, 0, 76, + 68, 12, 4, 64, 71, 78, 64, 77, 78, 91, 5, 71, + 78, 2, 75, 76, 88, 7, 66, 67, 72, 2, 4, 22, 0, + 0, 0, 68, 92, 97, 2, 2, 66, 52, 7, 69, 100, + 81, 82, 0, 74, 84, 78, 89, 66, 84, 81, 80, 96, + 96, 97, 97, 19, 64, 3, 83, 65, 80, 74, 80, 72, + 87, 80, 95, 14, 74, 65, 90, 82, 69, 72, 0, 7, + 2, 65, 12, 9, 73, 0, 1, 65, 2, 74, 12, 1, 13, + 19, 8, 17, 17, 12, 65, 11, 3, 1, 5, 83, 87, + 76, 80, 70, 75, 72, 4, 70, 72, 66, 64, 71, 72, + 66, 87, 89, 76, 95, 68, 75, 6, 66, 69, 15, 1, + 65, 69, 15, 71, 79, 1, 90, 26, 31, 26, 25, 31, + 24, 11, 27, 25, 64, 10, 12, 4, 1, 71, 7, 1, 1, + 4, 64, 70, 4, 64, 80, 70, 70, 77, 72, 89, 42, + 46, 40, 42, 40, 35, 33, 35, 29, 21, 23, 16, 5, + 3, 81, 23, 18, 1, 22, 13, 12, 7, 3, 64, 65, + 70, 82, 69, 79, 92, 86, 100, 66, 31, 21, 14, + 5, 5, 64, 68, 72, 76, 4, 44, 29, 23, 17, 24, + 8, 1, 67, 70, 73, 32, 19, 11, 5, 9, 0, 69, 73, + 83, 79, 11, 2, 0, 67, 65, 75, 79, 87, 65, 38, + 22, 14, 6, 13, 0, 67, 69, 75, 62, 83, 74, 66, + 66, 69, 1, 7, 8, 67, 6, 12, 12, 77, 71, 72, 4, + 12, 4, 2, 11, 16, 18, 67, 3, 14, 14, 77, 72, + 78, 85, 79, 71, 77, 72, 74, 70, 67, 72, 72, + 71, 66, 73, 74, 81, 88, 73, 98, 76, 66, 70, 6, + 69, 65, 12, 66, 68, 66, 9, 72, 71, 88, 34, 35, + 37, 31, 22, 32, 28, 24, 22, 20, 20, 16, 65, + 66, 73, 9, 10, 2, 75, 0, 64, 71, 72, 73, 73, + 75, 89, 83, 90, 42, 41, 39, 36, 27, 28, 25, + 16, 19, 14, 12, 2, 64, 70, 78, 21, 23, 64, 22, + 24, 13, 7, 8, 5, 2, 4, 65, 71, 75, 79, 84, 95, + 69, 79, 89, 93, 80, 85, 67, 68, 67, 33, 6, 5, + 68, 15, 45, 31, 51, 7, 41, 36, 16, 1, 71, 76, + 102, 105, 111, 70, 42, 28, 19, 9, 12, 2, 65, + 68, 77, 84, 76, 66, 71, 4, 6, 64, 64, 6, 9, + 10, 5, 14, 13, 1, 41, 37, 28, 21, 15, 9, 74, + 81, 88 }, + + { + + 46, + 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 70, 24, + 29, 53, 14, 6, 65, 7, 16, 0, 68, 66, 77, 93, + 6, 16, 109, 116, 118, 11, 71, 68, 7, 16, 0, + 76, 67, 12, 4, 64, 71, 78, 64, 78, 77, 91, 5, + 71, 77, 1, 75, 76, 88, 8, 65, 67, 71, 3, 4, + 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 52, 7, 69, + 99, 80, 82, 1, 72, 83, 76, 88, 65, 83, 79, 78, + 95, 95, 96, 97, 20, 64, 4, 82, 65, 80, 73, 78, + 72, 87, 79, 94, 14, 73, 64, 89, 81, 69, 72, 1, + 7, 2, 64, 13, 10, 74, 64, 1, 65, 2, 74, 12, 0, + 12, 19, 8, 17, 17, 11, 67, 11, 2, 64, 4, 84, + 86, 75, 79, 69, 74, 71, 5, 69, 71, 65, 0, 71, + 72, 65, 88, 89, 75, 95, 68, 75, 6, 66, 70, 16, + 1, 65, 71, 16, 71, 80, 1, 91, 24, 30, 25, 24, + 30, 23, 10, 26, 25, 65, 9, 12, 4, 1, 72, 6, 1, + 0, 4, 65, 71, 3, 65, 82, 71, 71, 78, 73, 89, + 40, 45, 38, 40, 38, 33, 30, 33, 26, 19, 21, + 13, 3, 1, 83, 21, 17, 64, 19, 11, 10, 5, 0, + 66, 68, 72, 85, 70, 80, 94, 87, 100, 66, 31, + 22, 14, 5, 5, 64, 68, 72, 76, 5, 45, 29, 23, + 17, 25, 8, 2, 67, 69, 72, 33, 20, 11, 5, 10, + 0, 68, 73, 82, 79, 12, 2, 0, 67, 64, 74, 79, + 86, 65, 39, 22, 14, 6, 14, 1, 66, 68, 74, 62, + 83, 74, 66, 66, 69, 1, 7, 8, 66, 6, 12, 12, + 77, 71, 72, 3, 13, 3, 1, 10, 15, 18, 68, 2, + 13, 14, 78, 73, 78, 84, 79, 70, 76, 72, 73, + 70, 66, 72, 72, 71, 66, 74, 74, 81, 87, 72, + 98, 76, 65, 70, 6, 69, 65, 13, 66, 68, 66, 10, + 72, 72, 89, 33, 35, 36, 30, 21, 31, 27, 23, + 21, 19, 19, 15, 66, 67, 74, 7, 8, 1, 77, 64, + 65, 72, 73, 74, 73, 75, 89, 83, 89, 40, 39, + 37, 33, 24, 26, 23, 13, 17, 12, 10, 0, 66, 72, + 79, 19, 21, 65, 20, 22, 11, 5, 6, 3, 0, 2, 67, + 74, 77, 81, 86, 96, 71, 81, 90, 92, 79, 84, + 67, 67, 66, 35, 7, 6, 68, 16, 46, 33, 52, 7, + 39, 34, 13, 65, 74, 79, 105, 107, 112, 70, 42, + 28, 19, 9, 12, 2, 65, 68, 77, 83, 75, 65, 70, + 5, 7, 64, 0, 7, 10, 11, 6, 14, 14, 1, 39, 35, + 26, 19, 13, 7, 76, 83, 89 }, + + { + + 45, + 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 71, 23, + 28, 53, 14, 8, 65, 7, 17, 0, 69, 66, 78, 94, + 5, 15, 110, 117, 119, 14, 70, 68, 7, 17, 0, + 75, 66, 13, 3, 0, 70, 77, 65, 78, 77, 91, 5, + 70, 77, 1, 75, 75, 88, 8, 65, 67, 71, 3, 4, + 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 52, 7, 69, + 98, 80, 82, 1, 71, 81, 74, 86, 64, 81, 78, 76, + 94, 94, 95, 96, 21, 64, 5, 82, 64, 79, 73, 76, + 72, 86, 79, 93, 14, 73, 64, 87, 81, 68, 71, 1, + 7, 2, 0, 13, 10, 74, 64, 1, 65, 2, 74, 12, 0, + 12, 19, 7, 17, 17, 11, 69, 11, 2, 66, 3, 85, + 86, 74, 79, 69, 73, 71, 6, 69, 71, 65, 2, 71, + 72, 65, 89, 88, 74, 95, 68, 75, 7, 65, 71, 16, + 1, 65, 72, 17, 72, 81, 1, 92, 23, 29, 25, 24, + 29, 23, 10, 25, 24, 66, 8, 12, 4, 1, 72, 5, 0, + 64, 3, 65, 72, 2, 65, 84, 72, 71, 79, 74, 89, + 39, 43, 37, 38, 36, 31, 28, 31, 24, 16, 19, + 11, 0, 65, 86, 19, 15, 65, 17, 8, 7, 2, 65, + 69, 70, 75, 87, 71, 82, 95, 88, 100, 65, 32, + 22, 15, 5, 5, 64, 68, 72, 75, 5, 45, 30, 23, + 17, 26, 9, 2, 66, 69, 71, 34, 20, 12, 5, 11, + 1, 68, 72, 81, 78, 13, 3, 1, 67, 64, 74, 78, + 84, 64, 39, 22, 14, 7, 14, 1, 65, 68, 73, 62, + 82, 73, 65, 66, 69, 1, 7, 8, 66, 7, 12, 13, + 77, 71, 73, 3, 13, 2, 0, 9, 14, 18, 69, 1, 13, + 14, 78, 74, 79, 83, 78, 69, 76, 71, 73, 69, + 66, 72, 71, 70, 65, 74, 74, 81, 87, 71, 98, + 76, 65, 70, 7, 69, 65, 14, 67, 68, 66, 10, 73, + 72, 90, 32, 34, 36, 29, 20, 31, 27, 22, 20, + 19, 18, 14, 67, 68, 75, 6, 7, 64, 79, 66, 67, + 73, 73, 74, 73, 75, 88, 84, 88, 38, 37, 35, + 31, 21, 24, 21, 11, 15, 9, 8, 66, 68, 73, 79, + 18, 20, 67, 18, 19, 9, 3, 4, 1, 65, 64, 69, + 76, 79, 83, 87, 98, 73, 83, 92, 91, 78, 83, + 66, 66, 65, 36, 8, 7, 68, 17, 48, 34, 54, 8, + 38, 33, 11, 68, 77, 81, 108, 109, 114, 69, 42, + 28, 19, 9, 12, 2, 65, 68, 76, 82, 75, 64, 69, + 6, 7, 0, 1, 7, 10, 11, 6, 15, 14, 1, 38, 34, + 24, 17, 12, 6, 79, 84, 90 }, + + { + + 43, + 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 73, 21, + 27, 53, 14, 10, 65, 8, 18, 0, 70, 66, 79, 95, + 5, 13, 112, 118, 119, 17, 69, 68, 8, 18, 0, + 75, 65, 13, 3, 0, 70, 76, 65, 79, 77, 91, 5, + 70, 76, 1, 76, 75, 88, 9, 65, 67, 71, 4, 4, + 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 52, 7, 69, + 97, 79, 82, 2, 70, 79, 72, 85, 0, 79, 77, 74, + 93, 94, 94, 95, 21, 64, 6, 81, 64, 79, 72, 74, + 72, 86, 78, 92, 14, 73, 0, 86, 80, 67, 71, 1, + 7, 2, 0, 14, 11, 75, 64, 1, 65, 2, 74, 12, 64, + 11, 19, 6, 17, 17, 11, 71, 11, 1, 68, 2, 86, + 85, 73, 78, 68, 73, 70, 7, 68, 70, 64, 3, 71, + 72, 65, 90, 88, 73, 95, 68, 75, 8, 65, 72, 17, + 1, 65, 73, 18, 72, 82, 1, 93, 21, 28, 24, 23, + 28, 22, 9, 24, 24, 68, 7, 11, 4, 1, 73, 4, 64, + 65, 2, 66, 73, 1, 66, 86, 73, 72, 80, 75, 89, + 37, 42, 35, 36, 34, 29, 26, 29, 21, 14, 17, 8, + 65, 67, 88, 17, 13, 67, 15, 6, 5, 0, 67, 71, + 73, 77, 90, 72, 84, 96, 89, 100, 65, 32, 22, + 15, 5, 5, 64, 68, 72, 75, 5, 45, 30, 23, 17, + 27, 9, 3, 66, 68, 71, 35, 21, 12, 5, 11, 1, + 67, 72, 80, 77, 14, 4, 1, 67, 0, 73, 77, 83, + 64, 39, 22, 14, 7, 15, 2, 65, 67, 72, 62, 82, + 73, 65, 66, 69, 1, 7, 8, 66, 7, 12, 13, 77, + 71, 73, 2, 14, 1, 64, 8, 13, 18, 71, 0, 13, + 14, 79, 75, 79, 83, 77, 68, 75, 71, 72, 69, + 65, 73, 71, 70, 65, 75, 74, 81, 86, 70, 98, + 76, 65, 70, 8, 69, 65, 15, 67, 69, 66, 11, 74, + 72, 91, 31, 34, 35, 28, 19, 30, 26, 21, 19, + 18, 17, 13, 68, 69, 76, 4, 6, 65, 81, 67, 68, + 74, 74, 75, 73, 75, 88, 84, 88, 35, 34, 33, + 29, 18, 22, 19, 8, 13, 7, 6, 68, 70, 75, 80, + 16, 18, 68, 16, 17, 7, 1, 1, 64, 67, 66, 71, + 79, 81, 85, 89, 99, 75, 85, 93, 90, 77, 82, + 65, 65, 64, 38, 9, 8, 68, 18, 49, 36, 55, 9, + 36, 31, 8, 71, 80, 84, 111, 111, 115, 69, 42, + 28, 19, 9, 12, 2, 65, 68, 76, 81, 74, 0, 69, + 7, 8, 0, 2, 8, 11, 12, 6, 15, 14, 1, 37, 32, + 22, 15, 10, 4, 81, 86, 91 }, + + { + + 42, + 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 74, 20, + 25, 53, 14, 13, 66, 9, 18, 0, 70, 65, 80, 96, + 4, 11, 114, 119, 120, 20, 67, 68, 9, 18, 0, + 75, 64, 13, 2, 0, 70, 76, 65, 79, 76, 91, 5, + 70, 75, 0, 76, 75, 88, 9, 64, 66, 70, 4, 4, + 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 52, 7, 69, + 96, 78, 82, 2, 68, 78, 70, 83, 1, 78, 75, 72, + 92, 93, 93, 95, 22, 64, 7, 80, 64, 78, 71, 72, + 72, 86, 78, 90, 15, 72, 0, 85, 80, 67, 71, 2, + 8, 3, 1, 14, 11, 75, 65, 1, 65, 2, 74, 12, 64, + 10, 19, 6, 17, 17, 10, 73, 11, 1, 69, 1, 87, + 84, 72, 77, 67, 72, 69, 8, 67, 70, 0, 4, 71, + 72, 64, 91, 87, 72, 95, 67, 75, 8, 65, 73, 18, + 1, 65, 75, 19, 73, 83, 1, 93, 20, 27, 24, 22, + 27, 21, 8, 24, 24, 69, 6, 11, 4, 1, 73, 4, 64, + 66, 2, 67, 74, 1, 67, 88, 74, 73, 81, 76, 89, + 35, 41, 33, 34, 33, 27, 23, 27, 19, 12, 15, 6, + 68, 69, 91, 15, 12, 69, 12, 4, 3, 65, 70, 73, + 76, 79, 92, 73, 85, 98, 89, 100, 65, 32, 23, + 15, 5, 5, 64, 68, 72, 74, 6, 46, 30, 23, 17, + 28, 10, 4, 66, 67, 70, 36, 22, 12, 6, 12, 2, + 67, 71, 79, 77, 16, 4, 1, 66, 1, 72, 77, 82, + 0, 40, 23, 14, 7, 16, 3, 64, 66, 71, 62, 82, + 73, 64, 66, 69, 1, 7, 8, 65, 7, 13, 14, 77, + 71, 73, 1, 14, 0, 65, 7, 13, 18, 72, 64, 12, + 14, 80, 76, 80, 82, 77, 67, 75, 70, 72, 68, + 64, 73, 71, 70, 65, 76, 74, 81, 86, 69, 98, + 76, 64, 70, 8, 69, 65, 16, 67, 69, 66, 12, 74, + 73, 91, 30, 34, 35, 28, 18, 29, 25, 20, 19, + 17, 16, 12, 69, 70, 77, 3, 4, 67, 83, 68, 69, + 75, 75, 75, 73, 74, 88, 85, 87, 33, 32, 31, + 26, 16, 20, 17, 6, 11, 5, 4, 70, 72, 76, 81, + 14, 16, 69, 14, 15, 5, 64, 64, 66, 69, 68, 73, + 81, 83, 87, 91, 100, 77, 87, 95, 89, 75, 81, + 65, 64, 0, 40, 10, 9, 68, 19, 51, 37, 57, 9, + 35, 29, 6, 74, 82, 87, 113, 113, 116, 69, 42, + 28, 19, 9, 12, 2, 65, 68, 75, 80, 73, 1, 68, + 8, 9, 1, 3, 9, 12, 13, 7, 16, 15, 1, 35, 31, + 21, 14, 8, 2, 83, 88, 92 }, + + { + + 41, + 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 76, 18, + 24, 53, 14, 15, 66, 10, 19, 0, 71, 65, 81, 97, + 4, 9, 115, 120, 120, 23, 66, 68, 10, 19, 0, + 74, 0, 14, 2, 0, 69, 75, 66, 80, 76, 91, 5, + 70, 75, 0, 76, 75, 88, 10, 64, 66, 70, 5, 4, + 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 52, 7, 69, + 95, 77, 82, 3, 67, 76, 68, 82, 2, 76, 74, 70, + 91, 92, 92, 94, 23, 64, 8, 79, 64, 78, 71, 70, + 72, 85, 77, 89, 15, 72, 1, 83, 79, 66, 71, 2, + 8, 3, 2, 15, 12, 76, 65, 1, 65, 2, 74, 12, 65, + 10, 19, 5, 17, 17, 10, 75, 11, 0, 71, 0, 88, + 83, 71, 76, 66, 71, 69, 9, 67, 69, 1, 5, 71, + 72, 64, 92, 87, 71, 95, 67, 75, 9, 65, 74, 19, + 1, 65, 76, 20, 73, 84, 1, 94, 18, 26, 23, 21, + 26, 20, 8, 23, 23, 70, 5, 11, 4, 1, 74, 3, 65, + 67, 1, 68, 75, 0, 67, 90, 75, 73, 82, 77, 89, + 34, 39, 32, 32, 31, 25, 21, 25, 16, 9, 13, 3, + 70, 72, 93, 13, 10, 70, 10, 2, 0, 68, 72, 76, + 78, 81, 95, 74, 87, 99, 90, 100, 65, 33, 23, + 15, 5, 5, 64, 68, 72, 74, 6, 46, 30, 23, 17, + 29, 10, 4, 65, 67, 69, 37, 22, 13, 6, 13, 2, + 66, 71, 78, 76, 17, 5, 2, 66, 2, 71, 76, 81, + 0, 40, 23, 14, 7, 17, 3, 0, 65, 70, 62, 81, + 72, 64, 66, 69, 1, 7, 8, 65, 7, 13, 14, 77, + 71, 73, 1, 15, 64, 66, 6, 12, 18, 73, 65, 12, + 14, 80, 77, 80, 81, 76, 66, 74, 70, 71, 68, 0, + 73, 71, 70, 64, 76, 74, 81, 85, 68, 98, 76, + 64, 70, 9, 69, 65, 17, 67, 69, 66, 13, 75, 73, + 92, 29, 33, 34, 27, 17, 28, 24, 19, 18, 16, + 15, 11, 70, 71, 78, 1, 3, 68, 85, 70, 70, 76, + 75, 76, 73, 74, 88, 85, 86, 31, 30, 29, 24, + 13, 18, 15, 3, 9, 3, 2, 73, 74, 78, 82, 12, + 15, 71, 12, 13, 3, 66, 66, 68, 71, 70, 75, 84, + 85, 89, 93, 101, 79, 89, 96, 88, 74, 80, 64, + 0, 1, 41, 11, 10, 68, 20, 52, 39, 58, 10, 33, + 28, 3, 77, 85, 90, 116, 115, 117, 69, 42, 28, + 19, 9, 12, 2, 65, 68, 75, 79, 72, 2, 67, 9, 9, + 1, 4, 9, 12, 13, 7, 16, 15, 1, 34, 29, 19, 12, + 6, 0, 85, 90, 93 }, + + { + + 40, + 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 77, 17, + 23, 53, 14, 17, 66, 11, 20, 0, 72, 65, 82, 98, + 3, 7, 117, 121, 121, 26, 65, 68, 11, 20, 0, + 74, 1, 14, 1, 0, 69, 74, 66, 80, 76, 91, 5, + 70, 74, 0, 76, 75, 88, 10, 64, 66, 70, 5, 4, + 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 52, 7, 69, + 94, 76, 82, 3, 66, 74, 66, 80, 3, 74, 73, 68, + 90, 91, 91, 93, 24, 64, 9, 78, 64, 77, 70, 68, + 72, 85, 77, 88, 15, 72, 1, 82, 79, 65, 71, 2, + 8, 3, 3, 15, 12, 76, 65, 1, 65, 2, 74, 12, 65, + 9, 19, 4, 17, 17, 10, 77, 11, 0, 73, 64, 89, + 82, 70, 75, 65, 70, 68, 10, 66, 69, 2, 6, 71, + 72, 64, 93, 86, 70, 95, 67, 75, 10, 65, 75, + 20, 1, 65, 77, 21, 74, 85, 1, 95, 17, 25, 23, + 20, 25, 19, 7, 22, 23, 71, 4, 11, 4, 1, 74, 2, + 66, 68, 0, 69, 76, 64, 68, 92, 76, 74, 83, 78, + 89, 32, 38, 30, 30, 29, 23, 19, 23, 14, 7, 11, + 1, 73, 74, 96, 11, 8, 72, 8, 0, 65, 70, 74, + 78, 81, 83, 97, 75, 89, 100, 91, 100, 65, 33, + 23, 15, 5, 5, 64, 68, 72, 73, 6, 46, 30, 23, + 17, 30, 11, 5, 65, 66, 68, 38, 23, 13, 6, 14, + 3, 66, 70, 77, 75, 18, 6, 2, 66, 3, 70, 75, + 80, 1, 40, 23, 14, 7, 18, 4, 1, 64, 69, 62, + 81, 72, 0, 66, 69, 1, 7, 8, 65, 7, 13, 15, 77, + 71, 73, 0, 15, 65, 67, 5, 11, 18, 74, 66, 12, + 14, 81, 78, 81, 80, 75, 65, 74, 69, 71, 67, 1, + 73, 71, 70, 64, 77, 74, 81, 85, 67, 98, 76, + 64, 70, 10, 69, 65, 18, 67, 69, 66, 14, 76, + 73, 93, 28, 33, 34, 26, 16, 27, 23, 18, 17, + 15, 14, 10, 71, 72, 79, 0, 2, 70, 87, 71, 71, + 77, 76, 76, 73, 74, 88, 86, 85, 29, 28, 27, + 22, 10, 16, 13, 1, 7, 1, 0, 75, 76, 79, 83, + 10, 13, 72, 10, 11, 1, 68, 68, 70, 73, 72, 77, + 86, 87, 91, 95, 102, 81, 91, 98, 87, 73, 79, + 0, 1, 2, 43, 12, 11, 68, 21, 54, 40, 60, 11, + 32, 26, 1, 80, 88, 93, 119, 117, 118, 69, 42, + 28, 19, 9, 12, 2, 65, 68, 74, 78, 71, 3, 66, + 10, 10, 2, 5, 10, 13, 14, 7, 17, 15, 1, 33, + 28, 17, 10, 4, 65, 87, 92, 94 }, + + { + + 38, + 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 79, 15, + 21, 52, 14, 19, 67, 11, 20, 64, 73, 65, 84, + 100, 2, 5, 119, 122, 122, 28, 64, 69, 11, 20, + 64, 74, 2, 14, 0, 0, 69, 74, 67, 81, 76, 92, + 5, 70, 74, 64, 77, 75, 88, 10, 64, 66, 70, 5, + 3, 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 52, 6, + 69, 93, 76, 82, 3, 65, 73, 65, 79, 4, 73, 72, + 67, 89, 91, 90, 93, 24, 64, 9, 78, 64, 77, 70, + 67, 72, 85, 77, 87, 15, 72, 1, 81, 79, 65, 71, + 2, 8, 3, 3, 15, 12, 77, 66, 1, 66, 2, 74, 11, + 66, 8, 19, 3, 16, 17, 9, 79, 10, 64, 75, 65, + 90, 82, 70, 75, 65, 70, 68, 11, 66, 69, 2, 7, + 72, 72, 64, 95, 86, 70, 95, 67, 76, 10, 65, + 76, 20, 1, 65, 79, 21, 75, 86, 1, 96, 15, 24, + 22, 19, 24, 18, 6, 21, 22, 73, 3, 10, 3, 1, + 75, 1, 67, 69, 64, 70, 77, 65, 69, 94, 78, 75, + 85, 80, 89, 30, 36, 28, 28, 27, 20, 16, 20, + 11, 4, 8, 65, 76, 77, 99, 9, 6, 74, 5, 66, 68, + 73, 77, 81, 84, 86, 100, 76, 91, 102, 92, 101, + 65, 33, 23, 15, 5, 5, 65, 68, 72, 73, 6, 46, + 30, 23, 17, 31, 11, 5, 65, 66, 68, 38, 23, 13, + 6, 14, 3, 66, 70, 76, 75, 19, 6, 2, 66, 3, 70, + 75, 79, 1, 40, 23, 14, 7, 18, 4, 1, 64, 69, + 62, 81, 72, 0, 66, 69, 1, 7, 8, 65, 7, 13, 15, + 77, 71, 74, 64, 15, 66, 68, 4, 10, 17, 76, 68, + 11, 13, 82, 80, 82, 80, 75, 64, 74, 69, 71, + 67, 1, 74, 71, 70, 64, 78, 74, 81, 85, 67, 99, + 76, 64, 70, 10, 70, 65, 18, 68, 70, 66, 14, + 77, 74, 94, 27, 32, 33, 25, 14, 26, 22, 17, + 16, 14, 13, 9, 72, 74, 81, 65, 0, 72, 89, 73, + 73, 78, 77, 77, 73, 74, 88, 87, 85, 26, 25, + 25, 19, 7, 13, 10, 65, 4, 65, 66, 78, 79, 81, + 84, 8, 11, 74, 8, 8, 65, 71, 71, 73, 75, 75, + 80, 89, 89, 94, 97, 104, 83, 93, 100, 86, 72, + 78, 0, 1, 2, 44, 12, 11, 68, 21, 55, 41, 61, + 11, 30, 24, 65, 84, 91, 96, 122, 120, 120, 69, + 42, 27, 18, 9, 12, 2, 66, 68, 74, 78, 71, 3, + 66, 11, 10, 2, 5, 10, 13, 14, 7, 17, 15, 0, + 31, 26, 15, 8, 2, 67, 90, 94, 95 }, + + { + + 37, + 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 80, 14, + 20, 52, 14, 22, 67, 12, 21, 64, 73, 64, 85, + 101, 2, 4, 120, 123, 122, 31, 1, 69, 12, 21, + 64, 73, 4, 15, 0, 1, 68, 73, 67, 81, 75, 92, + 5, 69, 73, 64, 77, 74, 88, 11, 0, 65, 69, 6, + 3, 22, 0, 0, 0, 64, 94, 97, 6, 67, 68, 52, 6, + 69, 91, 75, 82, 4, 0, 71, 0, 77, 6, 71, 70, + 65, 87, 90, 89, 92, 25, 0, 10, 77, 0, 76, 69, + 65, 71, 84, 76, 85, 16, 71, 2, 79, 78, 64, 70, + 3, 9, 4, 4, 16, 13, 77, 66, 2, 66, 2, 73, 11, + 66, 8, 19, 3, 16, 17, 9, 80, 10, 64, 76, 66, + 90, 81, 69, 74, 64, 69, 67, 12, 65, 68, 3, 9, + 72, 72, 0, 96, 85, 69, 95, 66, 76, 11, 64, 76, + 21, 1, 65, 80, 22, 75, 87, 1, 96, 14, 24, 22, + 19, 24, 18, 6, 21, 22, 74, 3, 10, 3, 1, 75, 1, + 67, 69, 64, 70, 78, 65, 69, 95, 79, 75, 86, + 81, 89, 29, 35, 27, 27, 26, 18, 14, 18, 9, 2, + 6, 67, 78, 79, 101, 8, 5, 75, 3, 68, 70, 75, + 79, 83, 86, 88, 102, 76, 92, 103, 92, 101, 64, + 34, 24, 16, 6, 5, 65, 67, 71, 72, 7, 47, 31, + 24, 17, 32, 12, 6, 64, 65, 67, 39, 24, 14, 7, + 15, 4, 65, 69, 74, 74, 21, 7, 3, 65, 4, 69, + 74, 77, 2, 41, 24, 15, 8, 19, 5, 2, 0, 68, 62, + 80, 71, 1, 66, 68, 1, 8, 9, 64, 8, 14, 16, 76, + 71, 74, 64, 16, 66, 68, 3, 10, 17, 77, 69, 11, + 13, 82, 81, 82, 79, 74, 0, 73, 68, 70, 66, 2, + 74, 70, 69, 0, 78, 73, 80, 84, 66, 99, 76, 0, + 70, 11, 70, 65, 19, 68, 70, 65, 15, 77, 74, + 94, 27, 32, 33, 25, 13, 26, 22, 17, 16, 14, + 13, 9, 72, 75, 82, 66, 64, 73, 90, 74, 74, 78, + 77, 77, 72, 73, 87, 87, 84, 24, 23, 23, 17, 5, + 11, 8, 67, 2, 67, 68, 80, 81, 82, 84, 7, 10, + 75, 7, 6, 67, 73, 73, 75, 77, 77, 82, 91, 90, + 96, 98, 105, 84, 94, 101, 84, 70, 76, 1, 2, 3, + 46, 13, 12, 68, 22, 57, 43, 62, 12, 29, 23, + 67, 87, 93, 98, 124, 122, 121, 68, 43, 27, 18, + 9, 13, 2, 66, 68, 73, 77, 70, 4, 65, 13, 11, + 3, 6, 11, 14, 15, 8, 18, 16, 0, 30, 25, 14, 7, + 1, 68, 92, 95, 95 }, + + { + + 36, + 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 81, 13, + 19, 52, 14, 24, 67, 13, 22, 64, 74, 64, 86, + 102, 1, 2, 122, 124, 123, 34, 2, 69, 13, 22, + 64, 73, 5, 15, 64, 1, 68, 72, 67, 81, 75, 92, + 5, 69, 72, 64, 77, 74, 88, 11, 0, 65, 69, 6, + 3, 22, 0, 0, 0, 0, 94, 97, 6, 68, 68, 52, 6, + 69, 90, 74, 82, 4, 1, 69, 2, 76, 7, 69, 69, 0, + 86, 89, 88, 91, 26, 0, 11, 76, 0, 76, 68, 0, + 71, 84, 76, 84, 16, 71, 2, 78, 78, 0, 70, 3, + 9, 4, 5, 16, 13, 78, 66, 2, 66, 2, 73, 11, 66, + 7, 19, 2, 16, 17, 9, 82, 10, 64, 78, 67, 91, + 80, 68, 73, 0, 68, 66, 13, 64, 68, 4, 10, 72, + 72, 0, 97, 85, 68, 95, 66, 76, 12, 64, 77, 22, + 1, 65, 81, 23, 76, 88, 1, 97, 12, 23, 21, 18, + 23, 17, 5, 20, 22, 75, 2, 10, 3, 1, 75, 0, 68, + 70, 65, 71, 79, 66, 70, 97, 80, 76, 87, 82, + 89, 27, 34, 25, 25, 24, 16, 12, 16, 6, 0, 4, + 70, 81, 81, 104, 6, 3, 77, 1, 70, 72, 77, 81, + 85, 89, 90, 104, 77, 94, 104, 93, 101, 64, 34, + 24, 16, 6, 5, 65, 67, 71, 71, 7, 47, 31, 24, + 17, 33, 12, 7, 64, 64, 66, 40, 25, 14, 7, 16, + 4, 65, 68, 73, 73, 22, 8, 3, 65, 5, 68, 73, + 76, 2, 41, 24, 15, 8, 20, 6, 3, 1, 67, 62, 80, + 71, 1, 66, 68, 1, 8, 9, 64, 8, 14, 17, 76, 71, + 74, 65, 16, 67, 69, 2, 9, 17, 78, 70, 11, 13, + 83, 82, 83, 78, 73, 1, 73, 68, 70, 65, 3, 74, + 70, 69, 0, 79, 73, 80, 84, 65, 99, 76, 0, 70, + 12, 70, 65, 20, 68, 70, 65, 16, 78, 74, 95, + 26, 32, 33, 24, 12, 25, 21, 16, 15, 13, 12, 8, + 73, 76, 83, 68, 65, 75, 92, 75, 75, 79, 78, + 77, 72, 73, 87, 88, 83, 22, 21, 21, 15, 2, 9, + 6, 70, 0, 69, 70, 82, 83, 83, 85, 5, 8, 76, 5, + 4, 69, 75, 75, 77, 79, 79, 84, 93, 92, 98, + 100, 106, 86, 96, 103, 83, 69, 75, 2, 3, 4, + 48, 14, 13, 68, 23, 58, 44, 62, 13, 28, 21, + 70, 90, 96, 101, 126, 124, 122, 68, 43, 27, + 18, 9, 13, 2, 66, 68, 72, 76, 69, 5, 64, 14, + 12, 4, 7, 12, 15, 16, 8, 19, 16, 0, 29, 23, + 12, 5, 64, 70, 94, 97, 96 }, + + { + + 35, + 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 83, 11, + 18, 52, 14, 26, 67, 14, 23, 64, 75, 64, 87, + 103, 1, 0, 123, 125, 123, 37, 3, 69, 14, 23, + 64, 72, 6, 16, 64, 1, 67, 71, 68, 82, 75, 92, + 5, 69, 72, 64, 77, 74, 88, 12, 0, 65, 69, 7, + 3, 22, 0, 0, 0, 0, 94, 97, 7, 69, 68, 52, 6, + 69, 89, 73, 82, 5, 2, 67, 4, 74, 8, 67, 68, 2, + 85, 88, 87, 90, 27, 0, 12, 75, 0, 75, 68, 2, + 71, 83, 75, 83, 16, 71, 3, 76, 77, 1, 70, 3, + 9, 4, 6, 17, 14, 78, 66, 2, 66, 2, 73, 11, 67, + 7, 19, 1, 16, 17, 9, 84, 10, 65, 80, 68, 92, + 79, 67, 72, 1, 67, 66, 14, 64, 67, 5, 11, 72, + 72, 0, 98, 84, 67, 95, 66, 76, 13, 64, 78, 23, + 1, 65, 82, 24, 76, 89, 1, 98, 11, 22, 21, 17, + 22, 16, 5, 19, 21, 76, 1, 10, 3, 1, 76, 64, + 69, 71, 66, 72, 80, 67, 70, 99, 81, 76, 88, + 83, 89, 26, 32, 24, 23, 22, 14, 10, 14, 4, 66, + 2, 72, 83, 84, 106, 4, 1, 78, 64, 72, 75, 80, + 83, 88, 91, 92, 107, 78, 96, 105, 94, 101, 64, + 35, 24, 16, 6, 5, 65, 67, 71, 71, 7, 47, 31, + 24, 17, 34, 13, 7, 0, 64, 65, 41, 25, 15, 7, + 17, 5, 64, 68, 72, 72, 23, 9, 4, 65, 6, 67, + 72, 75, 3, 41, 24, 15, 8, 21, 6, 4, 2, 66, 62, + 79, 70, 2, 66, 68, 1, 8, 9, 64, 8, 14, 17, 76, + 71, 74, 65, 17, 68, 70, 1, 8, 17, 79, 71, 11, + 13, 83, 83, 83, 77, 72, 2, 72, 67, 69, 65, 4, + 74, 70, 69, 1, 79, 73, 80, 83, 64, 99, 76, 0, + 70, 13, 70, 65, 21, 68, 70, 65, 17, 79, 74, + 96, 25, 31, 32, 23, 11, 24, 20, 15, 14, 12, + 11, 7, 74, 77, 84, 69, 66, 76, 94, 77, 76, 80, + 78, 78, 72, 73, 87, 88, 82, 20, 19, 19, 13, + 64, 7, 4, 72, 65, 71, 72, 85, 85, 85, 86, 3, + 7, 78, 3, 2, 71, 77, 77, 79, 81, 81, 86, 96, + 94, 100, 102, 107, 88, 98, 104, 82, 68, 74, 3, + 4, 5, 49, 15, 14, 68, 24, 60, 46, 62, 14, 26, + 20, 72, 93, 99, 104, 126, 126, 123, 68, 43, + 27, 18, 9, 13, 2, 66, 68, 72, 75, 68, 6, 0, + 15, 12, 4, 8, 12, 15, 16, 8, 19, 16, 0, 28, + 22, 10, 3, 66, 72, 96, 99, 97 }, + + { + + 33, + 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 84, 10, + 16, 52, 14, 29, 68, 15, 23, 64, 76, 64, 88, + 104, 0, 65, 125, 126, 124, 40, 4, 69, 15, 23, + 64, 72, 7, 16, 65, 1, 67, 71, 68, 82, 74, 92, + 5, 69, 71, 65, 78, 74, 88, 12, 1, 65, 68, 7, + 3, 22, 0, 0, 0, 1, 95, 97, 7, 70, 68, 52, 6, + 69, 88, 72, 82, 5, 4, 66, 6, 73, 9, 66, 66, 4, + 84, 88, 86, 90, 27, 0, 13, 74, 0, 75, 67, 4, + 71, 83, 75, 82, 16, 70, 3, 75, 77, 1, 70, 4, + 9, 4, 6, 17, 14, 79, 67, 2, 66, 2, 73, 11, 67, + 6, 19, 1, 16, 17, 8, 86, 10, 65, 82, 69, 93, + 78, 66, 71, 2, 67, 65, 15, 0, 67, 6, 12, 72, + 72, 1, 99, 84, 66, 95, 66, 76, 13, 64, 79, 24, + 1, 65, 84, 25, 77, 90, 1, 99, 9, 21, 20, 16, + 21, 15, 4, 18, 21, 78, 0, 9, 3, 1, 76, 65, 69, + 72, 66, 73, 81, 68, 71, 101, 82, 77, 89, 84, + 89, 24, 31, 22, 21, 20, 12, 7, 12, 1, 68, 0, + 75, 86, 86, 109, 2, 0, 80, 67, 74, 77, 82, 86, + 90, 94, 94, 109, 79, 97, 107, 95, 101, 64, 35, + 25, 16, 6, 5, 65, 67, 71, 70, 8, 48, 31, 24, + 17, 35, 13, 8, 0, 0, 65, 42, 26, 15, 7, 17, 5, + 64, 67, 71, 72, 24, 9, 4, 65, 7, 66, 72, 74, + 3, 42, 24, 15, 8, 22, 7, 4, 3, 65, 62, 79, 70, + 2, 66, 68, 1, 8, 9, 0, 8, 14, 18, 76, 71, 74, + 66, 17, 69, 71, 0, 7, 17, 81, 72, 10, 13, 84, + 84, 84, 77, 72, 3, 72, 67, 69, 64, 5, 75, 70, + 69, 1, 80, 73, 80, 83, 0, 99, 76, 1, 70, 13, + 70, 65, 22, 68, 71, 65, 18, 79, 75, 97, 24, + 31, 32, 22, 10, 23, 19, 14, 13, 11, 10, 6, 75, + 78, 85, 71, 68, 78, 96, 78, 77, 81, 79, 78, + 72, 73, 87, 89, 82, 17, 16, 17, 10, 67, 5, 2, + 75, 67, 73, 74, 87, 87, 86, 87, 1, 5, 79, 1, + 0, 73, 79, 80, 81, 83, 83, 88, 98, 96, 102, + 104, 108, 90, 100, 106, 81, 67, 73, 3, 5, 6, + 51, 16, 15, 68, 25, 61, 47, 62, 14, 25, 18, + 75, 96, 102, 107, 126, 126, 124, 68, 43, 27, + 18, 9, 13, 2, 66, 68, 71, 74, 67, 7, 0, 16, + 13, 5, 9, 13, 16, 17, 9, 20, 17, 0, 26, 20, 8, + 1, 68, 74, 98, 101, 98 }, + + { + + 32, + 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 86, 8, + 15, 52, 14, 31, 68, 16, 24, 64, 76, 0, 89, + 105, 0, 67, 126, 126, 124, 43, 6, 69, 16, 24, + 64, 72, 8, 16, 65, 1, 67, 70, 68, 83, 74, 92, + 5, 69, 70, 65, 78, 74, 88, 13, 1, 64, 68, 8, + 3, 22, 0, 0, 0, 1, 95, 97, 8, 71, 68, 52, 6, + 69, 87, 71, 82, 6, 5, 64, 8, 71, 10, 64, 65, + 6, 83, 87, 85, 89, 28, 0, 14, 73, 0, 74, 66, + 6, 71, 83, 74, 80, 17, 70, 4, 74, 76, 2, 70, + 4, 10, 5, 7, 18, 15, 79, 67, 2, 66, 2, 73, 11, + 68, 5, 19, 0, 16, 17, 8, 88, 10, 66, 83, 70, + 94, 77, 65, 70, 3, 66, 64, 16, 1, 66, 7, 13, + 72, 72, 1, 100, 83, 65, 95, 65, 76, 14, 64, + 80, 25, 1, 65, 85, 26, 77, 91, 1, 99, 8, 20, + 20, 15, 20, 14, 3, 18, 21, 79, 64, 9, 3, 1, + 77, 65, 70, 73, 67, 74, 82, 68, 72, 103, 83, + 78, 90, 85, 89, 22, 30, 20, 19, 19, 10, 5, 10, + 64, 70, 65, 77, 88, 88, 111, 0, 65, 82, 69, + 76, 79, 84, 88, 92, 97, 96, 112, 80, 99, 108, + 95, 101, 64, 35, 25, 16, 6, 5, 65, 67, 71, 70, + 8, 48, 31, 24, 17, 36, 14, 9, 0, 1, 64, 43, + 27, 15, 8, 18, 6, 0, 67, 70, 71, 26, 10, 4, + 64, 8, 65, 71, 73, 4, 42, 25, 15, 8, 23, 8, 5, + 4, 64, 62, 79, 70, 3, 66, 68, 1, 8, 9, 0, 8, + 15, 18, 76, 71, 74, 67, 18, 70, 72, 64, 7, 17, + 82, 73, 10, 13, 85, 85, 84, 76, 71, 4, 71, 66, + 68, 64, 6, 75, 70, 69, 1, 81, 73, 80, 82, 1, + 99, 76, 1, 70, 14, 70, 65, 23, 68, 71, 65, 19, + 80, 75, 97, 23, 31, 31, 22, 9, 22, 18, 13, 13, + 10, 9, 5, 76, 79, 86, 72, 69, 79, 98, 79, 78, + 82, 80, 79, 72, 72, 87, 89, 81, 15, 14, 15, 8, + 69, 3, 0, 77, 69, 75, 76, 89, 89, 88, 88, 64, + 3, 80, 64, 65, 75, 81, 82, 83, 85, 85, 90, + 101, 98, 104, 106, 109, 92, 102, 107, 80, 65, + 72, 4, 6, 7, 53, 17, 16, 68, 26, 62, 49, 62, + 15, 23, 16, 77, 99, 104, 110, 126, 126, 125, + 68, 43, 27, 18, 9, 13, 2, 66, 68, 71, 73, 66, + 8, 1, 17, 14, 5, 10, 14, 17, 18, 9, 20, 17, 0, + 25, 19, 7, 0, 70, 76, 100, 103, 99 }, + + { + + 31, + 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 87, 7, + 14, 52, 14, 33, 68, 16, 25, 64, 77, 0, 90, + 106, 64, 68, 126, 126, 125, 46, 7, 69, 16, 25, + 64, 71, 9, 17, 66, 2, 66, 69, 69, 83, 74, 92, + 5, 68, 70, 65, 78, 73, 88, 13, 1, 64, 68, 8, + 3, 22, 0, 0, 0, 2, 95, 97, 8, 71, 69, 52, 6, + 69, 86, 71, 82, 6, 6, 1, 10, 70, 11, 1, 64, 8, + 82, 86, 84, 88, 29, 0, 15, 73, 1, 74, 66, 8, + 71, 82, 74, 79, 17, 70, 4, 72, 76, 3, 69, 4, + 10, 5, 8, 18, 15, 80, 67, 2, 66, 2, 73, 11, + 68, 5, 19, 64, 16, 17, 8, 90, 10, 66, 85, 71, + 95, 77, 64, 70, 3, 65, 64, 17, 1, 66, 7, 15, + 72, 72, 1, 101, 83, 64, 95, 65, 76, 15, 0, 81, + 25, 1, 65, 86, 27, 78, 92, 1, 100, 6, 19, 19, + 15, 19, 14, 3, 17, 20, 80, 65, 9, 3, 1, 77, + 66, 71, 74, 68, 74, 83, 69, 72, 105, 84, 78, + 91, 86, 89, 21, 28, 19, 17, 17, 8, 3, 8, 67, + 73, 67, 80, 91, 91, 114, 65, 67, 83, 71, 79, + 82, 87, 90, 95, 99, 99, 114, 81, 101, 109, 96, + 101, 0, 36, 25, 17, 6, 5, 65, 67, 71, 69, 8, + 48, 32, 24, 17, 37, 14, 9, 1, 1, 0, 44, 27, + 16, 8, 19, 6, 0, 66, 69, 70, 27, 11, 5, 64, 8, + 65, 70, 71, 4, 42, 25, 15, 9, 23, 8, 6, 4, 0, + 62, 78, 69, 3, 66, 68, 1, 8, 9, 0, 9, 15, 19, + 76, 71, 75, 67, 18, 71, 73, 65, 6, 17, 83, 74, + 10, 13, 85, 86, 85, 75, 70, 5, 71, 66, 68, 0, + 6, 75, 69, 68, 2, 81, 73, 80, 82, 2, 99, 76, + 1, 70, 15, 70, 65, 24, 69, 71, 65, 19, 81, 75, + 98, 22, 30, 31, 21, 8, 22, 18, 12, 12, 10, 8, + 4, 77, 80, 87, 74, 70, 81, 100, 81, 80, 83, + 80, 79, 72, 72, 86, 90, 80, 13, 12, 13, 6, 72, + 1, 65, 80, 71, 78, 78, 92, 91, 89, 88, 65, 2, + 82, 66, 68, 77, 83, 84, 85, 87, 88, 92, 103, + 100, 106, 107, 111, 94, 104, 109, 79, 64, 71, + 5, 7, 8, 54, 18, 17, 68, 27, 62, 50, 62, 16, + 22, 15, 80, 102, 107, 112, 126, 126, 126, 67, + 43, 27, 18, 9, 13, 2, 66, 68, 70, 72, 66, 9, + 2, 18, 14, 6, 11, 14, 17, 18, 9, 21, 17, 0, + 24, 17, 5, 65, 71, 77, 103, 104, 100 }, + + { + + 30, + 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 89, 5, + 12, 52, 14, 36, 69, 17, 25, 64, 78, 0, 91, + 107, 64, 70, 126, 126, 125, 49, 8, 69, 17, 25, + 64, 71, 10, 17, 66, 2, 66, 69, 69, 84, 73, 92, + 5, 68, 69, 66, 78, 73, 88, 14, 2, 64, 67, 9, + 3, 22, 0, 0, 0, 2, 95, 97, 9, 72, 69, 52, 6, + 69, 85, 70, 82, 7, 8, 2, 12, 68, 12, 2, 1, 10, + 81, 85, 83, 88, 30, 0, 16, 72, 1, 73, 65, 10, + 71, 82, 73, 78, 17, 69, 5, 71, 75, 3, 69, 5, + 10, 5, 9, 19, 16, 80, 68, 2, 66, 2, 73, 11, + 69, 4, 19, 64, 16, 17, 7, 92, 10, 67, 87, 72, + 96, 76, 0, 69, 4, 64, 0, 18, 2, 65, 8, 16, 72, + 72, 2, 102, 82, 0, 95, 65, 76, 15, 0, 82, 26, + 1, 65, 88, 28, 78, 93, 1, 101, 5, 18, 19, 14, + 18, 13, 2, 16, 20, 81, 66, 9, 3, 1, 78, 67, + 71, 75, 68, 75, 84, 70, 73, 107, 85, 79, 92, + 87, 89, 19, 27, 17, 15, 15, 6, 0, 6, 69, 75, + 69, 82, 93, 93, 116, 67, 68, 85, 74, 81, 84, + 89, 93, 97, 102, 101, 117, 82, 102, 111, 97, + 101, 0, 36, 26, 17, 6, 5, 65, 67, 71, 69, 9, + 49, 32, 24, 17, 38, 15, 10, 1, 2, 1, 45, 28, + 16, 8, 20, 7, 1, 66, 68, 70, 28, 11, 5, 64, 9, + 64, 70, 70, 5, 43, 25, 15, 9, 24, 9, 7, 5, 1, + 62, 78, 69, 4, 66, 68, 1, 8, 9, 1, 9, 15, 19, + 76, 71, 75, 68, 19, 72, 74, 66, 5, 17, 84, 75, + 9, 13, 86, 87, 85, 74, 70, 6, 70, 65, 67, 0, + 7, 75, 69, 68, 2, 82, 73, 80, 81, 3, 99, 76, + 2, 70, 15, 70, 65, 25, 69, 71, 65, 20, 81, 76, + 99, 21, 30, 30, 20, 7, 21, 17, 11, 11, 9, 7, + 3, 78, 81, 88, 75, 72, 82, 102, 82, 81, 84, + 81, 80, 72, 72, 86, 90, 79, 11, 10, 11, 3, 75, + 64, 67, 82, 73, 80, 80, 94, 93, 91, 89, 67, 0, + 83, 68, 70, 79, 85, 86, 87, 89, 90, 94, 106, + 102, 108, 109, 112, 96, 106, 110, 78, 0, 70, + 5, 8, 9, 56, 19, 18, 68, 28, 62, 52, 62, 16, + 20, 13, 82, 105, 110, 115, 126, 126, 126, 67, + 43, 27, 18, 9, 13, 2, 66, 68, 70, 71, 65, 10, + 3, 19, 15, 6, 12, 15, 18, 19, 10, 21, 18, 0, + 22, 16, 3, 67, 73, 79, 105, 106, 101 }, + + { + + 28, + 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 90, 4, + 11, 52, 14, 38, 69, 18, 26, 64, 79, 0, 92, + 109, 65, 72, 126, 126, 126, 51, 9, 69, 18, 26, + 64, 71, 11, 17, 67, 2, 66, 68, 70, 84, 73, 93, + 5, 68, 69, 66, 79, 73, 88, 14, 2, 64, 67, 9, + 3, 22, 0, 0, 0, 3, 96, 97, 9, 73, 69, 52, 6, + 69, 84, 69, 82, 7, 9, 4, 14, 67, 13, 4, 2, 11, + 80, 85, 82, 87, 30, 0, 17, 71, 1, 73, 65, 11, + 71, 82, 73, 77, 17, 69, 5, 70, 75, 4, 69, 5, + 10, 5, 9, 19, 16, 81, 68, 2, 66, 2, 73, 11, + 69, 3, 19, 65, 16, 17, 7, 94, 10, 67, 89, 73, + 97, 75, 1, 68, 5, 64, 0, 19, 2, 65, 9, 17, 72, + 72, 2, 104, 82, 1, 95, 65, 77, 16, 0, 83, 27, + 1, 65, 89, 29, 79, 94, 1, 102, 3, 17, 18, 13, + 17, 12, 1, 15, 19, 83, 67, 8, 3, 1, 78, 68, + 72, 76, 69, 76, 85, 71, 74, 109, 87, 80, 93, + 88, 89, 17, 25, 15, 13, 13, 4, 65, 4, 72, 78, + 71, 85, 96, 96, 119, 69, 70, 87, 76, 83, 87, + 92, 95, 100, 105, 103, 119, 83, 104, 112, 98, + 102, 0, 36, 26, 17, 6, 5, 65, 67, 71, 68, 9, + 49, 32, 24, 17, 39, 15, 10, 1, 2, 1, 46, 28, + 16, 8, 20, 7, 1, 65, 67, 69, 29, 12, 5, 64, + 10, 0, 69, 69, 5, 43, 25, 15, 9, 25, 9, 7, 6, + 1, 62, 78, 69, 4, 66, 68, 1, 8, 9, 1, 9, 15, + 20, 76, 71, 75, 69, 19, 73, 75, 67, 4, 17, 86, + 77, 9, 13, 87, 88, 86, 74, 69, 7, 70, 65, 67, + 1, 8, 76, 69, 68, 2, 83, 73, 80, 81, 3, 100, + 76, 2, 70, 16, 70, 65, 25, 69, 72, 65, 21, 82, + 76, 100, 20, 29, 30, 19, 5, 20, 16, 10, 10, 8, + 6, 2, 79, 82, 89, 77, 73, 84, 104, 84, 82, 85, + 82, 80, 72, 72, 86, 91, 79, 8, 7, 9, 1, 78, + 67, 70, 85, 75, 82, 82, 97, 95, 92, 90, 69, + 65, 85, 70, 72, 82, 88, 89, 90, 91, 92, 97, + 108, 104, 111, 111, 113, 98, 108, 112, 77, 1, + 69, 6, 9, 9, 57, 20, 18, 68, 28, 62, 53, 62, + 17, 19, 11, 85, 108, 113, 118, 126, 126, 126, + 67, 43, 27, 18, 9, 13, 2, 66, 68, 69, 71, 64, + 11, 3, 20, 15, 7, 12, 15, 18, 19, 10, 22, 18, + 64, 21, 14, 1, 69, 75, 81, 107, 108, 102 }, + + { + + 27, + 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 91, 3, + 10, 52, 14, 40, 69, 19, 27, 64, 79, 1, 93, + 110, 66, 74, 126, 126, 126, 54, 11, 69, 19, + 27, 64, 70, 12, 18, 68, 2, 65, 67, 70, 84, 73, + 93, 5, 68, 68, 66, 79, 73, 88, 14, 2, 0, 67, + 9, 3, 22, 0, 0, 0, 4, 96, 97, 9, 74, 69, 52, + 6, 69, 83, 68, 82, 7, 10, 6, 16, 65, 15, 6, 3, + 13, 79, 84, 81, 86, 31, 1, 18, 70, 1, 72, 64, + 13, 71, 81, 73, 75, 18, 69, 5, 68, 75, 5, 69, + 5, 11, 6, 10, 19, 16, 81, 68, 3, 66, 2, 72, + 11, 69, 3, 19, 66, 16, 17, 7, 96, 10, 67, 90, + 74, 97, 74, 2, 67, 6, 0, 1, 20, 3, 65, 10, 18, + 72, 72, 2, 105, 81, 2, 95, 64, 77, 17, 0, 84, + 28, 1, 65, 90, 30, 80, 95, 1, 102, 2, 16, 18, + 12, 16, 11, 1, 15, 19, 84, 68, 8, 3, 1, 78, + 68, 73, 77, 70, 77, 86, 71, 74, 110, 88, 80, + 94, 89, 89, 16, 24, 14, 12, 12, 2, 67, 2, 74, + 80, 73, 87, 99, 98, 122, 70, 72, 88, 78, 85, + 89, 94, 97, 102, 107, 105, 121, 83, 106, 113, + 98, 102, 0, 37, 26, 17, 7, 5, 65, 66, 71, 67, + 9, 49, 32, 25, 17, 40, 16, 11, 2, 3, 2, 47, + 29, 17, 9, 21, 8, 1, 64, 66, 68, 31, 13, 6, 0, + 11, 1, 68, 68, 6, 43, 26, 16, 9, 26, 10, 8, 7, + 2, 62, 77, 68, 5, 66, 68, 1, 9, 10, 1, 9, 16, + 21, 76, 71, 75, 69, 19, 74, 75, 68, 4, 17, 87, + 78, 9, 13, 87, 89, 87, 73, 68, 8, 70, 64, 67, + 2, 9, 76, 69, 68, 3, 83, 73, 80, 81, 4, 100, + 76, 2, 70, 17, 70, 65, 26, 69, 72, 65, 22, 83, + 76, 100, 19, 29, 30, 19, 4, 19, 15, 9, 10, 7, + 5, 2, 79, 83, 90, 78, 74, 86, 106, 85, 83, 85, + 82, 80, 71, 71, 86, 92, 78, 6, 5, 7, 64, 80, + 69, 72, 87, 77, 84, 84, 99, 97, 93, 91, 71, + 66, 86, 72, 74, 84, 90, 91, 92, 93, 94, 99, + 110, 105, 113, 113, 114, 100, 110, 114, 76, 3, + 67, 7, 10, 10, 59, 21, 19, 68, 29, 62, 54, 62, + 18, 18, 10, 87, 111, 115, 121, 126, 126, 126, + 67, 43, 27, 18, 9, 14, 2, 66, 68, 68, 70, 0, + 12, 4, 22, 16, 8, 13, 16, 19, 20, 10, 23, 18, + 64, 20, 13, 0, 70, 77, 83, 109, 110, 102 }, + + { + + 26, + 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 93, 1, + 8, 52, 14, 43, 70, 20, 27, 64, 80, 1, 94, 111, + 66, 76, 126, 126, 126, 57, 12, 69, 20, 27, 64, + 70, 13, 18, 68, 2, 65, 67, 70, 85, 72, 93, 5, + 68, 67, 67, 79, 73, 88, 15, 3, 0, 66, 10, 3, + 22, 0, 0, 0, 4, 96, 97, 10, 75, 69, 52, 6, 69, + 82, 67, 82, 8, 12, 7, 18, 64, 16, 7, 5, 15, + 78, 83, 80, 86, 32, 1, 19, 69, 1, 72, 0, 15, + 71, 81, 72, 74, 18, 68, 6, 67, 74, 5, 69, 6, + 11, 6, 11, 20, 17, 82, 69, 3, 66, 2, 72, 11, + 70, 2, 19, 66, 16, 17, 6, 98, 10, 68, 92, 75, + 98, 73, 3, 66, 7, 1, 2, 21, 4, 64, 11, 19, 72, + 72, 3, 106, 81, 3, 95, 64, 77, 17, 0, 85, 29, + 1, 65, 92, 31, 80, 96, 1, 103, 0, 15, 17, 11, + 15, 10, 0, 14, 19, 85, 69, 8, 3, 1, 79, 69, + 73, 78, 70, 78, 87, 72, 75, 112, 89, 81, 95, + 90, 89, 14, 23, 12, 10, 10, 0, 70, 0, 77, 82, + 75, 90, 101, 100, 124, 72, 73, 90, 81, 87, 91, + 96, 100, 104, 110, 107, 124, 84, 107, 115, 99, + 102, 0, 37, 27, 17, 7, 5, 65, 66, 71, 67, 10, + 50, 32, 25, 17, 41, 16, 12, 2, 4, 3, 48, 30, + 17, 9, 22, 8, 2, 64, 65, 68, 32, 13, 6, 0, 12, + 2, 68, 67, 6, 44, 26, 16, 9, 27, 11, 9, 8, 3, + 62, 77, 68, 5, 66, 68, 1, 9, 10, 2, 9, 16, 21, + 76, 71, 75, 70, 20, 75, 76, 69, 3, 17, 88, 79, + 8, 13, 88, 90, 87, 72, 68, 9, 69, 64, 66, 2, + 10, 76, 69, 68, 3, 84, 73, 80, 80, 5, 100, 76, + 3, 70, 17, 70, 65, 27, 69, 72, 65, 23, 83, 77, + 101, 18, 29, 29, 18, 3, 18, 14, 8, 9, 6, 4, 1, + 80, 84, 91, 80, 76, 87, 108, 86, 84, 86, 83, + 81, 71, 71, 86, 92, 77, 4, 3, 5, 67, 83, 71, + 74, 90, 79, 86, 86, 101, 99, 95, 92, 73, 68, + 87, 74, 76, 86, 92, 93, 94, 95, 96, 101, 113, + 107, 115, 115, 115, 102, 112, 115, 75, 4, 66, + 7, 11, 11, 61, 22, 20, 68, 30, 62, 56, 62, 18, + 16, 8, 90, 114, 118, 124, 126, 126, 126, 67, + 43, 27, 18, 9, 14, 2, 66, 68, 68, 69, 1, 13, + 5, 23, 17, 8, 14, 17, 20, 21, 11, 23, 19, 64, + 18, 11, 65, 72, 79, 85, 111, 112, 103 }, + + { + + 25, + 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 94, 0, + 7, 52, 14, 45, 70, 20, 28, 64, 81, 1, 95, 112, + 67, 77, 126, 126, 126, 60, 13, 69, 20, 28, 64, + 69, 14, 19, 69, 3, 64, 66, 71, 85, 72, 93, 5, + 67, 67, 67, 79, 72, 88, 15, 3, 0, 66, 10, 3, + 22, 0, 0, 0, 5, 96, 97, 10, 75, 70, 52, 6, 69, + 81, 67, 82, 8, 13, 9, 20, 1, 17, 9, 6, 17, 77, + 82, 79, 85, 33, 1, 20, 69, 2, 71, 0, 17, 71, + 80, 72, 73, 18, 68, 6, 65, 74, 6, 68, 6, 11, + 6, 12, 20, 17, 82, 69, 3, 66, 2, 72, 11, 70, + 2, 19, 67, 16, 17, 6, 100, 10, 68, 94, 76, 99, + 73, 4, 66, 7, 2, 2, 22, 4, 64, 11, 21, 72, 72, + 3, 107, 80, 4, 95, 64, 77, 18, 1, 86, 29, 1, + 65, 93, 32, 81, 97, 1, 104, 64, 14, 17, 11, + 14, 10, 0, 13, 18, 86, 70, 8, 3, 1, 79, 70, + 74, 79, 71, 78, 88, 73, 75, 114, 90, 81, 96, + 91, 89, 13, 21, 11, 8, 8, 65, 72, 65, 79, 85, + 77, 92, 104, 103, 126, 74, 75, 91, 83, 90, 94, + 99, 102, 107, 112, 110, 126, 85, 109, 116, + 100, 102, 1, 38, 27, 18, 7, 5, 65, 66, 71, 66, + 10, 50, 33, 25, 17, 42, 17, 12, 3, 4, 4, 49, + 30, 18, 9, 23, 9, 2, 0, 64, 67, 33, 14, 7, 0, + 12, 2, 67, 65, 7, 44, 26, 16, 10, 27, 11, 10, + 8, 4, 62, 76, 67, 6, 66, 68, 1, 9, 10, 2, 10, + 16, 22, 76, 71, 76, 70, 20, 76, 77, 70, 2, 17, + 89, 80, 8, 13, 88, 91, 88, 71, 67, 10, 69, 0, + 66, 3, 10, 76, 68, 67, 4, 84, 73, 80, 80, 6, + 100, 76, 3, 70, 18, 70, 65, 28, 70, 72, 65, + 23, 84, 77, 102, 17, 28, 29, 17, 2, 18, 14, 7, + 8, 6, 3, 0, 81, 85, 92, 81, 77, 89, 110, 88, + 86, 87, 83, 81, 71, 71, 85, 93, 76, 2, 1, 3, + 69, 86, 73, 76, 92, 81, 89, 88, 104, 101, 96, + 92, 74, 69, 89, 76, 79, 88, 94, 95, 96, 97, + 99, 103, 115, 109, 117, 116, 117, 104, 114, + 117, 74, 5, 65, 8, 12, 12, 62, 23, 21, 68, 31, + 62, 57, 62, 19, 15, 7, 92, 117, 121, 126, 126, + 126, 126, 66, 43, 27, 18, 9, 14, 2, 66, 68, + 67, 68, 1, 14, 6, 24, 17, 9, 15, 17, 20, 21, + 11, 24, 19, 64, 17, 10, 67, 74, 80, 86, 114, + 113, 104 }, + + { + + 23, + 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 96, 65, + 6, 52, 14, 47, 70, 21, 29, 64, 82, 1, 96, 113, + 67, 79, 126, 126, 126, 62, 14, 69, 21, 29, 64, + 69, 15, 19, 69, 3, 64, 65, 71, 86, 72, 93, 5, + 67, 66, 67, 80, 72, 88, 16, 3, 0, 66, 11, 3, + 22, 0, 0, 0, 5, 97, 97, 11, 76, 70, 52, 6, 69, + 80, 66, 82, 9, 14, 11, 22, 2, 18, 11, 7, 19, + 76, 82, 78, 84, 33, 1, 21, 68, 2, 71, 1, 19, + 71, 80, 71, 72, 18, 68, 7, 64, 73, 7, 68, 6, + 11, 6, 12, 21, 18, 83, 69, 3, 66, 2, 72, 11, + 71, 1, 19, 68, 16, 17, 6, 102, 10, 69, 96, 77, + 100, 72, 5, 65, 8, 2, 3, 23, 5, 0, 12, 22, 72, + 72, 3, 108, 80, 5, 95, 64, 77, 19, 1, 87, 30, + 1, 65, 94, 33, 81, 98, 1, 105, 66, 13, 16, 10, + 13, 9, 64, 12, 18, 88, 71, 7, 3, 1, 80, 71, + 75, 80, 72, 79, 89, 74, 76, 116, 91, 82, 97, + 92, 89, 11, 20, 9, 6, 6, 67, 74, 67, 82, 87, + 79, 95, 106, 105, 126, 76, 77, 93, 85, 92, 96, + 101, 104, 109, 115, 112, 126, 86, 111, 117, + 101, 102, 1, 38, 27, 18, 7, 5, 65, 66, 71, 66, + 10, 50, 33, 25, 17, 43, 17, 13, 3, 5, 4, 50, + 31, 18, 9, 23, 9, 3, 0, 0, 66, 34, 15, 7, 0, + 13, 3, 66, 64, 7, 44, 26, 16, 10, 28, 12, 10, + 9, 5, 62, 76, 67, 6, 66, 68, 1, 9, 10, 2, 10, + 16, 22, 76, 71, 76, 71, 21, 77, 78, 71, 1, 17, + 91, 81, 8, 13, 89, 92, 88, 71, 66, 11, 68, 0, + 65, 3, 11, 77, 68, 67, 4, 85, 73, 80, 79, 7, + 100, 76, 3, 70, 19, 70, 65, 29, 70, 73, 65, + 24, 85, 77, 103, 16, 28, 28, 16, 1, 17, 13, 6, + 7, 5, 2, 64, 82, 86, 93, 83, 78, 90, 112, 89, + 87, 88, 84, 82, 71, 71, 85, 93, 76, 64, 65, 1, + 71, 89, 75, 78, 95, 83, 91, 90, 106, 103, 98, + 93, 76, 71, 90, 78, 81, 90, 96, 98, 98, 99, + 101, 105, 118, 111, 119, 118, 118, 106, 116, + 118, 73, 6, 64, 9, 13, 13, 62, 24, 22, 68, 32, + 62, 59, 62, 20, 13, 5, 95, 120, 124, 126, 126, + 126, 126, 66, 43, 27, 18, 9, 14, 2, 66, 68, + 67, 67, 2, 15, 6, 25, 18, 9, 16, 18, 21, 22, + 11, 24, 19, 64, 16, 8, 69, 76, 82, 88, 116, + 115, 105 }, + + { + + 22, + 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 66, + 4, 52, 14, 50, 71, 22, 29, 64, 82, 2, 97, 114, + 68, 81, 126, 126, 126, 62, 16, 69, 22, 29, 64, + 69, 16, 19, 70, 3, 64, 65, 71, 86, 71, 93, 5, + 67, 65, 68, 80, 72, 88, 16, 4, 1, 65, 11, 3, + 22, 0, 0, 0, 6, 97, 97, 11, 77, 70, 52, 6, 69, + 79, 65, 82, 9, 16, 12, 24, 4, 19, 12, 9, 21, + 75, 81, 77, 84, 34, 1, 22, 67, 2, 70, 2, 21, + 71, 80, 71, 70, 19, 67, 7, 0, 73, 7, 68, 7, + 12, 7, 13, 21, 18, 83, 70, 3, 66, 2, 72, 11, + 71, 0, 19, 68, 16, 17, 5, 104, 10, 69, 97, 78, + 101, 71, 6, 64, 9, 3, 4, 24, 6, 0, 13, 23, 72, + 72, 4, 109, 79, 6, 95, 0, 77, 19, 1, 88, 31, + 1, 65, 96, 34, 82, 99, 1, 105, 67, 12, 16, 9, + 12, 8, 65, 12, 18, 89, 72, 7, 3, 1, 80, 71, + 75, 81, 72, 80, 90, 74, 77, 118, 92, 83, 98, + 93, 89, 9, 19, 7, 4, 5, 69, 77, 69, 84, 89, + 81, 97, 109, 107, 126, 78, 78, 95, 88, 94, 98, + 103, 107, 111, 118, 114, 126, 87, 112, 119, + 101, 102, 1, 38, 28, 18, 7, 5, 65, 66, 71, 65, + 11, 51, 33, 25, 17, 44, 18, 14, 3, 6, 5, 51, + 32, 18, 10, 24, 10, 3, 1, 1, 66, 36, 15, 7, 1, + 14, 4, 66, 0, 8, 45, 27, 16, 10, 29, 13, 11, + 10, 6, 62, 76, 67, 7, 66, 68, 1, 9, 10, 3, 10, + 17, 23, 76, 71, 76, 72, 21, 78, 79, 72, 1, 17, + 92, 82, 7, 13, 90, 93, 89, 70, 66, 12, 68, 1, + 65, 4, 12, 77, 68, 67, 4, 86, 73, 80, 79, 8, + 100, 76, 4, 70, 19, 70, 65, 30, 70, 73, 65, + 25, 85, 78, 103, 15, 28, 28, 16, 0, 16, 12, 5, + 7, 4, 1, 65, 83, 87, 94, 84, 80, 92, 114, 90, + 88, 89, 85, 82, 71, 70, 85, 94, 75, 66, 67, + 64, 74, 91, 77, 80, 97, 85, 93, 92, 108, 105, + 99, 94, 78, 73, 91, 80, 83, 92, 98, 100, 100, + 101, 103, 107, 120, 113, 121, 120, 119, 108, + 118, 120, 72, 8, 0, 9, 14, 14, 62, 25, 23, 68, + 33, 62, 60, 62, 20, 12, 3, 97, 123, 126, 126, + 126, 126, 126, 66, 43, 27, 18, 9, 14, 2, 66, + 68, 66, 66, 3, 16, 7, 26, 19, 10, 17, 19, 22, + 23, 12, 25, 20, 64, 14, 7, 70, 77, 84, 90, + 118, 117, 106 }, + + { + + 21, + 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 68, + 3, 52, 14, 52, 71, 23, 30, 64, 83, 2, 98, 115, + 68, 83, 126, 126, 126, 62, 17, 69, 23, 30, 64, + 68, 17, 20, 70, 3, 0, 64, 72, 87, 71, 93, 5, + 67, 65, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, + 22, 0, 0, 0, 6, 97, 97, 12, 78, 70, 52, 6, 69, + 78, 64, 82, 10, 17, 14, 26, 5, 20, 14, 10, 23, + 74, 80, 76, 83, 35, 1, 23, 66, 2, 70, 2, 23, + 71, 79, 70, 69, 19, 67, 8, 2, 72, 8, 68, 7, + 12, 7, 14, 22, 19, 84, 70, 3, 66, 2, 72, 11, + 72, 0, 19, 69, 16, 17, 5, 106, 10, 70, 99, 79, + 102, 70, 7, 0, 10, 4, 4, 25, 6, 1, 14, 24, 72, + 72, 4, 110, 79, 7, 95, 0, 77, 20, 1, 89, 32, + 1, 65, 97, 35, 82, 100, 1, 106, 69, 11, 15, 8, + 11, 7, 65, 11, 17, 90, 73, 7, 3, 1, 81, 72, + 76, 82, 73, 81, 91, 75, 77, 120, 93, 83, 99, + 94, 89, 8, 17, 6, 2, 3, 71, 79, 71, 87, 92, + 83, 100, 111, 110, 126, 80, 80, 96, 90, 96, + 101, 106, 109, 114, 120, 116, 126, 88, 114, + 120, 102, 102, 1, 39, 28, 18, 7, 5, 65, 66, + 71, 65, 11, 51, 33, 25, 17, 45, 18, 14, 4, 6, + 6, 52, 32, 19, 10, 25, 10, 4, 1, 2, 65, 37, + 16, 8, 1, 15, 5, 65, 1, 8, 45, 27, 16, 10, 30, + 13, 12, 11, 7, 62, 75, 66, 7, 66, 68, 1, 9, + 10, 3, 10, 17, 23, 76, 71, 76, 72, 22, 79, 80, + 73, 0, 17, 93, 83, 7, 13, 90, 94, 89, 69, 65, + 13, 67, 1, 64, 4, 13, 77, 68, 67, 5, 86, 73, + 80, 78, 9, 100, 76, 4, 70, 20, 70, 65, 31, 70, + 73, 65, 26, 86, 78, 104, 14, 27, 27, 15, 64, + 15, 11, 4, 6, 3, 0, 66, 84, 88, 95, 86, 81, + 93, 116, 92, 89, 90, 85, 83, 71, 70, 85, 94, + 74, 68, 69, 66, 76, 94, 79, 82, 100, 87, 95, + 94, 111, 107, 101, 95, 80, 74, 93, 82, 85, 94, + 100, 102, 102, 103, 105, 109, 123, 115, 123, + 122, 120, 110, 120, 121, 71, 9, 1, 10, 15, 15, + 62, 26, 24, 68, 34, 62, 62, 62, 21, 10, 2, + 100, 126, 126, 126, 126, 126, 126, 66, 43, 27, + 18, 9, 14, 2, 66, 68, 66, 65, 4, 17, 8, 27, + 19, 10, 18, 19, 22, 23, 12, 25, 20, 64, 13, 5, + 72, 79, 86, 92, 120, 119, 107 }, + + { + + 20, + 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 100, 69, + 2, 52, 14, 54, 71, 24, 31, 64, 84, 2, 99, 116, + 69, 85, 126, 126, 126, 62, 18, 69, 24, 31, 64, + 68, 18, 20, 71, 3, 0, 0, 72, 87, 71, 93, 5, + 67, 64, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, + 22, 0, 0, 0, 7, 97, 97, 12, 79, 70, 52, 6, 69, + 77, 0, 82, 10, 18, 16, 28, 7, 21, 16, 11, 25, + 73, 79, 75, 82, 36, 1, 24, 65, 2, 69, 3, 25, + 71, 79, 70, 68, 19, 67, 8, 3, 72, 9, 68, 7, + 12, 7, 15, 22, 19, 84, 70, 3, 66, 2, 72, 11, + 72, 64, 19, 70, 16, 17, 5, 108, 10, 70, 101, + 80, 103, 69, 8, 1, 11, 5, 5, 26, 7, 1, 15, 25, + 72, 72, 4, 111, 78, 8, 95, 0, 77, 21, 1, 90, + 33, 1, 65, 98, 36, 83, 101, 1, 107, 70, 10, + 15, 7, 10, 6, 66, 10, 17, 91, 74, 7, 3, 1, 81, + 73, 77, 83, 74, 82, 92, 76, 78, 122, 94, 84, + 100, 95, 89, 6, 16, 4, 0, 1, 73, 81, 73, 89, + 94, 85, 102, 114, 112, 126, 82, 82, 98, 92, + 98, 103, 108, 111, 116, 123, 118, 126, 89, + 116, 121, 103, 102, 1, 39, 28, 18, 7, 5, 65, + 66, 71, 64, 11, 51, 33, 25, 17, 46, 19, 15, 4, + 7, 7, 53, 33, 19, 10, 26, 11, 4, 2, 3, 64, 38, + 17, 8, 1, 16, 6, 64, 2, 9, 45, 27, 16, 10, 31, + 14, 13, 12, 8, 62, 75, 66, 8, 66, 68, 1, 9, + 10, 3, 10, 17, 24, 76, 71, 76, 73, 22, 80, 81, + 74, 64, 17, 94, 84, 7, 13, 91, 95, 90, 68, 64, + 14, 67, 2, 64, 5, 14, 77, 68, 67, 5, 87, 73, + 80, 78, 10, 100, 76, 4, 70, 21, 70, 65, 32, + 70, 73, 65, 27, 87, 78, 105, 13, 27, 27, 14, + 65, 14, 10, 3, 5, 2, 64, 67, 85, 89, 96, 87, + 82, 95, 118, 93, 90, 91, 86, 83, 71, 70, 85, + 95, 73, 70, 71, 68, 78, 97, 81, 84, 102, 89, + 97, 96, 113, 109, 102, 96, 82, 76, 94, 84, 87, + 96, 102, 104, 104, 105, 107, 111, 125, 117, + 125, 124, 121, 112, 122, 123, 70, 10, 2, 11, + 16, 16, 62, 27, 25, 68, 35, 62, 62, 62, 22, 9, + 0, 102, 126, 126, 126, 126, 126, 126, 66, 43, + 27, 18, 9, 14, 2, 66, 68, 65, 64, 5, 18, 9, + 28, 20, 11, 19, 20, 23, 24, 12, 26, 20, 64, + 12, 4, 74, 81, 88, 94, 122, 121, 108 }, + + { + + 18, + 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 102, 71, + 0, 51, 14, 56, 72, 24, 31, 65, 85, 2, 101, + 118, 70, 87, 126, 126, 126, 62, 19, 70, 24, + 31, 65, 68, 19, 20, 72, 3, 0, 0, 73, 88, 71, + 94, 5, 67, 64, 69, 81, 72, 88, 17, 4, 1, 65, + 12, 2, 22, 0, 0, 0, 7, 98, 97, 12, 80, 71, 52, + 5, 69, 76, 0, 82, 10, 19, 17, 29, 8, 22, 17, + 12, 26, 72, 79, 74, 82, 36, 1, 24, 65, 2, 69, + 3, 26, 71, 79, 70, 67, 19, 67, 8, 4, 72, 9, + 68, 7, 12, 7, 15, 22, 19, 85, 71, 3, 67, 2, + 72, 10, 73, 65, 19, 71, 15, 17, 4, 110, 9, 71, + 103, 81, 104, 69, 8, 1, 11, 5, 5, 27, 7, 1, + 15, 26, 73, 72, 4, 113, 78, 8, 95, 0, 78, 21, + 1, 91, 33, 1, 65, 100, 36, 84, 102, 1, 108, + 72, 9, 14, 6, 9, 5, 67, 9, 16, 93, 75, 6, 2, + 1, 82, 74, 78, 84, 75, 83, 93, 77, 79, 124, + 96, 85, 102, 97, 89, 4, 14, 2, 65, 64, 76, 84, + 76, 92, 97, 88, 105, 117, 115, 126, 84, 84, + 100, 95, 101, 106, 111, 114, 119, 126, 121, + 126, 90, 118, 123, 104, 103, 1, 39, 28, 18, 7, + 5, 66, 66, 71, 64, 11, 51, 33, 25, 17, 47, 19, + 15, 4, 7, 7, 53, 33, 19, 10, 26, 11, 4, 2, 4, + 64, 39, 17, 8, 1, 16, 6, 64, 3, 9, 45, 27, 16, + 10, 31, 14, 13, 12, 8, 62, 75, 66, 8, 66, 68, + 1, 9, 10, 3, 10, 17, 24, 76, 71, 77, 74, 22, + 81, 82, 75, 65, 16, 96, 86, 6, 12, 92, 97, 91, + 68, 64, 15, 67, 2, 64, 5, 14, 78, 68, 67, 5, + 88, 73, 80, 78, 10, 101, 76, 4, 70, 21, 71, + 65, 32, 71, 74, 65, 27, 88, 79, 106, 12, 26, + 26, 13, 67, 13, 9, 2, 4, 1, 65, 68, 86, 91, + 98, 89, 84, 97, 120, 95, 92, 92, 87, 84, 71, + 70, 85, 96, 73, 73, 74, 70, 81, 100, 84, 87, + 105, 92, 100, 99, 116, 112, 104, 97, 84, 78, + 96, 86, 90, 99, 105, 107, 107, 107, 110, 114, + 126, 119, 126, 126, 123, 114, 124, 125, 69, + 11, 3, 11, 16, 16, 62, 27, 25, 68, 35, 62, 62, + 62, 22, 7, 65, 105, 126, 126, 126, 126, 126, + 126, 66, 43, 26, 17, 9, 14, 2, 67, 68, 65, 64, + 5, 18, 9, 29, 20, 11, 19, 20, 23, 24, 12, 26, + 20, 65, 10, 2, 76, 83, 90, 96, 125, 123, 109 }, + + { + + 17, + 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 103, 72, + 64, 51, 14, 59, 72, 25, 32, 65, 85, 3, 102, + 119, 70, 88, 126, 126, 126, 62, 21, 70, 25, + 32, 65, 67, 21, 21, 72, 4, 1, 1, 73, 88, 70, + 94, 5, 66, 0, 69, 81, 71, 88, 18, 5, 2, 64, + 13, 2, 22, 0, 0, 0, 8, 98, 97, 13, 80, 71, 52, + 5, 69, 74, 1, 82, 11, 21, 19, 31, 10, 24, 19, + 14, 28, 70, 78, 73, 81, 37, 2, 25, 64, 3, 68, + 4, 28, 70, 78, 69, 65, 20, 66, 9, 6, 71, 10, + 67, 8, 13, 8, 16, 23, 20, 85, 71, 4, 67, 2, + 71, 10, 73, 65, 19, 71, 15, 17, 4, 111, 9, 71, + 104, 82, 104, 68, 9, 2, 12, 6, 6, 28, 8, 2, + 16, 28, 73, 72, 5, 114, 77, 9, 95, 1, 78, 22, + 2, 91, 34, 1, 65, 101, 37, 84, 103, 1, 108, + 73, 9, 14, 6, 9, 5, 67, 9, 16, 94, 75, 6, 2, + 1, 82, 74, 78, 84, 75, 83, 94, 77, 79, 125, + 97, 85, 103, 98, 89, 3, 13, 1, 66, 65, 78, 86, + 78, 94, 99, 90, 107, 119, 117, 126, 85, 85, + 101, 97, 103, 108, 113, 116, 121, 126, 123, + 126, 90, 119, 124, 104, 103, 2, 40, 29, 19, 8, + 5, 66, 65, 70, 0, 12, 52, 34, 26, 17, 48, 20, + 16, 5, 8, 8, 54, 34, 20, 11, 27, 12, 5, 3, 6, + 0, 41, 18, 9, 2, 17, 7, 0, 5, 10, 46, 28, 17, + 11, 32, 15, 14, 13, 9, 62, 74, 65, 9, 66, 67, + 1, 10, 11, 4, 11, 18, 25, 75, 71, 77, 74, 23, + 81, 82, 76, 65, 16, 97, 87, 6, 12, 92, 98, 91, + 67, 0, 16, 66, 3, 0, 6, 15, 78, 67, 66, 6, 88, + 72, 79, 77, 11, 101, 76, 5, 70, 22, 71, 65, + 33, 71, 74, 64, 28, 88, 79, 106, 12, 26, 26, + 13, 68, 13, 9, 2, 4, 1, 65, 68, 86, 92, 99, + 90, 85, 98, 121, 96, 93, 92, 87, 84, 70, 69, + 84, 96, 72, 75, 76, 72, 83, 102, 86, 89, 107, + 94, 102, 101, 118, 114, 105, 97, 85, 79, 97, + 87, 92, 101, 107, 109, 109, 109, 112, 116, + 126, 120, 126, 126, 124, 115, 125, 126, 67, + 13, 5, 12, 17, 17, 62, 28, 26, 68, 36, 62, 62, + 62, 23, 6, 66, 107, 126, 126, 126, 126, 126, + 126, 65, 44, 26, 17, 9, 15, 2, 67, 68, 64, 0, + 6, 19, 10, 31, 21, 12, 20, 21, 24, 25, 13, 27, + 21, 65, 9, 1, 77, 84, 91, 97, 126, 124, 109 }, + + { + + 16, + 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 104, 73, + 65, 51, 14, 61, 72, 26, 33, 65, 86, 3, 103, + 120, 71, 90, 126, 126, 126, 62, 22, 70, 26, + 33, 65, 67, 22, 21, 73, 4, 1, 2, 73, 88, 70, + 94, 5, 66, 1, 69, 81, 71, 88, 18, 5, 2, 64, + 13, 2, 22, 0, 0, 0, 9, 98, 97, 13, 81, 71, 52, + 5, 69, 73, 2, 82, 11, 22, 21, 33, 11, 25, 21, + 15, 30, 69, 77, 72, 80, 38, 2, 26, 0, 3, 68, + 5, 30, 70, 78, 69, 64, 20, 66, 9, 7, 71, 11, + 67, 8, 13, 8, 17, 23, 20, 86, 71, 4, 67, 2, + 71, 10, 73, 66, 19, 72, 15, 17, 4, 113, 9, 71, + 106, 83, 105, 67, 10, 3, 13, 7, 7, 29, 9, 2, + 17, 29, 73, 72, 5, 115, 77, 10, 95, 1, 78, 23, + 2, 92, 35, 1, 65, 102, 38, 85, 104, 1, 109, + 75, 8, 13, 5, 8, 4, 68, 8, 16, 95, 76, 6, 2, + 1, 82, 75, 79, 85, 76, 84, 95, 78, 80, 126, + 98, 86, 104, 99, 89, 1, 12, 64, 68, 67, 80, + 88, 80, 97, 101, 92, 110, 122, 119, 126, 87, + 87, 103, 99, 105, 110, 115, 118, 123, 126, + 125, 126, 91, 121, 125, 105, 103, 2, 40, 29, + 19, 8, 5, 66, 65, 70, 1, 12, 52, 34, 26, 17, + 49, 20, 17, 5, 9, 9, 55, 35, 20, 11, 28, 12, + 5, 4, 7, 1, 42, 19, 9, 2, 18, 8, 1, 6, 10, 46, + 28, 17, 11, 33, 16, 15, 14, 10, 62, 74, 65, 9, + 66, 67, 1, 10, 11, 4, 11, 18, 26, 75, 71, 77, + 75, 23, 82, 83, 77, 66, 16, 98, 88, 6, 12, 93, + 99, 92, 66, 1, 17, 66, 3, 0, 7, 16, 78, 67, + 66, 6, 89, 72, 79, 77, 12, 101, 76, 5, 70, 23, + 71, 65, 34, 71, 74, 64, 29, 89, 79, 107, 11, + 26, 26, 12, 69, 12, 8, 1, 3, 0, 66, 69, 87, + 93, 100, 92, 86, 100, 123, 97, 94, 93, 88, 84, + 70, 69, 84, 97, 71, 77, 78, 74, 85, 105, 88, + 91, 110, 96, 104, 103, 120, 116, 106, 98, 87, + 81, 98, 89, 94, 103, 109, 111, 111, 111, 114, + 118, 126, 122, 126, 126, 125, 117, 126, 126, + 66, 14, 6, 13, 18, 18, 62, 29, 27, 68, 37, 62, + 62, 62, 24, 5, 68, 110, 126, 126, 126, 126, + 126, 126, 65, 44, 26, 17, 9, 15, 2, 67, 68, 0, + 1, 7, 20, 11, 32, 22, 13, 21, 22, 25, 26, 13, + 28, 21, 65, 8, 64, 79, 86, 93, 99, 126, 126, + 110 }, + + { + + 15, + 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 106, 75, + 66, 51, 14, 62, 72, 27, 34, 65, 87, 3, 104, + 121, 71, 92, 126, 126, 126, 62, 23, 70, 27, + 34, 65, 66, 23, 22, 73, 4, 2, 3, 74, 89, 70, + 94, 5, 66, 1, 69, 81, 71, 88, 19, 5, 2, 64, + 14, 2, 22, 0, 0, 0, 9, 98, 97, 14, 82, 71, 52, + 5, 69, 72, 3, 82, 12, 23, 23, 35, 13, 26, 23, + 16, 32, 68, 76, 71, 79, 39, 2, 27, 1, 3, 67, + 5, 32, 70, 77, 68, 0, 20, 66, 10, 9, 70, 12, + 67, 8, 13, 8, 18, 24, 21, 86, 71, 4, 67, 2, + 71, 10, 74, 66, 19, 73, 15, 17, 4, 115, 9, 72, + 108, 84, 106, 66, 11, 4, 14, 8, 7, 30, 9, 3, + 18, 30, 73, 72, 5, 116, 76, 11, 95, 1, 78, 24, + 2, 93, 36, 1, 65, 103, 39, 85, 105, 1, 110, + 76, 7, 13, 4, 7, 3, 68, 7, 15, 96, 77, 6, 2, + 1, 83, 76, 80, 86, 77, 85, 96, 79, 80, 126, + 99, 86, 105, 100, 89, 0, 10, 65, 70, 69, 82, + 90, 82, 99, 104, 94, 112, 124, 122, 126, 89, + 89, 104, 101, 107, 113, 118, 120, 126, 126, + 126, 126, 92, 123, 126, 106, 103, 2, 41, 29, + 19, 8, 5, 66, 65, 70, 1, 12, 52, 34, 26, 17, + 50, 21, 17, 6, 9, 10, 56, 35, 21, 11, 29, 13, + 6, 4, 8, 2, 43, 20, 10, 2, 19, 9, 2, 7, 11, + 46, 28, 17, 11, 34, 16, 16, 15, 11, 62, 73, + 64, 10, 66, 67, 1, 10, 11, 4, 11, 18, 26, 75, + 71, 77, 75, 24, 83, 84, 78, 67, 16, 99, 89, 6, + 12, 93, 100, 92, 65, 2, 18, 65, 4, 1, 7, 17, + 78, 67, 66, 7, 89, 72, 79, 76, 13, 101, 76, 5, + 70, 24, 71, 65, 35, 71, 74, 64, 30, 90, 79, + 108, 10, 25, 25, 11, 70, 11, 7, 0, 2, 64, 67, + 70, 88, 94, 101, 93, 87, 101, 125, 99, 95, 94, + 88, 85, 70, 69, 84, 97, 70, 79, 80, 76, 87, + 108, 90, 93, 112, 98, 106, 105, 123, 118, 108, + 99, 89, 82, 100, 91, 96, 105, 111, 113, 113, + 113, 116, 120, 126, 124, 126, 126, 126, 119, + 126, 126, 65, 15, 7, 14, 19, 19, 62, 30, 28, + 68, 38, 62, 62, 62, 25, 3, 69, 112, 126, 126, + 126, 126, 126, 126, 65, 44, 26, 17, 9, 15, 2, + 67, 68, 0, 2, 8, 21, 12, 33, 22, 13, 22, 22, + 25, 26, 13, 28, 21, 65, 7, 65, 81, 88, 95, + 101, 126, 126, 111 }, + + }, + +}; diff --git a/common/ih264_cabac_tables.h b/common/ih264_cabac_tables.h index 5cddc45..72377a3 100644 --- a/common/ih264_cabac_tables.h +++ b/common/ih264_cabac_tables.h @@ -20,22 +20,23 @@ /** ****************************************************************************** -* @file ih264_cabac_tables.h +* @file +* ih264_cabac_tables.h * * @brief * This file contains enumerations, macros and extern declarations of H264 * cabac tables * * @author -* Ittiam +* ittiam * * @remarks * none ****************************************************************************** */ -#ifndef IH264_CABAC_TABLES_H_ -#define IH264_CABAC_TABLES_H_ +#ifndef _IH264_CABAC_TABLES_H_ +#define _IH264_CABAC_TABLES_H_ /*****************************************************************************/ /* Constant Macros */ @@ -86,8 +87,7 @@ /** ****************************************************************************** - * @enum ctxBlockCat - +* @enum ctxBlockCat ****************************************************************************** */ typedef enum @@ -104,8 +104,7 @@ typedef enum /** ****************************************************************************** - * @enum ctxIdxOffset - +* @enum ctxIdxOffset ****************************************************************************** */ typedef enum @@ -151,10 +150,10 @@ typedef enum } cabac_table_num_t; + /** ****************************************************************************** - * @enum ctxIdxOffset - +* @enum ctxIdxOffset ****************************************************************************** */ typedef enum @@ -174,22 +173,10 @@ typedef enum } cabac_blk_cat_offset_t; - - /*****************************************************************************/ -/* Extern global declarations */ +/* Global declarations */ /*****************************************************************************/ - - -/* CABAC Table declaration*/ extern const UWORD32 gau4_ih264_cabac_table[128][4]; - - -/*****************************************************************************/ -/* Cabac tables for context initialization depending upon type of Slice, */ -/* cabac init Idc value and Qp. */ -/*****************************************************************************/ extern const UWORD8 gau1_ih264_cabac_ctxt_init_table[NUM_CAB_INIT_IDC_PLUS_ONE][QP_RANGE][NUM_CABAC_CTXTS]; - -#endif /* IH264_CABAC_TABLES_H_ */ +#endif /* _IH264_CABAC_TABLES_H_ */ diff --git a/common/ih264_cavlc_tables.c b/common/ih264_cavlc_tables.c index f122ab9..6fc51c5 100644 --- a/common/ih264_cavlc_tables.c +++ b/common/ih264_cavlc_tables.c @@ -18,7 +18,6 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ - /** ****************************************************************************** * @file @@ -29,23 +28,7 @@ * zeros and runs before zeros * * @author -* Ittiam -* -* @par List of Tables -* - gu1_code_coeff_token_table -* - gu1_size_coeff_token_table -* - gu1_code_coeff_token_table_chroma -* - gu1_size_coeff_token_table_chroma -* - gu1_threshold_vlc_level -* - gu1_size_zero_table -* - gu1_code_zero_table -* - gu1_size_zero_table_chroma -* - gu1_code_zero_table_chroma -* - gu1_index_zero_table -* - gu1_size_run_table -* - gu1_code_run_table -* - gu4_codeword_level_tables -* - gu1_codesize_level_tables +* ittiam * * @remarks * none @@ -72,7 +55,7 @@ * chroma format idc != 0 * input : cbp, intra - 0/inter - 1 * output : codenum - * @remarks Table 9-4 – Assignment of codeNum to values of coded_block_pattern + * @remarks Table 9-4 - Assignment of codeNum to values of coded_block_pattern * for macroblock prediction modes in H264 spec ****************************************************************************** */ @@ -269,6 +252,7 @@ const UWORD8 gu1_code_run_table[42] = 3, 0, 1, 3, 2, 5, 4, 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; + /** ****************************************************************************** * @brief index to access zero table (look up) diff --git a/common/ih264_cavlc_tables.h b/common/ih264_cavlc_tables.h index 78057b5..d64ac54 100644 --- a/common/ih264_cavlc_tables.h +++ b/common/ih264_cavlc_tables.h @@ -20,22 +20,23 @@ /** ****************************************************************************** -* @file ih264_cavlc_tables.h +* @file +* ih264_cavlc_tables.h * * @brief * This file contains enumerations, macros and extern declarations of H264 * cavlc tables * * @author -* Ittiam +* ittiam * -* @remarks -* none +* @remarks +* none ****************************************************************************** */ -#ifndef IH264_CAVLC_TABLES_H_ -#define IH264_CAVLC_TABLES_H_ +#ifndef _IH264_CAVLC_TABLES_H_ +#define _IH264_CAVLC_TABLES_H_ /*****************************************************************************/ /* Constant Macros */ @@ -48,86 +49,22 @@ #define MAX_ZERO_LEFT 6 /*****************************************************************************/ -/* Extern global declarations */ +/* global declarations */ /*****************************************************************************/ -/** - ****************************************************************************** - * @brief Assignment of cbp to a codenum for intra and inter prediction modes - * chroma format idc != 0 - * input : cbp, intra - 0/inter - 1 - * output : codenum - * @remarks Table 9-4 – Assignment of codeNum to values of coded_block_pattern - * for macroblock prediction modes in H264 spec - ****************************************************************************** - */ extern const UWORD8 gu1_cbp_map_tables[48][2]; - -/** - ****************************************************************************** - * @brief total non-zero coefficients and numbers of trailing ones of a residual - * block are mapped to coefftoken using the tables given below. - * input : VLC-Num | Trailing ones | Total coeffs - * output : coeff_token (code word, size of the code word) - * @remarks Table-9-5 coeff_token mapping to TotalCoeff( coeff_token ) - * and TrailingOnes( coeff_token ) in H264 spec - ****************************************************************************** - */ extern const UWORD8 gu1_code_coeff_token_table[3][4][16]; extern const UWORD8 gu1_size_coeff_token_table[3][4][16]; extern const UWORD8 gu1_code_coeff_token_table_chroma[4][4]; extern const UWORD8 gu1_size_coeff_token_table_chroma[4][4]; - -/** - ****************************************************************************** - * @brief Thresholds for determining whether to increment Level table number. - * input : suffix_length - * output : threshold - ****************************************************************************** - */ extern const UWORD8 gu1_threshold_vlc_level[6]; - -/** - ****************************************************************************** - * @brief table for encoding total number of zeros - * input : coeff_token, total zeros - * output : code word, size of the code word - * @remarks Table-9-7, 9-8 total_zeros tables for 4x4 blocks with - * TotalCoeff( coeff_token ) in H264 spec - ****************************************************************************** - */ extern const UWORD8 gu1_size_zero_table[135]; extern const UWORD8 gu1_code_zero_table[135]; extern const UWORD8 gu1_size_zero_table_chroma[9]; extern const UWORD8 gu1_code_zero_table_chroma[9]; - -/** - ****************************************************************************** - * @brief index to access zero table (for speed) - * input : TotalCoeff( coeff_token ) - * output : index to access zero table - ****************************************************************************** - */ extern const UWORD8 gu1_index_zero_table[15]; - -/** - ****************************************************************************** - * @brief table for encoding runs of zeros before - * input : zeros left, runs of zeros before - * output : code word, size of the code word - * @remarks Table-9-10 table for run_before in H264 spec - ****************************************************************************** - */ extern const UWORD8 gu1_size_run_table[42]; extern const UWORD8 gu1_code_run_table[42]; - -/** - ****************************************************************************** - * @brief index to access run table (look up) - * input : zeros left - * output : index to access run table - ****************************************************************************** - */ extern const UWORD8 gu1_index_run_table[7]; -#endif /* IH264_CAVLC_TABLES_H_ */ +#endif /* _IH264_CAVLC_TABLES_H_ */ diff --git a/common/ih264_chroma_intra_pred_filters.c b/common/ih264_chroma_intra_pred_filters.c index 1894bfc..3a615e9 100644 --- a/common/ih264_chroma_intra_pred_filters.c +++ b/common/ih264_chroma_intra_pred_filters.c @@ -17,25 +17,26 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file * ih264_chroma_intra_pred_filters.c * * @brief -* Contains function definitions for chroma intra prediction filters +* Contains function definitions for chroma intra prediction filters * * @author -* Ittiam +* ittiam * * @par List of Functions: -* -ih264_intra_pred_chroma_8x8_mode_dc -* -ih264_intra_pred_chroma_8x8_mode_horz -* -ih264_intra_pred_chroma_8x8_mode_vert -* -ih264_intra_pred_chroma_8x8_mode_plane +* - ih264_intra_pred_chroma_8x8_mode_dc +* - ih264_intra_pred_chroma_8x8_mode_horz +* - ih264_intra_pred_chroma_8x8_mode_vert +* - ih264_intra_pred_chroma_8x8_mode_plane * * @remarks -* None +* none * ******************************************************************************* */ @@ -44,66 +45,68 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <string.h> -/* User include files */ -#include "ih264_defs.h" +/* User Include Files */ #include "ih264_typedefs.h" #include "ih264_macros.h" -#include "ih264_platform_macros.h" +#include "ih264_defs.h" #include "ih264_intra_pred_filters.h" +#include "ih264_platform_macros.h" -/* Global variables used only in assembly files*/ +/*****************************************************************************/ +/* Global definitions */ +/*****************************************************************************/ +/* Note: used only in assembly files */ const WORD8 ih264_gai1_intrapred_chroma_plane_coeffs1[] = -{ 0x01,0x00,0x01,0x00, - 0x02,0x00,0x02,0x00, - 0x03,0x00,0x03,0x00, - 0x04,0x00,0x04,0x00 +{ + 0x01, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x02, 0x00, + 0x03, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x04, 0x00, +}; + +const WORD8 ih264_gai1_intrapred_chroma_plane_coeffs2[] = +{ + 0xfd, 0xff, 0xfe, 0xff, + 0xff, 0xff, 0x00, 0x00, + 0x01, 0x00, 0x02, 0x00, + 0x03, 0x00, 0x04, 0x00, }; - const WORD8 ih264_gai1_intrapred_chroma_plane_coeffs2[] = - { 0xfd,0xff,0xfe,0xff, - 0xff,0xff,0x00,0x00, - 0x01,0x00,0x02,0x00, - 0x03,0x00,0x04,0x00, - }; /*****************************************************************************/ -/* Chroma Intra prediction 8x8 filters */ +/* Function Definitions */ /*****************************************************************************/ /** ******************************************************************************* * -* ih264_intra_pred_chroma_8x8_mode_dc +* @brief Perform chroma_8x8 intra DC prediction * -* @brief -* Perform Intra prediction for chroma_8x8 mode:DC -* -* @par Description: -* Perform Intra prediction for chroma_8x8 mode:DC ,described in sec 8.3.4.1 +* @par Description +* Perform chroma_8x8 intra DC prediction (refer sec 8.3.4.1 of ITU T.h264) * * @param[in] pu1_src -* UWORD8 pointer to the source containing alternate U and V samples +* pointer to the source containing alternate U and V samples * * @param[out] pu1_dst -* UWORD8 pointer to the destination with alternate U and V samples +* pointer to the destination with alternate U and V samples * * @param[in] src_strd -* integer source stride +* source stride * * @param[in] dst_strd -* integer destination stride +* destination stride * -** @param[in] ngbr_avail +* @param[in] ngbr_avail * availability of neighbouring pixels * -* @returns +* @returns none * -* @remarks -* None +* @remarks none * ****************************************************************************** */ @@ -113,21 +116,28 @@ void ih264_intra_pred_chroma_8x8_mode_dc(UWORD8 *pu1_src, WORD32 dst_strd, WORD32 ngbr_avail) { - WORD32 left_avail, left_avail1, left_avail2; /* availability of left predictors (only for DC) */ - WORD32 top_avail; /* availability of top predictors (only for DC) */ - UWORD8 *pu1_left = NULL; /* Pointer to start of left predictors */ - UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */ + /* availability of left predictors (only for DC) */ + WORD32 left_avail, left_avail1, left_avail2; - /* temporary variables to store accumulated first left half,second left half, - * first top half,second top half of U and V values*/ + /* availability of top predictors (only for DC) */ + WORD32 top_avail; + + /* Pointer to start of left predictors */ + UWORD8 *pu1_left = NULL; + + /* Pointer to start of top predictors */ + UWORD8 *pu1_top = NULL; + + /* temporary variables to store accumulated first left half, second left half, + * first top half, second top half of U and V values*/ WORD32 val_u_l1 = 0, val_u_l2 = 0, val_u_t1 = 0, val_u_t2 = 0; WORD32 val_v_l1 = 0, val_v_l2 = 0, val_v_t1 = 0, val_v_t2 = 0; - WORD32 val_u1 = 0, val_u2 = 0, val_v1 = 0, val_v2 = 0; - WORD32 col, row; /*loop variables*/ - UNUSED(src_strd); + /* temp */ + WORD32 col, row; + UNUSED(src_strd); left_avail = ngbr_avail & 0x11; left_avail1 = ngbr_avail & 1; left_avail2 = (ngbr_avail >> 4) & 1; @@ -137,7 +147,8 @@ void ih264_intra_pred_chroma_8x8_mode_dc(UWORD8 *pu1_src, pu1_left = pu1_src + 2 * BLK8x8SIZE - 2; if(left_avail1) - { /* First 4x4 block*/ + { + /* First 4x4 block */ val_u_l1 += *pu1_left; val_v_l1 += *(pu1_left + 1); pu1_left -= 2; @@ -152,11 +163,13 @@ void ih264_intra_pred_chroma_8x8_mode_dc(UWORD8 *pu1_src, pu1_left -= 2; } else + { pu1_left -= 2 * 4; + } if(left_avail2) { - /* Second 4x4 block*/ + /* Second 4x4 block */ val_u_l2 += *pu1_left; val_v_l2 += *(pu1_left + 1); pu1_left -= 2; @@ -171,7 +184,9 @@ void ih264_intra_pred_chroma_8x8_mode_dc(UWORD8 *pu1_src, pu1_left -= 2; } else + { pu1_left -= 2 * 4; + } if(top_avail) { @@ -210,13 +225,13 @@ void ih264_intra_pred_chroma_8x8_mode_dc(UWORD8 *pu1_src, for(row = 0; row < 4; row++) { - /*top left 4x4 block*/ + /* top left 4x4 block */ for(col = 0; col < 8; col += 2) { *(pu1_dst + row * dst_strd + col) = val_u1; *(pu1_dst + row * dst_strd + col + 1) = val_v1; } - /*top right 4x4 block*/ + /* top right 4x4 block */ for(col = 8; col < 16; col += 2) { *(pu1_dst + row * dst_strd + col) = val_u2; @@ -246,13 +261,14 @@ void ih264_intra_pred_chroma_8x8_mode_dc(UWORD8 *pu1_src, >> (1 + left_avail2 + top_avail)) : 128; for(row = 4; row < 8; row++) - { /*bottom left 4x4 block*/ + { + /* bottom left 4x4 block */ for(col = 0; col < 8; col += 2) { *(pu1_dst + row * dst_strd + col) = val_u1; *(pu1_dst + row * dst_strd + col + 1) = val_v1; } - /*bottom right 4x4 block*/ + /* bottom right 4x4 block */ for(col = 8; col < 16; col += 2) { *(pu1_dst + row * dst_strd + col) = val_u2; @@ -273,33 +289,29 @@ void ih264_intra_pred_chroma_8x8_mode_dc(UWORD8 *pu1_src, /** ******************************************************************************* * -*ih264_intra_pred_chroma_8x8_mode_horz +* @brief Perform chroma_8x8 intra Horz prediction * -* @brief -* Perform Intra prediction for chroma_8x8 mode:Horizontal -* -* @par Description: -* Perform Intra prediction for chroma_8x8 mode:Horizontal ,described in sec 8.3.4.2 +* @par Description +* Perform chroma_8x8 intra Horz prediction (refer sec 8.3.4.2 of ITU T.h264) * * @param[in] pu1_src -* UWORD8 pointer to the source containing alternate U and V samples +* pointer to the source containing alternate U and V samples * * @param[out] pu1_dst -* UWORD8 pointer to the destination with alternate U and V samples +* pointer to the destination with alternate U and V samples * * @param[in] src_strd -* integer source stride +* source stride * * @param[in] dst_strd -* integer destination stride +* destination stride * * @param[in] ngbr_avail -* availability of neighbouring pixels(Not used in this function) +* availability of neighbouring pixels (Not used in this function) * * @returns * -* @remarks -* None +* @remarks none * ****************************************************************************** */ @@ -309,9 +321,12 @@ void ih264_intra_pred_chroma_8x8_mode_horz(UWORD8 *pu1_src, WORD32 dst_strd, WORD32 ngbr_avail) { + /* Pointer to start of left predictors */ + UWORD8 *pu1_left = NULL; + + /* temp */ + WORD32 rows, cols; - UWORD8 *pu1_left = NULL; /* Pointer to start of top predictors */ - WORD32 rows, cols; /* loop variables*/ UNUSED(src_strd); UNUSED(ngbr_avail); pu1_left = pu1_src + 2 * BLK8x8SIZE - 2; @@ -320,39 +335,34 @@ void ih264_intra_pred_chroma_8x8_mode_horz(UWORD8 *pu1_src, for(cols = 0; cols < 16; cols += 2) { *(pu1_dst + rows * dst_strd + cols) = *pu1_left; - *(pu1_dst + rows * dst_strd + cols + 1) = *(pu1_left + 1); } pu1_left -= 2; } - } /** ******************************************************************************* * -*ih264_intra_pred_chroma_8x8_mode_vert -* -* @brief -* Perform Intra prediction for chroma_8x8 mode:vertical +* @brief Perform chroma_8x8 intra Vert prediction * -* @par Description: -* Perform Intra prediction for chroma_8x8 mode:vertical ,described in sec 8.3.4.3 +* @par Description +* Perform chroma_8x8 intra Vert prediction (refer sec 8.3.4.3 of ITU T.h264) * * @param[in] pu1_src -* UWORD8 pointer to the source containing alternate U and V samples +* pointer to the source containing alternate U and V samples * * @param[out] pu1_dst -* UWORD8 pointer to the destination with alternate U and V samples +* pointer to the destination with alternate U and V samples * * @param[in] src_strd -* integer source stride +* source stride * * @param[in] dst_strd -* integer destination stride +* destination stride * * @param[in] ngbr_avail -* availability of neighbouring pixels(Not used in this function) +* availability of neighbouring pixels (Not used in this function) * * @returns * @@ -367,9 +377,12 @@ void ih264_intra_pred_chroma_8x8_mode_vert(UWORD8 *pu1_src, WORD32 dst_strd, WORD32 ngbr_avail) { + /* Pointer to start of top predictors */ + UWORD8 *pu1_top = NULL; + + /* temp */ + WORD32 row; - UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */ - WORD32 row;/*loop variable*/ UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + 2 * BLK8x8SIZE + 2; @@ -395,28 +408,25 @@ void ih264_intra_pred_chroma_8x8_mode_vert(UWORD8 *pu1_src, /** ******************************************************************************* * -* ih264_intra_pred_chroma_8x8_mode_plane -* -* @brief -* Perform Intra prediction for chroma_8x8 mode:PLANE +* @brief Perform chroma_8x8 intra Plane prediction * -* @par Description: -* Perform Intra prediction for chroma_8x8 mode:PLANE ,described in sec 8.3.4.4 +* @par Description +* Perform chroma_8x8 intra Plane prediction (refer sec 8.3.4.4 of ITU T.h264) * * @param[in] pu1_src -* UWORD8 pointer to the source containing alternate U and V samples +* pointer to the source containing alternate U and V samples * * @param[out] pu1_dst -* UWORD8 pointer to the destination with alternate U and V samples +* pointer to the destination with alternate U and V samples * * @param[in] src_strd -* integer source stride +* source stride * * @param[in] dst_strd -* integer destination stride +* destination stride * * @param[in] ngbr_avail -* availability of neighbouring pixels(Not used in this function) +* availability of neighbouring pixels (Not used in this function) * * @returns * @@ -431,45 +441,52 @@ void ih264_intra_pred_chroma_8x8_mode_plane(UWORD8 *pu1_src, WORD32 dst_strd, WORD32 ngbr_avail) { + /* Pointer to start of left predictors */ + UWORD8 *pu1_left = NULL; - UWORD8 *pu1_left = NULL; /* Pointer to start of left predictors */ - UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */ + /* Pointer to start of top predictors */ + UWORD8 *pu1_top = NULL; + + /* temp */ WORD32 val = 0; - WORD32 rows, cols; /* loop variables*/ - WORD32 a_u, b_u, c_u, h_u, v_u; /* Implementing section 8.3.4.4 . The variables represent the corresponding variables in the section*/ + WORD32 rows, cols; + + /* Implementing section 8.3.4.4. The variables represent the corresponding + * variables in the section */ + WORD32 a_u, b_u, c_u, h_u, v_u; WORD32 a_v, b_v, c_v, h_v, v_v; + UNUSED(src_strd); UNUSED(ngbr_avail); a_u = b_u = c_u = h_u = v_u = 0; a_v = b_v = c_v = h_v = v_v = 0; - /* As chroma format 4:2:0 is used,xCF = 4 * ( chroma_format_idc = = 3 ) = 0 and - yCF = 4 * ( chroma_format_idc != 1 ) = 0 */ + pu1_top = pu1_src + 2 * BLK8x8SIZE + 2; pu1_left = pu1_src + 2 * BLK8x8SIZE - 2; - /* Implementing section 8.3.4.4 */ + for(cols = 0; cols < 4; cols++) { - h_u += (cols + 1) * (pu1_top[8 + 2 * cols] - pu1_top[4 - 2 * cols]);/*section 8.3.4.4 equation (8-144)*/ + h_u += (cols + 1) * (pu1_top[8 + 2 * cols] - pu1_top[4 - 2 * cols]); h_v += (cols + 1) * (pu1_top[8 + 2 * cols + 1] - pu1_top[4 - 2 * cols+ 1]); v_u += (cols + 1) * (pu1_left[(4 + cols) * (-2)] - pu1_left[(2 - cols) * (-2)]); - v_v += (cols + 1) * (pu1_left[(4 + cols) * (-2) + 1] - pu1_left[(2 - cols) * (-2) + 1]);/*section 8.3.4.4 equation (8-145)*/ + v_v += (cols + 1) * (pu1_left[(4 + cols) * (-2) + 1] - pu1_left[(2 - cols) * (-2) + 1]); } a_u = 16 * (pu1_left[7 * (-2)] + pu1_top[14]); - a_v = 16 * (pu1_left[7 * (-2) + 1] + pu1_top[15]);/*section 8.3.3.4 equation (8-141)*/ - b_u = (34 * h_u + 32) >> 6;/*section 8.3.3.4 equation (8-142)*/ - b_v = (34 * h_v + 32) >> 6;/*section 8.3.3.4 equation (8-142)*/ - c_u = (34 * v_u + 32) >> 6;/*section 8.3.3.4 equation (8-143)*/ - c_v = (34 * v_v + 32) >> 6;/*section 8.3.3.4 equation (8-143)*/ + a_v = 16 * (pu1_left[7 * (-2) + 1] + pu1_top[15]); + b_u = (34 * h_u + 32) >> 6; + b_v = (34 * h_v + 32) >> 6; + c_u = (34 * v_u + 32) >> 6; + c_v = (34 * v_v + 32) >> 6; for(rows = 0; rows < 8; rows++) { for(cols = 0; cols < 8; cols++) { - val = (a_u + b_u * (cols - 3) + c_u * (rows - 3) );/*section 8.3.4.4 equation (8-140)*/ + val = (a_u + b_u * (cols - 3) + c_u * (rows - 3) ); val = (val + 16) >> 5; *(pu1_dst + rows * dst_strd + 2 * cols) = CLIP_U8(val); - val = (a_v + b_v * (cols - 3) + c_v * (rows - 3) );/*section 8.3.4.4 equation (8-140)*/ + val = (a_v + b_v * (cols - 3) + c_v * (rows - 3) ); val = (val + 16) >> 5; *(pu1_dst + rows * dst_strd + 2 * cols + 1) = CLIP_U8(val); } diff --git a/common/ih264_common_tables.c b/common/ih264_common_tables.c index df09f5a..1489628 100644 --- a/common/ih264_common_tables.c +++ b/common/ih264_common_tables.c @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,12 +27,10 @@ * Contains common global tables * * @author -* Harish M -* -* @par List of Functions: +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ @@ -40,27 +39,27 @@ /* File Includes */ /*****************************************************************************/ -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" -#include "ih264_defs.h" #include "ih264_macros.h" +#include "ih264_defs.h" #include "ih264_structs.h" #include "ih264_common_tables.h" /*****************************************************************************/ -/* Extern global definitions */ +/* Global definitions */ /*****************************************************************************/ /** - ****************************************************************************** - * @brief while encoding, basing on the input configuration parameters, the - * the level of the bitstream is computed basing on the table below. - * input : table_idx - * output : level_idc or cpb size - * @remarks Table A-1 – level table limits - ****************************************************************************** - */ +****************************************************************************** +* @brief while encoding, basing on the input configuration parameters, the +* the level of the bitstream is computed basing on the table below. +* input : table_idx +* output : level_idc or cpb size +* @remarks Table A-1 - level table limits +****************************************************************************** +*/ const level_tables_t gas_ih264_lvl_tbl[16] = { { IH264_LEVEL_10, 1485, 99, 297, 64, 175, 64 }, @@ -81,10 +80,7 @@ const level_tables_t gas_ih264_lvl_tbl[16] = { IH264_LEVEL_51, 983040, 36864, 138240, 240000, 240000, 512 }, }; - -/** - * Array containing supported levels - */ +/* Array containing supported levels */ const WORD32 gai4_ih264_levels[] = { IH264_LEVEL_10, @@ -104,10 +100,7 @@ const WORD32 gai4_ih264_levels[] = IH264_LEVEL_51, }; - -/** - * Array giving size of max luma samples in a picture for a given level - */ +/* Array giving size of max luma samples in a picture for a given level */ const WORD32 gai4_ih264_max_luma_pic_size[] = { /* Level 1 */ @@ -142,9 +135,8 @@ const WORD32 gai4_ih264_max_luma_pic_size[] = 9437184 }; - -/** Max width and height allowed for a given level */ -/** This is derived as SQRT(8 * gai4_ih264_max_luma_pic_size[]) */ +/* Max width and height allowed for a given level */ +/* This is derived as SQRT(8 * gai4_ih264_max_luma_pic_size[]) */ const WORD32 gai4_ih264_max_wd_ht[] = { /* Level 1 */ @@ -179,8 +171,8 @@ const WORD32 gai4_ih264_max_wd_ht[] = 8689 }; -/** Min width and height allowed for a given level */ -/** This is derived as gai4_ih264_max_luma_pic_size[]/gai4_ih264_max_wd_ht[] */ +/* Min width and height allowed for a given level */ +/* This is derived as gai4_ih264_max_luma_pic_size[]/gai4_ih264_max_wd_ht[] */ const WORD32 gai4_ih264_min_wd_ht[] = { /* Level 1 */ @@ -216,8 +208,7 @@ const WORD32 gai4_ih264_min_wd_ht[] = }; - -/** Table 7-11 Macroblock types for I slices */ +/* Table 7-11 Macroblock types for I slices */ intra_mbtype_info_t gas_ih264_i_mbtype_info[] = { /* For first entry, if transform_size_8x8_flag is 1, mode will be MBPART_I8x8 */ @@ -250,7 +241,7 @@ intra_mbtype_info_t gas_ih264_i_mbtype_info[] = {0, MBPART_IPCM, VERT_I16x16, 0, 0} }; -/** Table 7-13 Macroblock types for P slices */ +/* Table 7-13 Macroblock types for P slices */ inter_mbtype_info_t gas_ih264_p_mbtype_info[] = { {1, MBPART_L0, MBPART_NA, 16, 16}, @@ -260,7 +251,7 @@ inter_mbtype_info_t gas_ih264_p_mbtype_info[] = {4, MBPART_NA, MBPART_NA, 8, 8}, }; -/** Table 7-14 Macroblock types for B slices */ +/* Table 7-14 Macroblock types for B slices */ inter_mbtype_info_t gas_ih264_b_mbtype_info[] = { {0, MBPART_DIRECT, MBPART_NA, 8, 8, }, @@ -288,7 +279,7 @@ inter_mbtype_info_t gas_ih264_b_mbtype_info[] = {4, MBPART_NA, MBPART_NA, 8, 8, }, }; -/** Table 7-17 – Sub-macroblock types in P macroblocks */ +/* Table 7-17 - Sub-macroblock types in P macroblocks */ submbtype_info_t gas_ih264_p_submbtype_info[] = { {1, MBPART_L0, 8, 8}, @@ -297,7 +288,7 @@ submbtype_info_t gas_ih264_p_submbtype_info[] = {4, MBPART_L0, 4, 4}, }; -/** Table 7-18 – Sub-macroblock types in B macroblocks */ +/* Table 7-18 - Sub-macroblock types in B macroblocks */ submbtype_info_t gas_ih264_b_submbtype_info[] = { {4, MBPART_DIRECT, 4, 4}, @@ -315,9 +306,6 @@ submbtype_info_t gas_ih264_b_submbtype_info[] = {4, MBPART_BI, 4, 4}, }; - - - const UWORD8 gau1_ih264_inv_scan_prog4x4[] = { 0, 1, 4, 8, @@ -334,7 +322,7 @@ const UWORD8 gau1_ih264_inv_scan_int4x4[] = 3, 7, 11, 15 }; -/** Inverse scan tables for individual 4x4 blocks of 8x8 transform coeffs of CAVLC */ +/* Inverse scan tables for individual 4x4 blocks of 8x8 transform coeffs of CAVLC */ /* progressive */ const UWORD8 gau1_ih264_inv_scan_prog8x8_cavlc[64] = { @@ -347,7 +335,6 @@ const UWORD8 gau1_ih264_inv_scan_prog8x8_cavlc[64] = 16, 10, 25, 5, 33, 34, 6, 28, 56, 36, 23, 51, 45, 46, 54, 63 }; - /* interlace */ const UWORD8 gau1_ih264_inv_scan_int8x8_cavlc[64] = { @@ -361,11 +348,8 @@ const UWORD8 gau1_ih264_inv_scan_int8x8_cavlc[64] = 59, 21, 60, 37, 30, 46, 31, 63 }; - - /*Inverse scan tables for individual 8x8 blocks of 8x8 transform coeffs of CABAC */ /* progressive */ - const UWORD8 gau1_ih264_inv_scan_prog8x8_cabac[64] = { 0, 1, 8, 16, 9, 2, 3, 10, @@ -377,10 +361,7 @@ const UWORD8 gau1_ih264_inv_scan_prog8x8_cabac[64] = 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 }; - - /* interlace */ - const UWORD8 gau1_ih264_inv_scan_int8x8_cabac[64] = { 0, 8, 16, 1, 9, 24, 32, 17, @@ -393,7 +374,6 @@ const UWORD8 gau1_ih264_inv_scan_int8x8_cabac[64] = 54, 62, 23, 31, 39, 47, 55, 63 }; - const UWORD8 *const gpau1_ih264_inv_scan8x8[] = { gau1_ih264_inv_scan_prog8x8_cavlc, @@ -416,7 +396,6 @@ const UWORD8 gau1_ih264_8x8_subblk_idx[] = 10, 11, 14, 15 }; - /* Table 8-15 Chroma QP offset table */ const UWORD8 gau1_ih264_chroma_qp[] = { @@ -429,7 +408,6 @@ const UWORD8 gau1_ih264_chroma_qp[] = 39, 39, 39, 39 }; - /** ****************************************************************************** * @brief look up table to compute neigbour availability of 4x4 blocks @@ -493,7 +471,7 @@ const UWORD8 gau1_ih264_8x8_ngbr_avbl[16][4] = { 0xf, 0xf, 0xf, 0x7 }, }; -/** Table 7-3 Default intra 4x4 scaling list */ +/* Table 7-3 Default intra 4x4 scaling list */ const UWORD16 gau2_ih264_default_intra4x4_scaling_list[] = { 6, 13, 13, 20, @@ -502,7 +480,7 @@ const UWORD16 gau2_ih264_default_intra4x4_scaling_list[] = 32, 37, 37, 42 }; -/** Table 7-3 Default inter 4x4 scaling list */ +/* Table 7-3 Default inter 4x4 scaling list */ const UWORD16 gau2_ih264_default_inter4x4_scaling_list[] = { 10, 14, 14, 20, @@ -529,7 +507,7 @@ const UWORD16 gau2_ih264_default_inter4x4_weight_scale[] = 24, 27, 30, 34 }; -/** Table 7-4 Default intra 8x8 scaling list */ +/* Table 7-4 Default intra 8x8 scaling list */ const UWORD16 gau2_ih264_default_intra8x8_scaling_list[] = { 6, 10, 10, 13, 11, 13, 16, 16, @@ -542,7 +520,7 @@ const UWORD16 gau2_ih264_default_intra8x8_scaling_list[] = 36, 36, 38, 38, 38, 40, 40, 42 }; -/** Table 7-4 Default inter 8x8 scaling list */ +/* Table 7-4 Default inter 8x8 scaling list */ const UWORD16 gau2_ih264_default_inter8x8_scaling_list[] = { 9, 13, 13, 15, 13, 15, 17, 17, @@ -602,22 +580,20 @@ const UWORD16 gau2_ih264_flat_8x8_weight_scale[] = 16, 16, 16, 16, 16, 16, 16, 16 }; - /** - ****************************************************************************** - * @brief Scale Table for inverse quantizing 4x4 subblock. To inverse quantize - * a given 4x4 quantized block, the coefficient at index location (i,j) is scaled - * by one of the constants in this table and right shift the result by abs (4 - - * floor(qp/6)), here qp is the quantization parameter used to quantize the mb. - * - * input : 16 * qp%6, index location (i,j) - * output : scale constant. - * - * @remarks 16 constants for each index position of the subblock and 6 for each - * qp%6 in the range 0-5 inclusive. - ****************************************************************************** - */ - +****************************************************************************** +* @brief Scale Table for inverse quantizing 4x4 subblock. To inverse quantize +* a given 4x4 quantized block, the coefficient at index location (i,j) is scaled +* by one of the constants in this table and right shift the result by abs (4 - +* floor(qp/6)), here qp is the quantization parameter used to quantize the mb. +* +* input : 16 * qp%6, index location (i,j) +* output : scale constant. +* +* @remarks 16 constants for each index position of the subblock and 6 for each +* qp%6 in the range 0-5 inclusive. +****************************************************************************** +*/ const UWORD16 gau2_ih264_iquant_scale_matrix_4x4[96] = { 10, 13, 10, 13, @@ -653,19 +629,19 @@ const UWORD16 gau2_ih264_iquant_scale_matrix_4x4[96] = }; /** - ****************************************************************************** - * @brief Scale Table for inverse quantizing 8x8 subblock. To inverse quantize - * a given 8x8 quantized block, the coefficient at index location (i,j) is scaled - * by one of the constants in this table and right shift the result by abs (4 - - * floor(qp/6)), here qp is the quantization parameter used to quantize the mb. - * - * input : qp%6, index location (i,j) - * output : scale constant. - * - * @remarks 64 constants for each index position of the subblock and 6 for each - * qp%6 in the range 0-5 inclusive. - ****************************************************************************** - */ +****************************************************************************** +* @brief Scale Table for inverse quantizing 8x8 subblock. To inverse quantize +* a given 8x8 quantized block, the coefficient at index location (i,j) is scaled +* by one of the constants in this table and right shift the result by abs (4 - +* floor(qp/6)), here qp is the quantization parameter used to quantize the mb. +* +* input : qp%6, index location (i,j) +* output : scale constant. +* +* @remarks 64 constants for each index position of the subblock and 6 for each +* qp%6 in the range 0-5 inclusive. +****************************************************************************** +*/ const UWORD16 gau2_ih264_iquant_scale_matrix_8x8 [384] = { 20, 19, 25, 19, 20, 19, 25, 19, diff --git a/common/ih264_common_tables.h b/common/ih264_common_tables.h index d4ec147..945024f 100644 --- a/common/ih264_common_tables.h +++ b/common/ih264_common_tables.h @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,12 +27,10 @@ * Common tables * * @author -* Harish -* -* @par List of Functions: +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ @@ -78,15 +77,6 @@ typedef struct /* Extern global declarations */ /*****************************************************************************/ -/** - ****************************************************************************** - * @brief while encoding, basing on the input configuration parameters, the - * the level of the bitstream is computed basing on the table below. - * input : table_idx - * output : level_idc or cpb size - * @remarks Table A-1 – level table limits - ****************************************************************************** - */ extern const level_tables_t gas_ih264_lvl_tbl[16]; extern const WORD32 gai4_ih264_levels[]; diff --git a/common/ih264_deblk_edge_filters.c b/common/ih264_deblk_edge_filters.c index d2ffefd..c30f753 100644 --- a/common/ih264_deblk_edge_filters.c +++ b/common/ih264_deblk_edge_filters.c @@ -17,90 +17,90 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ -/**************************************************************************** */ -/* */ -/* File Name : ih264_deblk_edge_filters.c */ -/* */ -/* Description : Contains function definitions for deblocking */ -/* */ -/* List of Functions : ih264_deblk_luma_vert_bs4() */ -/* ih264_deblk_luma_horz_bs4() */ -/* ih264_deblk_luma_vert_bslt4() */ -/* ih264_deblk_luma_horz_bslt4() */ -/* ih264_deblk_luma_vert_bs4_mbaff() */ -/* ih264_deblk_luma_vert_bslt4_mbaff() */ -/* ih264_deblk_chroma_vert_bs4_bp() */ -/* ih264_deblk_chroma_horz_bs4_bp() */ -/* ih264_deblk_chroma_vert_bslt4_bp() */ -/* ih264_deblk_chroma_horz_bslt4_bp() */ -/* ih264_deblk_chroma_vert_bs4_mbaff_bp() */ -/* ih264_deblk_chroma_vert_bslt4_mbaff_bp() */ -/* ih264_deblk_chroma_vert_bs4() */ -/* ih264_deblk_chroma_horz_bs4() */ -/* ih264_deblk_chroma_vert_bslt4() */ -/* ih264_deblk_chroma_horz_bslt4() */ -/* ih264_deblk_chroma_vert_bs4_mbaff() */ -/* ih264_deblk_chroma_vert_bslt4_mbaff() */ -/* */ -/* Issues / Problems : None */ -/* */ -/* Revision History : */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 11 2013 Ittiam Draft */ -/* 29 12 2014 Kaushik Added double-call vertical */ -/* Senthoor deblocking and high profile */ -/* deblocking functions */ -/* */ -/******************************************************************************/ + +/** +******************************************************************************* +* @file +* ih264_deblk_edge_filters.c +* +* @brief +* Contains function definitions for deblocking +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264_deblk_luma_vert_bs4 +* - ih264_deblk_luma_horz_bs4 +* - ih264_deblk_chroma_vert_bs4_bp +* - ih264_deblk_chroma_horz_bs4_bp +* - ih264_deblk_luma_vert_bslt4 +* - ih264_deblk_chroma_vert_bslt4_bp +* - ih264_deblk_luma_horz_bslt4 +* - ih264_deblk_luma_horz_bslt4 +* - ih264_deblk_luma_vert_bs4_mbaff +* - ih264_deblk_chroma_vert_bs4_mbaff_bp +* - ih264_deblk_luma_vert_bslt4_mbaff +* - ih264_deblk_chroma_vert_bslt4_mbaff_bp +* - ih264_deblk_chroma_vert_bs4 +* - ih264_deblk_chroma_horz_bs4 +* - ih264_deblk_chroma_vert_bslt4 +* - ih264_deblk_chroma_horz_bslt4 +* - ih264_deblk_chroma_vert_bs4_mbaff +* - ih264_deblk_chroma_vert_bslt4_mbaff +* +* @remarks +* none +* +******************************************************************************* +*/ /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" -#include "ih264_platform_macros.h" -#include "ih264_deblk_edge_filters.h" #include "ih264_macros.h" +#include "ih264_deblk_edge_filters.h" +#include "ih264_platform_macros.h" + /*****************************************************************************/ /* Function Definitions */ /*****************************************************************************/ -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_luma_vert_bs4() */ -/* */ -/* Description : This function performs filtering of a luma block */ -/* vertical edge when the boundary strength is set to 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.4 under the */ -/* title "Filtering process for edges for bS equal to 4" in */ -/* ITU T Rec H.264. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 11 2013 Ittiam Draft */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief luma vertical edge deblock @ bs4 +* +* @par Description +* This function performs filtering of a luma block vertical edge when the +* boundary strength is set to 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.4 under the title +* "Filtering process for edges for bS equal to 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_luma_vert_bs4(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -191,36 +191,34 @@ void ih264_deblk_luma_vert_bs4(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_luma_horz_bs4() */ -/* */ -/* Description : This function performs filtering of a luma block */ -/* horizontal edge when the boundary strength is set to 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.4 under the */ -/* title "Filtering process for edges for bS equal to 4" in */ -/* ITU T Rec H.264. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 11 2013 Ittiam Draft */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief luma horizontal edge deblock @ bs4 +* +* @par Description +* This function performs filtering of a luma block horizontal edge when the +* boundary strength is set to 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.4 under the title +* "Filtering process for edges for bS equal to 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_luma_horz_bs4(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -314,36 +312,34 @@ void ih264_deblk_luma_horz_bs4(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_vert_bs4_bp() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* vertical edge when the boundary strength is set to 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.4 under the */ -/* title "Filtering process for edges for bS equal to 4" in */ -/* ITU T Rec H.264. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 11 2013 Ittiam Draft */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma vertical edge deblock @ bs4 +* +* @par Description +* This function performs filtering of a chroma block vertical edge when the +* boundary strength is set to 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.4 under the title +* "Filtering process for edges for bS equal to 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_vert_bs4_bp(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -404,36 +400,34 @@ void ih264_deblk_chroma_vert_bs4_bp(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_horz_bs4_bp() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* horizontal edge when the boundary strength is set to 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.4 under the */ -/* title "Filtering process for edges for bS equal to 4" in */ -/* ITU T Rec H.264. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 11 2013 Ittiam Draft */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma horizontal edge deblock @ bs4 +* +* @par Description +* This function performs filtering of a chroma block horizontal edge when the +* boundary strength is set to 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.4 under the title +* "Filtering process for edges for bS equal to 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_horz_bs4_bp(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -501,38 +495,40 @@ void ih264_deblk_chroma_horz_bs4_bp(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_luma_vert_bslt4() */ -/* */ -/* Description : This function performs filtering of a luma block */ -/* vertical edge when the boundary strength is less than 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* u4_bs - packed Boundary strength array */ -/* pu1_cliptab - tc0_table */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.3 under the */ -/* title "Filtering process for edges for bS less than 4" */ -/* in ITU T Rec H.264. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 11 2013 Ittiam Draft */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief luma vertical edge deblock @ bs < 4 +* +* @par Description +* This function performs filtering of a luma block vertical edge when the +* boundary strength is less than 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @param[in] u4_bs +* packed Boundary strength array +* +* @param[in] pu1_cliptab +* tc0_table +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.3 under the title +* "Filtering process for edges for bS less than 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_luma_vert_bslt4(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -617,38 +613,40 @@ void ih264_deblk_luma_vert_bslt4(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_vert_bslt4_bp() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* vertical edge when the boundary strength is less than 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* u4_bs - packed Boundary strength array */ -/* pu1_cliptab - tc0_table */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.3 under the */ -/* title "Filtering process for edges for bS less than 4" */ -/* in ITU T Rec H.264. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 11 2013 Ittiam Draft */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma vertical edge deblock @ bs < 4 +* +* @par Description +* This function performs filtering of a chroma block vertical edge when the +* boundary strength is less than 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @param[in] u4_bs +* packed Boundary strength array +* +* @param[in] pu1_cliptab +* tc0_table +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.3 under the title +* "Filtering process for edges for bS less than 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_vert_bslt4_bp(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -731,38 +729,40 @@ void ih264_deblk_chroma_vert_bslt4_bp(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_luma_horz_bslt4() */ -/* */ -/* Description : This function performs filtering of a luma block */ -/* horizontal edge when boundary strength is less than 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* u4_bs - packed Boundary strength array */ -/* pu1_cliptab - tc0_table */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.3 under the */ -/* title "Filtering process for edges for bS less than 4" */ -/* in ITU T Rec H.264. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 11 2013 Ittiam Draft */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief luma horizontal edge deblock @ bs < 4 +* +* @par Description +* This function performs filtering of a luma block horizontal edge when the +* boundary strength is less than 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @param[in] u4_bs +* packed Boundary strength array +* +* @param[in] pu1_cliptab +* tc0_table +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.3 under the title +* "Filtering process for edges for bS less than 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_luma_horz_bslt4(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -850,38 +850,40 @@ void ih264_deblk_luma_horz_bslt4(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_horz_bslt4_bp() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* horizontal edge when boundary strength is less than 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* u4_bs - packed Boundary strength array */ -/* pu1_cliptab - tc0_table */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.3 under the */ -/* title "Filtering process for edges for bS less than 4" */ -/* in ITU T Rec H.264. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 11 2013 Ittiam Draft */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma horizontal edge deblock @ bs < 4 +* +* @par Description +* This function performs filtering of a chroma block horizontal edge when the +* boundary strength is less than 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @param[in] u4_bs +* packed Boundary strength array +* +* @param[in] pu1_cliptab +* tc0_table +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.3 under the title +* "Filtering process for edges for bS less than 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_horz_bslt4_bp(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -975,37 +977,34 @@ void ih264_deblk_chroma_horz_bslt4_bp(UWORD8 *pu1_src, /* Function Definitions for vertical edge deblocking for double-call */ /*****************************************************************************/ -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_luma_vert_bs4_mbaff() */ -/* */ -/* Description : This function performs filtering of a luma block */ -/* vertical edge when boundary strength is set to 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* */ -/* Globals : None */ -/* */ -/* Processing : When the function is called twice, this operation is as */ -/* described in Sec. 8.7.2.3 under the title "Filtering */ -/* process for edges for bS equal to 4" in ITU T Rec H.264. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 29 12 2014 Kaushik Draft */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief luma vertical edge deblock @ bs4 +* +* @par Description +* This function performs filtering of a luma block vertical edge when the +* boundary strength is set to 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.4 under the title +* "Filtering process for edges for bS equal to 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_luma_vert_bs4_mbaff(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -1096,37 +1095,34 @@ void ih264_deblk_luma_vert_bs4_mbaff(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_vert_bs4_mbaff_bp() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* vertical edge when boundary strength is set to 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* */ -/* Globals : None */ -/* */ -/* Processing : When the function is called twice, this operation is as */ -/* described in Sec. 8.7.2.3 under the title "Filtering */ -/* process for edges for bS equal to 4" in ITU T Rec H.264. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 29 12 2014 Kaushik Draft */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma vertical edge deblock @ bs4 +* +* @par Description +* This function performs filtering of a chroma block vertical edge when the +* boundary strength is set to 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.4 under the title +* "Filtering process for edges for bS equal to 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_vert_bs4_mbaff_bp(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -1183,39 +1179,40 @@ void ih264_deblk_chroma_vert_bs4_mbaff_bp(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_luma_vert_bslt4_mbaff() */ -/* */ -/* Description : This function performs filtering of a luma block */ -/* vertical edge when boundary strength is less than 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* u4_bs - packed Boundary strength array */ -/* pu1_cliptab - tc0_table */ -/* */ -/* Globals : None */ -/* */ -/* Processing : When the function is called twice, this operation is as */ -/* described in Sec. 8.7.2.3 under the title "Filtering */ -/* process for edges for bS less than 4" in ITU T Rec H.264.*/ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 29 12 2014 Kaushik Draft */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief luma vertical edge deblock @ bs < 4 +* +* @par Description +* This function performs filtering of a luma block vertical edge when the +* boundary strength is less than 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @param[in] u4_bs +* packed Boundary strength array +* +* @param[in] pu1_cliptab +* tc0_table +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.3 under the title +* "Filtering process for edges for bS less than 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_luma_vert_bslt4_mbaff(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -1299,39 +1296,40 @@ void ih264_deblk_luma_vert_bslt4_mbaff(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_vert_bslt4_mbaff_bp() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* vertical edge when boundary strength is less than 4. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha - alpha value for the boundary */ -/* beta - beta value for the boundary */ -/* u4_bs - packed Boundary strength array */ -/* pu1_cliptab - tc0_table */ -/* */ -/* Globals : None */ -/* */ -/* Processing : When the function is called twice, this operation is as */ -/* described in Sec. 8.7.2.3 under the title "Filtering */ -/* process for edges for bS less than 4" in ITU T Rec H.264.*/ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 29 12 2014 Kaushik Draft */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma vertical edge deblock @ bs < 4 +* +* @par Description +* This function performs filtering of a chroma block vertical edge when the +* boundary strength is less than 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha +* alpha value for the boundary +* +* @param[in] beta +* beta value for the boundary +* +* @param[in] u4_bs +* packed Boundary strength array +* +* @param[in] pu1_cliptab +* tc0_table +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.3 under the title +* "Filtering process for edges for bS less than 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_vert_bslt4_mbaff_bp(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha, @@ -1415,41 +1413,40 @@ void ih264_deblk_chroma_vert_bslt4_mbaff_bp(UWORD8 *pu1_src, /* Function Definitions for chroma deblocking in high profile */ /*****************************************************************************/ -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_vert_bs4() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* vertical edge when the boundary strength is set to 4 in */ -/* high profile. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha_cb - alpha value for the boundary in U */ -/* beta_cb - beta value for the boundary in U */ -/* alpha_cr - alpha value for the boundary in V */ -/* beta_cr - beta value for the boundary in V */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.4 under the */ -/* title "Filtering process for edges for bS equal to 4" in */ -/* ITU T Rec H.264 with alpha and beta values different in */ -/* U and V. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 29 12 2014 Kaushik Draft */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma vertical edge deblock @ bs4 +* +* @par Description +* This function performs filtering of a chroma block vertical edge when the +* boundary strength is set to 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha_cb +* alpha value for the boundary of U +* +* @param[in] beta_cb +* beta value for the boundary of U +* +* @param[in] alpha_cr +* alpha value for the boundary of V +* +* @param[in] beta_cr +* beta value for the boundary of V +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.4 under the title +* "Filtering process for edges for bS equal to 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_vert_bs4(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha_cb, @@ -1512,41 +1509,40 @@ void ih264_deblk_chroma_vert_bs4(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_horz_bs4() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* horizontal edge when the boundary strength is set to 4 */ -/* in high profile. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha_cb - alpha value for the boundary in U */ -/* beta_cb - beta value for the boundary in U */ -/* alpha_cr - alpha value for the boundary in V */ -/* beta_cr - beta value for the boundary in V */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.4 under the */ -/* title "Filtering process for edges for bS equal to 4" in */ -/* ITU T Rec H.264 with alpha and beta values different in */ -/* U and V. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 29 12 2014 Kaushik Draft */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma horizontal edge deblock @ bs4 +* +* @par Description +* This function performs filtering of a chroma block horizontal edge when the +* boundary strength is set to 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha_cb +* alpha value for the boundary of U +* +* @param[in] beta_cb +* beta value for the boundary of U +* +* @param[in] alpha_cr +* alpha value for the boundary of V +* +* @param[in] beta_cr +* beta value for the boundary of V +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.4 under the title +* "Filtering process for edges for bS equal to 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_horz_bs4(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha_cb, @@ -1614,44 +1610,49 @@ void ih264_deblk_chroma_horz_bs4(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_vert_bslt4() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* vertical edge when the boundary strength is less than 4 */ -/* in high profile. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha_cb - alpha value for the boundary in U */ -/* beta_cb - beta value for the boundary in U */ -/* alpha_cr - alpha value for the boundary in V */ -/* beta_cr - beta value for the boundary in V */ -/* u4_bs - packed Boundary strength array */ -/* pu1_cliptab_cb - tc0_table for U */ -/* pu1_cliptab_cr - tc0_table for V */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.3 under the */ -/* title "Filtering process for edges for bS less than 4" */ -/* in ITU T Rec H.264 with alpha and beta values different */ -/* in U and V. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 29 12 2014 Kaushik Draft */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma vertical edge deblock @ bs < 4 +* +* @par Description +* This function performs filtering of a chroma block vertical edge when the +* boundary strength is less than 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha_cb +* alpha value for the boundary of U +* +* @param[in] beta_cb +* beta value for the boundary of U +* +* @param[in] alpha_cr +* alpha value for the boundary of V +* +* @param[in] beta_cr +* beta value for the boundary of V +* +* @param[in] u4_bs +* packed Boundary strength array +* +* @param[in] pu1_cliptab_cb +* tc0_table of U +* +* @param[in] pu1_cliptab_cr +* tc0_table of V +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.3 under the title +* "Filtering process for edges for bS less than 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_vert_bslt4(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha_cb, @@ -1737,44 +1738,49 @@ void ih264_deblk_chroma_vert_bslt4(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_horz_bslt4() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* horizontal edge when the boundary strength is less than */ -/* 4 in high profile. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha_cb - alpha value for the boundary in U */ -/* beta_cb - beta value for the boundary in U */ -/* alpha_cr - alpha value for the boundary in V */ -/* beta_cr - beta value for the boundary in V */ -/* u4_bs - packed Boundary strength array */ -/* pu1_cliptab_cb - tc0_table for U */ -/* pu1_cliptab_cr - tc0_table for V */ -/* */ -/* Globals : None */ -/* */ -/* Processing : This operation is described in Sec. 8.7.2.3 under the */ -/* title "Filtering process for edges for bS less than 4" */ -/* in ITU T Rec H.264 with alpha and beta values different */ -/* in U and V. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 29 12 2014 Kaushik Draft */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma horizontal edge deblock @ bs < 4 +* +* @par Description +* This function performs filtering of a chroma block horizontal edge when the +* boundary strength is less than 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha_cb +* alpha value for the boundary of U +* +* @param[in] beta_cb +* beta value for the boundary of U +* +* @param[in] alpha_cr +* alpha value for the boundary of V +* +* @param[in] beta_cr +* beta value for the boundary of V +* +* @param[in] u4_bs +* packed Boundary strength array +* +* @param[in] pu1_cliptab_cb +* tc0_table of U +* +* @param[in] pu1_cliptab_cr +* tc0_table of V +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.3 under the title +* "Filtering process for edges for bS less than 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_horz_bslt4(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha_cb, @@ -1869,44 +1875,40 @@ void ih264_deblk_chroma_horz_bslt4(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_vert_bs4_mbaff() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* vertical edge when boundary strength is set to 4 in high */ -/* profile. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha_cb - alpha value for the boundary in U */ -/* beta_cb - beta value for the boundary in U */ -/* alpha_cr - alpha value for the boundary in V */ -/* beta_cr - beta value for the boundary in V */ -/* u4_bs - packed Boundary strength array */ -/* pu1_cliptab_cb - tc0_table for U */ -/* pu1_cliptab_cr - tc0_table for V */ -/* */ -/* Globals : None */ -/* */ -/* Processing : When the function is called twice, this operation is as */ -/* described in Sec. 8.7.2.4 under the title "Filtering */ -/* process for edges for bS equal to 4" in ITU T Rec H.264 */ -/* with alpha and beta values different in U and V. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 29 12 2014 Kaushik Draft */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma vertical edge deblock @ bs4 +* +* @par Description +* This function performs filtering of a chroma block vertical edge when the +* boundary strength is set to 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha_cb +* alpha value for the boundary of U +* +* @param[in] beta_cb +* beta value for the boundary of U +* +* @param[in] alpha_cr +* alpha value for the boundary of V +* +* @param[in] beta_cr +* beta value for the boundary of V +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.4 under the title +* "Filtering process for edges for bS equal to 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_vert_bs4_mbaff(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha_cb, @@ -1965,44 +1967,49 @@ void ih264_deblk_chroma_vert_bs4_mbaff(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_deblk_chroma_vert_bslt4_mbaff() */ -/* */ -/* Description : This function performs filtering of a chroma block */ -/* vertical edge when boundary strength is less than 4 in */ -/* high profile. */ -/* */ -/* Inputs : pu1_src - pointer to the src sample q0 of U */ -/* src_strd - source stride */ -/* alpha_cb - alpha value for the boundary in U */ -/* beta_cb - beta value for the boundary in U */ -/* alpha_cr - alpha value for the boundary in V */ -/* beta_cr - beta value for the boundary in V */ -/* u4_bs - packed Boundary strength array */ -/* pu1_cliptab_cb - tc0_table for U */ -/* pu1_cliptab_cr - tc0_table for V */ -/* */ -/* Globals : None */ -/* */ -/* Processing : When the function is called twice, this operation is as */ -/* described in Sec. 8.7.2.4 under the title "Filtering */ -/* process for edges for bS less than 4" in ITU T Rec H.264 */ -/* with alpha and beta values different in U and V. */ -/* */ -/* Outputs : None */ -/* */ -/* Returns : None */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 29 12 2014 Kaushik Draft */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief chroma vertical edge deblock @ bs < 4 +* +* @par Description +* This function performs filtering of a chroma block vertical edge when the +* boundary strength is less than 4 +* +* @param[in] pu1_src +* pointer to the src sample q0 of U +* +* @param[in] src_strd +* source stride +* +* @param[in] alpha_cb +* alpha value for the boundary of U +* +* @param[in] beta_cb +* beta value for the boundary of U +* +* @param[in] alpha_cr +* alpha value for the boundary of V +* +* @param[in] beta_cr +* beta value for the boundary of V +* +* @param[in] u4_bs +* packed Boundary strength array +* +* @param[in] pu1_cliptab_cb +* tc0_table of U +* +* @param[in] pu1_cliptab_cr +* tc0_table of V +* +* @returns none +* +* @remarks This operation is described in Sec. 8.7.2.3 under the title +* "Filtering process for edges for bS less than 4" in ITU T Rec H.264 +* +****************************************************************************** +*/ void ih264_deblk_chroma_vert_bslt4_mbaff(UWORD8 *pu1_src, WORD32 src_strd, WORD32 alpha_cb, diff --git a/common/ih264_deblk_edge_filters.h b/common/ih264_deblk_edge_filters.h index 4079dd2..455d4b0 100644 --- a/common/ih264_deblk_edge_filters.h +++ b/common/ih264_deblk_edge_filters.h @@ -17,25 +17,26 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_deblk_edge_filters.h - * - * @brief - * This file contains declarations of functions used for deblocking - * - * @author - * Ittiam - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_deblk_edge_filters.h +* +* @brief +* This file contains declarations of functions used for deblocking +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ -#ifndef IH264_DEBLK_H_ -#define IH264_DEBLK_H_ +#ifndef _IH264_DEBLK_EDGE_FILTERS_H_ +#define _IH264_DEBLK_EDGE_FILTERS_H_ /*****************************************************************************/ /* Extern Function Declarations */ @@ -70,126 +71,92 @@ typedef void ih264_deblk_chroma_edge_bs4_ft(UWORD8 *pu1_src, WORD32 alpha_cr, WORD32 beta_cr); - - +/* C Declarations */ ih264_deblk_edge_bs4_ft ih264_deblk_luma_horz_bs4; ih264_deblk_edge_bs4_ft ih264_deblk_luma_vert_bs4; ih264_deblk_edge_bs4_ft ih264_deblk_luma_vert_bs4_mbaff; - - ih264_deblk_edge_bs4_ft ih264_deblk_chroma_horz_bs4_bp; ih264_deblk_edge_bs4_ft ih264_deblk_chroma_vert_bs4_bp; ih264_deblk_edge_bs4_ft ih264_deblk_chroma_vert_bs4_mbaff_bp; - - ih264_deblk_edge_bslt4_ft ih264_deblk_luma_horz_bslt4; ih264_deblk_edge_bslt4_ft ih264_deblk_luma_vert_bslt4; ih264_deblk_edge_bslt4_ft ih264_deblk_luma_vert_bslt4_mbaff; - - ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4_bp; ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_bp; ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_mbaff_bp; - ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_vert_bs4; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_horz_bs4; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_vert_bs4_mbaff; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_horz_bs4_mbaff; - ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_mbaff; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4_mbaff; - -/*A9*/ +/* A9 Declarations */ ih264_deblk_edge_bs4_ft ih264_deblk_luma_horz_bs4_a9; ih264_deblk_edge_bs4_ft ih264_deblk_luma_vert_bs4_a9; ih264_deblk_edge_bs4_ft ih264_deblk_luma_vert_bs4_mbaff_a9; - - ih264_deblk_edge_bs4_ft ih264_deblk_chroma_horz_bs4_bp_a9; ih264_deblk_edge_bs4_ft ih264_deblk_chroma_vert_bs4_bp_a9; ih264_deblk_edge_bs4_ft ih264_deblk_chroma_vert_bs4_mbaff_bp_a9; - - ih264_deblk_edge_bslt4_ft ih264_deblk_luma_horz_bslt4_a9; ih264_deblk_edge_bslt4_ft ih264_deblk_luma_vert_bslt4_a9; ih264_deblk_edge_bslt4_ft ih264_deblk_luma_vert_bslt4_mbaff_a9; - - ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4_bp_a9; ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_bp_a9; ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_mbaff_bp_a9; - ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_vert_bs4_a9; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_horz_bs4_a9; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_vert_bs4_mbaff_a9; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_horz_bs4_mbaff_a9; - ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_a9; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4_a9; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_mbaff_a9; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4_mbaff_a9; -/*AV8*/ +/* AV8 Declarations */ ih264_deblk_edge_bs4_ft ih264_deblk_luma_horz_bs4_av8; ih264_deblk_edge_bs4_ft ih264_deblk_luma_vert_bs4_av8; ih264_deblk_edge_bs4_ft ih264_deblk_luma_vert_bs4_mbaff_av8; - - ih264_deblk_edge_bs4_ft ih264_deblk_chroma_horz_bs4_bp_av8; ih264_deblk_edge_bs4_ft ih264_deblk_chroma_vert_bs4_bp_av8; ih264_deblk_edge_bs4_ft ih264_deblk_chroma_vert_bs4_mbaff_bp_av8; - - ih264_deblk_edge_bslt4_ft ih264_deblk_luma_horz_bslt4_av8; ih264_deblk_edge_bslt4_ft ih264_deblk_luma_vert_bslt4_av8; ih264_deblk_edge_bslt4_ft ih264_deblk_luma_vert_bslt4_mbaff_av8; - - ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4_bp_av8; ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_bp_av8; ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_mbaff_bp_av8; - ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_vert_bs4_av8; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_horz_bs4_av8; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_vert_bs4_mbaff_av8; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_horz_bs4_mbaff_av8; - ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_av8; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4_av8; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_mbaff_av8; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4_mbaff_av8; -/*SSE3*/ +/* SSSE3 Declarations */ ih264_deblk_edge_bs4_ft ih264_deblk_luma_horz_bs4_ssse3; ih264_deblk_edge_bs4_ft ih264_deblk_luma_vert_bs4_ssse3; ih264_deblk_edge_bs4_ft ih264_deblk_luma_vert_bs4_mbaff_ssse3; - - ih264_deblk_edge_bs4_ft ih264_deblk_chroma_horz_bs4_bp_ssse3; ih264_deblk_edge_bs4_ft ih264_deblk_chroma_vert_bs4_bp_ssse3; ih264_deblk_edge_bs4_ft ih264_deblk_chroma_vert_bs4_mbaff_bp_ssse3; - - ih264_deblk_edge_bslt4_ft ih264_deblk_luma_horz_bslt4_ssse3; ih264_deblk_edge_bslt4_ft ih264_deblk_luma_vert_bslt4_ssse3; ih264_deblk_edge_bslt4_ft ih264_deblk_luma_vert_bslt4_mbaff_ssse3; - - ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4_bp_ssse3; ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_bp_ssse3; ih264_deblk_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_mbaff_bp_ssse3; - ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_vert_bs4_ssse3; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_horz_bs4_ssse3; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_vert_bs4_mbaff_ssse3; ih264_deblk_chroma_edge_bs4_ft ih264_deblk_chroma_horz_bs4_mbaff_ssse3; - ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_ssse3; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4_ssse3; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_vert_bslt4_mbaff_ssse3; ih264_deblk_chroma_edge_bslt4_ft ih264_deblk_chroma_horz_bslt4_mbaff_ssse3; -#endif /* IH264_DEBLK_H_ */ +#endif /* _IH264_DEBLK_EDGE_FILTERS_H_ */ diff --git a/common/ih264_deblk_tables.c b/common/ih264_deblk_tables.c index 91e28e0..b0106e3 100644 --- a/common/ih264_deblk_tables.c +++ b/common/ih264_deblk_tables.c @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,16 +27,10 @@ * Contains tables used for deblocking * * @author -* Ittiam -* -* @par List of Tables: -* - guc_ih264_qp_scale_cr[] -* - guc_ih264_alpha_table[] -* - guc_ih264_beta_table[] -* - guc_ih264_clip_table[][] +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ @@ -61,7 +56,7 @@ * input : indexA [0-51] & indexB [0-51] * output : alpha & beta * - * @remarks Table 8-16 – in H264 Specification, + * @remarks Table 8-16 - in H264 Specification, * Derivation of offset dependent threshold variables * alpha and beta from indexA and indexB ****************************************************************************** @@ -96,7 +91,7 @@ const UWORD8 gu1_ih264_beta_table[52] = * input : indexA [0-51] and bS [1,3] * output : t'C0 * - * @remarks Table 8-17 – in H264 Specification, + * @remarks Table 8-17 - in H264 Specification, * Value of variable t'C0 as a function of indexA and bS ****************************************************************************** */ diff --git a/common/ih264_deblk_tables.h b/common/ih264_deblk_tables.h index 3935dcb..c365788 100644 --- a/common/ih264_deblk_tables.h +++ b/common/ih264_deblk_tables.h @@ -17,57 +17,34 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_deblk_tables.h - * - * @brief - * This file contains declarations of tables used for deblocking - * - * @author - * Ittiam - * - * @par List of Functions: - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_deblk_tables.h +* +* @brief +* This file contains declarations of tables used for deblocking +* +* @author +* ittiam +* +* @remarks +* None +* +******************************************************************************* +*/ -#ifndef IH264_DEBLK_TABLES_H_ -#define IH264_DEBLK_TABLES_H_ +#ifndef _IH264_DEBLK_TABLES_H_ +#define _IH264_DEBLK_TABLES_H_ /*****************************************************************************/ /* Extern global declarations */ /*****************************************************************************/ - -/** - ****************************************************************************** - * @brief alpha & beta tables for deblocking - * input : indexA [0-51] & indexB [0-51] - * output : alpha & beta - * - * @remarks Table 8-16 – in H264 Specification, - * Derivation of offset dependent threshold variables - * alpha and beta from indexA and indexB - ****************************************************************************** - */ extern const UWORD8 gu1_ih264_alpha_table[52]; extern const UWORD8 gu1_ih264_beta_table[52]; -/** - ****************************************************************************** - * @brief t'C0 table for deblocking - * input : indexA [0-51] and bS [1,3] - * output : t'C0 - * - * @remarks Table 8-17 – in H264 Specification, - * Value of variable t'C0 as a function of indexA and bS - ****************************************************************************** - */ extern const UWORD8 gu1_ih264_clip_table[52][4]; -#endif /* IH264_DEBLK_TABLES_H_ */ +#endif /* _IH264_DEBLK_TABLES_H_ */ diff --git a/common/ih264_debug.h b/common/ih264_debug.h index 63d5c71..afadc4d 100644 --- a/common/ih264_debug.h +++ b/common/ih264_debug.h @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,12 +27,10 @@ * Definitions for codec debugging * * @author -* Ittiam -* -* @par List of Functions: +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ @@ -40,23 +39,21 @@ #include <assert.h> -#if DEBUG_PRINT +/*****************************************************************************/ +/* Function Macros */ +/*****************************************************************************/ +#if DEBUG_PRINT #define DEBUG(...) \ { \ printf("\n[H264 DBG] %s/%d:: ", __FUNCTION__, __LINE__); \ printf(__VA_ARGS__); \ } - #else - #define DEBUG(...) {} - #endif - #define ASSERT(x) assert((x)) - #endif /* _IH264_DEBUG_H_ */ diff --git a/common/ih264_defs.h b/common/ih264_defs.h index 62b2783..5157116 100644 --- a/common/ih264_defs.h +++ b/common/ih264_defs.h @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,17 +27,16 @@ * Definitions used in the codec * * @author -* Ittiam -* +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264_DEFS_H_ -#define IH264_DEFS_H_ +#ifndef _IH264_DEFS_H_ +#define _IH264_DEFS_H_ /*****************************************************************************/ /* Enums */ @@ -456,18 +456,16 @@ typedef enum B_BI_4x4, }SUBMBTYPE_BSLICE_T; +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ + /** * DC Mode pattern for 4 4x4 sub blocks in an MB row */ #define DC_I16X16_MB_ROW (DC_I16x16 << 24) | (DC_I16x16 << 16) | \ (DC_I16x16 << 8) | DC_I16x16 - - -/*****************************************************************************/ -/* Constant Macros */ -/*****************************************************************************/ - /*****************************************************************************/ /* Reference frame defs */ /*****************************************************************************/ @@ -540,7 +538,7 @@ typedef enum /* Number of max PU in a MB */ /*****************************************************************************/ -/* Note though for 64 x 64 MB, Max PU in MB is 128, in order to store */ +/* Note though for 64 x 64 MB, Max PU in MB is 128, in order to store */ /* intra pred info, 256 entries are needed */ /*****************************************************************************/ #define MAX_PU_IN_MB ((MB_SIZE / MIN_PU_SIZE) * \ @@ -792,4 +790,4 @@ typedef enum #define SEI_FGC_MAX_NUM_MODEL_VALUES 6 #define SEI_FGC_MAX_NUM_INTENSITY_INTERVALS 256 -#endif /* IH264_DEFS_H_ */ +#endif /* _IH264_DEFS_H_ */ diff --git a/common/ih264_disp_mgr.c b/common/ih264_disp_mgr.c index 2bdb524..caf1d0f 100644 --- a/common/ih264_disp_mgr.c +++ b/common/ih264_disp_mgr.c @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,40 +27,49 @@ * Contains function definitions for display management * * @author -* Srinivas T +* ittiam * * @par List of Functions: -* - ih264_disp_mgr_init() -* - ih264_disp_mgr_add() -* - ih264_disp_mgr_get() +* - ih264_disp_mgr_init +* - ih264_disp_mgr_add +* - ih264_disp_mgr_get * * @remarks -* None +* none * ******************************************************************************* */ + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ + +/* System Include Files */ #include <stdlib.h> + +/* User Include Files */ #include "ih264_typedefs.h" #include "ih264_macros.h" #include "ih264_disp_mgr.h" +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ /** ******************************************************************************* * -* @brief -* Initialization function for display buffer manager +* @brief Initialization function for display buffer manager * -* @par Description: -* Initializes the display buffer management structure +* @par Description +* Initializes the display buffer management structure * * @param[in] ps_disp_mgr * Pointer to the display buffer management structure * * @returns none * -* @remarks -* None +* @remarks none * ******************************************************************************* */ @@ -76,15 +86,13 @@ void ih264_disp_mgr_init(disp_mgr_t *ps_disp_mgr) } } - /** ******************************************************************************* * -* @brief -* Adds a buffer to the display manager +* @brief Adds a buffer to the display manager * * @par Description: -* Adds a buffer to the display buffer manager +* Adds a buffer to the display buffer manager * * @param[in] ps_disp_mgr * Pointer to the display buffer management structure @@ -122,15 +130,14 @@ WORD32 ih264_disp_mgr_add(disp_mgr_t *ps_disp_mgr, ps_disp_mgr->apv_ptr[buf_id] = pv_ptr; ps_disp_mgr->ai4_abs_poc[buf_id] = abs_poc; + return 0; } - /** ******************************************************************************* * -* @brief -* Gets the next buffer +* @brief Gets the next buffer * * @par Description: * Gets the next display buffer @@ -151,14 +158,9 @@ WORD32 ih264_disp_mgr_add(disp_mgr_t *ps_disp_mgr, void* ih264_disp_mgr_get(disp_mgr_t *ps_disp_mgr, WORD32 *pi4_buf_id) { WORD32 id; - void *pv_ret_ptr; - WORD32 i4_min_poc; - WORD32 min_poc_id; - - - pv_ret_ptr = NULL; - i4_min_poc = 0x7FFFFFFF; - min_poc_id = -1; + void *pv_ret_ptr = NULL; + WORD32 i4_min_poc = 0x7FFFFFFF; + WORD32 min_poc_id = -1; /* Find minimum POC */ for(id = 0; id < DISP_MGR_MAX_CNT; id++) @@ -182,5 +184,6 @@ void* ih264_disp_mgr_get(disp_mgr_t *ps_disp_mgr, WORD32 *pi4_buf_id) /* Set abs poc to default and apv_ptr to null so that the buffer is not returned again */ ps_disp_mgr->apv_ptr[min_poc_id] = NULL; ps_disp_mgr->ai4_abs_poc[min_poc_id] = DEFAULT_POC; + return pv_ret_ptr; } diff --git a/common/ih264_disp_mgr.h b/common/ih264_disp_mgr.h index 6f56493..d634e77 100644 --- a/common/ih264_disp_mgr.h +++ b/common/ih264_disp_mgr.h @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,20 +27,26 @@ * Function declarations used for display management * * @author -* Srinivas T -* +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef _DISP_MGR_H_ -#define _DISP_MGR_H_ +#ifndef _IH264_DISP_MGR_H_ +#define _IH264_DISP_MGR_H_ + +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ #define DISP_MGR_MAX_CNT 64 #define DEFAULT_POC 0x7FFFFFFF +/*****************************************************************************/ +/* Structure Definitions */ +/*****************************************************************************/ typedef struct { /** @@ -55,9 +62,12 @@ typedef struct /** * apv_ptr[DISP_MGR_MAX_CNT] */ - void *apv_ptr[DISP_MGR_MAX_CNT]; + void *apv_ptr[DISP_MGR_MAX_CNT]; }disp_mgr_t; +/*****************************************************************************/ +/* Function Declarations */ +/*****************************************************************************/ void ih264_disp_mgr_init(disp_mgr_t *ps_disp_mgr); WORD32 ih264_disp_mgr_add(disp_mgr_t *ps_disp_mgr, @@ -67,4 +77,4 @@ WORD32 ih264_disp_mgr_add(disp_mgr_t *ps_disp_mgr, void* ih264_disp_mgr_get(disp_mgr_t *ps_disp_mgr, WORD32 *pi4_buf_id); -#endif //_DISP_MGR_H_ +#endif /* _IH264_DISP_MGR_H_ */ diff --git a/common/ih264_dpb_mgr.c b/common/ih264_dpb_mgr.c index 9380b7e..afb8630 100644 --- a/common/ih264_dpb_mgr.c +++ b/common/ih264_dpb_mgr.c @@ -17,89 +17,97 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_dpb_mgr.c - * - * @brief - * Function definitions used for decoded picture buffer management - * - * @author - * Srinivas T - * - * @par List of Functions: - * - ih264_dpb_mgr_init() - * - ih264_dpb_mgr_sort_short_term_fields_by_frame_num() - * - ih264_dpb_mgr_sort_short_term_fields_by_poc_l0() - * - ih264_dpb_mgr_sort_short_term_fields_by_poc_l1() - * - ih264_dpb_mgr_sort_long_term_fields_by_frame_idx() - * - ih264_dpb_mgr_alternate_ref_fields() - * - ih264_dpb_mgr_insert_ref_field() - * - ih264_dpb_mgr_insert_ref_frame() - * - ih264_dpb_mgr_count_ref_frames() - * - ih264_dpb_mgr_delete_ref_frame() - * - ih264_dpb_mgr_delete_long_ref_fields_max_frame_idx() - * - ih264_dpb_mgr_delete_short_ref_frame() - * - ih264_dpb_mgr_delete_all_ref_frames() - * - ih264_dpb_mgr_reset() - * - ih264_dpb_mgr_release_pics() - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_dpb_mgr.c +* +* @brief +* Function definitions used for decoded picture buffer management +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264_dpb_mgr_init +* - ih264_dpb_mgr_sort_short_term_fields_by_frame_num +* - ih264_dpb_mgr_sort_short_term_fields_by_poc_l0 +* - ih264_dpb_mgr_sort_short_term_fields_by_poc_l1 +* - ih264_dpb_mgr_sort_long_term_fields_by_frame_idx +* - ih264_dpb_mgr_alternate_ref_fields +* - ih264_dpb_mgr_insert_ref_field +* - ih264_dpb_mgr_insert_ref_frame +* - ih264_dpb_mgr_count_ref_frames +* - ih264_dpb_mgr_delete_ref_frame +* - ih264_dpb_mgr_delete_long_ref_fields_max_frame_idx +* - ih264_dpb_mgr_delete_short_ref_frame +* - ih264_dpb_mgr_delete_all_ref_frames +* - ih264_dpb_mgr_reset +* - ih264_dpb_mgr_release_pics +* +* @remarks +* none +* +******************************************************************************* +*/ + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ +/* System Include Files */ #include <stdio.h> #include <stdlib.h> #include <assert.h> +/* User Include Files */ #include "ih264_typedefs.h" -#include "ih264_defs.h" +#include "ih264_debug.h" #include "ih264_macros.h" #include "ih264_error.h" +#include "ih264_defs.h" #include "ih264_structs.h" #include "ih264_buf_mgr.h" #include "ih264_dpb_mgr.h" -#include "ih264_debug.h" -/** - ******************************************************************************* - * - * @brief - * DPB manager initializer - * - * @par Description: - * Initialises the DPB manager structure - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ + +/** +******************************************************************************* +* +* @brief DPB manager initializer +* +* @par Description Initialises the DPB manager structure +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ void ih264_dpb_mgr_init(dpb_mgr_t *ps_dpb_mgr) { UWORD32 i; dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info; + for(i = 0; i < MAX_DPB_BUFS; i++) { ps_dpb_info[i].ps_prev_dpb = NULL; ps_dpb_info[i].ps_pic_buf = NULL; - ps_dpb_mgr->as_top_field_pics[i].i4_used_as_ref = INVALID; + ps_dpb_mgr->as_top_field_pics[i].i4_used_as_ref = INVALID; ps_dpb_mgr->as_bottom_field_pics[i].i4_used_as_ref = INVALID; - ps_dpb_mgr->as_top_field_pics[i].i1_field_type = INVALID; - ps_dpb_mgr->as_bottom_field_pics[i].i1_field_type = INVALID; - ps_dpb_mgr->as_top_field_pics[i].i4_long_term_frame_idx = -1; + ps_dpb_mgr->as_top_field_pics[i].i1_field_type = INVALID; + ps_dpb_mgr->as_bottom_field_pics[i].i1_field_type = INVALID; + ps_dpb_mgr->as_top_field_pics[i].i4_long_term_frame_idx = -1; ps_dpb_mgr->as_bottom_field_pics[i].i4_long_term_frame_idx = -1; } - ps_dpb_mgr->u1_num_short_term_ref_bufs = 0; ps_dpb_mgr->u1_num_long_term_ref_bufs = 0; ps_dpb_mgr->ps_dpb_short_term_head = NULL; @@ -107,34 +115,34 @@ void ih264_dpb_mgr_init(dpb_mgr_t *ps_dpb_mgr) } /** - ******************************************************************************* - * - * @brief - * Function to sort sort term pics by frame_num. - * - * @par Description: - * Sorts short term fields by frame_num. For 2 fields having same frame_num, - * orders them based on requested first field type. - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @param[in] curr_frame_num - * frame_num of the current pic - * - * @param[in] first_field_type - * For complementary fields, required first field - * - * @param[in] max_frame_num - * Maximum frame_num allowed - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Function to sort short term pics by frame_num. +* +* @par Description: +* Sorts short term fields by frame_num. For 2 fields having same frame_num, +* orders them based on requested first field type. +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] curr_frame_num +* frame_num of the current pic +* +* @param[in] first_field_type +* For complementary fields, required first field +* +* @param[in] max_frame_num +* Maximum frame_num allowed +* +* @returns +* +* @remarks +* +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_sort_short_term_fields_by_frame_num(dpb_mgr_t *ps_dpb_mgr, WORD32 curr_frame_num, WORD32 first_field_type, @@ -195,35 +203,33 @@ WORD32 ih264_dpb_mgr_sort_short_term_fields_by_frame_num(dpb_mgr_t *ps_dpb_mgr, ps_dpb_node2 = ps_dpb_node2->ps_prev_dpb; } return 0; - } /** - ******************************************************************************* - * - * @brief - * Function to sort sort term pics by poc for list 0. - * - * @par Description: - * Orders all the pocs less than current poc in the descending order. - * Then orders all the pocs greater than current poc in the ascending order. - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @param[in] curr_poc - * Poc of the current pic - * - * @param[in] first_field_type - * For complementary fields, required first field - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Function to sort sort term pics by poc for list 0. +* +* @par Description: +* Orders all the pocs less than current poc in the descending order. +* Then orders all the pocs greater than current poc in the ascending order. +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] curr_poc +* Poc of the current pic +* +* @param[in] first_field_type +* For complementary fields, required first field +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_sort_short_term_fields_by_poc_l0(dpb_mgr_t *ps_dpb_mgr, WORD32 curr_poc, WORD32 first_field_type) @@ -284,35 +290,34 @@ WORD32 ih264_dpb_mgr_sort_short_term_fields_by_poc_l0(dpb_mgr_t *ps_dpb_mgr, ps_dpb_node2 = ps_dpb_node2->ps_prev_dpb; } return 0; - } /** - ******************************************************************************* - * - * @brief - * Function to sort sort term pics by poc for list 1. - * - * @par Description: - * Orders all the pocs greater than current poc in the ascending order. - * Then rrders all the pocs less than current poc in the descending order. - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @param[in] curr_poc - * Poc of the current pic - * - * @param[in] first_field_type - * For complementary fields, required first field - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Function to sort sort term pics by poc for list 1. +* +* @par Description: +* Orders all the pocs greater than current poc in the ascending order. +* Then rrders all the pocs less than current poc in the descending order. +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] curr_poc +* Poc of the current pic +* +* @param[in] first_field_type +* For complementary fields, required first field +* +* @returns +* +* @remarks +* +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_sort_short_term_fields_by_poc_l1(dpb_mgr_t *ps_dpb_mgr, WORD32 curr_poc, WORD32 first_field_type) @@ -374,29 +379,29 @@ WORD32 ih264_dpb_mgr_sort_short_term_fields_by_poc_l1(dpb_mgr_t *ps_dpb_mgr, } return 0; } + /** - ******************************************************************************* - * - * @brief - * Function to sort long term pics by long term frame idx. - * - * @par Description: - * Sorts long term fields by long term frame idx. For 2 fields - * having same frame_num, orders them based on requested first field type. - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @param[in] first_field_type - * For complementary fields, required first field - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Function to sort long term pics by long term frame idx. +* +* @par Description: +* Sorts long term fields by long term frame idx. For 2 fields +* having same frame_num, orders them based on requested first field type. +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] first_field_type +* For complementary fields, required first field +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_sort_long_term_fields_by_frame_idx(dpb_mgr_t *ps_dpb_mgr, WORD32 first_field_type) { @@ -454,31 +459,30 @@ WORD32 ih264_dpb_mgr_sort_long_term_fields_by_frame_idx(dpb_mgr_t *ps_dpb_mgr, } /** - ******************************************************************************* - * - * @brief - * Function to alternate fields. - * - * @par Description: - * In the ordered list of fields, alternate fields starting with - * first_field_type - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @param[in] reference_type - * This is used to select between short-term and long-term linked list. - * - * @param[in] first_field_type - * For complementary fields, required first field - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Function to alternate fields. +* +* @par Description: +* In the ordered list of fields, alternate fields starting with +* first_field_type +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] reference_type +* This is used to select between short-term and long-term linked list. +* +* @param[in] first_field_type +* For complementary fields, required first field +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_alternate_ref_fields(dpb_mgr_t *ps_dpb_mgr, WORD32 reference_type, WORD32 first_field_type) @@ -549,40 +553,39 @@ WORD32 ih264_dpb_mgr_alternate_ref_fields(dpb_mgr_t *ps_dpb_mgr, } /** - ******************************************************************************* - * - * @brief - * Add a ref field to short-term or long-term linked list. - * - * @par Description: - * This function adds a ref field to either short-term or long-term linked - * list. It picks up memory for the link from the array of dpb_info in - * dpb_mgr. The field is added to the beginning of the linked list and the - * head is set the the field. - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @param[in] ps_pic_buf - * Pic buf structure for the field being added. - * - * @param[in] reference_type - * This is used to select between short-term and long-term linked list. - * - * @param[in] frame_num - * frame_num for the field. - * - * @param[in] long_term_frame_idx - * If the ref being added is long-term, long_term_frame_idx of the field. - * Otherwise invalid. - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Add a ref field to short-term or long-term linked list. +* +* @par Description: +* This function adds a ref field to either short-term or long-term linked +* list. It picks up memory for the link from the array of dpb_info in +* dpb_mgr. The field is added to the beginning of the linked list and the +* head is set the the field. +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] ps_pic_buf +* Pic buf structure for the field being added. +* +* @param[in] reference_type +* This is used to select between short-term and long-term linked list. +* +* @param[in] frame_num +* frame_num for the field. +* +* @param[in] long_term_frame_idx +* If the ref being added is long-term, long_term_frame_idx of the field. +* Otherwise invalid. +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_insert_ref_field(dpb_mgr_t *ps_dpb_mgr, pic_buf_t *ps_pic_buf, WORD32 reference_type, @@ -653,38 +656,37 @@ WORD32 ih264_dpb_mgr_insert_ref_field(dpb_mgr_t *ps_dpb_mgr, } /** - ******************************************************************************* - * - * @brief - * Add a ref frame to short-term or long-term linked list. - * - * @par Description: - * This function adds a ref frame to either short-term or long-term linked - * list. Internally it calls add ref field twice to add top and bottom field. - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @param[in] ps_pic_buf - * Pic buf structure for the field being added. - * - * @param[in] reference_type - * This is used to select between short-term and long-term linked list. - * - * @param[in] frame_num - * frame_num for the field. - * - * @param[in] long_term_frame_idx - * If the ref being added is long-term, long_term_frame_idx of the field. - * Otherwise invalid. - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Add a ref frame to short-term or long-term linked list. +* +* @par Description: +* This function adds a ref frame to either short-term or long-term linked +* list. Internally it calls add ref field twice to add top and bottom field. +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] ps_pic_buf +* Pic buf structure for the field being added. +* +* @param[in] reference_type +* This is used to select between short-term and long-term linked list. +* +* @param[in] frame_num +* frame_num for the field. +* +* @param[in] long_term_frame_idx +* If the ref being added is long-term, long_term_frame_idx of the field. +* Otherwise invalid. +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_insert_ref_frame(dpb_mgr_t *ps_dpb_mgr, pic_buf_t *ps_pic_buf, WORD32 reference_type, @@ -728,31 +730,30 @@ WORD32 ih264_dpb_mgr_insert_ref_frame(dpb_mgr_t *ps_dpb_mgr, } /** - ******************************************************************************* - * - * @brief - * Returns the number of ref frames in both the linked list. - * - * @par Description: - * Returns the count of number of frames, number of complementary field pairs - * and number of unpaired fields. - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @param[in] curr_frame_num - * frame_num for the field. - * - * @param[in] max_frame_num - * Maximum frame_num allowed - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Returns the number of ref frames in both the linked list. +* +* @par Description: +* Returns the count of number of frames, number of complementary field pairs +* and number of unpaired fields. +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] curr_frame_num +* frame_num for the field. +* +* @param[in] max_frame_num +* Maximum frame_num allowed +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_count_ref_frames(dpb_mgr_t *ps_dpb_mgr, WORD32 curr_frame_num, WORD32 max_frame_num) @@ -823,29 +824,28 @@ WORD32 ih264_dpb_mgr_count_ref_frames(dpb_mgr_t *ps_dpb_mgr, } /** - ******************************************************************************* - * - * @brief - * Deletes the ref frame at the end of the linked list. - * - * @par Description: - * Deletes the ref frame at the end of the linked list. For unpaired fields, - * it deletes just the last node. For frame or complementary field pair, it - * deletes the last two nodes. - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @param[in] reference_type - * This is used to select between short-term and long-term linked list. - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Deletes the ref frame at the end of the linked list. +* +* @par Description: +* Deletes the ref frame at the end of the linked list. For unpaired fields, +* it deletes just the last node. For frame or complementary field pair, it +* deletes the last two nodes. +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] reference_type +* This is used to select between short-term and long-term linked list. +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_delete_ref_frame(dpb_mgr_t *ps_dpb_mgr, WORD32 reference_type) { @@ -856,8 +856,6 @@ WORD32 ih264_dpb_mgr_delete_ref_frame(dpb_mgr_t *ps_dpb_mgr, /* * Assumption: The nodes sorted for frame num. */ - - /* Select bw short-term and long-term list. */ ps_dpb_node1 = (reference_type == SHORT_TERM_REF) ?ps_dpb_mgr->ps_dpb_short_term_head @@ -957,33 +955,34 @@ WORD32 ih264_dpb_mgr_delete_ref_frame(dpb_mgr_t *ps_dpb_mgr, return 0; } + /** - ******************************************************************************* - * - * @brief - * Delete long-term ref fields above max frame idx. - * - * @par Description: - * Deletes all the long-term ref fields having idx greater than max_frame_idx - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @param[in] max_frame_idx - * Max long-term frame idx allowed. - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Delete long-term ref fields above max frame idx. +* +* @par Description: +* Deletes all the long-term ref fields having idx greater than max_frame_idx +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] max_frame_idx +* Max long-term frame idx allowed. +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_delete_long_ref_fields_max_frame_idx(dpb_mgr_t *ps_dpb_mgr, WORD32 max_frame_idx) { dpb_info_t *ps_dpb_node1; dpb_info_t *ps_dpb_node2; + /* * Loop until there is node which isn't to be deleted is encountered. */ @@ -1023,37 +1022,37 @@ WORD32 ih264_dpb_mgr_delete_long_ref_fields_max_frame_idx(dpb_mgr_t *ps_dpb_mgr, } /** - ******************************************************************************* - * - * @brief - * Deletes the short-term with least frame_num - * - * @par Description: - * Deletes the short-term with least frame_num. It sorts the function the - * short-term linked list by frame-num and the function that deletes the last - * frame in the linked list. - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @param[in] curr_frame_num - * frame_num of the current pic - * - * @param[in] max_frame_num - * Maximum frame_num allowed - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Deletes the short-term with least frame_num +* +* @par Description: +* Deletes the short-term with least frame_num. It sorts the function the +* short-term linked list by frame-num and the function that deletes the last +* frame in the linked list. +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] curr_frame_num +* frame_num of the current pic +* +* @param[in] max_frame_num +* Maximum frame_num allowed +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_delete_short_ref_frame(dpb_mgr_t *ps_dpb_mgr, WORD32 curr_frame_num, WORD32 max_frame_num) { WORD32 ret; + /* Sort the short-term list by frame_num */ ret = ih264_dpb_mgr_sort_short_term_fields_by_frame_num(ps_dpb_mgr, curr_frame_num, @@ -1070,26 +1069,26 @@ WORD32 ih264_dpb_mgr_delete_short_ref_frame(dpb_mgr_t *ps_dpb_mgr, return ret; } + /** - ******************************************************************************* - * - * @brief - * Deletes all the ref frames. - * - * @par Description: - * Deletes all of the ref frames/fields in the short-term and long-term linked - * list. - * - * @param[in] ps_dpb_mgr - * Pointer to the DPB manager structure - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Deletes all the ref frames. +* +* @par Description: +* Deletes all of the ref frames/fields in the short-term and long-term linked +* list. +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ WORD32 ih264_dpb_mgr_delete_all_ref_frames(dpb_mgr_t *ps_dpb_mgr) { /* Loop over short-term linked list. */ @@ -1106,23 +1105,41 @@ WORD32 ih264_dpb_mgr_delete_all_ref_frames(dpb_mgr_t *ps_dpb_mgr) return 0; } - +/** +******************************************************************************* +* +* @brief +* deletes all pictures from DPB and reset dpb +* +* @par Description: +* deletes all pictures from DPB and reset dpb +* +* @param[in] ps_dpb_mgr +* Pointer to the DPB manager structure +* +* @param[in] ps_buf_mgr +* Pointer to buffer manager structure +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ void ih264_dpb_mgr_reset(dpb_mgr_t *ps_dpb_mgr, buf_mgr_t *ps_buf_mgr) { WORD32 i; dpb_info_t *ps_dpb_info; - ASSERT(0); - + ASSERT(0); ps_dpb_info = ps_dpb_mgr->as_dpb_info; - for(i = 0; i < MAX_DPB_BUFS; i++) { if(ps_dpb_info[i].ps_pic_buf->i4_used_as_ref) { ps_dpb_info[i].ps_pic_buf->i4_used_as_ref = UNUSED_FOR_REF; ps_dpb_info[i].ps_prev_dpb = NULL; - //Release physical buffer + // Release physical buffer ih264_buf_mgr_release(ps_buf_mgr, ps_dpb_info[i].ps_pic_buf->i4_buf_id, BUF_MGR_REF); @@ -1133,38 +1150,35 @@ void ih264_dpb_mgr_reset(dpb_mgr_t *ps_dpb_mgr, buf_mgr_t *ps_buf_mgr) ps_dpb_mgr->u1_num_long_term_ref_bufs = 0; ps_dpb_mgr->ps_dpb_short_term_head = NULL; ps_dpb_mgr->ps_dpb_long_term_head = NULL; - } /** - ******************************************************************************* - * - * @brief - * deletes all pictures from DPB - * - * @par Description: - * Deletes all pictures present in the DPB manager - * - * @param[in] ps_buf_mgr - * Pointer to buffer manager structure - * - * @param[in] u1_disp_bufs - * Number of buffers to be deleted - * - * @returns - * - * @remarks - * - * - ******************************************************************************* - */ - +******************************************************************************* +* +* @brief +* deletes all pictures from DPB +* +* @par Description: +* Deletes all pictures present in the DPB manager +* +* @param[in] ps_buf_mgr +* Pointer to buffer manager structure +* +* @param[in] u1_disp_bufs +* Number of buffers to be deleted +* +* @returns +* +* @remarks +* +******************************************************************************* +*/ void ih264_dpb_mgr_release_pics(buf_mgr_t *ps_buf_mgr, UWORD8 u1_disp_bufs) { WORD8 i; UWORD32 buf_status; - ASSERT(0); + ASSERT(0); for(i = 0; i < u1_disp_bufs; i++) { buf_status = ih264_buf_mgr_get_status(ps_buf_mgr, i); diff --git a/common/ih264_dpb_mgr.h b/common/ih264_dpb_mgr.h index b0cf0fd..1e7198c 100644 --- a/common/ih264_dpb_mgr.h +++ b/common/ih264_dpb_mgr.h @@ -19,27 +19,27 @@ */ /** - ******************************************************************************* - * @file - * ih264_dpb_mgr.h - * - * @brief - * Function declarations used for decoded picture buffer management - * - * @author - * Srinivas T - * - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_dpb_mgr.h +* +* @brief +* Function declarations used for decoded picture buffer management +* +* @author +* none +* +* @remarks +* none +* +******************************************************************************* +*/ #ifndef _IH264_DPB_MGR_H_ #define _IH264_DPB_MGR_H_ -/* Temporary definitions. Have to be defined later */ - +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ #define MAX_DPB_BUFS (MAX_DPB_SIZE * 4) #define MARK_ST_PICNUM_AS_NONREF 1 @@ -47,16 +47,21 @@ #define MARK_ST_PICNUM_AS_LT_INDEX 3 #define RESET_REF_PICTURES 5 -typedef struct dpb_info_t dpb_info_t; - +/*****************************************************************************/ +/* Enums */ +/*****************************************************************************/ enum { INVALID = -1, - UNUSED_FOR_REF = 0 , - LONG_TERM_REF , - SHORT_TERM_REF , + UNUSED_FOR_REF = 0, + LONG_TERM_REF, + SHORT_TERM_REF, }; -struct dpb_info_t + +/*****************************************************************************/ +/* Structure Definitions */ +/*****************************************************************************/ +typedef struct dpb_info_t { /** * Pointer to picture buffer structure @@ -66,9 +71,9 @@ struct dpb_info_t /** * Link to the DPB buffer with previous link */ - dpb_info_t *ps_prev_dpb; + struct dpb_info_t *ps_prev_dpb; -}; +} dpb_info_t; typedef struct { @@ -114,6 +119,9 @@ typedef struct } dpb_mgr_t; +/*****************************************************************************/ +/* Function Declarations */ +/*****************************************************************************/ void ih264_dpb_mgr_init(dpb_mgr_t *ps_dpb_mgr); WORD32 ih264_dpb_mgr_insert_ref_frame(dpb_mgr_t *ps_dpb_mgr, diff --git a/common/ih264_error.h b/common/ih264_error.h index ff1662d..654955b 100644 --- a/common/ih264_error.h +++ b/common/ih264_error.h @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,12 +27,10 @@ * Definitions related to error handling for common modules * * @author -* Harish -* -* @par List of Functions: +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ diff --git a/common/ih264_ihadamard_scaling.c b/common/ih264_ihadamard_scaling.c index e4729c8..0e265f7 100644 --- a/common/ih264_ihadamard_scaling.c +++ b/common/ih264_ihadamard_scaling.c @@ -17,74 +17,82 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_ihadamard_scaling.c - * - * @brief - * Contains definition of functions for h264 inverse hadamard 4x4 transform and scaling - * - * @author - * Mohit - * - * @par List of Functions: - * - ih264_ihadamard_scaling_4x4() - * - * @remarks - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_ihadamard_scaling.c +* +* @brief +* Contains definition of functions for h264 inverse hadamard 4x4 transform and +* scaling +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264_ihadamard_scaling_4x4 +* - ih264_ihadamard_scaling_2x2_uv +* +* @remarks +* none +* +******************************************************************************* +*/ /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" +#include "ih264_macros.h" #include "ih264_defs.h" #include "ih264_trans_macros.h" -#include "ih264_macros.h" #include "ih264_trans_data.h" #include "ih264_size_defs.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" -/* - ******************************************************************************** - * - * @brief This function performs a 4x4 inverse hadamard transform on the 4x4 DC coefficients - * of a 16x16 intra prediction macroblock, and then performs scaling. - * prediction buffer - * - * @par Description: - * The DC coefficients pass through a 2-stage inverse hadamard transform. - * This inverse transformed content is scaled to based on Qp value. - * - * @param[in] pi2_src - * input 4x4 block of DC coefficients - * - * @param[out] pi2_out - * output 4x4 block - * - * @param[in] pu2_iscal_mat - * pointer to scaling list - * - * @param[in] pu2_weigh_mat - * pointer to weight matrix - * - * @param[in] u4_qp_div_6 - * Floor (qp/6) - * - * @param[in] pi4_tmp - * temporary buffer of size 1*16 - * - * @returns none - * - * @remarks none - * - ******************************************************************************* - */ + +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ + +/** +******************************************************************************** +* +* @brief This function performs a 4x4 inverse hadamard transform on the luma +* DC coefficients and then performs scaling. +* +* @par Description: +* The DC coefficients pass through a 2-stage inverse hadamard transform. +* This inverse transformed content is scaled to based on Qp value. +* +* @param[in] pi2_src +* input 4x4 block of DC coefficients +* +* @param[out] pi2_out +* output 4x4 block +* +* @param[in] pu2_iscal_mat +* pointer to scaling list +* +* @param[in] pu2_weigh_mat +* pointer to weight matrix +* +* @param[in] u4_qp_div_6 +* Floor (qp/6) +* +* @param[in] pi4_tmp +* temporary buffer of size 1*16 +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_ihadamard_scaling_4x4(WORD16* pi2_src, WORD16* pi2_out, const UWORD16 *pu2_iscal_mat, @@ -94,13 +102,15 @@ void ih264_ihadamard_scaling_4x4(WORD16* pi2_src, { WORD32 i; WORD32 x0, x1, x2, x3, x4, x5, x6, x7; - WORD16* pi2_src_ptr, *pi2_out_ptr; - WORD32* pi4_tmp_ptr; + WORD16 *pi2_src_ptr, *pi2_out_ptr; + WORD32 *pi4_tmp_ptr; WORD32 rnd_fact = (u4_qp_div_6 < 6) ? (1 << (5 - u4_qp_div_6)) : 0; + pi4_tmp_ptr = pi4_tmp; pi2_src_ptr = pi2_src; pi2_out_ptr = pi2_out; - // Horizontal transform + + /* horizontal transform */ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++) { x4 = pi2_src_ptr[0]; @@ -121,8 +131,9 @@ void ih264_ihadamard_scaling_4x4(WORD16* pi2_src, pi4_tmp_ptr += SUB_BLK_WIDTH_4x4; pi2_src_ptr += SUB_BLK_WIDTH_4x4; } + + /* vertical transform */ pi4_tmp_ptr = pi4_tmp; - // Vertical Transform for(i = 0; i < SUB_BLK_WIDTH_4x4; i++) { x4 = pi4_tmp_ptr[0]; @@ -143,15 +154,50 @@ void ih264_ihadamard_scaling_4x4(WORD16* pi2_src, pi4_tmp_ptr++; } pi4_tmp_ptr = pi4_tmp; - //Scaling + + /* scaling */ for(i = 0; i < (SUB_BLK_WIDTH_4x4 * SUB_BLK_WIDTH_4x4); i++) { - INV_QUANT(pi4_tmp_ptr[i], pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, - rnd_fact, 6); - pi2_out_ptr[i] = pi4_tmp_ptr[i]; + INV_QUANT(pi4_tmp_ptr[i], pu2_iscal_mat[0], pu2_weigh_mat[0], + u4_qp_div_6, rnd_fact, 6); + pi2_out_ptr[i] = pi4_tmp_ptr[i]; } } +/** +******************************************************************************** +* +* @brief This function performs a 2x2 inverse hadamard transform on the chroma +* DC coefficients and then performs scaling. +* +* @par Description: +* The DC coefficients pass through a 2-stage inverse hadamard transform. +* This inverse transformed content is scaled to based on Qp value. +* +* @param[in] pi2_src +* input 2x2 block of DC coefficients +* +* @param[out] pi2_out +* output 2x2 block +* +* @param[in] pu2_iscal_mat +* pointer to scaling list +* +* @param[in] pu2_weigh_mat +* pointer to weight matrix +* +* @param[in] u4_qp_div_6 +* Floor (qp/6) +* +* @param[in] pi4_tmp +* temporary buffer of size 1*16 +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_ihadamard_scaling_2x2_uv(WORD16* pi2_src, WORD16* pi2_out, const UWORD16 *pu2_iscal_mat, @@ -159,58 +205,60 @@ void ih264_ihadamard_scaling_2x2_uv(WORD16* pi2_src, UWORD32 u4_qp_div_6, WORD32* pi4_tmp) { - WORD32 i4_x0,i4_x1,i4_x2,i4_x3,i4_x4,i4_x5,i4_x6,i4_x7; - WORD32 i4_y0,i4_y1,i4_y2,i4_y3,i4_y4,i4_y5,i4_y6,i4_y7; - - UNUSED(pi4_tmp); - - i4_x4 = pi2_src[0]; - i4_x5 = pi2_src[1]; - i4_x6 = pi2_src[2]; - i4_x7 = pi2_src[3]; - - i4_x0 = i4_x4 + i4_x5; - i4_x1 = i4_x4 - i4_x5; - i4_x2 = i4_x6 + i4_x7; - i4_x3 = i4_x6 - i4_x7; - - i4_x4 = i4_x0+i4_x2; - i4_x5 = i4_x1+i4_x3; - i4_x6 = i4_x0-i4_x2; - i4_x7 = i4_x1-i4_x3; - - INV_QUANT(i4_x4,pu2_iscal_mat[0],pu2_weigh_mat[0],u4_qp_div_6,0,5); - INV_QUANT(i4_x5,pu2_iscal_mat[0],pu2_weigh_mat[0],u4_qp_div_6,0,5); - INV_QUANT(i4_x6,pu2_iscal_mat[0],pu2_weigh_mat[0],u4_qp_div_6,0,5); - INV_QUANT(i4_x7,pu2_iscal_mat[0],pu2_weigh_mat[0],u4_qp_div_6,0,5); - - pi2_out[0] = i4_x4; - pi2_out[1] = i4_x5; - pi2_out[2] = i4_x6; - pi2_out[3] = i4_x7; - - i4_y4 = pi2_src[4]; - i4_y5 = pi2_src[5]; - i4_y6 = pi2_src[6]; - i4_y7 = pi2_src[7]; - - i4_y0 = i4_y4 + i4_y5; - i4_y1 = i4_y4 - i4_y5; - i4_y2 = i4_y6 + i4_y7; - i4_y3 = i4_y6 - i4_y7; - - i4_y4 = i4_y0+i4_y2; - i4_y5 = i4_y1+i4_y3; - i4_y6 = i4_y0-i4_y2; - i4_y7 = i4_y1-i4_y3; - - INV_QUANT(i4_y4,pu2_iscal_mat[0],pu2_weigh_mat[0],u4_qp_div_6,0,5); - INV_QUANT(i4_y5,pu2_iscal_mat[0],pu2_weigh_mat[0],u4_qp_div_6,0,5); - INV_QUANT(i4_y6,pu2_iscal_mat[0],pu2_weigh_mat[0],u4_qp_div_6,0,5); - INV_QUANT(i4_y7,pu2_iscal_mat[0],pu2_weigh_mat[0],u4_qp_div_6,0,5); - - pi2_out[4] = i4_y4; - pi2_out[5] = i4_y5; - pi2_out[6] = i4_y6; - pi2_out[7] = i4_y7; + WORD32 i4_x0, i4_x1, i4_x2, i4_x3, i4_x4, i4_x5, i4_x6, i4_x7; + WORD32 i4_y0, i4_y1, i4_y2, i4_y3, i4_y4, i4_y5, i4_y6, i4_y7; + + UNUSED(pi4_tmp); + + /* U Plane */ + i4_x4 = pi2_src[0]; + i4_x5 = pi2_src[1]; + i4_x6 = pi2_src[2]; + i4_x7 = pi2_src[3]; + + i4_x0 = i4_x4 + i4_x5; + i4_x1 = i4_x4 - i4_x5; + i4_x2 = i4_x6 + i4_x7; + i4_x3 = i4_x6 - i4_x7; + + i4_x4 = i4_x0 + i4_x2; + i4_x5 = i4_x1 + i4_x3; + i4_x6 = i4_x0 - i4_x2; + i4_x7 = i4_x1 - i4_x3; + + INV_QUANT(i4_x4, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5); + INV_QUANT(i4_x5, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5); + INV_QUANT(i4_x6, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5); + INV_QUANT(i4_x7, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5); + + pi2_out[0] = i4_x4; + pi2_out[1] = i4_x5; + pi2_out[2] = i4_x6; + pi2_out[3] = i4_x7; + + /* V Plane */ + i4_y4 = pi2_src[4]; + i4_y5 = pi2_src[5]; + i4_y6 = pi2_src[6]; + i4_y7 = pi2_src[7]; + + i4_y0 = i4_y4 + i4_y5; + i4_y1 = i4_y4 - i4_y5; + i4_y2 = i4_y6 + i4_y7; + i4_y3 = i4_y6 - i4_y7; + + i4_y4 = i4_y0 + i4_y2; + i4_y5 = i4_y1 + i4_y3; + i4_y6 = i4_y0 - i4_y2; + i4_y7 = i4_y1 - i4_y3; + + INV_QUANT(i4_y4, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5); + INV_QUANT(i4_y5, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5); + INV_QUANT(i4_y6, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5); + INV_QUANT(i4_y7, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, 0, 5); + + pi2_out[4] = i4_y4; + pi2_out[5] = i4_y5; + pi2_out[6] = i4_y6; + pi2_out[7] = i4_y7; } diff --git a/common/ih264_inter_pred_filters.c b/common/ih264_inter_pred_filters.c index 7d1e407..93bd944 100644 --- a/common/ih264_inter_pred_filters.c +++ b/common/ih264_inter_pred_filters.c @@ -17,36 +17,37 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_inter_pred_filters.c - * - * @brief - * Contains function definitions for inter prediction interpolation filters - * - * @author - * Ittiam - * - * @par List of Functions: - * - ih264_inter_pred_luma_copy - * - ih264_interleave_copy - * - ih264_inter_pred_luma_horz - * - ih264_inter_pred_luma_vert - * - ih264_inter_pred_luma_horz_hpel_vert_hpel - * - ih264_inter_pred_luma_horz_qpel - * - ih264_inter_pred_luma_vert_qpel - * - ih264_inter_pred_luma_horz_qpel_vert_qpel - * - ih264_inter_pred_luma_horz_hpel_vert_qpel - * - ih264_inter_pred_luma_horz_qpel_vert_hpel - * - ih264_inter_pred_luma_bilinear - * - ih264_inter_pred_chroma - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_inter_pred_filters.c +* +* @brief +* Contains function definitions for inter prediction interpolation filters +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264_inter_pred_luma_copy +* - ih264_interleave_copy +* - ih264_inter_pred_luma_horz +* - ih264_inter_pred_luma_vert +* - ih264_inter_pred_luma_horz_hpel_vert_hpel +* - ih264_inter_pred_luma_horz_qpel +* - ih264_inter_pred_luma_vert_qpel +* - ih264_inter_pred_luma_horz_qpel_vert_qpel +* - ih264_inter_pred_luma_horz_hpel_vert_qpel +* - ih264_inter_pred_luma_horz_qpel_vert_hpel +* - ih264_inter_pred_luma_bilinear +* - ih264_inter_pred_chroma +* +* @remarks +* none +* +******************************************************************************* +*/ /*****************************************************************************/ /* File Includes */ @@ -55,68 +56,79 @@ /* User include files */ #include "ih264_typedefs.h" #include "ih264_macros.h" -#include "ih264_platform_macros.h" #include "ih264_inter_pred_filters.h" +#include "ih264_platform_macros.h" /*****************************************************************************/ /* Constant Data variables */ /*****************************************************************************/ - -/* coefficients for 6 tap filtering*/ -const WORD32 ih264_g_six_tap[3] ={1,-5,20}; +/** + ****************************************************************************** + * @brief coefficients for 6 tap filtering + ****************************************************************************** + */ +const WORD32 ih264_g_six_tap[3] = +{ + 1, -5, 20 +}; /*****************************************************************************/ /* Function definitions . */ /*****************************************************************************/ -/** - ******************************************************************************* - * - * @brief - * Interprediction luma function for copy - * - * @par Description: - * Copies the array of width 'wd' and height 'ht' from the location pointed - * by 'src' to the location pointed by 'dst' - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * - * @param[in] ht - * integer height of the array - * - * @param[in] wd - * integer width of the array - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +/** +******************************************************************************* +* +* @brief function for luma copy +* +* @par Description: +* Copies the array of width 'wd' and height 'ht' from the location pointed +* by 'src' to the location pointed by 'dst' +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ht +* height of the array +* +* @param[in] wd +* width of the array +* +* @param[in] pu1_tmp +* temporary buffer +* +* @param[in] dydx +* x and y reference offset for qpel calculations +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_inter_pred_luma_copy(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, WORD32 dst_strd, WORD32 ht, WORD32 wd, - UWORD8* pu1_tmp, + UWORD8 *pu1_tmp, WORD32 dydx) { WORD32 row, col; + UNUSED(pu1_tmp); UNUSED(dydx); for(row = 0; row < ht; row++) @@ -132,41 +144,40 @@ void ih264_inter_pred_luma_copy(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - * @brief - * Fucntion for copying to an interleaved destination - * - * @par Description: - * Copies the array of width 'wd' and height 'ht' from the location pointed - * by 'src' to the location pointed by 'dst' - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ht - * integer height of the array - * - * @param[in] wd - * integer width of the array - * - * @returns - * - * @remarks - * The alternate elements of src will be copied to alternate locations in dsr - * Other locations are not touched - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief interleaved copy +* +* @par Description: +* Copies the array of width 'wd' and height 'ht' from the location pointed +* by 'src' to the location pointed by 'dst' +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ht +* height of the array +* +* @param[in] wd +* width of the array +* +* @returns +* +* @remarks +* The alternate elements of src will be copied to alternate locations in dsr +* Other locations are not touched +* +******************************************************************************* +*/ void ih264_interleave_copy(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -175,150 +186,151 @@ void ih264_interleave_copy(UWORD8 *pu1_src, WORD32 wd) { WORD32 row, col; - wd *= 2; + wd *= 2; for(row = 0; row < ht; row++) { - for(col = 0; col < wd; col+=2) + for(col = 0; col < wd; col += 2) { pu1_dst[col] = pu1_src[col]; } - pu1_src += src_strd; pu1_dst += dst_strd; } } /** - ******************************************************************************* - * - * @brief - * Interprediction luma filter for horizontal input - * - * @par Description: - * Applies a 6 tap horizontal filter .The output is clipped to 8 bits - * sec 8.4.2.2.1 titled "Luma sample interpolation process" - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ht - * integer height of the array - * - * @param[in] wd - * integer width of the array - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Luma hpel Horizontal Interprediction +* +* @par Description: +* Applies a 6 tap horizontal filter. The output is clipped to 8 bits. +* Refer sec 8.4.2.2.1 titled "Luma sample interpolation process" +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ht +* height of the array +* +* @param[in] wd +* width of the array +* +* @param[in] pu1_tmp +* temporary buffer +* +* @param[in] dydx +* x and y reference offset for qpel calculations +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_inter_pred_luma_horz(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, WORD32 dst_strd, WORD32 ht, WORD32 wd, - UWORD8* pu1_tmp, + UWORD8 *pu1_tmp, WORD32 dydx) { WORD32 row, col; WORD16 i2_tmp; + UNUSED(pu1_tmp); UNUSED(dydx); - for(row = 0; row < ht; row++) { for(col = 0; col < wd; col++) { - i2_tmp = 0;/*ih264_g_six_tap[] is the array containing the filter coeffs*/ - i2_tmp = ih264_g_six_tap[0] * - (pu1_src[col - 2] + pu1_src[col + 3]) - + ih264_g_six_tap[1] * - (pu1_src[col - 1] + pu1_src[col + 2]) - + ih264_g_six_tap[2] * - (pu1_src[col] + pu1_src[col + 1]); + i2_tmp = ih264_g_six_tap[0] * (pu1_src[col - 2] + pu1_src[col + 3]) + + ih264_g_six_tap[1] * (pu1_src[col - 1] + pu1_src[col + 2]) + + ih264_g_six_tap[2] * (pu1_src[col] + pu1_src[col + 1]); i2_tmp = (i2_tmp + 16) >> 5; pu1_dst[col] = CLIP_U8(i2_tmp); } - pu1_src += src_strd; pu1_dst += dst_strd; } - } /** - ******************************************************************************* - * - * @brief - * Interprediction luma filter for vertical input - * - * @par Description: - * Applies a 6 tap vertical filter.The output is clipped to 8 bits - * sec 8.4.2.2.1 titled "Luma sample interpolation process" - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ht - * integer height of the array - * - * @param[in] wd - * integer width of the array - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Luma hpel Vertical Interprediction +* +* @par Description: +* Applies a 6 tap vertical filter.The output is clipped to 8 bits +* Refer sec 8.4.2.2.1 titled "Luma sample interpolation process" +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ht +* height of the array +* +* @param[in] wd +* width of the array +* +* @param[in] pu1_tmp +* temporary buffer +* +* @param[in] dydx +* x and y reference offset for qpel calculations +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_inter_pred_luma_vert(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, WORD32 dst_strd, WORD32 ht, WORD32 wd, - UWORD8* pu1_tmp, + UWORD8 *pu1_tmp, WORD32 dydx) { WORD32 row, col; WORD16 i2_tmp; + UNUSED(pu1_tmp); UNUSED(dydx); - for(row = 0; row < ht; row++) { for(col = 0; col < wd; col++) { - i2_tmp = 0; /*ih264_g_six_tap[] is the array containing the filter coeffs*/ - i2_tmp = ih264_g_six_tap[0] * - (pu1_src[col - 2 * src_strd] + pu1_src[col + 3 * src_strd]) - + ih264_g_six_tap[1] * - (pu1_src[col - 1 * src_strd] + pu1_src[col + 2 * src_strd]) - + ih264_g_six_tap[2] * - (pu1_src[col] + pu1_src[col + 1 * src_strd]); + i2_tmp = ih264_g_six_tap[0] * (pu1_src[col - 2 * src_strd] + pu1_src[col + 3 * src_strd]) + + ih264_g_six_tap[1] * (pu1_src[col - 1 * src_strd] + pu1_src[col + 2 * src_strd]) + + ih264_g_six_tap[2] * (pu1_src[col] + pu1_src[col + 1 * src_strd]); i2_tmp = (i2_tmp + 16) >> 5; pu1_dst[col] = CLIP_U8(i2_tmp); } @@ -327,70 +339,82 @@ void ih264_inter_pred_luma_vert(UWORD8 *pu1_src, } } -/*! - ************************************************************************** - * \if Function name : ih264_inter_pred_luma_horz_hpel_vert_hpel \endif - * - * \brief - * This function implements a two stage cascaded six tap filter. It - * applies the six tap filter in the horizontal direction on the - * predictor values, followed by applying the same filter in the - * vertical direction on the output of the first stage. The six tap - * filtering operation is described in sec 8.4.2.2.1 titled "Luma sample - * interpolation process" - * - * \param pu1_src: Pointer to the buffer containing the predictor values. - * pu1_src could point to the frame buffer or the predictor buffer. - * \param pu1_dst: Pointer to the destination buffer where the output of - * the six tap filter is stored. - * \param ht: Height of the rectangular pixel grid to be interpolated - * \param wd: Width of the rectangular pixel grid to be interpolated - * \param src_strd: Width of the buffer pointed to by pu1_src. - * \param dst_strd: Width of the destination buffer - * \param pu1_tmp: temporary buffer. - * \param dydx: x and y reference offset for qpel calculations: UNUSED in this function. - * - * \return - * None. - * - * \note - * This function takes the 8 bit predictor values, applies the six tap - * filter in the horizontal direction and outputs the result clipped to - * 8 bit precision. The input is stored in the buffer pointed to by - * pu1_src while the output is stored in the buffer pointed by pu1_dst. - * Both pu1_src and pu1_dst could point to the same buffer i.e. the - * six tap filter could be done in place. - * - ************************************************************************** - */ +/** +******************************************************************************* +* +* @brief +* Luma Horizontal hpel & Vertical hpel Interprediction +* +* @par Description: +* This function implements a two stage cascaded six tap filter. It +* applies the six tap filter in the horizontal direction on the +* predictor values, followed by applying the same filter in the +* vertical direction on the output of the first stage. The six tap +* filtering operation is described in sec 8.4.2.2.1 titled "Luma sample +* interpolation process" +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ht +* height of the array +* +* @param[in] wd +* width of the array +* +* @param[in] pu1_tmp +* temporary buffer +* +* @param[in] dydx +* x and y reference offset for qpel calculations +* +* @returns +* +* @remarks +* This function takes the 8 bit predictor values, applies the six tap +* filter in the horizontal direction and outputs the result clipped to +* 8 bit precision. The input is stored in the buffer pointed to by +* pu1_src while the output is stored in the buffer pointed by pu1_dst. +* Both pu1_src and pu1_dst could point to the same buffer i.e. the +* six tap filter could be done in place. +* +******************************************************************************* +*/ void ih264_inter_pred_luma_horz_hpel_vert_hpel(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, WORD32 dst_strd, WORD32 ht, WORD32 wd, - UWORD8* pu1_tmp, + UWORD8 *pu1_tmp, WORD32 dydx) { WORD32 row, col; WORD32 tmp; - WORD16* pi2_pred1_temp; - WORD16* pi2_pred1; + WORD16 *pi2_pred1_temp; + WORD16 *pi2_pred1; + UNUSED(dydx); pi2_pred1_temp = (WORD16*)pu1_tmp; pi2_pred1_temp += 2; pi2_pred1 = pi2_pred1_temp; + for(row = 0; row < ht; row++) { for(col = -2; col < wd + 3; col++) { - tmp = 0;/*ih264_g_six_tap[] is the array containing the filter coeffs*/ - tmp = ih264_g_six_tap[0] * - (pu1_src[col - 2 * src_strd] + pu1_src[col + 3 * src_strd]) - + ih264_g_six_tap[1] * - (pu1_src[col - 1 * src_strd] + pu1_src[col + 2 * src_strd]) - + ih264_g_six_tap[2] * - (pu1_src[col] + pu1_src[col + 1 * src_strd]); + tmp = ih264_g_six_tap[0] * (pu1_src[col - 2 * src_strd] + pu1_src[col + 3 * src_strd]) + + ih264_g_six_tap[1] * (pu1_src[col - 1 * src_strd] + pu1_src[col + 2 * src_strd]) + + ih264_g_six_tap[2] * (pu1_src[col] + pu1_src[col + 1 * src_strd]); pi2_pred1_temp[col] = tmp; } pu1_src += src_strd; @@ -401,11 +425,8 @@ void ih264_inter_pred_luma_horz_hpel_vert_hpel(UWORD8 *pu1_src, { for(col = 0; col < wd; col++) { - tmp = 0;/*ih264_g_six_tap[] is the array containing the filter coeffs*/ - tmp = ih264_g_six_tap[0] * - (pi2_pred1[col - 2] + pi2_pred1[col + 3]) - + ih264_g_six_tap[1] * - (pi2_pred1[col - 1] + pi2_pred1[col + 2]) + tmp = ih264_g_six_tap[0] * (pi2_pred1[col - 2] + pi2_pred1[col + 3]) + + ih264_g_six_tap[1] * (pi2_pred1[col - 1] + pi2_pred1[col + 2]) + ih264_g_six_tap[2] * (pi2_pred1[col] + pi2_pred1[col + 1]); tmp = (tmp + 512) >> 10; pu1_dst[col] = CLIP_U8(tmp); @@ -415,39 +436,55 @@ void ih264_inter_pred_luma_horz_hpel_vert_hpel(UWORD8 *pu1_src, } } -/*! - ************************************************************************** - * \if Function name : ih264_inter_pred_luma_horz_qpel \endif - * - * \brief - * This routine applies the six tap filter to the predictors in the - * horizontal direction. The six tap filtering operation is described in - * sec 8.4.2.2.1 titled "Luma sample interpolation process" - * - * \param pu1_src: Pointer to the buffer containing the predictor values. - * pu1_src could point to the frame buffer or the predictor buffer. - * \param pu1_dst: Pointer to the destination buffer where the output of - * the six tap filter is stored. - * \param ht: Height of the rectangular pixel grid to be interpolated - * \param wd: Width of the rectangular pixel grid to be interpolated - * \param src_strd: Width of the buffer pointed to by pu1_src. - * \param dst_strd: Width of the destination buffer - * \param pu1_tmp: temporary buffer: UNUSED in this function - * \param dydx: x and y reference offset for qpel calculations. - * - * \return - * None. - * - * \note - * This function takes the 8 bit predictor values, applies the six tap - * filter in the horizontal direction and outputs the result clipped to - * 8 bit precision. The input is stored in the buffer pointed to by - * pu1_src while the output is stored in the buffer pointed by pu1_dst. - * Both pu1_src and pu1_dst could point to the same buffer i.e. the - * six tap filter could be done in place. - * - ************************************************************************** - */ +/** +******************************************************************************* +* +* @brief +* Luma Horizontal qpel Interprediction +* +* @par Description: +* This routine applies the six tap filter to the predictors in the +* horizontal direction and interpolates them to obtain pixels at quarter +* horizontal positions (1/4, 0) and (3/4, 0). The six tap filtering operation +* is described in sec 8.4.2.2.1 titled "Luma sample interpolation process" +* +* @param[in] pu1_src +* Pointer to the buffer containing the predictor values. +* +* @param[out] pu1_dst +* Pointer to the destination buffer where the output of the six tap filter is +* stored +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ht +* Height of the rectangular pixel grid to be interpolated +* +* @param[in] wd +* Width of the rectangular pixel grid to be interpolated +* +* @param[in] pu1_tmp +* temporary buffer. UNUSED in this function +* +* @param[in] dydx +* x and y reference offset for qpel calculations +* +* @returns +* +* @remarks +* This function takes the 8 bit predictor values, applies the six tap +* filter in the horizontal direction and outputs the result clipped to +* 8 bit precision. The input is stored in the buffer pointed to by +* pu1_src while the output is stored in the buffer pointed by pu1_dst. +* Both pu1_src and pu1_dst could point to the same buffer i.e. the +* six tap filter could be done in place. +* +******************************************************************************* +*/ void ih264_inter_pred_luma_horz_qpel(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -487,43 +524,55 @@ void ih264_inter_pred_luma_horz_qpel(UWORD8 *pu1_src, } } -/*! - ************************************************************************** - * \if Function name : ih264_inter_pred_luma_vert_qpel \endif - * - * \brief - * This routine applies the six tap filter to the predictors in the - * vertical direction and interpolates them to obtain pixels at quarter vertical - * positions (0, 1/4) and (0, 3/4). The six tap filtering operation is - * described in sec 8.4.2.2.1 titled "Luma sample interpolation process" - * - * \param pu1_src: Pointer to the buffer containing the predictor values. - * pu1_src could point to the frame buffer or the predictor buffer. - * \param pu1_dst: Pointer to the destination buffer where the output of - * the six tap filter is stored. - * \param ht: Height of the rectangular pixel grid to be interpolated - * \param wd: Width of the rectangular pixel grid to be interpolated - * \param src_strd: Width of the buffer pointed to by puc_pred. - * \param dst_strd: Width of the destination buffer - * \param pu1_tmp: temporary buffer: UNUSED in this function - * \param dydx: x and y reference offset for qpel calculations. - * - * \return - * void - * - * \note - * This function takes the 8 bit predictor values, applies the six tap - * filter in the vertical direction and outputs the result clipped to - * 8 bit precision. The input is stored in the buffer pointed to by - * puc_pred while the output is stored in the buffer pointed by puc_dest. - * Both puc_pred and puc_dest could point to the same buffer i.e. the - * six tap filter could be done in place. - * - * \para <title> - * <paragraph> - * ... - ************************************************************************** - */ +/** +******************************************************************************* +* +* @brief +* Luma vertical qpel Interprediction +* +* @par Description: +* This routine applies the six tap filter to the predictors in the +* vertical direction and interpolates them to obtain pixels at quarter +* vertical positions (0, 1/4) and (0, 3/4). The six tap filtering operation +* is described in sec 8.4.2.2.1 titled "Luma sample interpolation process" +* +* @param[in] pu1_src +* Pointer to the buffer containing the predictor values. +* +* @param[out] pu1_dst +* Pointer to the destination buffer where the output of the six tap filter is +* stored +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ht +* Height of the rectangular pixel grid to be interpolated +* +* @param[in] wd +* Width of the rectangular pixel grid to be interpolated +* +* @param[in] pu1_tmp +* temporary buffer. UNUSED in this function +* +* @param[in] dydx +* x and y reference offset for qpel calculations +* +* @returns +* +* @remarks +* This function takes the 8 bit predictor values, applies the six tap +* filter in the horizontal direction and outputs the result clipped to +* 8 bit precision. The input is stored in the buffer pointed to by +* pu1_src while the output is stored in the buffer pointed by pu1_dst. +* Both pu1_src and pu1_dst could point to the same buffer i.e. the +* six tap filter could be done in place. +* +******************************************************************************* +*/ void ih264_inter_pred_luma_vert_qpel(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -570,43 +619,55 @@ void ih264_inter_pred_luma_vert_qpel(UWORD8 *pu1_src, } } -/*! - ************************************************************************** - * \if Function name : ih264_inter_pred_luma_horz_qpel_vert_qpel \endif - * - * \brief - * This routine applies the six tap filter to the predictors in the - * vertical and horizontal direction and averages them to get pixels at locations - * (1/4,1/4), (1/4, 3/4), (3/4, 1/4) & (3/4, 3/4). The six tap filtering operation - * is described in sec 8.4.2.2.1 titled "Luma sample interpolation process" - * - * \param pu1_src: Pointer to the buffer containing the predictor values. - * pu1_src could point to the frame buffer or the predictor buffer. - * \param pu1_dst: Pointer to the destination buffer where the output of - * the six tap filter is stored. - * \param wd: Width of the rectangular pixel grid to be interpolated - * \param ht: Height of the rectangular pixel grid to be interpolated - * \param src_strd: Width of the buffer pointed to by puc_pred. - * \param dst_strd: Width of the destination buffer - * \param pu1_tmp: temporary buffer, UNUSED in this function - * \param dydx: x and y reference offset for qpel calculations. - * - * \return - * void - * - * \note - * This function takes the 8 bit predictor values, applies the six tap - * filter in the vertical direction and outputs the result clipped to - * 8 bit precision. The input is stored in the buffer pointed to by - * puc_pred while the output is stored in the buffer pointed by puc_dest. - * Both puc_pred and puc_dest could point to the same buffer i.e. the - * six tap filter could be done in place. - * - * \para <title> - * <paragraph> - * ... - ************************************************************************** - */ +/** +******************************************************************************* +* +* @brief +* Luma Horizontal qpel and vertical qpel Interprediction +* +* @par Description: +* This routine applies the six tap filter to the predictors in the +* vertical and horizontal direction averages them to get pixels at locations +* (1/4, 1/4), (1/4, 3/4), (3/4, 1/4) & (3/4, 3/4). The six tap filtering operation +* is described in sec 8.4.2.2.1 titled "Luma sample interpolation process" +* +* @param[in] pu1_src +* Pointer to the buffer containing the predictor values. +* +* @param[out] pu1_dst +* Pointer to the destination buffer where the output of the six tap filter is +* stored +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ht +* Height of the rectangular pixel grid to be interpolated +* +* @param[in] wd +* Width of the rectangular pixel grid to be interpolated +* +* @param[in] pu1_tmp +* temporary buffer. UNUSED in this function +* +* @param[in] dydx +* x and y reference offset for qpel calculations +* +* @returns +* +* @remarks +* This function takes the 8 bit predictor values, applies the six tap +* filter in the horizontal direction and outputs the result clipped to +* 8 bit precision. The input is stored in the buffer pointed to by +* pu1_src while the output is stored in the buffer pointed by pu1_dst. +* Both pu1_src and pu1_dst could point to the same buffer i.e. the +* six tap filter could be done in place. +* +******************************************************************************* +*/ void ih264_inter_pred_luma_horz_qpel_vert_qpel(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -670,44 +731,56 @@ void ih264_inter_pred_luma_horz_qpel_vert_qpel(UWORD8 *pu1_src, } } -/*! - ************************************************************************** - * \if Function name : ih264_inter_pred_luma_horz_qpel_vert_hpel \endif - * - * \brief - * This routine applies the six tap filter to the predictors in the vertical - * and horizontal direction to obtain the pixel at (1/2,1/2). It then interpolates - * pixel at (0,1/2) and (1/2,1/2) to obtain pixel at (1/4,1/2). Similarly for (3/4,1/2). - * The six tap filtering operation is described in sec 8.4.2.2.1 titled - * "Luma sample interpolation process" - * - * \param pu1_src: Pointer to the buffer containing the predictor values. - * pu1_src could point to the frame buffer or the predictor buffer. - * \param pu1_dst: Pointer to the destination buffer where the output of - * the six tap filter followed by interpolation is stored. - * \param wd: Width of the rectangular pixel grid to be interpolated - * \param ht: Height of the rectangular pixel grid to be interpolated - * \param src_strd: Width of the buffer pointed to by puc_pred. - * \param dst_strd: Width of the destination buffer - * \param pu1_tmp: buffer to store temporary output after 1st 6-tap filter. - * \param dydx: x and y reference offset for qpel calculations. - * - * \return - * void - * - * \note - * This function takes the 8 bit predictor values, applies the six tap - * filter in the vertical direction and outputs the result clipped to - * 8 bit precision. The input is stored in the buffer pointed to by - * puc_pred while the output is stored in the buffer pointed by puc_dest. - * Both puc_pred and puc_dest could point to the same buffer i.e. the - * six tap filter could be done in place. - * - * \para <title> - * <paragraph> - * ... - ************************************************************************** - */ +/** +******************************************************************************* +* +* @brief +* Luma Horizontal qpel and vertical hpel Interprediction +* +* @par Description: +* This routine applies the six tap filter to the predictors in the vertical +* and horizontal direction to obtain the pixel at (1/2,1/2). It then interpolates +* pixel at (0, 1/2) and (1/2, 1/2) to obtain pixel at (1/4, 1/2). Similarly for +* (3/4,1/2). The six tap filtering operation is described in sec 8.4.2.2.1 +* titled "Luma sample interpolation process" +* +* @param[in] pu1_src +* Pointer to the buffer containing the predictor values. +* +* @param[out] pu1_dst +* Pointer to the destination buffer where the output of the six tap filter is +* stored +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ht +* Height of the rectangular pixel grid to be interpolated +* +* @param[in] wd +* Width of the rectangular pixel grid to be interpolated +* +* @param[in] pu1_tmp +* temporary buffer. UNUSED in this function +* +* @param[in] dydx +* x and y reference offset for qpel calculations +* +* @returns +* +* @remarks +* This function takes the 8 bit predictor values, applies the six tap +* filter in the horizontal direction and outputs the result clipped to +* 8 bit precision. The input is stored in the buffer pointed to by +* pu1_src while the output is stored in the buffer pointed by pu1_dst. +* Both pu1_src and pu1_dst could point to the same buffer i.e. the +* six tap filter could be done in place. +* +******************************************************************************* +*/ void ih264_inter_pred_luma_horz_qpel_vert_hpel(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -823,6 +896,56 @@ void ih264_inter_pred_luma_horz_qpel_vert_hpel(UWORD8 *pu1_src, * ... ************************************************************************** */ +/** +******************************************************************************* +* +* @brief +* Luma Horizontal hpel and vertical qpel Interprediction +* +* @par Description: +* This routine applies the six tap filter to the predictors in the vertical +* and horizontal direction to obtain the pixel at (1/2,1/2). It then interpolates +* pixel at (1/2, 0) and (1/2, 1/2) to obtain pixel at (1/2, 1/4). Similarly for +* (1/2, 3/4). The six tap filtering operation is described in sec 8.4.2.2.1 +* titled "Luma sample interpolation process" +* +* @param[in] pu1_src +* Pointer to the buffer containing the predictor values. +* +* @param[out] pu1_dst +* Pointer to the destination buffer where the output of the six tap filter is +* stored +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ht +* Height of the rectangular pixel grid to be interpolated +* +* @param[in] wd +* Width of the rectangular pixel grid to be interpolated +* +* @param[in] pu1_tmp +* temporary buffer. UNUSED in this function +* +* @param[in] dydx +* x and y reference offset for qpel calculations +* +* @returns +* +* @remarks +* This function takes the 8 bit predictor values, applies the six tap +* filter in the horizontal direction and outputs the result clipped to +* 8 bit precision. The input is stored in the buffer pointed to by +* pu1_src while the output is stored in the buffer pointed by pu1_dst. +* Both pu1_src and pu1_dst could point to the same buffer i.e. the +* six tap filter could be done in place. +* +******************************************************************************* +*/ void ih264_inter_pred_luma_horz_hpel_vert_qpel(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -898,52 +1021,49 @@ void ih264_inter_pred_luma_horz_hpel_vert_qpel(UWORD8 *pu1_src, } /** - ******************************************************************************* - * function:ih264_inter_pred_luma_bilinear - * - * @brief - * This routine applies the bilinear filter to the predictors . - * The filtering operation is described in - * sec 8.4.2.2.1 titled "Luma sample interpolation process" - * - * @par Description: -\note - * This function is called to obtain pixels lying at the following - * locations (1/4,1), (3/4,1),(1,1/4), (1,3/4) ,(1/4,1/2), (3/4,1/2),(1/2,1/4), (1/2,3/4),(3/4,1/4),(1/4,3/4),(3/4,3/4)&& (1/4,1/4) . - * The function averages the two adjacent values from the two input arrays in horizontal direction. - * - * - * @param[in] pu1_src1: - * UWORD8 Pointer to the buffer containing the first input array. - * - * @param[in] pu1_src2: - * UWORD8 Pointer to the buffer containing the second input array. - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination where the output of bilinear filter is stored. - * - * @param[in] src_strd1 - * Stride of the first input buffer - * - * @param[in] src_strd2 - * Stride of the second input buffer - * - * @param[in] dst_strd - * integer destination stride of pu1_dst - * - * @param[in] ht - * integer height of the array - * - * @param[in] wd - * integer width of the array - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief This routine applies the bilinear filter to the predictors. +* +* @par Description This routine applies the bilinear filter to the predictors. +* The filtering operation is described in sec 8.4.2.2.1 titled +* "Luma sample interpolation process". This function is called to obtain +* pixels lying at the following locations (1/4,1), (3/4,1),(1,1/4), (1,3/4), +* (1/4,1/2), (3/4,1/2), (1/2,1/4), (1/2,3/4), (3/4,1/4), (1/4,3/4), (3/4,3/4) +* and (1/4,1/4). The function averages the two adjacent values from the two +* input arrays in horizontal direction. +* +* @param[in] pu1_src1: +* Pointer to the buffer containing the first input array. +* +* @param[in] pu1_src2: +* Pointer to the buffer containing the second input array. +* +* @param[out] pu1_dst +* pointer to the destination where the output of bilinear filter is stored. +* +* @param[in] src_strd1 +* Stride of the first input buffer +* +* @param[in] src_strd2 +* Stride of the second input buffer +* +* @param[in] dst_strd +* destination stride of pu1_dst +* +* @param[in] ht +* height of the array +* +* @param[in] wd +* width of the array +* +* @returns +* +* @remarks +* None +* +******************************************************************************* +*/ void ih264_inter_pred_luma_bilinear(UWORD8 *pu1_src1, UWORD8 *pu1_src2, UWORD8 *pu1_dst, @@ -968,50 +1088,48 @@ void ih264_inter_pred_luma_bilinear(UWORD8 *pu1_src1, pu1_src2 += src_strd2; pu1_dst += dst_strd; } - } /** - ******************************************************************************* - * - * @brief - * Interprediction chroma filter - * - * @par Description: - * Applies filtering to chroma samples as mentioned in - * sec 8.4.2.2.2 titled "chroma sample interpolation process" - * - * @param[in] pu1_src - * UWORD8 pointer to the source containing alternate U and V samples - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] u1_dx - * dx value where the sample is to be produced(refer sec 8.4.2.2.2 ) - * - * @param[in] u1_dy - * dy value where the sample is to be produced(refer sec 8.4.2.2.2 ) - * - * @param[in] ht - * integer height of the array - * - * @param[in] wd - * integer width of the array - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief Interprediction chroma filter +* +* @par Description: +* Applies filtering to chroma samples as mentioned in sec 8.4.2.2.2 titled +* "chroma sample interpolation process" +* +* @param[in] pu1_src +* pointer to the source containing alternate U and V samples +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] dx +* dx value where the sample is to be produced (refer sec 8.4.2.2.2 ) +* +* @param[in] dy +* dy value where the sample is to be produced (refer sec 8.4.2.2.2 ) +* +* @param[in] ht +* integer height of the array +* +* @param[in] wd +* integer width of the array +* +* @returns +* +* @remarks +* None +* +******************************************************************************* +*/ void ih264_inter_pred_chroma(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, diff --git a/common/ih264_inter_pred_filters.h b/common/ih264_inter_pred_filters.h index c439ab8..f42222f 100644 --- a/common/ih264_inter_pred_filters.h +++ b/common/ih264_inter_pred_filters.h @@ -19,76 +19,24 @@ */ /** - ******************************************************************************* - * @file - * ih264_inter_pred_filters.h - * - * @brief - * Declarations of functions used for inter prediction - * - * @author - * Ittiam - * - * @par List of Functions: - * -ih264_inter_pred_luma_copy - * -ih264_interleave_copy - * -ih264_inter_pred_luma_horz - * -ih264_inter_pred_luma_vert - * -ih264_inter_pred_luma_horz_hpel_vert_hpel - * -ih264_inter_pred_luma_vert_qpel - * -ih264_inter_pred_luma_horz_qpel - * -ih264_inter_pred_luma_horz_qpel_vert_qpel - * -ih264_inter_pred_luma_horz_qpel_vert_hpel - * -ih264_inter_pred_luma_horz_hpel_vert_qpel - * -ih264_inter_pred_luma_bilinear - * -ih264_inter_pred_chroma - * -ih264_inter_pred_luma_copy_a9q - * -ih264_interleave_copy_a9 - * -ih264_inter_pred_luma_horz_a9q - * -ih264_inter_pred_luma_vert_a9q - * -ih264_inter_pred_luma_bilinear_a9q - * -ih264_inter_pred_luma_horz_hpel_vert_hpel_a9q - * -ih264_inter_pred_luma_horz_qpel_a9q - * -ih264_inter_pred_luma_vert_qpel_a9q - * -ih264_inter_pred_luma_horz_qpel_vert_qpel_a9q - * -ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q - * -ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q - * -ih264_inter_pred_chroma_a9q - * -ih264_inter_pred_luma_copy_av8 - * -ih264_interleave_copy_av8 - * -ih264_inter_pred_luma_horz_av8 - * -ih264_inter_pred_luma_vert_av8 - * -ih264_inter_pred_luma_bilinear_av8 - * -ih264_inter_pred_luma_horz_hpel_vert_hpel_av8 - * -ih264_inter_pred_luma_horz_qpel_av8 - * -ih264_inter_pred_luma_vert_qpel_av8 - * -ih264_inter_pred_luma_horz_qpel_vert_qpel_av8 - * -ih264_inter_pred_luma_horz_qpel_vert_hpel_av8 - * -ih264_inter_pred_luma_horz_hpel_vert_qpel_av8 - * -ih264_inter_pred_chroma_av8 - * -ih264_inter_pred_chroma_dx_zero_av8 - * -ih264_inter_pred_chroma_dy_zero_av8 - * -ih264_inter_pred_luma_copy_ssse3 - * -ih264_inter_pred_luma_copy_ssse3 - * -ih264_inter_pred_luma_horz_ssse3 - * -ih264_inter_pred_luma_vert_ssse3 - * -ih264_inter_pred_luma_bilinear_ssse3 - * -ih264_inter_pred_luma_horz_hpel_vert_hpel_ssse3 - * -ih264_inter_pred_luma_horz_qpel_ssse3 - * -ih264_inter_pred_luma_vert_qpel_ssse3 - * -ih264_inter_pred_luma_horz_qpel_vert_qpel_ssse3 - * -ih264_inter_pred_luma_horz_qpel_vert_hpel_ssse3 - * -ih264_inter_pred_luma_horz_hpel_vert_qpel_ssse3 - * -ih264_inter_pred_chroma_ssse3 - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_inter_pred_filters.h +* +* @brief +* Declarations of functions used for inter prediction +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ -#ifndef _IH264_INTER_PRED_H_ -#define _IH264_INTER_PRED_H_ +#ifndef _IH264_INTER_PRED_FILTERS_H_ +#define _IH264_INTER_PRED_FILTERS_H_ /*****************************************************************************/ /* Constant Data variables */ @@ -134,108 +82,60 @@ typedef void ih264_inter_pred_chroma_ft(UWORD8 *pu1_src, WORD32 ht, WORD32 wd); -/* No NEON Declarations */ - +/* C Declarations */ ih264_inter_pred_luma_ft ih264_inter_pred_luma_copy; - ih264_interleave_copy_ft ih264_interleave_copy; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_vert; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_hpel_vert_hpel; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_vert_qpel; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel_vert_qpel; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel_vert_hpel; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_hpel_vert_qpel; - ih264_inter_pred_luma_bilinear_ft ih264_inter_pred_luma_bilinear; - ih264_inter_pred_chroma_ft ih264_inter_pred_chroma; /* A9 NEON Declarations */ ih264_inter_pred_luma_ft ih264_inter_pred_luma_copy_a9q; - ih264_interleave_copy_ft ih264_interleave_copy_a9; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_a9q; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_vert_a9q; - ih264_inter_pred_luma_bilinear_ft ih264_inter_pred_luma_bilinear_a9q; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_hpel_vert_hpel_a9q; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel_a9q; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_vert_qpel_a9q; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel_vert_qpel_a9q; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q; - ih264_inter_pred_chroma_ft ih264_inter_pred_chroma_a9q; /* AV8 NEON Declarations */ ih264_inter_pred_luma_ft ih264_inter_pred_luma_copy_av8; - ih264_interleave_copy_ft ih264_interleave_copy_av8; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_av8; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_vert_av8; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_hpel_vert_hpel_av8; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel_av8; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_vert_qpel_av8; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel_vert_qpel_av8; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel_vert_hpel_av8; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_hpel_vert_qpel_av8; - ih264_inter_pred_chroma_ft ih264_inter_pred_chroma_av8; - ih264_inter_pred_chroma_ft ih264_inter_pred_chroma_dx_zero_av8; - ih264_inter_pred_chroma_ft ih264_inter_pred_chroma_dy_zero_av8; - /* SSSE3 Intrinsic Declarations */ ih264_inter_pred_luma_ft ih264_inter_pred_luma_copy_ssse3; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_ssse3; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_vert_ssse3; - ih264_inter_pred_luma_bilinear_ft ih264_inter_pred_luma_bilinear_ssse3; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_hpel_vert_hpel_ssse3; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel_ssse3; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_vert_qpel_ssse3; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel_vert_qpel_ssse3; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_qpel_vert_hpel_ssse3; - ih264_inter_pred_luma_ft ih264_inter_pred_luma_horz_hpel_vert_qpel_ssse3; - ih264_inter_pred_chroma_ft ih264_inter_pred_chroma_ssse3; -#endif - -/** Nothing past this point */ +#endif /* _IH264_INTER_PRED_FILTERS_H_ */ diff --git a/common/ih264_intra_pred_filters.h b/common/ih264_intra_pred_filters.h index caf6b33..20530b5 100644 --- a/common/ih264_intra_pred_filters.h +++ b/common/ih264_intra_pred_filters.h @@ -17,40 +17,41 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ -/** - ******************************************************************************* - * @file - * ih264_intra_pred_filters.h - * - * @brief - * Declarations of functions used for intra prediction - * - * @author - * Ittiam - * - * @remarks - * None - * - ******************************************************************************* - */ -#ifndef IH264_INTRA_PRED_FILTERS_H_ +/** +******************************************************************************* +* @file +* ih264_intra_pred_filters.h +* +* @brief +* Declarations of functions used for intra prediction +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ -#define IH264_INTRA_PRED_FILTERS_H_ +#ifndef _IH264_INTRA_PRED_FILTERS_H_ +#define _IH264_INTRA_PRED_FILTERS_H_ /*****************************************************************************/ -/* Macro Expansion */ +/* Function Macros */ /*****************************************************************************/ /*! Filter (1,2,1) i.e (a + 2b + c) / 4 */ -#define FILT121(a,b,c) ((a + (b<<1) + c + 2)>>2) +#define FILT121(a,b,c) ((a + (b << 1) + c + 2) >> 2) + /*! Filter (1,1) i.e (a + b) / 2 */ -#define FILT11(a,b) ((a + b + 1)>>1) +#define FILT11(a,b) ((a + b + 1) >> 1) + /*****************************************************************************/ /* Global Variables */ /*****************************************************************************/ - -/* Global variables used only in assembly files*/ +/* Note: Global variables used only in assembly files */ extern const WORD8 ih264_gai1_intrapred_luma_plane_coeffs[]; extern const WORD8 ih264_gai1_intrapred_chroma_plane_coeffs1[]; extern const WORD8 ih264_gai1_intrapred_chroma_plane_coeffs2[]; @@ -60,7 +61,6 @@ extern const WORD8 ih264_gai1_intrapred_luma_8x8_horz_u[]; /* Extern Function Declarations */ /*****************************************************************************/ - typedef void ih264_intra_pred_ref_filtering_ft(UWORD8 *pu1_left, UWORD8 *pu1_topleft, UWORD8 *pu1_top, @@ -74,258 +74,136 @@ typedef void ih264_intra_pred_luma_ft(UWORD8 *pu1_src, WORD32 dst_strd, WORD32 ngbr_avail); -/* No Neon Definitions */ +typedef ih264_intra_pred_luma_ft ih264_intra_pred_chroma_ft; +/* C Declarations */ /* Luma 4x4 Intra pred filters */ - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_dc; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_diag_dl; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_diag_dr; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert_r; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz_d; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert_l; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz_u; - /* Luma 8x8 Intra pred filters */ - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_dc; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_diag_dl; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_diag_dr; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert_r; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz_d; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert_l; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz_u; - /* Luma 16x16 Intra pred filters */ - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_vert; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_horz; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_dc; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_plane; - /* Chroma 8x8 Intra pred filters */ - -typedef ih264_intra_pred_luma_ft ih264_intra_pred_chroma_ft; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_dc; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_horz; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_vert; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_plane; - - ih264_intra_pred_ref_filtering_ft ih264_intra_pred_luma_8x8_mode_ref_filtering; -/* A9 Definition */ - +/* A9 Declarations */ /* Luma 4x4 Intra pred filters */ - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_dc_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_diag_dl_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_diag_dr_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert_r_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz_d_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert_l_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz_u_a9q; - /* Luma 8x8 Intra pred filters */ - ih264_intra_pred_ref_filtering_ft ih264_intra_pred_luma_8x8_mode_ref_filtering_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_dc_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_diag_dl_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_diag_dr_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert_r_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz_d_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert_l_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz_u_a9q; - /* Luma 16x16 Intra pred filters */ - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_vert_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_horz_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_dc_a9q; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_plane_a9q; - /* Chroma 8x8 Intra pred filters */ - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_dc_a9q; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_horz_a9q; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_vert_a9q; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_plane_a9q; -/* X86 Intrinsic Definitions */ - +/* SSSE3 Intrinsic Declarationss */ /* Luma 4x4 Intra pred filters */ - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_dc_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_diag_dl_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_diag_dr_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert_r_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz_d_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert_l_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz_u_ssse3; - /* Luma 8x8 Intra pred filters */ - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_dc_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_diag_dl_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_diag_dr_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert_r_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz_d_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert_l_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz_u_ssse3; - /* Luma 16x16 Intra pred filters */ - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_vert_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_horz_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_dc_ssse3; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_plane_ssse3; - /* Chroma 8x8 Intra pred filters */ - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_dc_ssse3; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_horz_ssse3; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_vert_ssse3; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_plane_ssse3; -/* AV8 Definition */ - +/* AV8 Declarations */ /* Luma 4x4 Intra pred filters */ ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_dc_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_diag_dl_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_diag_dr_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert_r_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz_d_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_vert_l_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_4x4_mode_horz_u_av8; - /* Luma 8x8 Intra pred filters */ - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_dc_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_diag_dl_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_diag_dr_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert_r_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz_d_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_vert_l_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_8x8_mode_horz_u_av8; - /* Luma 16x16 Intra pred filters */ - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_vert_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_horz_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_dc_av8; - ih264_intra_pred_luma_ft ih264_intra_pred_luma_16x16_mode_plane_av8; - /* Chroma 8x8 Intra pred filters */ - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_dc_av8; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_horz_av8; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_vert_av8; - ih264_intra_pred_chroma_ft ih264_intra_pred_chroma_8x8_mode_plane_av8; -#endif /* IH264_INTRA_PRED_FILTERS_H_ */ +#endif /* _IH264_INTRA_PRED_FILTERS_H_ */ diff --git a/common/ih264_iquant_itrans_recon.c b/common/ih264_iquant_itrans_recon.c index 3c14046..8a27c9a 100644 --- a/common/ih264_iquant_itrans_recon.c +++ b/common/ih264_iquant_itrans_recon.c @@ -17,92 +17,101 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_iquant_itrans_recon.c - * - * @brief - * Contains definition of functions for h264 inverse quantization inverse transformation and recon - * - * @author - * Ittiam - * - * @par List of Functions: - * - ih264_iquant_itrans_recon_4x4() - * - ih264_iquant_itrans_recon_8x8() - * - ih264_iquant_itrans_recon_4x4_dc() - * - ih264_iquant_itrans_recon_8x8_dc() - * - ih264_iquant_itrans_recon_chroma_4x4() - * -ih264_iquant_itrans_recon_chroma_4x4_dc() - * - * @remarks - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_iquant_itrans_recon.c +* +* @brief +* Contains definition of functions for h264 inverse quantization, +* inverse transformation and recon +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264_iquant_itrans_recon_4x4 +* - ih264_iquant_itrans_recon_8x8 +* - ih264_iquant_itrans_recon_4x4_dc +* - ih264_iquant_itrans_recon_8x8_dc +* - ih264_iquant_itrans_recon_chroma_4x4 +* - ih264_iquant_itrans_recon_chroma_4x4_dc +* +* @remarks +* +******************************************************************************* +*/ /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "ih264_defs.h" -#include "ih264_trans_macros.h" #include "ih264_macros.h" -#include "ih264_platform_macros.h" -#include "ih264_trans_data.h" #include "ih264_size_defs.h" +#include "ih264_trans_macros.h" +#include "ih264_trans_data.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_platform_macros.h" -/* - ******************************************************************************** - * - * @brief This function reconstructs a 4x4 sub block from quantized resiude and - * prediction buffer - * - * @par Description: - * The quantized residue is first inverse quantized, then inverse transformed. - * This inverse transformed content is added to the prediction buffer to recon- - * struct the end output - * - * @param[in] pi2_src - * quantized 4x4 block - * - * @param[in] pu1_pred - * prediction 4x4 block - * - * @param[out] pu1_out - * reconstructed 4x4 block - * - * @param[in] src_strd - * quantization buffer stride - * - * @param[in] pred_strd, - * Prediction buffer stride - * - * @param[in] out_strd - * recon buffer Stride - * - * @param[in] pu2_scaling_list - * pointer to scaling list - * - * @param[in] pu2_norm_adjust - * pointer to inverse scale matrix - * - * @param[in] u4_qp_div_6 - * Floor (qp/6) - * - * @param[in] pi4_tmp - * temporary buffer of size 1*16 - * - * @returns none - * - * @remarks none - * - ******************************************************************************* - */ +/*****************************************************************************/ +/* Function definitions */ +/*****************************************************************************/ + +/** +******************************************************************************** +* +* @brief This function reconstructs a 4x4 sub block from quantized residue and +* prediction buffer +* +* @par Description: +* The quantized residue is first inverse quantized, then inverse transformed. +* This inverse transformed content is added to the prediction buffer to recon- +* struct the end output +* +* @param[in] pi2_src +* quantized 4x4 block +* +* @param[in] pu1_pred +* prediction 4x4 block +* +* @param[out] pu1_out +* reconstructed 4x4 block +* +* @param[in] pred_strd +* Prediction buffer stride +* +* @param[in] out_strd +* recon buffer Stride +* +* @param[in] pu2_iscal_mat +* pointer to inverse scaling matrix +* +* @param[in] pu2_weigh_mat +* pointer to weight matrix +* +* @param[in] u4_qp_div_6 +* Floor (qp/6) +* +* @param[in] pi2_tmp +* temporary buffer of size 1*16 +* +* @param[in] iq_start_idx +* Differentiates b/w intra or inter +* +* @param[in] pi2_dc_ld_addr +* Address to load DC value of the 4x4 blk +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_iquant_itrans_recon_4x4(WORD16 *pi2_src, UWORD8 *pu1_pred, UWORD8 *pu1_out, @@ -113,8 +122,7 @@ void ih264_iquant_itrans_recon_4x4(WORD16 *pi2_src, UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx, - WORD16 *pi2_dc_ld_addr -) + WORD16 *pi2_dc_ld_addr) { WORD16 *pi2_src_ptr = pi2_src; WORD16 *pi2_tmp_ptr = pi2_tmp; @@ -126,29 +134,28 @@ void ih264_iquant_itrans_recon_4x4(WORD16 *pi2_src, WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0; /* inverse quant */ - /*horizontal inverse transform */ + /* horizontal inverse transform */ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++) { q0 = pi2_src_ptr[0]; - INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, - 4); + INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4); + /* Restoring dc value for intra case */ if (i==0 && iq_start_idx == 1) - q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case + { + q0 = pi2_dc_ld_addr[0]; + } q2 = pi2_src_ptr[2]; - INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, - 4); + INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4); x0 = q0 + q2; x1 = q0 - q2; q1 = pi2_src_ptr[1]; - INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, - 4); + INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4); q3 = pi2_src_ptr[3]; - INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, - 4); + INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4); x2 = (q1 >> 1) - q3; x3 = q1 + (q3 >> 1); @@ -207,9 +214,58 @@ void ih264_iquant_itrans_recon_4x4(WORD16 *pi2_src, pu1_out_ptr++; pu1_pred++; } - } +/** +******************************************************************************** +* +* @brief This function reconstructs a 4x4 sub block from quantized residue and +* prediction buffer, if only dc value is present for residue +* +* @par Description: +* The quantized residue is first inverse quantized, then inverse transformed. +* This inverse transformed content is added to the prediction buffer to recon- +* struct the end output +* +* @param[in] pi2_src +* quantized 4x4 block +* +* @param[in] pu1_pred +* prediction 4x4 block +* +* @param[out] pu1_out +* reconstructed 4x4 block +* +* @param[in] pred_strd +* Prediction buffer stride +* +* @param[in] out_strd +* recon buffer Stride +* +* @param[in] pu2_iscal_mat +* pointer to inverse scaling matrix +* +* @param[in] pu2_weigh_mat +* pointer to weight matrix +* +* @param[in] u4_qp_div_6 +* Floor (qp/6) +* +* @param[in] pi2_tmp +* temporary buffer of size 1*16 +* +* @param[in] iq_start_idx +* Differentiates b/w intra or inter +* +* @param[in] pi2_dc_ld_addr +* Address to load DC value of the 4x4 blk +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_iquant_itrans_recon_4x4_dc(WORD16 *pi2_src, UWORD8 *pu1_pred, UWORD8 *pu1_out, @@ -227,16 +283,16 @@ void ih264_iquant_itrans_recon_4x4_dc(WORD16 *pi2_src, WORD32 q0; WORD16 x, i_macro, i; WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0; - UNUSED(pi2_tmp); - if (iq_start_idx == 0) + UNUSED(pi2_tmp); + if(iq_start_idx == 0) { - q0 = pi2_src[0]; - INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4); + q0 = pi2_src[0]; + INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4); } else { - q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case3 + q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case3 } i_macro = ((q0 + 32) >> 6); for(i = 0; i < SUB_BLK_WIDTH_4x4; i++) @@ -245,7 +301,6 @@ void ih264_iquant_itrans_recon_4x4_dc(WORD16 *pi2_src, pu1_out = pu1_out_ptr; /* inverse prediction */ - x = i_macro + *pu1_pred_ptr; *pu1_out = CLIP_U8(x); pu1_pred_ptr += pred_strd; @@ -270,56 +325,56 @@ void ih264_iquant_itrans_recon_4x4_dc(WORD16 *pi2_src, } /** - ******************************************************************************* - * - * @brief - * This function performs inverse quant and Inverse transform type Ci4 for 8x8 block - * - * @par Description: - * Performs inverse transform Ci8 and adds the residue to get the - * reconstructed block - * - * @param[in] pi2_src - * Input 8x8coefficients - * - * @param[in] pu1_pred - * Prediction 8x8 block - * - * @param[out] pu1_recon - * Output 8x8 block - * - * @param[in] q_div - * QP/6 - * - * @param[in] q_rem - * QP%6 - * - * @param[in] q_lev - * Quantizer level - * - * @param[in] src_strd - * Input stride - * - * @param[in] pred_strd, - * Prediction stride - * - * @param[in] out_strd - * Output Stride - * - * @param[in] pi4_tmp - * temporary buffer of size 1*16 we dont need a bigger blcok since we reuse - * the tmp for each block - * - * @param[in] pu4_iquant_mat - * Pointer to the inverse quantization matrix - * - * @returns Void - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************** +* +* @brief This function reconstructs a 8x8 sub block from quantized residue and +* prediction buffer +* +* @par Description: +* The quantized residue is first inverse quantized, then inverse transformed. +* This inverse transformed content is added to the prediction buffer to recon- +* struct the end output +* +* @param[in] pi2_src +* quantized 4x4 block +* +* @param[in] pu1_pred +* prediction 4x4 block +* +* @param[out] pu1_out +* reconstructed 4x4 block +* +* @param[in] pred_strd +* Prediction buffer stride +* +* @param[in] out_strd +* recon buffer Stride +* +* @param[in] pu2_iscal_mat +* pointer to inverse scaling matrix +* +* @param[in] pu2_weigh_mat +* pointer to weight matrix +* +* @param[in] u4_qp_div_6 +* Floor (qp/6) +* +* @param[in] pi2_tmp +* temporary buffer of size 1*16. we dont need a bigger block since we reuse +* the tmp for each block +* +* @param[in] iq_start_idx +* UNUSED +* +* @param[in] pi2_dc_ld_addr +* UNUSED +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_iquant_itrans_recon_8x8(WORD16 *pi2_src, UWORD8 *pu1_pred, UWORD8 *pu1_out, @@ -330,8 +385,7 @@ void ih264_iquant_itrans_recon_8x8(WORD16 *pi2_src, UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx, - WORD16 *pi2_dc_ld_addr -) + WORD16 *pi2_dc_ld_addr) { WORD32 i; WORD16 *pi2_tmp_ptr = pi2_tmp; @@ -342,6 +396,7 @@ void ih264_iquant_itrans_recon_8x8(WORD16 *pi2_src, WORD16 i_macro; WORD32 q; WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0; + UNUSED(iq_start_idx); UNUSED(pi2_dc_ld_addr); /*************************************************************/ @@ -432,13 +487,13 @@ void ih264_iquant_itrans_recon_8x8(WORD16 *pi2_src, //pi2_src_ptr += SUB_BLK_WIDTH_8x8; pi2_tmp_ptr += SUB_BLK_WIDTH_8x8; } + /*--------------------------------------------------------------------*/ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */ /* */ /* Add the prediction and store it back to reconstructed frame buffer */ /* [Prediction buffer itself in this case] */ /*--------------------------------------------------------------------*/ - pi2_tmp_ptr = pi2_tmp; for(i = 0; i < SUB_BLK_WIDTH_8x8; i++) { @@ -548,6 +603,57 @@ void ih264_iquant_itrans_recon_8x8(WORD16 *pi2_src, } } +/** +******************************************************************************** +* +* @brief This function reconstructs a 8x8 sub block from quantized residue and +* prediction buffer, if only dc value is present +* +* @par Description: +* The quantized residue is first inverse quantized, then inverse transformed. +* This inverse transformed content is added to the prediction buffer to recon- +* struct the end output +* +* @param[in] pi2_src +* quantized 4x4 block +* +* @param[in] pu1_pred +* prediction 4x4 block +* +* @param[out] pu1_out +* reconstructed 4x4 block +* +* @param[in] pred_strd +* Prediction buffer stride +* +* @param[in] out_strd +* recon buffer Stride +* +* @param[in] pu2_iscal_mat +* pointer to inverse scaling matrix +* +* @param[in] pu2_weigh_mat +* pointer to weight matrix +* +* @param[in] u4_qp_div_6 +* Floor (qp/6) +* +* @param[in] pi2_tmp +* temporary buffer of size 1*16. we dont need a bigger block since we reuse +* the tmp for each block +* +* @param[in] iq_start_idx +* UNUSED +* +* @param[in] pi2_dc_ld_addr +* UNUSED +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_iquant_itrans_recon_8x8_dc(WORD16 *pi2_src, UWORD8 *pu1_pred, UWORD8 *pu1_out, @@ -565,6 +671,7 @@ void ih264_iquant_itrans_recon_8x8_dc(WORD16 *pi2_src, WORD16 x, i, i_macro; WORD32 q; WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0; + UNUSED(pi2_tmp); UNUSED(iq_start_idx); UNUSED(pi2_dc_ld_addr); @@ -634,53 +741,53 @@ void ih264_iquant_itrans_recon_8x8_dc(WORD16 *pi2_src, } } -/* - ******************************************************************************** - * - * @brief This function reconstructs a 4x4 sub block from quantized resiude and - * prediction buffer - * - * @par Description: - * The quantized residue is first inverse quantized, then inverse transformed. - * This inverse transformed content is added to the prediction buffer to recon- - * struct the end output - * - * @param[in] pi2_src - * quantized 4x4 block - * - * @param[in] pu1_pred - * prediction 4x4 block - * - * @param[out] pu1_out - * reconstructed 4x4 block - * - * @param[in] src_strd - * quantization buffer stride - * - * @param[in] pred_strd, - * Prediction buffer stride - * - * @param[in] out_strd - * recon buffer Stride - * - * @param[in] pu2_scaling_list - * pointer to scaling list - * - * @param[in] pu2_norm_adjust - * pointer to inverse scale matrix - * - * @param[in] u4_qp_div_6 - * Floor (qp/6) - * - * @param[in] pi4_tmp - * temporary buffer of size 1*16 - * - * @returns none - * - * @remarks none - * - ******************************************************************************* - */ +/** +******************************************************************************** +* +* @brief This function reconstructs a 4x4 sub block from quantized residue and +* prediction buffer +* +* @par Description: +* The quantized residue is first inverse quantized, then inverse transformed. +* This inverse transformed content is added to the prediction buffer to recon- +* struct the end output +* +* @param[in] pi2_src +* quantized 4x4 block +* +* @param[in] pu1_pred +* prediction 4x4 block +* +* @param[out] pu1_out +* reconstructed 4x4 block +* +* @param[in] pred_strd +* Prediction buffer stride +* +* @param[in] out_strd +* recon buffer Stride +* +* @param[in] pu2_iscal_mat +* pointer to inverse scaling matrix +* +* @param[in] pu2_weigh_mat +* pointer to weight matrix +* +* @param[in] u4_qp_div_6 +* Floor (qp/6) +* +* @param[in] pi2_tmp +* temporary buffer of size 1*16 +* +* @param[in] pi2_dc_src +* Address to load DC value of the 4x4 blk +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_iquant_itrans_recon_chroma_4x4(WORD16 *pi2_src, UWORD8 *pu1_pred, UWORD8 *pu1_out, @@ -702,46 +809,43 @@ void ih264_iquant_itrans_recon_chroma_4x4(WORD16 *pi2_src, WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0; /* inverse quant */ - /*horizontal inverse transform */ + /* horizontal inverse transform */ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++) { - if(i==0) - { - q0 = pi2_dc_src[0]; - } - else - { - q0 = pi2_src_ptr[0]; - INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4); - } + if(i == 0) + { + q0 = pi2_dc_src[0]; + } + else + { + q0 = pi2_src_ptr[0]; + INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4); + } - q2 = pi2_src_ptr[2]; - INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, - 4); + q2 = pi2_src_ptr[2]; + INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4); - x0 = q0 + q2; - x1 = q0 - q2; + x0 = q0 + q2; + x1 = q0 - q2; - q1 = pi2_src_ptr[1]; - INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, - 4); + q1 = pi2_src_ptr[1]; + INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4); - q3 = pi2_src_ptr[3]; - INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, - 4); + q3 = pi2_src_ptr[3]; + INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4); - x2 = (q1 >> 1) - q3; - x3 = q1 + (q3 >> 1); + x2 = (q1 >> 1) - q3; + x3 = q1 + (q3 >> 1); - pi2_tmp_ptr[0] = x0 + x3; - pi2_tmp_ptr[1] = x1 + x2; - pi2_tmp_ptr[2] = x1 - x2; - pi2_tmp_ptr[3] = x0 - x3; + pi2_tmp_ptr[0] = x0 + x3; + pi2_tmp_ptr[1] = x1 + x2; + pi2_tmp_ptr[2] = x1 - x2; + pi2_tmp_ptr[3] = x0 - x3; - pi2_src_ptr += SUB_BLK_WIDTH_4x4; - pi2_tmp_ptr += SUB_BLK_WIDTH_4x4; - pu2_iscal_mat += SUB_BLK_WIDTH_4x4; - pu2_weigh_mat += SUB_BLK_WIDTH_4x4; + pi2_src_ptr += SUB_BLK_WIDTH_4x4; + pi2_tmp_ptr += SUB_BLK_WIDTH_4x4; + pu2_iscal_mat += SUB_BLK_WIDTH_4x4; + pu2_weigh_mat += SUB_BLK_WIDTH_4x4; } /* vertical inverse transform */ @@ -754,7 +858,7 @@ void ih264_iquant_itrans_recon_chroma_4x4(WORD16 *pi2_src, x0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[8]); x1 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[8]); x2 = (pi2_tmp_ptr[4] >> 1) - pi2_tmp_ptr[12]; - x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1); + x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1); /* inverse prediction */ i_macro = x0 + x3; @@ -784,41 +888,55 @@ void ih264_iquant_itrans_recon_chroma_4x4(WORD16 *pi2_src, *pu1_out = CLIP_U8(i_macro); pi2_tmp_ptr++; - pu1_out_ptr+= 2; //Interleaved store for output - pu1_pred+= 2; //Interleaved load for pred buffer + pu1_out_ptr += 2; // Interleaved store for output + pu1_pred += 2; // Interleaved load for pred buffer } } -/* - ******************************************************************************** - * - * @brief This function reconstructs a 4x4 sub block from quantized resiude and - * prediction buffer if only dc value is present for residue - * - * @par Description: - * The quantized residue is first inverse quantized, - * This inverse quantized content is added to the prediction buffer to recon- - * struct the end output - * - * @param[in] pi2_src - * quantized dc coefficient - * - * @param[in] pu1_pred - * prediction 4x4 block in interleaved format - * - * @param[in] pred_strd, - * Prediction buffer stride in interleaved format - * - * @param[in] out_strd - * recon buffer Stride - * - * @returns none - * - * @remarks none - * - ******************************************************************************* - */ - +/** +******************************************************************************** +* +* @brief This function reconstructs a 4x4 sub block from quantized residue and +* prediction buffer if only dc value is present for residue +* +* @par Description: +* The quantized residue is first inverse quantized, +* This inverse quantized content is added to the prediction buffer to recon- +* struct the end output +* +* @param[in] pi2_src +* quantized dc coefficient +* +* @param[in] pu1_pred +* prediction 4x4 block in interleaved format +* +* @param[in] pred_strd, +* Prediction buffer stride in interleaved format +* +* @param[in] out_strd +* recon buffer Stride +* +* @param[in] pu2_iscal_mat +* pointer to inverse scaling matrix +* +* @param[in] pu2_weigh_mat +* pointer to weight matrix +* +* @param[in] u4_qp_div_6 +* Floor (qp/6) +* +* @param[in] pi2_tmp +* temporary buffer of size 1*16 +* +* @param[in] pi2_dc_src +* Address to load DC value of the 4x4 blk +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_iquant_itrans_recon_chroma_4x4_dc(WORD16 *pi2_src, UWORD8 *pu1_pred, UWORD8 *pu1_out, @@ -834,6 +952,7 @@ void ih264_iquant_itrans_recon_chroma_4x4_dc(WORD16 *pi2_src, UWORD8 *pu1_out_ptr = pu1_out; WORD32 q0; WORD16 x, i_macro, i; + UNUSED(pi2_src); UNUSED(pu2_iscal_mat); UNUSED(pu2_weigh_mat); diff --git a/common/ih264_list.c b/common/ih264_list.c index 736b41c..7f38842 100644 --- a/common/ih264_list.c +++ b/common/ih264_list.c @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,55 +27,66 @@ * Contains functions for buf queue * * @author -* Harish +* ittiam * * @par List of Functions: -* ih264_list_size() -* ih264_list_lock() -* ih264_list_unlock() -* ih264_list_yield() -* ih264_list_free() -* ih264_list_init() -* ih264_list_reset() -* ih264_list_deinit() -* ih264_list_terminate() -* ih264_list_queue() -* ih264_list_dequeue() +* - ih264_list_size +* - ih264_list_lock +* - ih264_list_unlock +* - ih264_list_yield +* - ih264_list_free +* - ih264_list_init +* - ih264_list_reset +* - ih264_list_deinit +* - ih264_list_terminate +* - ih264_list_queue +* - ih264_list_dequeue * * @remarks -* None +* none * ******************************************************************************* */ + /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ + +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <string.h> #include <assert.h> +/* User Include Files */ #include "ih264_typedefs.h" #include "ithread.h" -#include "ih264_platform_macros.h" -#include "ih264_macros.h" #include "ih264_debug.h" +#include "ih264_macros.h" #include "ih264_error.h" #include "ih264_list.h" +#include "ih264_platform_macros.h" + +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ /** ******************************************************************************* * -* @brief Returns size for buf queue context. Does not include buf queue buffer -* requirements +* @brief Returns size for job queue context. * -* @par Description -* Returns size for buf queue context. Does not include buf queue buffer -* requirements. Buffer size required to store the bufs should be allocated in -* addition to the value returned here. +* @par Description +* Returns size for job queue context. * -* @returns Size of the buf queue context +* @param[in] num_entries +* max number of jobs that can be queued +* +* @param[in] entry_size +* memory needed for a single job +* +* @returns Size of the job queue context * * @remarks * @@ -84,6 +96,7 @@ WORD32 ih264_list_size(WORD32 num_entries, WORD32 entry_size) { WORD32 size; WORD32 clz; + size = sizeof(list_t); size += ithread_get_mutex_lock_size(); @@ -91,21 +104,20 @@ WORD32 ih264_list_size(WORD32 num_entries, WORD32 entry_size) clz = CLZ(num_entries); num_entries = 1 << (32 - clz); - size += num_entries * entry_size; + size += num_entries * entry_size; return size; } /** ******************************************************************************* * -* @brief -* Locks the list context +* @brief Locks the list context * -* @par Description -* Locks the list context by calling ithread_mutex_lock() +* @par Description +* Locks the list context by calling ithread_mutex_lock() * * @param[in] ps_list -* Job Queue context +* Pointer to job queue context * * @returns IH264_FAIL if mutex lock fails else IH264_SUCCESS * @@ -116,25 +128,23 @@ WORD32 ih264_list_size(WORD32 num_entries, WORD32 entry_size) IH264_ERROR_T ih264_list_lock(list_t *ps_list) { WORD32 retval; + retval = ithread_mutex_lock(ps_list->pv_mutex); if(retval) - { return IH264_FAIL; - } return IH264_SUCCESS; } /** ******************************************************************************* * -* @brief -* Unlocks the list context +* @brief Unlocks the list context * -* @par Description -* Unlocks the list context by calling ithread_mutex_unlock() +* @par Description +* Unlocks the list context by calling ithread_mutex_unlock() * * @param[in] ps_list -* Job Queue context +* Pointer to job queue context * * @returns IH264_FAIL if mutex unlock fails else IH264_SUCCESS * @@ -142,33 +152,29 @@ IH264_ERROR_T ih264_list_lock(list_t *ps_list) * ******************************************************************************* */ - IH264_ERROR_T ih264_list_unlock(list_t *ps_list) { WORD32 retval; + retval = ithread_mutex_unlock(ps_list->pv_mutex); if(retval) - { return IH264_FAIL; - } return IH264_SUCCESS; - } + /** ******************************************************************************* * -* @brief -* Yields the thread +* @brief Yields the thread * -* @par Description -* Unlocks the list context by calling -* ih264_list_unlock(), ithread_yield() and then ih264_list_lock() -* list is unlocked before to ensure the list can be accessed by other threads -* If unlock is not done before calling yield then no other thread can access -* the list functions and update list. +* @par Description +* Unlocks the list context by calling ih264_list_unlock(), ithread_yield() +* and then ih264_list_lock(). List is unlocked before to ensure its +* access by other threads. If unlock is not done before calling yield then +* no other thread can access the list functions and update list. * * @param[in] ps_list -* Job Queue context +* pointer to Job Queue context * * @returns IH264_FAIL if mutex lock unlock or yield fails else IH264_SUCCESS * @@ -178,51 +184,47 @@ IH264_ERROR_T ih264_list_unlock(list_t *ps_list) */ IH264_ERROR_T ih264_list_yield(list_t *ps_list) { + IH264_ERROR_T ret; - IH264_ERROR_T ret = IH264_SUCCESS; - - IH264_ERROR_T rettmp; - rettmp = ih264_list_unlock(ps_list); - RETURN_IF((rettmp != IH264_SUCCESS), rettmp); + ret = ih264_list_unlock(ps_list); + RETURN_IF((ret != IH264_SUCCESS), ret); ithread_yield(); - if(ps_list->i4_yeild_interval_us > 0) - ithread_usleep(ps_list->i4_yeild_interval_us); + if(ps_list->i4_yield_interval_us > 0) + ithread_usleep(ps_list->i4_yield_interval_us); - rettmp = ih264_list_lock(ps_list); - RETURN_IF((rettmp != IH264_SUCCESS), rettmp); - return ret; + ret = ih264_list_lock(ps_list); + RETURN_IF((ret != IH264_SUCCESS), ret); + return IH264_SUCCESS; } - /** ******************************************************************************* * -* @brief free the buf queue pointers +* @brief free the list context * -* @par Description -* Frees the list context +* @par Description +* Frees the list context * -* @param[in] pv_buf -* Memory for buf queue buffer and buf queue context +* @param[in] ps_list +* pointer to Job Queue context * -* @returns Pointer to buf queue context +* @returns IH264_FAIL if mutex desttroy fails else IH264_SUCCESS * * @remarks -* Since it will be called only once by master thread this is not thread safe. +* Since it will be called only once by master thread this is not thread safe. * ******************************************************************************* */ IH264_ERROR_T ih264_list_free(list_t *ps_list) { WORD32 ret; - ret = ithread_mutex_destroy(ps_list->pv_mutex); + ret = ithread_mutex_destroy(ps_list->pv_mutex); if(0 == ret) return IH264_SUCCESS; - else - return IH264_FAIL; + return IH264_FAIL; } /** @@ -230,20 +232,29 @@ IH264_ERROR_T ih264_list_free(list_t *ps_list) * * @brief Initialize the buf queue * -* @par Description -* Initializes the list context and sets write and read pointers to start of -* buf queue buffer +* @par Description +* Initializes the list context and sets write and read pointers to start of +* buf queue buffer * * @param[in] pv_buf -* Memoy for buf queue buffer and buf queue context +* Memory for job queue context * * @param[in] buf_size -* Size of the total memory allocated +* Size of the total memory allocated +* +* @param[in] num_entries +* max number of jobs that can be queued +* +* @param[in] entry_size +* memory needed for a single job * -* @returns Pointer to buf queue context +* @param[in] yield_interval_us +* Thread sleep duration +* +* @returns Pointer to job queue context * * @remarks -* Since it will be called only once by master thread this is not thread safe. +* Since it will be called only once by master thread this is not thread safe. * ******************************************************************************* */ @@ -251,14 +262,11 @@ void* ih264_list_init(void *pv_buf, WORD32 buf_size, WORD32 num_entries, WORD32 entry_size, - WORD32 yeild_interval_us) + WORD32 yield_interval_us) { - list_t *ps_list; - UWORD8 *pu1_buf; - - pu1_buf = (UWORD8 *)pv_buf; + list_t *ps_list = (list_t *)pv_buf; + UWORD8 *pu1_buf = (UWORD8 *)pv_buf; - ps_list = (list_t *)pu1_buf; pu1_buf += sizeof(list_t); buf_size -= sizeof(list_t); @@ -284,21 +292,21 @@ void* ih264_list_init(void *pv_buf, ps_list->i4_buf_wr_idx = 0; ps_list->i4_log2_buf_max_idx = 32 - CLZ(num_entries); ps_list->i4_buf_max_idx = num_entries; - ps_list->i4_yeild_interval_us = yeild_interval_us; + ps_list->i4_yield_interval_us = yield_interval_us; return ps_list; } + /** ******************************************************************************* * -* @brief -* Resets the list context +* @brief Resets the list context * -* @par Description -* Resets the list context by initializing buf queue context elements +* @par Description +* Resets the list context by initializing buf queue context elements * * @param[in] ps_list -* Job Queue context +* Pointer to job queue context * * @returns IH264_FAIL if lock unlock fails else IH264_SUCCESS * @@ -309,6 +317,7 @@ void* ih264_list_init(void *pv_buf, IH264_ERROR_T ih264_list_reset(list_t *ps_list) { IH264_ERROR_T ret = IH264_SUCCESS; + ret = ih264_list_lock(ps_list); RETURN_IF((ret != IH264_SUCCESS), ret); @@ -325,15 +334,14 @@ IH264_ERROR_T ih264_list_reset(list_t *ps_list) /** ******************************************************************************* * -* @brief -* Deinitializes the list context +* @brief De-initializes the list context * -* @par Description -* Deinitializes the list context by calling ih264_list_reset() -* and then destrying the mutex created +* @par Description +* De-initializes the list context by calling ih264_list_reset() and then +* destroying the mutex created * * @param[in] ps_list -* Job Queue context +* Pointer to job queue context * * @returns IH264_FAIL if lock unlock fails else IH264_SUCCESS * @@ -351,25 +359,20 @@ IH264_ERROR_T ih264_list_deinit(list_t *ps_list) retval = ithread_mutex_destroy(ps_list->pv_mutex); if(retval) - { return IH264_FAIL; - } - return IH264_SUCCESS; } - /** ******************************************************************************* * -* @brief -* Terminates the list +* @brief Terminates the list * -* @par Description -* Terminates the list by setting a flag in context. +* @par Description +* Terminates the list by setting a flag in context. * * @param[in] ps_list -* Job Queue context +* Pointer to job queue context * * @returns IH264_FAIL if lock unlock fails else IH264_SUCCESS * @@ -377,10 +380,10 @@ IH264_ERROR_T ih264_list_deinit(list_t *ps_list) * ******************************************************************************* */ - IH264_ERROR_T ih264_list_terminate(list_t *ps_list) { IH264_ERROR_T ret = IH264_SUCCESS; + ret = ih264_list_lock(ps_list); RETURN_IF((ret != IH264_SUCCESS), ret); @@ -391,34 +394,28 @@ IH264_ERROR_T ih264_list_terminate(list_t *ps_list) return ret; } - /** ******************************************************************************* * -* @brief Adds a buf to the queue +* @brief Adds a job to the queue * -* @par Description -* Adds a buf to the queue and updates wr address to next location. -* Format/content of the buf structure is abstracted and hence size of the buf -* buffer is being passed. +* @par Description +* Adds a buffer to the queue and updates write address to next location. * * @param[in] ps_list -* Job Queue context +* Pointer to job queue context * * @param[in] pv_buf -* Pointer to the location that contains details of the buf to be added -* -* @param[in] buf_size -* Size of the buf buffer +* Pointer to the location that contains details of the job to be added * * @param[in] blocking -* To signal if the write is blocking or non-blocking. +* To signal if the write is blocking or non-blocking. * -* @returns +* @returns IH264_SUCCESS on success and IH264_FAIL on fail * * @remarks -* Job Queue buffer is assumed to be allocated to handle worst case number of bufs -* Wrap around is not supported +* Job Queue buffer is assumed to be allocated to handle worst case number of +* buffers. Wrap around is not supported * ******************************************************************************* */ @@ -426,10 +423,8 @@ IH264_ERROR_T ih264_list_queue(list_t *ps_list, void *pv_buf, WORD32 blocking) { IH264_ERROR_T ret = IH264_SUCCESS; IH264_ERROR_T rettmp; - WORD32 diff; void *pv_buf_wr; - volatile WORD32 *pi4_wr_idx, *pi4_rd_idx; WORD32 buf_size = ps_list->i4_entry_size; @@ -437,8 +432,6 @@ IH264_ERROR_T ih264_list_queue(list_t *ps_list, void *pv_buf, WORD32 blocking) rettmp = ih264_list_lock(ps_list); RETURN_IF((rettmp != IH264_SUCCESS), rettmp); - - while(1) { /* Ensure wr idx does not go beyond rd idx by more than number of entries @@ -470,7 +463,6 @@ IH264_ERROR_T ih264_list_queue(list_t *ps_list, void *pv_buf, WORD32 blocking) break; } } - } ps_list->i4_terminate = 0; @@ -479,35 +471,32 @@ IH264_ERROR_T ih264_list_queue(list_t *ps_list, void *pv_buf, WORD32 blocking) return ret; } + /** ******************************************************************************* * -* @brief Gets next from the Job queue +* @brief Gets next job from the job queue * * @par Description -* Gets next buf from the buf queue and updates rd address to next location. -* Format/content of the buf structure is abstracted and hence size of the buf -* buffer is being passed. If it is a blocking call and if there is no new buf -* then this functions unlocks the mutex and calls yield and then locks it back. -* and continues till a buf is available or terminate is set +* Gets next job from the job queue and updates rd address to next location. +* If it is a blocking call and if there is no new buf then this functions +* unlocks the mutex and calls yield and then locks it back and continues +* till a buf is available or terminate is set * * @param[in] ps_list -* Job Queue context +* Pointer to Job Queue context * * @param[out] pv_buf -* Pointer to the location that contains details of the buf to be written -* -* @param[in] buf_size -* Size of the buf buffer +* Pointer to the location that contains details of the buf to be written * * @param[in] blocking -* To signal if the read is blocking or non-blocking. +* To signal if the read is blocking or non-blocking. * * @returns * * @remarks -* Job Queue buffer is assumed to be allocated to handle worst case number of bufs -* Wrap around is not supported +* Job Queue buffer is assumed to be allocated to handle worst case number of +* buffers. Wrap around is not supported * ******************************************************************************* */ @@ -517,7 +506,6 @@ IH264_ERROR_T ih264_list_dequeue(list_t *ps_list, void *pv_buf, WORD32 blocking) IH264_ERROR_T rettmp; WORD32 buf_size = ps_list->i4_entry_size; WORD32 diff; - void *pv_buf_rd; volatile WORD32 *pi4_wr_idx, *pi4_rd_idx; @@ -533,7 +521,6 @@ IH264_ERROR_T ih264_list_dequeue(list_t *ps_list, void *pv_buf, WORD32 blocking) pi4_rd_idx = &ps_list->i4_buf_rd_idx; diff = *pi4_wr_idx - *pi4_rd_idx; - if(diff > 0) { WORD32 rd_idx; @@ -563,10 +550,8 @@ IH264_ERROR_T ih264_list_dequeue(list_t *ps_list, void *pv_buf, WORD32 blocking) break; } } - } - rettmp = ih264_list_unlock(ps_list); RETURN_IF((rettmp != IH264_SUCCESS), rettmp); diff --git a/common/ih264_list.h b/common/ih264_list.h index fc59d95..4b97d59 100644 --- a/common/ih264_list.h +++ b/common/ih264_list.h @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,12 +27,10 @@ * Contains functions for buf queue * * @author -* Harish -* -* @par List of Functions: +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ @@ -39,6 +38,9 @@ #ifndef _IH264_LIST_H_ #define _IH264_LIST_H_ +/*****************************************************************************/ +/* Structure Definitions */ +/*****************************************************************************/ typedef struct { /** Pointer to buffer base which contains the bufs */ @@ -73,21 +75,29 @@ typedef struct * For eg: For picture level queues this can be a large value like 100us * but for jobq this will be zero. */ - WORD32 i4_yeild_interval_us; + WORD32 i4_yield_interval_us; }list_t; +/*****************************************************************************/ +/* Function Declarations */ +/*****************************************************************************/ WORD32 ih264_list_size(WORD32 num_entries, WORD32 entry_size); -void* ih264_list_init(void *pv_buf, - WORD32 buf_size, - WORD32 num_entries, - WORD32 entry_size, - WORD32 yeild_interval_us); + +void* ih264_list_init(void *pv_buf, WORD32 buf_size, WORD32 num_entries, + WORD32 entry_size, WORD32 yeild_interval_us); + IH264_ERROR_T ih264_list_free(list_t *ps_list); + IH264_ERROR_T ih264_list_reset(list_t *ps_list); + IH264_ERROR_T ih264_list_deinit(list_t *ps_list); + IH264_ERROR_T ih264_list_terminate(list_t *ps_list); + IH264_ERROR_T ih264_list_queue(list_t *ps_list, void *pv_buf, WORD32 blocking); -IH264_ERROR_T ih264_list_dequeue(list_t *ps_list, void *pv_buf, WORD32 blocking); -#endif /* _IH264_PROCESS_SLICE_H_ */ +IH264_ERROR_T ih264_list_dequeue(list_t *ps_list, void *pv_buf, + WORD32 blocking); + +#endif /* _IH264_LIST_H_ */ diff --git a/common/ih264_luma_intra_pred_filters.c b/common/ih264_luma_intra_pred_filters.c index 4a5b143..fc925ca 100644 --- a/common/ih264_luma_intra_pred_filters.c +++ b/common/ih264_luma_intra_pred_filters.c @@ -17,48 +17,48 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_luma_intra_pred_filters.c - * - * @brief - * Contains function definitions for intra prediction filters - * - * @author - * Ittiam - * - * @par List of Functions: - * - ih264_intra_pred_luma_4x4_mode_vert - * - ih264_intra_pred_luma_4x4_mode_horz - * - ih264_intra_pred_luma_4x4_mode_dc - * - ih264_intra_pred_luma_4x4_mode_diag_dl - * - ih264_intra_pred_luma_4x4_mode_diag_dr - * - ih264_intra_pred_luma_4x4_mode_vert_r - * - ih264_intra_pred_luma_4x4_mode_horz_d - * - ih264_intra_pred_luma_4x4_mode_vert_l - * - ih264_intra_pred_luma_4x4_mode_horz_u - * - ih264_intra_pred_luma_8x8_mode_ref_filtering - * - ih264_intra_pred_luma_8x8_mode_vert - * - ih264_intra_pred_luma_8x8_mode_horz - * - ih264_intra_pred_luma_8x8_mode_dc - * - ih264_intra_pred_luma_8x8_mode_diag_dl - * - ih264_intra_pred_luma_8x8_mode_diag_dr - * - ih264_intra_pred_luma_8x8_mode_vert_r - * - ih264_intra_pred_luma_8x8_mode_horz_d - * - ih264_intra_pred_luma_8x8_mode_vert_l - * - ih264_intra_pred_luma_8x8_mode_horz_u - * - ih264_intra_pred_luma_16x16_mode_vert - * - ih264_intra_pred_luma_16x16_mode_horz - * - ih264_intra_pred_luma_16x16_mode_dc - * - ih264_intra_pred_luma_16x16_mode_plane - * - * - * @remarks - * None - * - ****************************************************************************** - */ +******************************************************************************* +* @file +* ih264_luma_intra_pred_filters.c +* +* @brief +* Contains function definitions for intra prediction filters +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264_intra_pred_luma_4x4_mode_vert +* - ih264_intra_pred_luma_4x4_mode_horz +* - ih264_intra_pred_luma_4x4_mode_dc +* - ih264_intra_pred_luma_4x4_mode_diag_dl +* - ih264_intra_pred_luma_4x4_mode_diag_dr +* - ih264_intra_pred_luma_4x4_mode_vert_r +* - ih264_intra_pred_luma_4x4_mode_horz_d +* - ih264_intra_pred_luma_4x4_mode_vert_l +* - ih264_intra_pred_luma_4x4_mode_horz_u +* - ih264_intra_pred_luma_8x8_mode_ref_filtering +* - ih264_intra_pred_luma_8x8_mode_vert +* - ih264_intra_pred_luma_8x8_mode_horz +* - ih264_intra_pred_luma_8x8_mode_dc +* - ih264_intra_pred_luma_8x8_mode_diag_dl +* - ih264_intra_pred_luma_8x8_mode_diag_dr +* - ih264_intra_pred_luma_8x8_mode_vert_r +* - ih264_intra_pred_luma_8x8_mode_horz_d +* - ih264_intra_pred_luma_8x8_mode_vert_l +* - ih264_intra_pred_luma_8x8_mode_horz_u +* - ih264_intra_pred_luma_16x16_mode_vert +* - ih264_intra_pred_luma_16x16_mode_horz +* - ih264_intra_pred_luma_16x16_mode_dc +* - ih264_intra_pred_luma_16x16_mode_plane +* +* @remarks +* none +* +****************************************************************************** +*/ /*****************************************************************************/ /* File Includes */ @@ -69,63 +69,68 @@ #include <string.h> /* User include files */ -#include "ih264_defs.h" #include "ih264_typedefs.h" #include "ih264_macros.h" -#include "ih264_platform_macros.h" +#include "ih264_defs.h" #include "ih264_intra_pred_filters.h" +#include "ih264_platform_macros.h" -/* Global variables used only in assembly files*/ +/*****************************************************************************/ +/* Global definitions */ +/*****************************************************************************/ +/* Note: Global variables used only in assembly files */ const WORD8 ih264_gai1_intrapred_luma_plane_coeffs[] = -{ 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, }; +{ + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, +}; const WORD8 ih264_gai1_intrapred_luma_8x8_horz_u[] = -{ 0x06,0x15,0x05,0x14, - 0x04,0x13,0x03,0x12, - 0x02,0x11,0x01,0x10, - 0x00,0x1F,0x0F,0x0F +{ + 0x06, 0x15, 0x05, 0x14, + 0x04, 0x13, 0x03, 0x12, + 0x02, 0x11, 0x01, 0x10, + 0x00, 0x1F, 0x0F, 0x0F, }; -/******************* LUMA INTRAPREDICTION *******************/ -/******************* 4x4 Modes *******************/ +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ /** - ******************************************************************************* - * - *ih264_intra_pred_luma_4x4_mode_vert - * - * @brief - * Perform Intra prediction for luma_4x4 mode:vertical - * - * @par Description: - * Perform Intra prediction for luma_4x4 mode:vertical ,described in sec 8.3.1.2.1 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_4x4 mode:vertical +* +* @par Description: +* Perform Intra prediction for luma_4x4 mode:vertical, described in sec 8.3.1.2.1 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_4x4_mode_vert(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -133,10 +138,10 @@ void ih264_intra_pred_luma_4x4_mode_vert(UWORD8 *pu1_src, WORD32 ngbr_avail) { UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */ + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + BLK_SIZE + 1; - memcpy(pu1_dst, pu1_top, 4); memcpy(pu1_dst + dst_strd, pu1_top, 4); memcpy(pu1_dst + 2 * dst_strd, pu1_top, 4); @@ -144,38 +149,37 @@ void ih264_intra_pred_luma_4x4_mode_vert(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_4x4_mode_horz - * - * @brief - * Perform Intra prediction for luma_4x4 mode:horizontal - * - * @par Description: - * Perform Intra prediction for luma_4x4 mode:horizontal ,described in sec 8.3.1.2.2 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_4x4 mode:horizontal +* +* @par Description: +* Perform Intra prediction for luma_4x4 mode:horizontal, described in +* sec 8.3.1.2.2 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_4x4_mode_horz(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -187,7 +191,6 @@ void ih264_intra_pred_luma_4x4_mode_horz(UWORD8 *pu1_src, UNUSED(src_strd); UNUSED(ngbr_avail); pu1_left = pu1_src + BLK_SIZE - 1; - memset(pu1_dst, *pu1_left, 4); memset(pu1_dst + dst_strd, *(pu1_left - 1), 4); memset(pu1_dst + 2 * dst_strd, *(pu1_left - 2), 4); @@ -195,37 +198,36 @@ void ih264_intra_pred_luma_4x4_mode_horz(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_4x4_mode_dc - * - * @brief - * Perform Intra prediction for luma_4x4 mode:DC - * - * @par Description: - * Perform Intra prediction for luma_4x4 mode:DC ,described in sec 8.3.1.2.3 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_4x4 mode:DC +* +* @par Description: +* Perform Intra prediction for luma_4x4 mode:DC, described in sec 8.3.1.2.3 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_4x4_mode_dc(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -237,6 +239,7 @@ void ih264_intra_pred_luma_4x4_mode_dc(UWORD8 *pu1_src, UWORD8 *pu1_left = NULL; /* Pointer to start of left predictors */ UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */ WORD32 val = 0; + UNUSED(src_strd); UNUSED(ngbr_avail); u1_useleft = BOOLEAN(ngbr_avail & LEFT_MB_AVAILABLE_MASK); @@ -259,7 +262,6 @@ void ih264_intra_pred_luma_4x4_mode_dc(UWORD8 *pu1_src, /* Since 2 is added if either left/top pred is there, val still being zero implies both preds are not there */ val = (val) ? (val >> (1 + u1_useleft + u1_usetop)) : 128; - /* 4 bytes are copied from src to dst */ memset(pu1_dst, val, 4); memset(pu1_dst + dst_strd, val, 4); @@ -268,37 +270,37 @@ void ih264_intra_pred_luma_4x4_mode_dc(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_4x4_mode_diag_dl - * - * @brief - * Perform Intra prediction for luma_4x4 mode:Diagonal_Down_Left - * - * @par Description: - * Perform Intra prediction for luma_4x4 mode:Diagonal_Down_Left ,described in sec 8.3.1.2.4 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_4x4 mode:Diagonal_Down_Left +* +* @par Description: +* Perform Intra prediction for luma_4x4 mode:Diagonal_Down_Left, described in +* sec 8.3.1.2.4 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_4x4_mode_diag_dl(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -308,6 +310,7 @@ void ih264_intra_pred_luma_4x4_mode_diag_dl(UWORD8 *pu1_src, UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */ UWORD32 ui4_a, ui4_b, ui4_c, ui4_d, ui4_e, ui4_f, ui4_g, ui4_h; UWORD8 predicted_pixels[7]; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src +BLK_SIZE + 1; @@ -336,37 +339,37 @@ void ih264_intra_pred_luma_4x4_mode_diag_dl(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_4x4_mode_diag_dr - * - * @brief - * Perform Intra prediction for luma_4x4 mode:Diagonal_Down_Right - * - * @par Description: - * Perform Intra prediction for luma_4x4 mode:Diagonal_Down_Right ,described in sec 8.3.1.2.5 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_4x4 mode:Diagonal_Down_Right +* +* @par Description: +* Perform Intra prediction for luma_4x4 mode:Diagonal_Down_Right, described in +* sec 8.3.1.2.5 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_4x4_mode_diag_dr(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -378,6 +381,7 @@ void ih264_intra_pred_luma_4x4_mode_diag_dr(UWORD8 *pu1_src, UWORD8 *pu1_topleft = NULL;/* Pointer to top left predictor */ UWORD32 ui4_a, ui4_b, ui4_c, ui4_d, ui4_i, ui4_j, ui4_k, ui4_l, ui4_m; UWORD8 predicted_pixels[7]; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + BLK_SIZE + 1; @@ -409,37 +413,37 @@ void ih264_intra_pred_luma_4x4_mode_diag_dr(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_4x4_mode_vert_r - * - * @brief - * Perform Intra prediction for luma_4x4 mode:Vertical_Right - * - * @par Description: - * Perform Intra prediction for luma_4x4 mode:Vertical_Right ,described in sec 8.3.1.2.6 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_4x4 mode:Vertical_Right +* +* @par Description: +* Perform Intra prediction for luma_4x4 mode:Vertical_Right, described in +* sec 8.3.1.2.6 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_4x4_mode_vert_r(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -452,6 +456,7 @@ void ih264_intra_pred_luma_4x4_mode_vert_r(UWORD8 *pu1_src, UWORD8 *pu1_left = NULL; /* Pointer to start of left predictors */ UWORD8 *pu1_topleft = NULL;/* Pointer to top left predictor */ UWORD8 predicted_pixels[10]; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src +BLK_SIZE + 1; @@ -485,37 +490,37 @@ void ih264_intra_pred_luma_4x4_mode_vert_r(UWORD8 *pu1_src, } /* - ******************************************************************************* - * - *ih264_intra_pred_luma_4x4_mode_horz_d - * - * @brief - * Perform Intra prediction for luma_4x4 mode:Horizontal_Down - * - * @par Description: - * Perform Intra prediction for luma_4x4 mode:Horizontal_Down ,described in sec 8.3.1.2.7 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_4x4 mode:Horizontal_Down +* +* @par Description: +* Perform Intra prediction for luma_4x4 mode:Horizontal_Down, described in +* sec 8.3.1.2.7 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_4x4_mode_horz_d(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -527,6 +532,7 @@ void ih264_intra_pred_luma_4x4_mode_horz_d(UWORD8 *pu1_src, UWORD8 *pu1_topleft = NULL;/* Pointer to top left predictor */ UWORD32 ui4_a, ui4_b, ui4_c, ui4_i, ui4_j, ui4_k, ui4_l, ui4_m; UWORD8 predicted_pixels[10]; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + BLK_SIZE + 1; @@ -560,37 +566,37 @@ void ih264_intra_pred_luma_4x4_mode_horz_d(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_4x4_mode_vert_l - * - * @brief - * Perform Intra prediction for luma_4x4 mode:Vertical_Left - * - * @par Description: - * Perform Intra prediction for luma_4x4 mode:Vertical_Left ,described in sec 8.3.1.2.8 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_4x4 mode:Vertical_Left +* +* @par Description: +* Perform Intra prediction for luma_4x4 mode:Vertical_Left, described in +* sec 8.3.1.2.8 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_4x4_mode_vert_l(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -600,6 +606,7 @@ void ih264_intra_pred_luma_4x4_mode_vert_l(UWORD8 *pu1_src, UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */ UWORD32 ui4_a, ui4_b, ui4_c, ui4_d, ui4_e, ui4_f, ui4_g; UWORD8 predicted_pixels[10]; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + BLK_SIZE + 1; @@ -630,37 +637,37 @@ void ih264_intra_pred_luma_4x4_mode_vert_l(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_4x4_mode_horz_u - * - * @brief - * Perform Intra prediction for luma_4x4 mode:Horizontal_Up - * - * @par Description: - * Perform Intra prediction for luma_4x4 mode:Horizontal_Up ,described in sec 8.3.1.2.9 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_4x4 mode:Horizontal_Up +* +* @par Description: +* Perform Intra prediction for luma_4x4 mode:Horizontal_Up, described in +* sec 8.3.1.2.9 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_4x4_mode_horz_u(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -670,6 +677,7 @@ void ih264_intra_pred_luma_4x4_mode_horz_u(UWORD8 *pu1_src, UWORD8 *pu1_left = NULL; /* Pointer to start of left predictors */ UWORD32 ui4_i, ui4_j, ui4_k, ui4_l; UWORD8 predicted_pixels[10]; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_left = pu1_src + BLK_SIZE - 1; @@ -696,46 +704,45 @@ void ih264_intra_pred_luma_4x4_mode_horz_u(UWORD8 *pu1_src, memcpy(pu1_dst + 3 * dst_strd, predicted_pixels + 6, 4); } -/******************* 8x8 Modes *******************/ - /** - ******************************************************************************* - * - *ih264_intra_pred_luma_8x8_mode_ref_filtering - * - * @brief - * Reference sample filtering process for Intra_8x8 sample prediction - * - * @par Description: - * Perform Reference sample filtering process for Intra_8x8 sample prediction ,described in sec 8.3.2.2.1 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride[Not Used] - * - * @param[in] dst_strd - * integer destination stride[Not Used] - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Reference sample filtering process for Intra_8x8 sample prediction +* +* @par Description: +* Perform Reference sample filtering process for Intra_8x8 sample prediction, +* described in sec 8.3.2.2.1 +* +* @param[in] pu1_left +* pointer to the left pixel wrt current mb +* +* @param[in] pu1_topleft +* pointer to the topleft pixel wrt current mb +* +* @param[in] pu1_top +* pointer to the top pixel wrt current mb +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride[Not Used] +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +*******************************************************************************/ void ih264_intra_pred_luma_8x8_mode_ref_filtering(UWORD8 *pu1_left, UWORD8 *pu1_topleft, UWORD8 *pu1_top, UWORD8 *pu1_dst, - WORD32 left_strd, + WORD32 src_strd, WORD32 ngbr_avail) { WORD32 top_avail, left_avail, top_left_avail, top_right_avail; @@ -764,7 +771,6 @@ void ih264_intra_pred_luma_8x8_mode_ref_filtering(UWORD8 *pu1_left, { pu1_dst[8 + 1 + 0] = FILT121((*pu1_topleft), pu1_top[0], pu1_top[1]); - } else { @@ -775,7 +781,6 @@ void ih264_intra_pred_luma_8x8_mode_ref_filtering(UWORD8 *pu1_left, { pu1_dst[8 + 1 + i] = FILT121(pu1_top[i - 1], pu1_top[i], pu1_top[i + 1]); - } /* First byte of Top Right input is in pu1_dst[8 + 1 + 8]*/ pu1_dst[8 + 1 + 7] = FILT121(pu1_top[6], pu1_top[7], @@ -796,7 +801,6 @@ void ih264_intra_pred_luma_8x8_mode_ref_filtering(UWORD8 *pu1_left, } pu1_dst[8 + 1 + 15] = (u4_xm1 + (3 * pu1_dst[8 + 1 + 15]) + 2) >> 2; - } /* pu1_topleft is overloaded. It is both: */ @@ -824,59 +828,57 @@ void ih264_intra_pred_luma_8x8_mode_ref_filtering(UWORD8 *pu1_left, if(0 != pu1_topleft) { pu1_dst[7] = FILT121((*pu1_topleft), pu1_left[0], - pu1_left[left_strd]); + pu1_left[src_strd]); } else { - pu1_dst[7] = ((3 * pu1_left[0]) + pu1_left[left_strd] + 2) >> 2; + pu1_dst[7] = ((3 * pu1_left[0]) + pu1_left[src_strd] + 2) >> 2; } for(idx = 1; idx <= 6; idx++) { - pu1_dst[7 - idx] = FILT121(pu1_left[(idx - 1) * left_strd], - pu1_left[idx * left_strd], - pu1_left[(idx + 1) * left_strd]); + pu1_dst[7 - idx] = FILT121(pu1_left[(idx - 1) * src_strd], + pu1_left[idx * src_strd], + pu1_left[(idx + 1) * src_strd]); } - pu1_dst[0] = (pu1_left[6 * left_strd] + 3 * pu1_left[7 * left_strd] + 2) + pu1_dst[0] = (pu1_left[6 * src_strd] + 3 * pu1_left[7 * src_strd] + 2) >> 2; - } } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_8x8_mode_vert - * - * @brief - * Perform Intra prediction for luma_8x8 mode:vertical - * - * @par Description: - * Perform Intra prediction for luma_8x8 mode:vertical ,described in sec 8.3.2.2.2 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_8x8 mode:vertical +* +* @par Description: +* Perform Intra prediction for luma_8x8 mode:vertical, described in +* sec 8.3.2.2.2 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_8x8_mode_vert(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -884,6 +886,7 @@ void ih264_intra_pred_luma_8x8_mode_vert(UWORD8 *pu1_src, WORD32 ngbr_avail) { UWORD8 *pu1_top = NULL; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + BLK8x8SIZE + 1; @@ -899,39 +902,37 @@ void ih264_intra_pred_luma_8x8_mode_vert(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_8x8_mode_horz - * - * @brief - * Perform Intra prediction for luma_8x8 mode:horizontal - * - * @par Description: - * Perform Intra prediction for luma_8x8 mode:horizontal ,described in sec 8.3.2.2.2 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ - +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_8x8 mode:horizontal +* +* @par Description: +* Perform Intra prediction for luma_8x8 mode:horizontal, described in +* sec 8.3.2.2.2 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_8x8_mode_horz(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -939,6 +940,7 @@ void ih264_intra_pred_luma_8x8_mode_horz(UWORD8 *pu1_src, WORD32 ngbr_avail) { UWORD8 *pu1_left = pu1_src + BLK8x8SIZE - 1; + UNUSED(src_strd); UNUSED(ngbr_avail); memset(pu1_dst, *pu1_left, 8); @@ -952,37 +954,36 @@ void ih264_intra_pred_luma_8x8_mode_horz(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_8x8_mode_dc - * - * @brief - * Perform Intra prediction for luma_8x8 mode:DC - * - * @par Description: - * Perform Intra prediction for luma_8x8 mode:DC ,described in sec 8.3.2.2.4 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_8x8 mode:DC +* +* @par Description: +* Perform Intra prediction for luma_8x8 mode:DC, described in sec 8.3.2.2.4 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_8x8_mode_dc(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -995,8 +996,8 @@ void ih264_intra_pred_luma_8x8_mode_dc(UWORD8 *pu1_src, UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */ WORD32 row; WORD32 val = 0; - UNUSED(src_strd); + UNUSED(src_strd); u1_useleft = BOOLEAN(ngbr_avail & LEFT_MB_AVAILABLE_MASK); u1_usetop = BOOLEAN(ngbr_avail & TOP_MB_AVAILABLE_MASK); pu1_top = pu1_src + BLK8x8SIZE + 1; @@ -1030,37 +1031,37 @@ void ih264_intra_pred_luma_8x8_mode_dc(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_8x8_mode_diag_dl - * - * @brief - * Perform Intra prediction for luma_8x8 mode:Diagonal_Down_Left - * - * @par Description: - * Perform Intra prediction for luma_8x8 mode:Diagonal_Down_Left ,described in sec 8.3.2.2.5 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_8x8 mode:Diagonal_Down_Left +* +* @par Description: +* Perform Intra prediction for luma_8x8 mode:Diagonal_Down_Left, described in +* sec 8.3.2.2.5 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_8x8_mode_diag_dl(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -1071,6 +1072,7 @@ void ih264_intra_pred_luma_8x8_mode_diag_dl(UWORD8 *pu1_src, UWORD32 ui4_a, ui4_b, ui4_c, ui4_d, ui4_e, ui4_f, ui4_g, ui4_h; UWORD32 ui4_i, ui4_j, ui4_k, ui4_l, ui4_m, ui4_n, ui4_o, ui4_p; UWORD8 predicted_pixels[15]; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + BLK8x8SIZE + 1; @@ -1119,37 +1121,37 @@ void ih264_intra_pred_luma_8x8_mode_diag_dl(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_8x8_mode_diag_dr - * - * @brief - * Perform Intra prediction for luma_8x8 mode:Diagonal_Down_Right - * - * @par Description: - * Perform Intra prediction for luma_8x8 mode:Diagonal_Down_Right ,described in sec 8.3.2.2.6 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_8x8 mode:Diagonal_Down_Right +* +* @par Description: +* Perform Intra prediction for luma_8x8 mode:Diagonal_Down_Right, described +* in sec 8.3.2.2.6 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_8x8_mode_diag_dr(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -1163,6 +1165,7 @@ void ih264_intra_pred_luma_8x8_mode_diag_dr(UWORD8 *pu1_src, UWORD32 ui4_b, ui4_c, ui4_d, ui4_e, ui4_f, ui4_g, ui4_h, ui4_i; UWORD32 ui4_j, ui4_k, ui4_l, ui4_m, ui4_n, ui4_o, ui4_p, ui4_q; UWORD8 predicted_pixels[15]; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + BLK8x8SIZE + 1; @@ -1214,37 +1217,37 @@ void ih264_intra_pred_luma_8x8_mode_diag_dr(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_8x8_mode_vert_r - * - * @brief - * Perform Intra prediction for luma_8x8 mode:Vertical_Right - * - * @par Description: - * Perform Intra prediction for luma_8x8 mode:Vertical_Right ,described in sec 8.3.2.2.7 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_8x8 mode:Vertical_Right +* +* @par Description: +* Perform Intra prediction for luma_8x8 mode:Vertical_Right, described in +* sec 8.3.2.2.7 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_8x8_mode_vert_r(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -1314,42 +1317,40 @@ void ih264_intra_pred_luma_8x8_mode_vert_r(UWORD8 *pu1_src, memcpy(pu1_dst + 5 * dst_strd, predicted_pixels + 12, 8); memcpy(pu1_dst + 6 * dst_strd, predicted_pixels, 8); memcpy(pu1_dst + 7 * dst_strd, predicted_pixels + 11, 8); - } -/* - ******************************************************************************* - * - *ih264_intra_pred_luma_8x8_mode_horz_d - * - * @brief - * Perform Intra prediction for luma_8x8 mode:Horizontal_Down - * - * @par Description: - * Perform Intra prediction for luma_8x8 mode:Horizontal_Down ,described in sec 8.3.2.2.8 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ - +/** +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_8x8 mode:Horizontal_Down +* +* @par Description: +* Perform Intra prediction for luma_8x8 mode:Horizontal_Down, described in +* sec 8.3.2.2.8 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_8x8_mode_horz_d(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -1363,6 +1364,7 @@ void ih264_intra_pred_luma_8x8_mode_horz_d(UWORD8 *pu1_src, UWORD32 ui4_b, ui4_c, ui4_d, ui4_e, ui4_f, ui4_g, ui4_h, ui4_i; UWORD32 ui4_j, ui4_k, ui4_l, ui4_m, ui4_n, ui4_o, ui4_p; UWORD8 predicted_pixels[22]; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + BLK8x8SIZE + 1; @@ -1420,37 +1422,37 @@ void ih264_intra_pred_luma_8x8_mode_horz_d(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_8x8_mode_vert_l - * - * @brief - * Perform Intra prediction for luma_8x8 mode:Vertical_Left - * - * @par Description: - * Perform Intra prediction for luma_8x8 mode:Vertical_Left ,described in sec 8.3.2.2.9 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_8x8 mode:Vertical_Left +* +* @par Description: +* Perform Intra prediction for luma_8x8 mode:Vertical_Left, described in +* sec 8.3.2.2.9 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_8x8_mode_vert_l(UWORD8 *pu1_src, UWORD8 *pu1_dst, @@ -1462,6 +1464,7 @@ void ih264_intra_pred_luma_8x8_mode_vert_l(UWORD8 *pu1_src, UWORD32 ui4_a, ui4_b, ui4_c, ui4_d, ui4_e, ui4_f, ui4_g, ui4_h; UWORD32 ui4_i, ui4_j, ui4_k, ui4_l, ui4_m; UWORD8 predicted_pixels[22]; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + BLK8x8SIZE + 1; @@ -1514,48 +1517,47 @@ void ih264_intra_pred_luma_8x8_mode_vert_l(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_8x8_mode_horz_u - * - * @brief - * Perform Intra prediction for luma_8x8 mode:Horizontal_Up - * - * @par Description: - * Perform Intra prediction for luma_8x8 mode:Horizontal_Up ,described in sec 8.3.2.2.10 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ - +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_8x8 mode:Horizontal_Up +* +* @par Description: +* Perform Intra prediction for luma_8x8 mode:Horizontal_Up, described in +* sec 8.3.2.2.10 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_8x8_mode_horz_u(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, WORD32 dst_strd, WORD32 ngbr_avail) - { UWORD8 *pu1_left = NULL; /* Pointer to start of left predictors */ UWORD32 ui4_j, ui4_k, ui4_l, ui4_m, ui4_n, ui4_o, ui4_p, ui4_q; UWORD8 predicted_pixels[22]; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_left = pu1_src + BLK8x8SIZE - 1; @@ -1597,42 +1599,38 @@ void ih264_intra_pred_luma_8x8_mode_horz_u(UWORD8 *pu1_src, memcpy(pu1_dst + 7 * dst_strd, predicted_pixels + 14, 8); } - -/******************* 16x16 Modes *******************/ - /** - ******************************************************************************* - * - *ih264_intra_pred_luma_16x16_mode_vert - * - * @brief - * Perform Intra prediction for luma_16x16 mode:Vertical - * - * @par Description: - * Perform Intra prediction for luma_16x16 mode:Vertical, described in sec 8.3.3.1 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels (Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ - +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_16x16 mode:Vertical +* +* @par Description: +* Perform Intra prediction for luma_16x16 mode:Vertical, described in +* sec 8.3.3.1 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_16x16_mode_vert(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -1641,10 +1639,10 @@ void ih264_intra_pred_luma_16x16_mode_vert(UWORD8 *pu1_src, { UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */ WORD32 rows; /* loop variables*/ + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + MB_SIZE + 1; - for(rows = 0; rows < 16; rows += 4, pu1_dst += dst_strd) { memcpy(pu1_dst, pu1_top, 16); @@ -1658,38 +1656,37 @@ void ih264_intra_pred_luma_16x16_mode_vert(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_16x16_mode_horz - * - * @brief - * Perform Intra prediction for luma_16x16 mode:Horizontal - * - * @par Description: - * Perform Intra prediction for luma_16x16 mode:Horizontal, described in sec 8.3.3.2 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ - +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_16x16 mode:Horizontal +* +* @par Description: +* Perform Intra prediction for luma_16x16 mode:Horizontal, described in +* sec 8.3.3.2 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_16x16_mode_horz(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -1698,10 +1695,10 @@ void ih264_intra_pred_luma_16x16_mode_horz(UWORD8 *pu1_src, { UWORD8 *pu1_left = NULL; /* Pointer to start of top predictors */ WORD32 rows; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_left = pu1_src + MB_SIZE - 1; - for(rows = 0; rows < 16; rows += 4, pu1_dst += dst_strd, pu1_left --) { memset(pu1_dst, *pu1_left, 16); /* copy the left value to the entire row*/ @@ -1718,38 +1715,36 @@ void ih264_intra_pred_luma_16x16_mode_horz(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_16x16_mode_dc - * - * @brief - * Perform Intra prediction for luma_16x16 mode:DC - * - * @par Description: - * Perform Intra prediction for luma_16x16 mode:DC, described in sec 8.3.3.3 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - ** @param[in] ngbr_avail - * availability of neighbouring pixels - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ - +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_16x16 mode:DC +* +* @par Description: +* Perform Intra prediction for luma_16x16 mode:DC, described in sec 8.3.3.3 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_16x16_mode_dc(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -1762,8 +1757,8 @@ void ih264_intra_pred_luma_16x16_mode_dc(UWORD8 *pu1_src, UWORD8 *pu1_top = NULL; /* Pointer to start of top predictors */ WORD32 rows; /* loop variables*/ WORD32 val = 0; - UNUSED(src_strd); + UNUSED(src_strd); u1_useleft = BOOLEAN(ngbr_avail & LEFT_MB_AVAILABLE_MASK); u1_usetop = BOOLEAN(ngbr_avail & TOP_MB_AVAILABLE_MASK); pu1_top = pu1_src + MB_SIZE + 1; @@ -1797,38 +1792,36 @@ void ih264_intra_pred_luma_16x16_mode_dc(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - *ih264_intra_pred_luma_16x16_mode_plane - * - * @brief - * Perform Intra prediction for luma_16x16 mode:PLANE - * - * @par Description: - * Perform Intra prediction for luma_16x16 mode:PLANE, described in sec 8.3.3.4 - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[out] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] src_strd - * integer source stride - * - * @param[in] dst_strd - * integer destination stride - * - * @param[in] ngbr_avail - * availability of neighbouring pixels(Not used in this function) - * - * @returns - * - * @remarks - * None - * - *******************************************************************************/ - +******************************************************************************* +* +* @brief +* Perform Intra prediction for luma_16x16 mode:PLANE +* +* @par Description: +* Perform Intra prediction for luma_16x16 mode:PLANE, described in sec 8.3.3.4 +* +* @param[in] pu1_src +* pointer to the source +* +* @param[out] pu1_dst +* pointer to the destination +* +* @param[in] src_strd +* source stride +* +* @param[in] dst_strd +* destination stride +* +* @param[in] ngbr_avail +* availability of neighbouring pixels +* +* @returns +* +* @remarks +* none +* +******************************************************************************* +*/ void ih264_intra_pred_luma_16x16_mode_plane(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -1842,6 +1835,7 @@ void ih264_intra_pred_luma_16x16_mode_plane(UWORD8 *pu1_src, WORD32 a, b, c, tmp; UWORD8 *pu1_tmp1, *pu1_tmp2; WORD32 shift; + UNUSED(src_strd); UNUSED(ngbr_avail); pu1_top = pu1_src + MB_SIZE + 1; diff --git a/common/ih264_macros.h b/common/ih264_macros.h index 969012f..9b95eff 100644 --- a/common/ih264_macros.h +++ b/common/ih264_macros.h @@ -18,7 +18,8 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ -/********************************************************************************* +/** +********************************************************************************** * @file * ih264_macros.h * @@ -26,13 +27,14 @@ * Macro definitions used in the codec * * @author -* Ittiam +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ + #ifndef _IH264_MACROS_H_ #define _IH264_MACROS_H_ @@ -105,6 +107,7 @@ #define GET_BIT(x, pos) ((x) >> (pos)) & 0x1 #define INSERT_BIT(x, pos, bit) { RESET_BIT(x, pos); (x) = (x) | (bit << pos); } -#endif /*_IH264_MACROS_H_*/ + +#endif /*_IH264_MACROS_H_ */ diff --git a/common/ih264_mem_fns.c b/common/ih264_mem_fns.c index 1c1f328..66a0947 100644 --- a/common/ih264_mem_fns.c +++ b/common/ih264_mem_fns.c @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,18 +27,18 @@ * Functions used for memory operations * * @author - * Ittiam + * ittiam * * @par List of Functions: - * ih264_memcpy() - * ih264_memcpy_mul_8() - * ih264_memset() - * ih264_memset_mul_8() - * ih264_memset_16bit() - * ih264_memset_16bit_mul_8() + * ih264_memcpy + * ih264_memcpy_mul_8 + * ih264_memset + * ih264_memset_mul_8 + * ih264_memset_16bit + * ih264_memset_16bit_mul_8 * * @remarks - * None + * none * ****************************************************************************** */ @@ -45,118 +46,116 @@ /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* System include files */ + +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <string.h> #include <assert.h> - -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" + +#include "ih264_debug.h" #include "ih264_mem_fns.h" /** - ******************************************************************************* - * - * @brief - * memcpy of a 8,16 or 32 bytes - * - * @par Description: - * Does memcpy of 8bit data from source to destination for 8,16 or 32 number of bytes - * - * @param[in] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] pu1_src - * UWORD8 pointer to the source - * - * @param[in] num_bytes - * number of bytes to copy - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ - +******************************************************************************* +* +* @brief memcpy of a 8,16 or 32 bytes +* +* @par Description +* Does memcpy of 8bit data from source to destination for 8,16 or 32 number of +* bytes +* +* @param[in] pu1_dst +* pointer to the destination +* +* @param[in] pu1_src +* pointer to the source +* +* @param[in] num_bytes +* number of bytes to copy +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_memcpy(UWORD8 *pu1_dst, UWORD8 *pu1_src, UWORD32 num_bytes) { memcpy(pu1_dst, pu1_src, num_bytes); } - void ih264_memcpy_mul_8(UWORD8 *pu1_dst, UWORD8 *pu1_src, UWORD32 num_bytes) { + ASSERT(num_bytes % 8 == 0); memcpy(pu1_dst, pu1_src, num_bytes); } /** - ******************************************************************************* - * - * @brief - * memset of a 8,16 or 32 bytes - * - * @par Description: - * Does memset of 8bit data for 8,16 or 32 number of bytes - * - * @param[in] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] value - * UWORD8 value used for memset - * - * @param[in] num_bytes - * number of bytes to set - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ - +******************************************************************************* +* +* @brief memset of a 8,16 or 32 bytes +* +* @par Description +* Does memset of 8bit data for 8,16 or 32 number of bytes +* +* @param[in] pu1_dst +* pointer to the destination +* +* @param[in] value +* value used for memset +* +* @param[in] num_bytes +* number of bytes to set +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_memset(UWORD8 *pu1_dst, UWORD8 value, UWORD32 num_bytes) { memset(pu1_dst, value, num_bytes); } - void ih264_memset_mul_8(UWORD8 *pu1_dst, UWORD8 value, UWORD32 num_bytes) { + ASSERT(num_bytes % 8 == 0); memset(pu1_dst, value, num_bytes); } /** - ******************************************************************************* - * - * @brief - * memset of 16bit data of a 8,16 or 32 bytes - * - * @par Description: - * Does memset of 16bit data for 8,16 or 32 number of bytes - * - * @param[in] pu2_dst - * UWORD8 pointer to the destination - * - * @param[in] value - * UWORD16 value used for memset - * - * @param[in] num_words - * number of words to set - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ - +******************************************************************************* +* +* @brief memset of 16bit data of a 8,16 or 32 bytes +* +* @par Description +* Does memset of 16bit data for 8,16 or 32 number of bytes +* +* @param[in] pu2_dst +* pointer to the destination +* +* @param[in] value +* value used for memset +* +* @param[in] num_words +* number of words to set +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_memset_16bit(UWORD16 *pu2_dst, UWORD16 value, UWORD32 num_words) { UWORD32 i; + for(i = 0; i < num_words; i++) { *pu2_dst++ = value; @@ -168,6 +167,8 @@ void ih264_memset_16bit_mul_8(UWORD16 *pu2_dst, UWORD32 num_words) { UWORD32 i; + + ASSERT(num_words % 8 == 0); for(i = 0; i < num_words; i++) { *pu2_dst++ = value; diff --git a/common/ih264_mem_fns.h b/common/ih264_mem_fns.h index e0167f4..a951b3c 100644 --- a/common/ih264_mem_fns.h +++ b/common/ih264_mem_fns.h @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -26,74 +27,37 @@ * Function declarations used for memory functions * * @author -* Ittiam +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ + #ifndef _IH264_MEM_FNS_H_ #define _IH264_MEM_FNS_H_ -typedef void ih264_memcpy_ft(UWORD8 *pu1_dst, UWORD8 *pu1_src, UWORD32 num_bytes); +/*****************************************************************************/ +/* Extern Function Declarations */ +/*****************************************************************************/ +typedef void ih264_memcpy_ft(UWORD8 *pu1_dst, UWORD8 *pu1_src, + UWORD32 num_bytes); -typedef void ih264_memcpy_mul_8_ft(UWORD8 *pu1_dst, UWORD8 *pu1_src, UWORD32 num_bytes); -/** - ******************************************************************************* - * - * @brief - * memset of a 8,16 or 32 bytes - * - * @par Description: - * Does memset of 8bit data for 8,16 or 32 number of bytes - * - * @param[in] pu1_dst - * UWORD8 pointer to the destination - * - * @param[in] value - * UWORD8 value used for memset - * - * @param[in] num_bytes - * number of bytes to set - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ -typedef void ih264_memset_ft(UWORD8 *pu1_dst, UWORD8 value, UWORD32 num_bytes); +typedef void ih264_memcpy_mul_8_ft(UWORD8 *pu1_dst, UWORD8 *pu1_src, + UWORD32 num_bytes); -typedef void ih264_memset_mul_8_ft(UWORD8 *pu1_dst, UWORD8 value, UWORD32 num_bytes); +typedef void ih264_memset_ft(UWORD8 *pu1_dst, UWORD8 value, + UWORD32 num_bytes); -/** - ******************************************************************************* - * - * @brief - * memset of 16bit data of a 8,16 or 32 bytes - * - * @par Description: - * Does memset of 16bit data for 8,16 or 32 number of bytes - * - * @param[in] pu2_dst - * UWORD8 pointer to the destination - * - * @param[in] value - * UWORD16 value used for memset - * - * @param[in] num_words - * number of words to set - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ -typedef void ih264_memset_16bit_ft(UWORD16 *pu2_dst, UWORD16 value, UWORD32 num_words); +typedef void ih264_memset_mul_8_ft(UWORD8 *pu1_dst, UWORD8 value, + UWORD32 num_bytes); + +typedef void ih264_memset_16bit_ft(UWORD16 *pu2_dst, UWORD16 value, + UWORD32 num_words); -typedef void ih264_memset_16bit_mul_8_ft(UWORD16 *pu2_dst, UWORD16 value, UWORD32 num_words); +typedef void ih264_memset_16bit_mul_8_ft(UWORD16 *pu2_dst, UWORD16 value, + UWORD32 num_words); /* C function declarations */ ih264_memcpy_ft ih264_memcpy; @@ -119,8 +83,9 @@ ih264_memset_mul_8_ft ih264_memset_mul_8_av8; ih264_memset_16bit_ft ih264_memset_16bit_av8; ih264_memset_16bit_mul_8_ft ih264_memset_16bit_mul_8_av8; - +/*SSSE3 Declarations*/ ih264_memcpy_mul_8_ft ih264_memcpy_mul_8_ssse3; ih264_memset_mul_8_ft ih264_memset_mul_8_ssse3; ih264_memset_16bit_mul_8_ft ih264_memset_16bit_mul_8_ssse3; -#endif //_MEM_FNS_H_ + +#endif /* _IH264_MEM_FNS_H_ */ diff --git a/common/ih264_padding.c b/common/ih264_padding.c index 8e8f3e2..075187b 100644 --- a/common/ih264_padding.c +++ b/common/ih264_padding.c @@ -27,18 +27,18 @@ * Contains function definitions for Padding * * @author -* Ittiam +* ittiam * * @par List of Functions: -* - ih264_pad_top() -* - ih264_pad_bottom() -* - ih264_pad_left_luma() -* - ih264_pad_left_chroma() -* - ih264_pad_right_luma() -* - ih264_pad_right_chroma() +* - ih264_pad_top +* - ih264_pad_bottom +* - ih264_pad_left_luma +* - ih264_pad_left_chroma +* - ih264_pad_right_luma +* - ih264_pad_right_chroma * * @remarks -* None +* none * ******************************************************************************* */ @@ -47,11 +47,11 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stddef.h> #include <string.h> -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "ih264_macros.h" #include "ih264_padding.h" @@ -70,16 +70,16 @@ * The top row of a 2d array is replicated for pad_size times at the top * * @param[in] pu1_src -* UWORD8 pointer to the source +* pointer to the source * * @param[in] src_strd -* integer source stride +* source stride * * @param[in] wd -* integer width of the array +* width of the array * * @param[in] pad_size -* integer -padding size of the array +* padding size of the array * * @returns none * @@ -100,8 +100,6 @@ void ih264_pad_top(UWORD8 *pu1_src, } } - - /** ******************************************************************************* * @@ -111,16 +109,16 @@ void ih264_pad_top(UWORD8 *pu1_src, * The bottom row of a 2d array is replicated for pad_size times at the bottom * * @param[in] pu1_src -* UWORD8 pointer to the source +* pointer to the source * * @param[in] src_strd -* integer source stride +* source stride * * @param[in] wd -* integer width of the array +* width of the array * * @param[in] pad_size -* integer -padding size of the array +* padding size of the array * * @returns none * @@ -147,26 +145,26 @@ void ih264_pad_bottom(UWORD8 *pu1_src, * @brief pad (luma block) at the left of a 2d array * * @par Description: -* The left column of a 2d array is replicated for pad_size times to the left +* The left column of a 2d array is replicated for pad_size times to the left * * @param[in] pu1_src -* UWORD8 pointer to the source +* pointer to the source * * @param[in] src_strd -* integer source stride +* source stride * * @param[in] ht -* integer height of the array +* height of the array * * @param[in] pad_size -* integer -padding size of the array +* padding size of the array * * @returns none * * @remarks none * ******************************************************************************* - */ +*/ void ih264_pad_left_luma(UWORD8 *pu1_src, WORD32 src_strd, WORD32 ht, @@ -176,9 +174,7 @@ void ih264_pad_left_luma(UWORD8 *pu1_src, for(row = 0; row < ht; row++) { - memset(pu1_src - pad_size, *pu1_src, pad_size); - pu1_src += src_strd; } } @@ -189,19 +185,19 @@ void ih264_pad_left_luma(UWORD8 *pu1_src, * @brief pad (chroma block) at the left of a 2d array * * @par Description: -* The left column of a 2d array is replicated for pad_size times to the left +* The left column of a 2d array is replicated for pad_size times to the left * * @param[in] pu1_src -* UWORD8 pointer to the source +* pointer to the source * * @param[in] src_strd -* integer source stride +* source stride * * @param[in] ht -* integer height of the array +* height of the array * * @param[in] pad_size -* integer -padding size of the array +* padding size of the array * * @returns none * @@ -214,11 +210,8 @@ void ih264_pad_left_chroma(UWORD8 *pu1_src, WORD32 ht, WORD32 pad_size) { - /* temp var */ WORD32 row, col; UWORD16 u2_uv_val; - - /* pointer to src */ UWORD16 *pu2_src = (UWORD16 *)pu1_src; src_strd >>= 1; @@ -227,12 +220,10 @@ void ih264_pad_left_chroma(UWORD8 *pu1_src, for(row = 0; row < ht; row++) { u2_uv_val = pu2_src[0]; - - for (col = -pad_size; col < 0; col++) + for(col = -pad_size; col < 0; col++) { pu2_src[col] = u2_uv_val; } - pu2_src += src_strd; } } @@ -246,16 +237,16 @@ void ih264_pad_left_chroma(UWORD8 *pu1_src, * The right column of a 2d array is replicated for pad_size times at the right * * @param[in] pu1_src -* UWORD8 pointer to the source +* pointer to the source * * @param[in] src_strd -* integer source stride +* source stride * * @param[in] ht -* integer height of the array +* height of the array * * @param[in] pad_size -* integer -padding size of the array +* padding size of the array * * @returns none * @@ -273,7 +264,6 @@ void ih264_pad_right_luma(UWORD8 *pu1_src, for(row = 0; row < ht; row++) { memset(pu1_src, *(pu1_src -1), pad_size); - pu1_src += src_strd; } } @@ -287,16 +277,16 @@ void ih264_pad_right_luma(UWORD8 *pu1_src, * The right column of a 2d array is replicated for pad_size times at the right * * @param[in] pu1_src -* UWORD8 pointer to the source +* pointer to the source * * @param[in] src_strd -* integer source stride +* source stride * * @param[in] ht -* integer height of the array +* height of the array * * @param[in] pad_size -* integer -padding size of the array +* padding size of the array * * @returns none * @@ -319,12 +309,10 @@ void ih264_pad_right_chroma(UWORD8 *pu1_src, for(row = 0; row < ht; row++) { u2_uv_val = pu2_src[-1]; - - for (col = 0; col < pad_size; col++) + for(col = 0; col < pad_size; col++) { pu2_src[col] = u2_uv_val; } - pu2_src += src_strd; } } diff --git a/common/ih264_padding.h b/common/ih264_padding.h index e4e18fb..1f9a846 100644 --- a/common/ih264_padding.h +++ b/common/ih264_padding.h @@ -24,16 +24,17 @@ * ih264_padding.h * * @brief -* Declarations for padding functions +* Declarations of padding functions * * @author -* Ittiam +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ + #ifndef _IH264_PADDING_H_ #define _IH264_PADDING_H_ @@ -65,10 +66,10 @@ ih264_pad ih264_pad_left_chroma_av8; ih264_pad ih264_pad_right_luma_av8; ih264_pad ih264_pad_right_chroma_av8; - +/* SSSE3 Declarations */ ih264_pad ih264_pad_left_luma_ssse3; ih264_pad ih264_pad_left_chroma_ssse3; ih264_pad ih264_pad_right_luma_ssse3; ih264_pad ih264_pad_right_chroma_ssse3; -#endif /*_IH264_PADDING_H_*/ +#endif /* _IH264_PADDING_H_ */ diff --git a/common/ih264_resi_trans_quant.c b/common/ih264_resi_trans_quant.c index a17b078..0e1b794 100644 --- a/common/ih264_resi_trans_quant.c +++ b/common/ih264_resi_trans_quant.c @@ -17,98 +17,104 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_resi_trans_quant.c - * - * @brief - * Contains function definitions single stage forward transform for H.264 - * It will calculate the residue, do the cf and then do quantization - * - * @author - * Ittiam - * - * @par List of Functions: - * - ih264_resi_trans_quant_4x4() - * - ih264_resi_trans_quant_chroma_4x4 - * - ih264_hadamard_quant_4x4 - * - ih264_hadamard_quant_2x2_uv - * - ih264_resi_trans_quant_8x8 - * - * @remarks - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_resi_trans_quant.c +* +* @brief +* Contains function definitions single stage forward transform for H.264 +* It will calculate the residue, do the cf and then do quantization +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264_resi_trans_quant_4x4 +* - ih264_resi_trans_quant_chroma_4x4 +* - ih264_hadamard_quant_4x4 +* - ih264_hadamard_quant_2x2_uv +* - ih264_resi_trans_quant_8x8 +* +* @remarks +* none +* +******************************************************************************* +*/ + /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stddef.h> -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "ih264_defs.h" -#include "ih264_size_defs.h" #include "ih264_macros.h" +#include "ih264_size_defs.h" #include "ih264_trans_macros.h" #include "ih264_trans_data.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" + +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ + /** - ******************************************************************************* - * - * @brief - * This function performs forward transform and quantization on a 4*4 block - * - * @par Description: - * The function accepts source buffer and estimation buffer. From these, it - * computes the residue. This is residue is then transformed and quantized. - * The transform and quantization are in placed computed. They use the residue - * buffer for this. - * - * @param[in] pu1_src - * Pointer to source sub-block - * - * @param[in] pu1_pred - * Pointer to prediction sub-block - * - * @param[in] pi2_out - * Pointer to residual sub-block - * - * @param[in] src_strd - * Source stride - * - * @param[in] pred_strd - * Prediction stride - * - * @param[in] dst_strd - * Destination stride - * - * @param[in] u4_qbits - * QP_BITS_h264_4x4 + floor(QP/6) - * - * @param[in] pu2_threshold_matrix - * Pointer to Forward Quant Threshold Matrix - * - * @param[in] pu2_scale_matrix - * Pointer to Forward Quant Scale Matrix - * - * @param[in] u4_round_factor - * Quantization Round factor - * - * @param[out] pu1_nnz - * Total non-zero coefficients in the current sub-block - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* This function performs forward transform and quantization on a 4x4 block +* +* @par Description: +* The function accepts source buffer and estimation buffer. From these, it +* computes the residue. This is residue is then transformed and quantized. +* The transform and quantization are in placed computed. They use the residue +* buffer for this. +* +* @param[in] pu1_src +* Pointer to source sub-block +* +* @param[in] pu1_pred +* Pointer to prediction sub-block +* +* @param[in] pi2_out +* Pointer to residual sub-block +* +* @param[in] src_strd +* Source stride +* +* @param[in] pred_strd +* Prediction stride +* +* @param[in] pu2_scale_matrix +* Pointer to Forward Quant Scale Matrix +* +* @param[in] pu2_threshold_matrix +* Pointer to Forward Quant Threshold Matrix +* +* @param[in] u4_qbits +* QP_BITS_h264_4x4 + floor(QP/6) +* +* @param[in] u4_round_factor +* Quantization Round factor +* +* @param[out] pu1_nnz +* Total non-zero coefficients in the current sub-block +* +* @param[in] pi2_alt_dc_addr +* DC Coefficient of the block +* +* @remarks none +* +******************************************************************************* +*/ void ih264_resi_trans_quant_4x4(UWORD8 *pu1_src, UWORD8 *pu1_pred, WORD16 *pi2_out, @@ -122,9 +128,9 @@ void ih264_resi_trans_quant_4x4(UWORD8 *pu1_src, WORD16 *pi2_alt_dc_addr) { UWORD32 i; - WORD32 x0, x1, x2, x3, x4, x5, x6, x7; - WORD32 i4_value; - WORD16 *pi2_out_tmp = pi2_out; + WORD32 x0, x1, x2, x3, x4, x5, x6, x7; + WORD32 i4_value; + WORD16 *pi2_out_tmp = pi2_out; UWORD32 u4_nonzero_coeff = 0; for (i = 0; i < SUB_BLK_WIDTH_4x4; i++) @@ -142,60 +148,60 @@ void ih264_resi_trans_quant_4x4(UWORD8 *pu1_src, x3 = x4 - x7; pi2_out_tmp[0] = x0 + x1; - pi2_out_tmp[1] = (x3 <<1) + x2; + pi2_out_tmp[1] = (x3 << 1) + x2; pi2_out_tmp[2] = x0 - x1; - pi2_out_tmp[3] = x3 - (x2<<1); + pi2_out_tmp[3] = x3 - (x2 << 1); /* pointing to next row; */ pu1_src += src_strd; pu1_pred += pred_strd; pi2_out_tmp += 4; - } + pi2_out_tmp = pi2_out; for (i = 0; i < SUB_BLK_WIDTH_4x4; i++) { - /* Vertical transform and quantization */ x4 = pi2_out_tmp[0]; x5 = pi2_out_tmp[4]; x6 = pi2_out_tmp[8]; x7 = pi2_out_tmp[12]; - x0 = x4 + x7; x1 = x5 + x6; x2 = x5 - x6; x3 = x4 - x7; /* quantization is done in place */ - i4_value = x0 + x1; - - if(i==0) + if(i == 0) { - (*pi2_alt_dc_addr) = i4_value; + (*pi2_alt_dc_addr) = i4_value; } - - FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits, u4_nonzero_coeff); + FWD_QUANT(i4_value, pu2_threshold_matrix[0], + pu2_scale_matrix[0], u4_round_factor, u4_qbits, + u4_nonzero_coeff); pi2_out_tmp[0] = i4_value; - i4_value = (x3 << 1) + x2; - FWD_QUANT(i4_value, pu2_threshold_matrix[4], pu2_scale_matrix[4], u4_round_factor, u4_qbits, u4_nonzero_coeff); + FWD_QUANT(i4_value, pu2_threshold_matrix[4], + pu2_scale_matrix[4], u4_round_factor, u4_qbits, + u4_nonzero_coeff); pi2_out_tmp[4] = i4_value; - i4_value = x0 - x1; - FWD_QUANT(i4_value, pu2_threshold_matrix[8], pu2_scale_matrix[8], u4_round_factor, u4_qbits, u4_nonzero_coeff); + FWD_QUANT(i4_value, pu2_threshold_matrix[8], + pu2_scale_matrix[8], u4_round_factor, u4_qbits, + u4_nonzero_coeff); pi2_out_tmp[8] = i4_value; - i4_value = x3 - (x2 << 1); - FWD_QUANT(i4_value, pu2_threshold_matrix[12], pu2_scale_matrix[12], u4_round_factor, u4_qbits, u4_nonzero_coeff); + FWD_QUANT(i4_value, pu2_threshold_matrix[12], + pu2_scale_matrix[12], u4_round_factor, u4_qbits, + u4_nonzero_coeff); pi2_out_tmp[12] = i4_value; - pi2_out_tmp ++; + pi2_out_tmp++; pu2_scale_matrix++; pu2_threshold_matrix++; } @@ -203,59 +209,57 @@ void ih264_resi_trans_quant_4x4(UWORD8 *pu1_src, /* Return total nonzero coefficients in the current sub block */ *pu1_nnz = u4_nonzero_coeff; } + /** - ******************************************************************************* - * - * @brief - * This function performs forward transform and quantization on a 4*4 chroma block - * with interleaved values - * - * @par Description: - * The function accepts source buffer and estimation buffer. From these, it - * computes the residue. This is residue is then transformed and quantized. - * The transform and quantization are in placed computed. They use the residue - * buffer for this. - * - * @param[in] pu1_src - * Pointer to source sub-block - * - * @param[in] pu1_pred - * Pointer to prediction sub-block - * - * @param[in] pi2_out - * Pointer to residual sub-block - * - * @param[in] src_strd - * Source stride - * - * @param[in] pred_strd - * Prediction stride - * - * @param[in] dst_strd - * Destination stride - * - * @param[in] u4_qbits - * QP_BITS_h264_4x4 + floor(QP/6) - * - * @param[in] pu2_threshold_matrix - * Pointer to Forward Quant Threshold Matrix - * - * @param[in] pu2_scale_matrix - * Pointer to Forward Quant Scale Matrix - * - * @param[in] u4_round_factor - * Quantization Round factor - * - * @param[out] pu1_nnz - * Total non-zero coefficients in the current sub-block - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* This function performs forward transform and quantization on a 4x4 +* chroma block with interleaved values +* +* @par Description: +* The function accepts source buffer and estimation buffer. From these, it +* computes the residue. This is residue is then transformed and quantized. +* The transform and quantization are in placed computed. They use the residue +* buffer for this. +* +* @param[in] pu1_src +* Pointer to source sub-block +* +* @param[in] pu1_pred +* Pointer to prediction sub-block +* +* @param[in] pi2_out +* Pointer to residual sub-block +* +* @param[in] src_strd +* Source stride +* +* @param[in] pred_strd +* Prediction stride +* +* @param[in] pu2_scale_matrix +* Pointer to Forward Quant Scale Matrix +* +* @param[in] pu2_threshold_matrix +* Pointer to Forward Quant Threshold Matrix +* +* @param[in] u4_qbits +* QP_BITS_h264_4x4 + floor(QP/6) +* +* @param[in] u4_round_factor +* Quantization Round factor +* +* @param[out] pu1_nnz +* Total non-zero coefficients in the current sub-block +* +* @param[in] pi2_alt_dc_addr +* DC Coefficient of the block +* +* @remarks none +* +******************************************************************************* +*/ void ih264_resi_trans_quant_chroma_4x4(UWORD8 *pu1_src, UWORD8 *pu1_pred, WORD16 *pi2_out, @@ -269,12 +273,12 @@ void ih264_resi_trans_quant_chroma_4x4(UWORD8 *pu1_src, WORD16 *pu1_dc_alt_addr) { UWORD32 i; - WORD32 x0, x1, x2, x3, x4, x5, x6, x7; - WORD32 i4_value; - WORD16 *pi2_out_tmp = pi2_out; + WORD32 x0, x1, x2, x3, x4, x5, x6, x7; + WORD32 i4_value; + WORD16 *pi2_out_tmp = pi2_out; UWORD32 u4_nonzero_coeff = 0; - for (i = 0; i < SUB_BLK_WIDTH_4x4; i++) + for(i = 0; i < SUB_BLK_WIDTH_4x4; i++) { /* computing prediction error (residue) */ x4 = pu1_src[0] - pu1_pred[0]; @@ -289,41 +293,36 @@ void ih264_resi_trans_quant_chroma_4x4(UWORD8 *pu1_src, x3 = x4 - x7; pi2_out_tmp[0] = x0 + x1; - pi2_out_tmp[1] = (x3 <<1) + x2; + pi2_out_tmp[1] = (x3 << 1) + x2; pi2_out_tmp[2] = x0 - x1; - pi2_out_tmp[3] = x3 - (x2<<1); + pi2_out_tmp[3] = x3 - (x2 << 1); /* pointing to next row; */ pu1_src += src_strd; pu1_pred += pred_strd; pi2_out_tmp += 4; - } + pi2_out_tmp = pi2_out; - for (i = 0; i < SUB_BLK_WIDTH_4x4; i++) + for(i = 0; i < SUB_BLK_WIDTH_4x4; i++) { - /* Vertical transform and quantization */ x4 = pi2_out_tmp[0]; x5 = pi2_out_tmp[4]; x6 = pi2_out_tmp[8]; x7 = pi2_out_tmp[12]; - x0 = x4 + x7; x1 = x5 + x6; x2 = x5 - x6; x3 = x4 - x7; /* quantization is done in place */ - i4_value = x0 + x1; - - if(i==0) + if(i == 0) { - *pu1_dc_alt_addr = i4_value; + *pu1_dc_alt_addr = i4_value; } - FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits, u4_nonzero_coeff); @@ -347,7 +346,7 @@ void ih264_resi_trans_quant_chroma_4x4(UWORD8 *pu1_src, u4_nonzero_coeff); pi2_out_tmp[12] = i4_value; - pi2_out_tmp ++; + pi2_out_tmp++; pu2_scale_matrix++; pu2_threshold_matrix++; } @@ -357,57 +356,43 @@ void ih264_resi_trans_quant_chroma_4x4(UWORD8 *pu1_src, } /** - ******************************************************************************* - * - * @brief - * This function performs forward hadamard transform and quantization on a 4*4 block - * - * @par Description: - * The function accepts source buffer and estimation buffer. From these, it - * computes the residue. This is residue is then transformed and quantized. - * The transform and quantization are in placed computed. They use the residue - * buffer for this. - * - * @param[in] pu1_src - * Pointer to source sub-block - * - * @param[in] pu1_pred - * Pointer to prediction sub-block - * - * @param[in] pi2_out - * Pointer to residual sub-block - * - * @param[in] src_strd - * Source stride - * - * @param[in] pred_strd - * Prediction stride - * - * @param[in] dst_strd - * Destination stride - * - * @param[in] u4_qbits - * QP_BITS_h264_4x4 + floor(QP/6) - * - * @param[in] pu2_threshold_matrix - * Pointer to Forward Quant Threshold Matrix - * - * @param[in] pu2_scale_matrix - * Pointer to Forward Quant Scale Matrix - * - * @param[in] u4_round_factor - * Quantization Round factor - * - * @param[out] pu1_nnz - * Total non-zero coefficients in the current sub-block - * - * @returns - * - * @remarks - * None - * - */ - +******************************************************************************* +* +* @brief +* This function performs forward hadamard transform and quantization on a +* 4x4 block +* +* @par Description: +* The function accepts source buffer and estimation buffer. From these, it +* computes the residue. This is residue is then transformed and quantized. +* The transform and quantization are in placed computed. They use the residue +* buffer for this. +* +* @param[in] pu1_src +* Pointer to source sub-block +* +* @param[in] pi2_dst +* Pointer to destination sub-block +* +* @param[in] pu2_threshold_matrix +* Pointer to Forward Quant Threshold Matrix +* +* @param[in] pu2_scale_matrix +* Pointer to Forward Quant Scale Matrix +* +* @param[in] u4_qbits +* QP_BITS_h264_4x4 + floor(QP/6) +* +* @param[in] u4_round_factor +* Quantization Round factor +* +* @param[out] pu1_nnz +* Total non-zero coefficients in the current sub-block +* +* @remarks none +* +******************************************************************************** +*/ void ih264_hadamard_quant_4x4(WORD16 *pi2_src, WORD16 *pi2_dst, const UWORD16 *pu2_scale_matrix, @@ -416,12 +401,12 @@ void ih264_hadamard_quant_4x4(WORD16 *pi2_src, UWORD32 u4_round_factor, UWORD8 *pu1_nnz) { - WORD32 i; - WORD32 x0,x1,x2,x3,x4,x5,x6,x7,i4_value; + WORD32 i; + WORD32 x0, x1, x2, x3, x4, x5, x6, x7, i4_value; - *pu1_nnz = 0; + *pu1_nnz = 0; - for (i = 0; i < SUB_BLK_WIDTH_4x4; i++) + for(i = 0; i < SUB_BLK_WIDTH_4x4; i++) { x4 = pi2_src[0]; x5 = pi2_src[1]; @@ -443,21 +428,20 @@ void ih264_hadamard_quant_4x4(WORD16 *pi2_src, } /* Vertical transform and quantization */ - pi2_dst -= SUB_BLK_WIDTH_4x4<<2; + pi2_dst -= SUB_BLK_WIDTH_4x4 << 2; - for (i = 0; i < SUB_BLK_WIDTH_4x4; i++) + for(i = 0; i < SUB_BLK_WIDTH_4x4; i++) { x4 = pi2_dst[0]; x5 = pi2_dst[4]; x6 = pi2_dst[8]; - x7 = pi2_dst[12] ; + x7 = pi2_dst[12]; x0 = x4 + x7; x1 = x5 + x6; x2 = x5 - x6; x3 = x4 - x7; - i4_value = (x0 + x1) >> 1; FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits, pu1_nnz[0]); @@ -478,63 +462,49 @@ void ih264_hadamard_quant_4x4(WORD16 *pi2_src, pu2_scale_matrix[0], u4_round_factor, u4_qbits, pu1_nnz[0]); pi2_dst[12] = i4_value; - pi2_dst ++; + pi2_dst++; } } /** - ******************************************************************************* - * - * @brief - * This function performs forward hadamard transform and quantization on a 2*2 block - * for both U and V planes - * - * @par Description: - * The function accepts source buffer and estimation buffer. From these, it - * computes the residue. This is residue is then transformed and quantized. - * The transform and quantization are in placed computed. They use the residue - * buffer for this. - * - * @param[in] pu1_src - * Pointer to source sub-block - * - * @param[in] pu1_pred - * Pointer to prediction sub-block - * - * @param[in] pi2_out - * Pointer to residual sub-block - * - * @param[in] src_strd - * Source stride - * - * @param[in] pred_strd - * Prediction stride - * - * @param[in] dst_strd - * Destination stride - * - * @param[in] u4_qbits - * QP_BITS_h264_4x4 + floor(QP/6) - * - * @param[in] pu2_threshold_matrix - * Pointer to Forward Quant Threshold Matrix - * - * @param[in] pu2_scale_matrix - * Pointer to Forward Quant Scale Matrix - * - * @param[in] u4_round_factor - * Quantization Round factor - * - * @param[out] pu1_nnz - * Total non-zero coefficients in the current sub-block - * - * @returns - * - * @remarks - * NNZ for dc is populated at 0 and 5th position of pu1_nnz - * - */ - +******************************************************************************* +* +* @brief +* This function performs forward hadamard transform and quantization on a +* 2x2 block for both U and V planes +* +* @par Description: +* The function accepts source buffer and estimation buffer. From these, it +* computes the residue. This is residue is then transformed and quantized. +* The transform and quantization are in placed computed. They use the residue +* buffer for this. +* +* @param[in] pu1_src +* Pointer to source sub-block +* +* @param[in] pi2_dst +* Pointer to destination sub-block +* +* @param[in] pu2_threshold_matrix +* Pointer to Forward Quant Threshold Matrix +* +* @param[in] pu2_scale_matrix +* Pointer to Forward Quant Scale Matrix +* +* @param[in] u4_qbits +* QP_BITS_h264_4x4 + floor(QP/6) +* +* @param[in] u4_round_factor +* Quantization Round factor +* +* @param[out] pu1_nnz +* Total non-zero coefficients in the current sub-block +* +* @remarks +* NNZ for dc is populated at 0 and 5th position of pu1_nnz +* +******************************************************************************* +*/ void ih264_hadamard_quant_2x2_uv(WORD16 *pi2_src, WORD16 *pi2_dst, const UWORD16 *pu2_scale_matrix, @@ -588,56 +558,60 @@ void ih264_hadamard_quant_2x2_uv(WORD16 *pi2_src, pi2_dst += 4; pi2_src += 4; - } } -/* - ******************************************************************************* - * - * @brief - * This function performs Single stage forward transform CF8 and quantization on 8*8 blocks - * for h.264 - * - * @par Description: - * Performs single stage 8x8 forward transform CF8 after calculating the residue - * The result is then quantized - * - * @param[in] pu1_src - * Input 8x8 pixels - * - * @param[in] pu1_pred - * Input 8x8 pixels - * - * @param[in] pi1_out - * Output 8x8 pixels - * - * @param[in] u4_thresh - * Threshold under which the coeffs are not quantized - * - * @param[in] u4_qp_div - * QP/6 - * - * @param[in] u4_qp_rem - * QP%6 - * - * @param[in] u2_src_stride - * Source stride - * - * @param[in] pred_strd - * stride for prediciton buffer - * - * @param[in] dst_strd - * stride for destination buffer - * - * @param[in] pu4_quant_mat - * Pointer to the 4x4 quantization matrix - * - * @returns Void - * - * - ******************************************************************************* - */ +/** +******************************************************************************* +* +* @brief +* This function performs Single stage forward transform CF8 and quantization +* on 8x8 blocks +* +* @par Description: +* Performs single stage 8x8 forward transform CF8 after calculating the residue +* The result is then quantized +* +* @param[in] pu1_src +* Pointer to source sub-block +* +* @param[in] pu1_pred +* Pointer to prediction sub-block +* +* @param[in] pi2_out +* Pointer to residual sub-block +* +* @param[in] src_strd +* Source stride +* +* @param[in] pred_strd +* Prediction stride +* +* @param[in] pu2_scale_matrix +* Pointer to Forward Quant Scale Matrix +* +* @param[in] pu2_threshold_matrix +* Pointer to Forward Quant Threshold Matrix +* +* @param[in] u4_qbits +* QP_BITS_h264_8x8 + floor(QP/6) +* +* @param[in] u4_round_factor +* Quantization Round factor +* +* @param[out] pu1_nnz +* Total non-zero coefficients in the current sub-block +* +* @param[in] pi2_alt_dc_addr +* UNUSED +* +* @returns none +* +* @remarks: +* TODO: This function needs to be tested before integration +* +******************************************************************************* +*/ void ih264_resi_trans_quant_8x8(UWORD8 *pu1_src, UWORD8 *pu1_pred, WORD16 *pi2_out, @@ -649,32 +623,28 @@ void ih264_resi_trans_quant_8x8(UWORD8 *pu1_src, UWORD32 u4_round_factor, UWORD8 *pu1_nnz, WORD16 *pu1_dc_alt_addr) - { WORD16 *pi2_out_tmp = pi2_out; - UWORD32 i; + WORD32 i; WORD32 a0, a1, a2, a3, a4, a5, a6, a7; WORD32 r0, r1, r2, r3, r4, r5, r6, r7; UWORD32 u4_nonzero_coeff = 0; UNUSED(pu1_dc_alt_addr); - /*Horizontal transform */ - /* we are going to use the a's and r's in a twisted way since */ - /*i dont want to declare more variables */ + /* Horizontal transform */ for(i = 0; i < SUB_BLK_WIDTH_8x8; ++i) { r0 = pu1_src[0]; r0 -= pu1_pred[0]; r1 = pu1_src[1]; r1 -= pu1_pred[1]; - r2 = pu1_src[2];r2 -= pu1_pred[2]; - r3 = pu1_src[3];r3 -= pu1_pred[3]; - r4 = pu1_src[4];r4 -= pu1_pred[4]; - r5 = pu1_src[5];r5 -= pu1_pred[5]; - r6 = pu1_src[6];r6 -= pu1_pred[6]; - r7 = pu1_src[7];r7 -= pu1_pred[7]; - + r2 = pu1_src[2]; r2 -= pu1_pred[2]; + r3 = pu1_src[3]; r3 -= pu1_pred[3]; + r4 = pu1_src[4]; r4 -= pu1_pred[4]; + r5 = pu1_src[5]; r5 -= pu1_pred[5]; + r6 = pu1_src[6]; r6 -= pu1_pred[6]; + r7 = pu1_src[7]; r7 -= pu1_pred[7]; a0 = r0 + r7; a1 = r1 + r6; @@ -687,38 +657,34 @@ void ih264_resi_trans_quant_8x8(UWORD8 *pu1_src, a7 = a1 - a2; pi2_out_tmp[0] = a4 + a5; - - pi2_out_tmp[2] = a6 + (a7>>1); + pi2_out_tmp[2] = a6 + (a7 >> 1); pi2_out_tmp[4] = a4 - a5; - pi2_out_tmp[6] = (a6>>1) - a7; + pi2_out_tmp[6] = (a6 >> 1) - a7; a0 = r0 - r7; a1 = r1 - r6; a2 = r2 - r5; a3 = r3 - r4; - a4 = a1 + a2 + ((a0>>1) + a0); - a5 = a0 - a3 - ((a2>>1) + a2); - a6 = a0 + a3 - ((a1>>1) + a1); - a7 = a1 - a2 + ((a3>>1) + a3); + a4 = a1 + a2 + ((a0 >> 1) + a0); + a5 = a0 - a3 - ((a2 >> 1) + a2); + a6 = a0 + a3 - ((a1 >> 1) + a1); + a7 = a1 - a2 + ((a3 >> 1) + a3); - pi2_out_tmp[1] = a4 + (a7>>2); - pi2_out_tmp[3] = a5 + (a6>>2); - pi2_out_tmp[5] = a6 - (a5>>2); - pi2_out_tmp[7] = (a4>>2) - a7; + pi2_out_tmp[1] = a4 + (a7 >> 2); + pi2_out_tmp[3] = a5 + (a6 >> 2); + pi2_out_tmp[5] = a6 - (a5 >> 2); + pi2_out_tmp[7] = (a4 >> 2) - a7; pu1_src += src_strd; pu1_pred += pred_strd; pi2_out_tmp += 8; } - /*vertical transform and quant */ - + /* vertical transform and quant */ pi2_out_tmp = pi2_out; - - for (i = 0; i < SUB_BLK_WIDTH_8x8; ++i) + for(i = 0; i < SUB_BLK_WIDTH_8x8; ++i) { - r0 = pi2_out_tmp[0]; r1 = pi2_out_tmp[8]; r2 = pi2_out_tmp[16]; @@ -744,19 +710,19 @@ void ih264_resi_trans_quant_8x8(UWORD8 *pu1_src, a3 = r3 - r4; r0 = a4 + a5; - r2 = a6 + (a7>>1); + r2 = a6 + (a7 >> 1); r4 = a4 - a5; - r6 = (a6>>1) - a7; + r6 = (a6 >> 1) - a7; - a4 = a1 + a2 + ((a0>>1) + a0); - a5 = a0 - a3 - ((a2>>1) + a2); - a6 = a0 + a3 - ((a1>>1) + a1); - a7 = a1 - a2 + ((a3>>1) + a3); + a4 = a1 + a2 + ((a0 >> 1) + a0); + a5 = a0 - a3 - ((a2 >> 1) + a2); + a6 = a0 + a3 - ((a1 >> 1) + a1); + a7 = a1 - a2 + ((a3 >> 1) + a3); - r1 = a4 + (a7>>2); - r3 = a5 + (a6>>2); - r5 = a6 - (a5>>2); - r7 = (a4>>2) - a7; + r1 = a4 + (a7 >> 2); + r3 = a5 + (a6 >> 2); + r5 = a6 - (a5 >> 2); + r7 = (a4 >> 2) - a7; FWD_QUANT(r0, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits, @@ -802,6 +768,6 @@ void ih264_resi_trans_quant_8x8(UWORD8 *pu1_src, pu2_scale_matrix++; pu2_threshold_matrix++; } - /* Return total nonzero coefficients in the current sub block */ - *pu1_nnz = u4_nonzero_coeff; + /* Return total nonzero coefficients in the current sub block */ + *pu1_nnz = u4_nonzero_coeff; } diff --git a/common/ih264_size_defs.h b/common/ih264_size_defs.h index 4555647..e2a584b 100644 --- a/common/ih264_size_defs.h +++ b/common/ih264_size_defs.h @@ -17,23 +17,26 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_size_defs.h - * - * @brief - * Contains declaration of global variables for H264 transform , quant and inverse quant - * - * @author - * Ittiam - * - * @remarks - * - ********************************************************************************/ +******************************************************************************* +* @file +* ih264_size_defs.h +* +* @brief +* Contains macro definitions used in h264 transform, quant and inverse quant +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ -#ifndef IH264_SIZE_DEFS_H_ -#define IH264_SIZE_DEFS_H_ +#ifndef _IH264_SIZE_DEFS_H_ +#define _IH264_SIZE_DEFS_H_ /*****************************************************************************/ /* Constant Macros */ @@ -84,4 +87,4 @@ #define SIZE_TMP_BUFF_ITRANS ((SUB_BLK_WIDTH_4x4*SUB_BLK_WIDTH_4x4) +\ (SUB_BLK_WIDTH_4x4*SUB_BLK_WIDTH_4x4)) -#endif /* IH264_DEFS_H_ */ +#endif /* _IH264_SIZE_DEFS_H_ */ diff --git a/common/ih264_structs.h b/common/ih264_structs.h index 7699451..72f4d10 100644 --- a/common/ih264_structs.h +++ b/common/ih264_structs.h @@ -19,23 +19,21 @@ */ /** - ******************************************************************************* - * @file - * ih264_structs.h - * - * @brief - * Structure definitions used in the code - * - * @author - * Ittiam - * - * @par List of Functions: - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_structs.h +* +* @brief +* Structure definitions used in the code +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ #ifndef _IH264_STRUCTS_H_ #define _IH264_STRUCTS_H_ @@ -569,16 +567,16 @@ typedef struct UWORD8 u1_cpb_cnt_minus1; /** - * (together with bit_rate_value_minus1) specifies the - * maximum input bit rate of the i-th CPB - */ + * (together with bit_rate_value_minus1) specifies the + * maximum input bit rate of the i-th CPB + */ UWORD32 u4_bit_rate_scale; /** - * (together with cpb_size_du_value_minus1) specifies - * CPB size of the i-th CPB when the CPB operates - * at the access unit level - */ + * (together with cpb_size_du_value_minus1) specifies + * CPB size of the i-th CPB when the CPB operates + * at the access unit level + */ UWORD32 u4_cpb_size_scale; /** @@ -600,18 +598,18 @@ typedef struct /** - * specifies the length, in bits for initial cpb delay (nal/vcl)syntax in bp sei - */ + * specifies the length, in bits for initial cpb delay (nal/vcl)syntax in bp sei + */ UWORD8 u1_initial_cpb_removal_delay_length_minus1; /** - * specifies the length, in bits for the cpb delay syntax in pt_sei - */ + * specifies the length, in bits for the cpb delay syntax in pt_sei + */ UWORD8 u1_cpb_removal_delay_length_minus1; /** - * specifies the length, in bits, of the pic_dpb_output_delay syntax element in the pt SEI message - */ + * specifies the length, in bits, of the pic_dpb_output_delay syntax element in the pt SEI message + */ UWORD8 u1_dpb_output_delay_length_minus1; /** @@ -628,104 +626,104 @@ typedef struct typedef struct { /** - * indicates the presence of aspect_ratio - */ + * indicates the presence of aspect_ratio + */ UWORD8 u1_aspect_ratio_info_present_flag; /** - * specifies the aspect ratio of the luma samples - */ + * specifies the aspect ratio of the luma samples + */ UWORD8 u1_aspect_ratio_idc; /** - * width of the luma samples. user dependent - */ + * width of the luma samples. user dependent + */ UWORD16 u2_sar_width; /** - * Height of the luma samples. user dependent - */ + * Height of the luma samples. user dependent + */ UWORD16 u2_sar_height; /** - * if 1, specifies that the overscan_appropriate_flag is present - * if 0, the preferred display method for the video signal is unspecified - */ + * if 1, specifies that the overscan_appropriate_flag is present + * if 0, the preferred display method for the video signal is unspecified + */ UWORD8 u1_overscan_info_present_flag; /** - * if 1,indicates that the cropped decoded pictures output - * are suitable for display using overscan - */ + * if 1,indicates that the cropped decoded pictures output + * are suitable for display using overscan + */ UWORD8 u1_overscan_appropriate_flag; /** - * if 1 specifies that video_format, video_full_range_flag and - * colour_description_present_flag are present - */ + * if 1 specifies that video_format, video_full_range_flag and + * colour_description_present_flag are present + */ UWORD8 u1_video_signal_type_present_flag; /** - * pal, secam, ntsc, ... - */ + * pal, secam, ntsc, ... + */ UWORD8 u1_video_format; /** - * indicates the black level and range of the luma and chroma signals - */ + * indicates the black level and range of the luma and chroma signals + */ UWORD8 u1_video_full_range_flag; /** - * if 1,to 1 specifies that colour_primaries, transfer_characteristics - * and matrix_coefficients are present - */ + * if 1,to 1 specifies that colour_primaries, transfer_characteristics + * and matrix_coefficients are present + */ UWORD8 u1_colour_description_present_flag; /** - * indicates the chromaticity coordinates of the source primaries - */ + * indicates the chromaticity coordinates of the source primaries + */ UWORD8 u1_colour_primaries; /** - * indicates the opto-electronic transfer characteristic of the source picture - */ + * indicates the opto-electronic transfer characteristic of the source picture + */ UWORD8 u1_transfer_characteristics; /** - * the matrix coefficients used in deriving luma and chroma signals - * from the green, blue, and red primaries - */ + * the matrix coefficients used in deriving luma and chroma signals + * from the green, blue, and red primaries + */ UWORD8 u1_matrix_coefficients; /** - * if 1, specifies that chroma_sample_loc_type_top_field and - * chroma_sample_loc_type_bottom_field are present - */ + * if 1, specifies that chroma_sample_loc_type_top_field and + * chroma_sample_loc_type_bottom_field are present + */ UWORD8 u1_chroma_loc_info_present_flag; /** - * location of chroma samples - */ + * location of chroma samples + */ UWORD8 u1_chroma_sample_loc_type_top_field; UWORD8 u1_chroma_sample_loc_type_bottom_field; /** - * Indicates the presence of the - * num_units_in_ticks, time_scale flag - */ + * Indicates the presence of the + * num_units_in_ticks, time_scale flag + */ UWORD8 u1_vui_timing_info_present_flag; /** - * Number of units that - * correspond to one increment of the - * clock. Indicates the resolution - */ + * Number of units that + * correspond to one increment of the + * clock. Indicates the resolution + */ UWORD32 u4_vui_num_units_in_tick; /** - * The number of time units that pass in one second - */ + * The number of time units that pass in one second + */ UWORD32 u4_vui_time_scale; /** @@ -764,37 +762,37 @@ typedef struct UWORD8 u1_pic_struct_present_flag; /** - * 1, specifies that the following cvs bitstream restriction parameters are present - */ + * 1, specifies that the following cvs bitstream restriction parameters are present + */ UWORD8 u1_bitstream_restriction_flag; /** - * if 0, indicates that no pel outside the pic boundaries and - * no sub-pels derived using pels outside the pic boundaries is used for inter prediction - */ + * if 0, indicates that no pel outside the pic boundaries and + * no sub-pels derived using pels outside the pic boundaries is used for inter prediction + */ UWORD8 u1_motion_vectors_over_pic_boundaries_flag; /** - * Indicates a number of bytes not exceeded by the sum of the sizes of the VCL NAL units - * associated with any coded picture - */ + * Indicates a number of bytes not exceeded by the sum of the sizes of the VCL NAL units + * associated with any coded picture + */ UWORD8 u1_max_bytes_per_pic_denom; /** - * Indicates an upper bound for the number of bits of coding_unit() data - */ + * Indicates an upper bound for the number of bits of coding_unit() data + */ UWORD8 u1_max_bits_per_mb_denom; /** - * Indicate the maximum absolute value of a decoded horizontal MV component - * in quarter-pel luma units - */ + * Indicate the maximum absolute value of a decoded horizontal MV component + * in quarter-pel luma units + */ UWORD8 u1_log2_max_mv_length_horizontal; /** - * Indicate the maximum absolute value of a decoded vertical MV component - * in quarter-pel luma units - */ + * Indicate the maximum absolute value of a decoded vertical MV component + * in quarter-pel luma units + */ UWORD8 u1_log2_max_mv_length_vertical; /** @@ -805,7 +803,7 @@ typedef struct /** * specifies required size of the HRD DPB in units of frame buffers. */ - UWORD8 u1_max_dec_frame_buffering; + UWORD8 u1_max_dec_frame_buffering; } vui_t; @@ -820,16 +818,24 @@ typedef struct */ UWORD8 u1_profile_idc; - /** constraint_set0_flag */ + /** + * constraint_set0_flag + */ UWORD8 u1_constraint_set0_flag; - /** constraint_set1_flag */ + /** + * constraint_set1_flag + */ UWORD8 u1_constraint_set1_flag; - /** constraint_set2_flag */ + /** + * constraint_set2_flag + */ UWORD8 u1_constraint_set2_flag; - /** constraint_set3_flag */ + /** + * constraint_set3_flag + */ UWORD8 u1_constraint_set3_flag; /** @@ -1180,7 +1186,9 @@ typedef struct */ typedef struct { - /* memory management control operation command */ + /* + * memory management control operation command + */ UWORD8 u1_memory_management_control_operation; /* @@ -1213,10 +1221,14 @@ typedef struct */ typedef struct { - /* ref_pic_list_modification_flag_l0 */ + /* + * ref_pic_list_modification_flag_l0 + */ WORD8 i1_ref_pic_list_modification_flag_l0; - /* Modification required in list0 */ + /* + * Modification required in list0 + */ WORD8 i1_modification_of_pic_nums_idc_l0[MAX_MODICATION_IDC]; /* @@ -1232,10 +1244,14 @@ typedef struct */ UWORD8 u1_long_term_pic_num_l0[MAX_MODICATION_IDC]; - /* ref_pic_list_modification_flag_l1 */ + /* + * ref_pic_list_modification_flag_l1 + */ WORD8 i1_ref_pic_list_modification_flag_l1; - /* Modification required in list1 */ + /* + * Modification required in list1 + */ WORD8 i1_modification_of_pic_nums_idc_l1[MAX_MODICATION_IDC]; /* @@ -1471,60 +1487,92 @@ typedef struct */ WORD32 i4_abs_bottom_pic_order_cnt; - /** Flag signaling if the current slice is ref slice */ + /** + * Flag signaling if the current slice is ref slice + */ UWORD8 i1_nal_ref_idc; - /** Flag to indicate if the current slice is MBAFF Frame */ + /** + * Flag to indicate if the current slice is MBAFF Frame + */ UWORD8 u1_mbaff_frame_flag; - /** luma_log2_weight_denom */ + /** + * luma_log2_weight_denom + */ UWORD8 u1_luma_log2_weight_denom; - /** chroma_log2_weight_denom */ + /** + * chroma_log2_weight_denom + */ UWORD8 u1_chroma_log2_weight_denom; - /** luma_weight_l0_flag */ + /** + * luma_weight_l0_flag + */ UWORD8 au1_luma_weight_l0_flag[MAX_DPB_SIZE]; - /** luma_weight_l0 : (-128, 127 )is the range of weights - * when weighted pred is enabled, 128 is default value */ + /** + * luma_weight_l0 : (-128, 127 )is the range of weights + * when weighted pred is enabled, 128 is default value + */ WORD16 ai2_luma_weight_l0[MAX_DPB_SIZE]; - /** luma_offset_l0 : (-128, 127 )is the range of offset - * when weighted pred is enabled, 0 is default value */ + /** + * luma_offset_l0 : (-128, 127 )is the range of offset + * when weighted pred is enabled, 0 is default value + */ WORD8 ai1_luma_offset_l0[MAX_DPB_SIZE]; - /** chroma_weight_l0_flag */ + /** + * chroma_weight_l0_flag + */ UWORD8 au1_chroma_weight_l0_flag[MAX_DPB_SIZE]; - /** chroma_weight_l0 : (-128, 127 )is the range of weights - * when weighted pred is enabled, 128 is default value*/ + /** + * chroma_weight_l0 : (-128, 127 )is the range of weights + * when weighted pred is enabled, 128 is default value + */ WORD16 ai2_chroma_weight_l0[MAX_DPB_SIZE][2]; - /** chroma_offset_l0 : (-128, 127 )is the range of offset - * when weighted pred is enabled, 0 is default value*/ + /** + * chroma_offset_l0 : (-128, 127 )is the range of offset + * when weighted pred is enabled, 0 is default value + */ WORD8 ai1_chroma_offset_l0[MAX_DPB_SIZE][2]; - /** luma_weight_l0_flag */ + /** + * luma_weight_l0_flag + */ UWORD8 au1_luma_weight_l1_flag[MAX_DPB_SIZE]; - /** luma_weight_l1 : (-128, 127 )is the range of weights - * when weighted pred is enabled, 128 is default value */ + /** + * luma_weight_l1 : (-128, 127 )is the range of weights + * when weighted pred is enabled, 128 is default value + */ WORD16 ai2_luma_weight_l1[MAX_DPB_SIZE]; - /** luma_offset_l1 : (-128, 127 )is the range of offset - * when weighted pred is enabled, 0 is default value */ + /** + * luma_offset_l1 : (-128, 127 )is the range of offset + * when weighted pred is enabled, 0 is default value + */ WORD8 ai1_luma_offset_l1[MAX_DPB_SIZE]; - /** chroma_weight_l1_flag */ + /** + * chroma_weight_l1_flag + */ UWORD8 au1_chroma_weight_l1_flag[MAX_DPB_SIZE]; - /** chroma_weight_l1 : (-128, 127 )is the range of weights - * when weighted pred is enabled, 128 is default value */ + /** + * chroma_weight_l1 : (-128, 127 )is the range of weights + * when weighted pred is enabled, 128 is default value + */ WORD16 ai2_chroma_weight_l1[MAX_DPB_SIZE][2]; - /** chroma_offset_l1 :(-128, 127 )is the range of offset - * when weighted pred is enabled, 0 is default value */ + /** + * chroma_offset_l1 :(-128, 127 )is the range of offset + * when weighted pred is enabled, 0 is default value + */ WORD8 ai1_chroma_offset_l1[MAX_DPB_SIZE][2]; }slice_header_t; diff --git a/common/ih264_trans_data.c b/common/ih264_trans_data.c index a1231e6..4a1a01f 100644 --- a/common/ih264_trans_data.c +++ b/common/ih264_trans_data.c @@ -17,67 +17,35 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_trans_data.c - * - * @brief - * Contains definition of global variables for H264 encoder - * - * @author - * Ittiam - * - * @remarks - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_trans_data.c +* +* @brief +* Contains definition of global variables for H264 encoder +* +* @author +* ittiam +* +* @remarks +* +******************************************************************************* +*/ + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ +/* User Include Files */ #include "ih264_typedefs.h" #include "ih264_trans_data.h" /*****************************************************************************/ -/* Extern global definitions */ +/* Global definitions */ /*****************************************************************************/ -/* - * Since we don't have a division operation in neon - * we will multiply by LCM of 16,6,10 and scale accordingly - * so care that to get the actual transform you need to divide by LCM - * LCM = 240 - */ - -const UWORD16 g_scal_coff_h264_4x4[16] ={ - 15,40,40,40, - 40,24,40,24, - 15,40,40,15, - 40,24,40,24}; - - - -const UWORD16 g_scal_coff_h264_8x8[16]= - { - 16, 15, 20, 15, - 15, 14, 19, 14, - 20, 19, 25, 19, - 15, 14, 19, 14 - }; -/* - * The scaling is by an 8x8 matrix, but due its 4x4 symmetry we can use - * a 4x4 matrix for scaling - * now since divide is to be avoided, we will compute 1/ values and scale it up - * to preserve information since our data is max 10 bit +1 sign bit we can shift a maximum of 21 bits up - * hence multiply the matrix as such -{16.000 15.059 20.227 15.059 -15.059 14.173 19.051 14.173 -20.227 19.051 25.600 19.051 -15.059 14.173 19.051 14.173}; -{512, 544, 405, 544, -544, 578, 430, 578, -405, 430, 320, 430, -544, 578, 430, 578};*/ - - /** ****************************************************************************** * @brief Scale Table for quantizing 4x4 subblock. To quantize a given 4x4 DCT @@ -123,7 +91,6 @@ const UWORD16 gu2_quant_scale_matrix_4x4[96] = 4559, 2893, 4559, 2893, 7282, 4559, 7282, 4559, 4559, 2893, 4559, 2893, - }; /** @@ -148,19 +115,18 @@ const UWORD16 gu2_quant_scale_matrix_4x4[96] = 174762, 349525, 699050, 1398101, 2796202, } - * * round factor constructed by setting a = 0.49 - *{ - 16056, 32112, 64225, - 128450, 256901, 513802, - 1027604, 2055208, 4110417, - }; - - * round factor constructed by setting a = 0.5 + { + 16056, 32112, 64225, + 128450, 256901, 513802, + 1027604, 2055208, 4110417, + } + * round factor constructed by setting a = 0.5 + { 16384, 32768, 65536, 131072, 262144, 524288, - 1048576, 2097152, 4194304, - + 1048576, 2097152, 4194304, + } ****************************************************************************** */ const UWORD32 gu4_forward_quant_round_factor_4x4[9] = @@ -170,8 +136,6 @@ const UWORD32 gu4_forward_quant_round_factor_4x4[9] = 2796202, }; - - /** ****************************************************************************** * @brief Threshold Table. Quantizing the given DCT coefficient is done only if @@ -286,17 +250,13 @@ const UWORD16 gu2_quant_scale_matrix_8x8 [384] = 6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428, 9118, 8640, 11570, 8640, 9118, 8640, 11570, 8640, 6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428, - }; - /** ****************************************************************************** * @brief Specification of QPc as a function of qPi - * * input : qp luma * output : qp chroma. - * * @remarks Refer Table 8-15 of h264 specification. ****************************************************************************** */ diff --git a/common/ih264_trans_data.h b/common/ih264_trans_data.h index dc77ae7..8c60668 100644 --- a/common/ih264_trans_data.h +++ b/common/ih264_trans_data.h @@ -17,109 +17,40 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_trans_data.h - * - * @brief - * Contains declaration of global variables for H264 transform , qnat and inverse quant - * - * @author - * Ittiam - * - * @remarks - * - ******************************************************************************* - */ -#ifndef IH264_GLOBAL_DATA_H_ -#define IH264_GLOBAL_DATA_H_ +******************************************************************************* +* @file +* ih264_trans_data.h +* +* @brief +* Contains declaration of global variables for H264 transform, qunat and +* inverse quant +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ + +#ifndef _IH264_TRANS_DATA_H_ +#define _IH264_TRANS_DATA_H_ /*****************************************************************************/ /* Extern global declarations */ /*****************************************************************************/ -/* Scaling matrices for h264 quantization */ -extern const UWORD16 g_scal_coff_h264_4x4[16]; -extern const UWORD16 g_scal_coff_h264_8x8[16]; - - -/** - ****************************************************************************** - * @brief Scale Table for quantizing 4x4 subblock. To quantize a given 4x4 DCT - * transformed block, the coefficient at index location (i,j) is scaled by one of - * the constants in this table and right shift the result by (QP_BITS_h264_4x4 + - * floor(qp/6)), here qp is the quantization parameter used to quantize the mb. - * - * input : qp%6, index location (i,j) - * output : scale constant. - * - * @remarks 16 constants for each index position of the subblock and 6 for each - * qp%6 in the range 0-5 inclusive. - ****************************************************************************** - */ extern const UWORD16 gu2_quant_scale_matrix_4x4[96]; -/** - ****************************************************************************** - * @brief Round Factor for quantizing subblock. While quantizing a given 4x4 DCT - * transformed block, the coefficient at index location (i,j) is scaled by one of - * the constants in the table gu2_forward_quant_scalar_4x4 and then right shift - * the result by (QP_BITS_h264_4x4 + floor(qp/6)). - * Before right shifting a round factor is added. - * The round factor can be any value [a * (1 << (QP_BITS_h264_4x4 + floor(qp/6)))] - * for 'a' lies in the range 0-0.5. - * Here qp is the quantization parameter used to quantize the mb. - * - * input : qp/6 - * output : round factor. - * - * @remarks The round factor is constructed by setting a = 1/3 - ****************************************************************************** - */ extern const UWORD32 gu4_forward_quant_round_factor_4x4[9]; -/** - ****************************************************************************** - * @brief Threshold Table. Quantizing the given DCT coefficient is done only if - * it exceeds the threshold value presented in this table. - * - * input : qp/6, qp%6, index location (i,j) - * output : Threshold constant. - * - * @remarks 16 constants for each index position of the subblock and 6 for each - * qp%6 in the range 0-5 inclusive and 9 for each qp/6 in the range 0-51. - ****************************************************************************** - */ extern const UWORD16 gu2_forward_quant_threshold_4x4[96]; -/** - ****************************************************************************** - * @brief Scale Table for quantizing 8x8 subblock. To quantize a given 8x8 DCT - * transformed block, the coefficient at index location (i,j) is scaled by one of - * the constants in this table and right shift the result by (QP_BITS_h264_8x8 + - * floor(qp/6)), here qp is the quantization parameter used to quantize the mb. - * - * input : qp%6, index location (i,j) - * output : scale constant. - * - * @remarks 64 constants for each index position of the subblock and 6 for each - * qp%6 in the range 0-5 inclusive. - ****************************************************************************** - */ extern const UWORD16 gu2_quant_scale_matrix_8x8 [384]; -/** - ****************************************************************************** - * @brief Specification of QPc as a function of qPi - * - * input : qp luma - * output : qp chroma. - * - * @remarks Refer Table 8-15 of h264 specification. - ****************************************************************************** - */ extern const UWORD8 gu1_qpc_fqpi[52]; - -#endif /* IH264_GLOBAL_DATA_H_ */ +#endif /* _IH264_TRANS_DATA_H_ */ diff --git a/common/ih264_trans_macros.h b/common/ih264_trans_macros.h index 79e3aa3..7325d8d 100644 --- a/common/ih264_trans_macros.h +++ b/common/ih264_trans_macros.h @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -27,16 +28,16 @@ * quantization * * @author -* Ittiam +* ittiam * * @remark -* None +* none * ******************************************************************************* */ -#ifndef IH264_TRANS_MACROS_H_ -#define IH264_TRANS_MACROS_H_ +#ifndef _IH264_TRANS_MACROS_H_ +#define _IH264_TRANS_MACROS_H_ /*****************************************************************************/ /* Function Macros */ @@ -124,4 +125,4 @@ shft+= add_f, \ shft = shft>>w) -#endif /* IH264_TRANS_MACROS_H_ */ +#endif /* _IH264_TRANS_MACROS_H_ */ diff --git a/common/ih264_trans_quant_itrans_iquant.h b/common/ih264_trans_quant_itrans_iquant.h index 83551aa..f629382 100644 --- a/common/ih264_trans_quant_itrans_iquant.h +++ b/common/ih264_trans_quant_itrans_iquant.h @@ -17,56 +17,56 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** - ******************************************************************************* - * @file - * ih264_trans_quant.h - * - * @brief - * Contains declarations for forward and inverse transform paths for H264 - * - * @author - * Ittiam - * - * @remarks - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264_trans_quant_itrans_iquant.h +* +* @brief +* Contains declarations for forward and inverse transform / quant functions +* for H264 +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ -#ifndef IH264_TRANS_QUANT_H_ -#define IH264_TRANS_QUANT_H_ +#ifndef _IH264_TRANS_QUANT_ITRANS_IQUANT_H_ +#define _IH264_TRANS_QUANT_ITRANS_IQUANT_H_ /*****************************************************************************/ /* Extern Function Declarations */ /*****************************************************************************/ - typedef void ih264_resi_trans_dctrans_quant_ft(UWORD8*pu1_src, - UWORD8 *pu1_pred, - WORD16 *pi2_out, - WORD32 src_strd, - WORD32 pred_strd, - WORD32 dst_strd, - const UWORD16 *pu2_scale_mat, - const UWORD16 *pu2_thresh_mat, - UWORD32 u4_qbit, - UWORD32 u4_round_fact, - UWORD8 *pu1_nnz); + UWORD8 *pu1_pred, + WORD16 *pi2_out, + WORD32 src_strd, + WORD32 pred_strd, + WORD32 dst_strd, + const UWORD16 *pu2_scale_mat, + const UWORD16 *pu2_thresh_mat, + UWORD32 u4_qbit, + UWORD32 u4_round_fact, + UWORD8 *pu1_nnz); typedef void ih264_idctrans_iquant_itrans_recon_ft(WORD16 *pi2_src, - UWORD8 *pu1_pred, - UWORD8 *pu1_out, - WORD32 src_strd, - WORD32 pred_strd, - WORD32 out_strd, - const UWORD16 *pu2_iscale_mat, - const UWORD16 *pu2_weigh_mat, - UWORD32 qp_div, - UWORD32 pi4_cntrl, - WORD32 *pi4_tmp); - + UWORD8 *pu1_pred, + UWORD8 *pu1_out, + WORD32 src_strd, + WORD32 pred_strd, + WORD32 out_strd, + const UWORD16 *pu2_iscale_mat, + const UWORD16 *pu2_weigh_mat, + UWORD32 qp_div, + UWORD32 pi4_cntrl, + WORD32 *pi4_tmp); -/*Function prototype declarations*/ typedef void ih264_resi_trans_quant_ft(UWORD8*pu1_src, UWORD8 *pu1_pred, WORD16 *pi2_out, @@ -166,6 +166,7 @@ typedef void ih264_hadamard_quant_ft(WORD16 *pi2_src, WORD16 *pi2_dst, const UWORD16 *pu2_threshold_matrix, UWORD32 u4_qbits, UWORD32 u4_round_factor,UWORD8 *pu1_nnz); +/* C Declarations */ ih264_resi_trans_quant_ft ih264_resi_trans_quant_4x4; ih264_resi_trans_quant_ft ih264_resi_trans_quant_chroma_4x4; ih264_resi_trans_quant_ft ih264_resi_trans_quant_8x8; @@ -180,7 +181,7 @@ ih264_ihadamard_scaling_ft ih264_ihadamard_scaling_2x2_uv; ih264_hadamard_quant_ft ih264_hadamard_quant_4x4; ih264_hadamard_quant_ft ih264_hadamard_quant_2x2_uv; -/*A9 Declarations*/ +/* A9 Declarations */ ih264_resi_trans_quant_ft ih264_resi_trans_quant_4x4_a9; ih264_resi_trans_quant_ft ih264_resi_trans_quant_chroma_4x4_a9; ih264_iquant_itrans_recon_ft ih264_iquant_itrans_recon_4x4_a9; @@ -198,7 +199,7 @@ ih264_ihadamard_scaling_ft ih264_ihadamard_scaling_2x2_uv_a9; ih264_hadamard_quant_ft ih264_hadamard_quant_4x4_a9; ih264_hadamard_quant_ft ih264_hadamard_quant_2x2_uv_a9; -/*Av8 Declarations*/ +/* AV8 Declarations */ ih264_resi_trans_quant_ft ih264_resi_trans_quant_4x4_av8; ih264_resi_trans_quant_ft ih264_resi_trans_quant_chroma_4x4_av8; ih264_iquant_itrans_recon_ft ih264_iquant_itrans_recon_4x4_av8; @@ -212,7 +213,7 @@ ih264_ihadamard_scaling_ft ih264_ihadamard_scaling_2x2_uv_av8; ih264_hadamard_quant_ft ih264_hadamard_quant_4x4_av8; ih264_hadamard_quant_ft ih264_hadamard_quant_2x2_uv_av8; -/*SSSE3 Declarations*/ +/* SSSE3 Declarations */ ih264_iquant_itrans_recon_ft ih264_iquant_itrans_recon_4x4_ssse3; ih264_iquant_itrans_recon_ft ih264_iquant_itrans_recon_8x8_ssse3; ih264_iquant_itrans_recon_ft ih264_iquant_itrans_recon_4x4_dc_ssse3; @@ -220,7 +221,8 @@ ih264_iquant_itrans_recon_ft ih264_iquant_itrans_recon_8x8_dc_ssse3; ih264_iquant_itrans_recon_chroma_ft ih264_iquant_itrans_recon_chroma_4x4_dc_ssse3; ih264_ihadamard_scaling_ft ih264_ihadamard_scaling_4x4_ssse3; ih264_ihadamard_scaling_ft ih264_ihadamard_scaling_2x2_uv_ssse3; -/*SSSE42 Declarations*/ + +/* SSSE42 Declarations */ ih264_resi_trans_quant_ft ih264_resi_trans_quant_4x4_sse42; ih264_resi_trans_quant_ft ih264_resi_trans_quant_chroma_4x4_sse42; ih264_iquant_itrans_recon_ft ih264_iquant_itrans_recon_4x4_sse42; @@ -229,4 +231,4 @@ ih264_ihadamard_scaling_ft ih264_ihadamard_scaling_4x4_sse42; ih264_hadamard_quant_ft ih264_hadamard_quant_4x4_sse42; ih264_hadamard_quant_ft ih264_hadamard_quant_2x2_uv_sse42; -#endif /* IH264_TRANS_QUANT_H_ */ +#endif /* _IH264_TRANS_QUANT_ITRANS_IQUANT_H_ */ diff --git a/common/ih264_typedefs.h b/common/ih264_typedefs.h index 29138c6..4456649 100644 --- a/common/ih264_typedefs.h +++ b/common/ih264_typedefs.h @@ -17,19 +17,20 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file * ih264_typedefs.h * * @brief -* Type definitions used in the code +* Type definitions used in the software * * @author -* Ittiam +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ @@ -61,4 +62,4 @@ typedef int64_t WORD64; typedef char CHAR; typedef double DOUBLE; -#endif /* _IH264_TYPEDEFS_H_ */ +#endif /* _IH264_TYPEDEFS_H_ */ diff --git a/common/ih264_weighted_pred.c b/common/ih264_weighted_pred.c index d5d73f2..bc46bd6 100644 --- a/common/ih264_weighted_pred.c +++ b/common/ih264_weighted_pred.c @@ -17,71 +17,88 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ -/*****************************************************************************/ -/* */ -/* File Name : ih264_weighted_pred.c */ -/* */ -/* Description : Contains function definitions for weighted */ -/* prediction functions */ -/* */ -/* List of Functions : ih264_default_weighted_pred_luma() */ -/* ih264_default_weighted_pred_chroma() */ -/* ih264_weighted_pred_luma() */ -/* ih264_weighted_pred_chroma() */ -/* ih264_weighted_bipred_luma() */ -/* ih264_weighted_bipred_chroma() */ -/* */ -/* Issues / Problems : None */ -/* */ -/* Revision History : */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 01 2015 Kaushik Initial version */ -/* Senthoor */ -/* */ -/*****************************************************************************/ + +/** +******************************************************************************* +* @file +* ih264_weighted_pred.c +* +* @brief +* Contains function definitions for weighted prediction functions +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264_default_weighted_pred_luma +* - ih264_default_weighted_pred_chroma +* - ih264_weighted_pred_luma +* - ih264_weighted_pred_chroma +* - ih264_weighted_bipred_luma +* - ih264_weighted_bipred_chroma +* +* @remarks +* +******************************************************************************* +*/ + /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "ih264_macros.h" -#include "ih264_platform_macros.h" #include "ih264_weighted_pred.h" +#include "ih264_platform_macros.h" + /*****************************************************************************/ -/* Function definitions . */ -/*****************************************************************************/ -/*****************************************************************************/ -/* */ -/* Function Name : ih264_default_weighted_pred_luma */ -/* */ -/* Description : This function performs the default weighted prediction */ -/* as described in sec 8.4.2.3.1 titled "Default weighted */ -/* sample prediction process" for luma. The function gets */ -/* two ht x wd blocks, calculates their rounded-average and */ -/* stores it in the destination block. (ht,wd) can be */ -/* (4,4), (8,4), (4,8), (8,8), (16,8), (8,16) or (16,16). */ -/* */ -/* Inputs : puc_src1 - Pointer to source 1 */ -/* puc_src2 - Pointer to source 2 */ -/* puc_dst - Pointer to destination */ -/* src_strd1 - stride for source 1 */ -/* src_strd1 - stride for source 2 */ -/* dst_strd - stride for destination */ -/* ht - height of the block */ -/* wd - width of the block */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 01 2015 Kaushik Initial Version */ -/* Senthoor */ -/* */ +/* Function definitions */ /*****************************************************************************/ + +/** +******************************************************************************* +* +* @brief default weighted prediction luma. +* +* @par Description +* This function performs the default weighted prediction as described in +* sec 8.4.2.3.1 titled "Default weighted sample prediction process" for luma. +* The function gets two ht x wd blocks, calculates their rounded-average and +* stores it in the destination block. (ht,wd) can be (4,4), (8,4), (4,8), +* (8,8), (16,8), (8,16) or (16,16) +* +* @param[in] pu1_src1 +* Pointer to source 1 +* +* @param[in] pu1_src2 +* Pointer to source 2 +* +* @param[in] pu1_dst +* Pointer to destination +* +* @param[in] src_strd1 +* stride for source 1 +* +* @param[in] src_strd2 +* stride for source 2 +* +* @param[in] dst_strd +* stride for destination +* +* @param[in] ht +* height of the block +* +* @param[in] wd +* width of the block +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_default_weighted_pred_luma(UWORD8 *pu1_src1, UWORD8 *pu1_src2, UWORD8 *pu1_dst, @@ -108,35 +125,48 @@ void ih264_default_weighted_pred_luma(UWORD8 *pu1_src1, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_default_weighted_pred_chroma */ -/* */ -/* Description : This function performs the default weighted prediction */ -/* as described in sec 8.4.2.3.1 titled "Default weighted */ -/* sample prediction process" for chroma. The function gets */ -/* two ht x wd blocks, calculates their rounded-average and */ -/* stores it in the destination block. (ht,wd) can be */ -/* (2,2), (4,2) , (2,4), (4,4), (8,4), (4,8) or (8,8). */ -/* */ -/* Inputs : puc_src1 - Pointer to source 1 */ -/* puc_src2 - Pointer to source 2 */ -/* puc_dst - Pointer to destination */ -/* src_strd1 - stride for source 1 */ -/* src_strd1 - stride for source 2 */ -/* dst_strd - stride for destination */ -/* ht - height of the block */ -/* wd - width of the block */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 01 2015 Kaushik Initial Version */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief default weighted prediction chroma. +* +* @par Description +* This function performs the default weighted prediction as described in +* sec 8.4.2.3.1 titled "Default weighted sample prediction process" for chroma. +* The function gets two ht x wd blocks, calculates their rounded-average and +* stores it in the destination block. (ht,wd) can be (2,2), (4,2), (2,4), +* (4,4), (8,4), (4,8) or (8,8). +* +* @param[in] pu1_src1 +* Pointer to source 1 +* +* @param[in] pu1_src2 +* Pointer to source 2 +* +* @param[in] pu1_dst +* Pointer to destination +* +* @param[in] src_strd1 +* stride for source 1 +* +* @param[in] src_strd2 +* stride for source 2 +* +* @param[in] dst_strd +* stride for destination +* +* @param[in] ht +* height of the block +* +* @param[in] wd +* width of the block +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_default_weighted_pred_chroma(UWORD8 *pu1_src1, UWORD8 *pu1_src2, UWORD8 *pu1_dst, @@ -165,37 +195,51 @@ void ih264_default_weighted_pred_chroma(UWORD8 *pu1_src1, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_weighted_pred_luma */ -/* */ -/* Description : This function performs the weighted prediction as */ -/* described in sec 8.4.2.3.2 titled "Weighted sample */ -/* prediction process" for luma. The function gets one */ -/* ht x wd block, weights it, rounds it off, offsets it, */ -/* saturates it to unsigned 8-bit and stores it in the */ -/* destination block. (ht,wd) can be (4,4), (8,4), (4,8), */ -/* (8,8), (16,8), (8,16) or (16,16). */ -/* */ -/* Inputs : puc_src - Pointer to source */ -/* puc_dst - Pointer to destination */ -/* src_strd - stride for source */ -/* dst_strd - stride for destination */ -/* log_wd - number of bits to be rounded off */ -/* wt - weight value */ -/* ofst - offset value */ -/* ht - height of the block */ -/* wd - width of the block */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 01 2015 Kaushik Initial Version */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief weighted prediction luma. +* +* @par Description +* This function performs the weighted prediction as described in +* sec 8.4.2.3.2 titled "weighted sample prediction process" for luma. +* The function gets one ht x wd block, weights it, rounds it off, offsets it, +* saturates it to unsigned 8-bit and stores it in the destination block. +* (ht,wd) can be (4,4), (8,4), (4,8), (8,8), (16,8), (8,16) or (16,16) +* +* @param[in] pu1_src +* Pointer to source +* +* @param[in] pu1_dst +* Pointer to destination +* +* @param[in] src_strd +* stride for source +* +* @param[in] dst_strd +* stride for destination +* +* @param[in] log_wd +* number of bits to be rounded off +* +* @param[in] wt +* weight value +* +* @param[in] ofst +* offset value +* +* @param[in] ht +* height of the block +* +* @param[in] wd +* width of the block +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_weighted_pred_luma(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -239,37 +283,51 @@ void ih264_weighted_pred_luma(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_weighted_pred_chroma */ -/* */ -/* Description : This function performs the weighted prediction as */ -/* described in sec 8.4.2.3.2 titled "Weighted sample */ -/* prediction process" for chroma. The function gets one */ -/* ht x wd block, weights it, rounds it off, offsets it, */ -/* saturates it to unsigned 8-bit and stores it in the */ -/* destination block. (ht,wd) can be (2,2), (4,2), (2,4), */ -/* (4,4), (8,4), (4,8) or (8,8). */ -/* */ -/* Inputs : puc_src - Pointer to source */ -/* puc_dst - Pointer to destination */ -/* src_strd - stride for source */ -/* dst_strd - stride for destination */ -/* log_wd - number of bits to be rounded off */ -/* wt - weight values for u and v */ -/* ofst - offset values for u and v */ -/* ht - height of the block */ -/* wd - width of the block */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 01 2015 Kaushik Initial Version */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief weighted prediction chroma. +* +* @par Description +* This function performs the weighted prediction as described in +* sec 8.4.2.3.2 titled "weighted sample prediction process" for chroma. +* The function gets one ht x wd block, weights it, rounds it off, offsets it, +* saturates it to unsigned 8-bit and stores it in the destination block. +* (ht,wd) can be (2,2), (4,2), (2,4), (4,4), (8,4), (4,8) or (8,8). +* +* @param[in] pu1_src +* Pointer to source +* +* @param[in] pu1_dst +* Pointer to destination +* +* @param[in] src_strd +* stride for source +* +* @param[in] dst_strd +* stride for destination +* +* @param[in] log_wd +* number of bits to be rounded off +* +* @param[in] wt +* weight values for u and v +* +* @param[in] ofst +* offset values for u and v +* +* @param[in] ht +* height of the block +* +* @param[in] wd +* width of the block +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_weighted_pred_chroma(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, @@ -328,41 +386,64 @@ void ih264_weighted_pred_chroma(UWORD8 *pu1_src, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_weighted_bi_pred_luma */ -/* */ -/* Description : This function performs the weighted biprediction as */ -/* described in sec 8.4.2.3.2 titled "Weighted sample */ -/* prediction process" for luma. The function gets two */ -/* ht x wd blocks, weights them, adds them, rounds off the */ -/* sum, offsets it, saturates it to unsigned 8-bit and */ -/* stores it in the destination block. (ht,wd) can be */ -/* (4,4), (8,4), (4,8), (8,8), (16,8), (8,16) or (16,16). */ -/* */ -/* Inputs : puc_src1 - Pointer to source 1 */ -/* puc_src2 - Pointer to source 2 */ -/* puc_dst - Pointer to destination */ -/* src_strd1 - stride for source 1 */ -/* src_strd2 - stride for source 2 */ -/* dst_strd2 - stride for destination */ -/* log_wd - number of bits to be rounded off */ -/* wt1 - weight value for source 1 */ -/* wt2 - weight value for source 2 */ -/* ofst1 - offset value for source 1 */ -/* ofst2 - offset value for source 2 */ -/* ht - height of the block */ -/* wd - width of the block */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 01 2015 Kaushik Initial Version */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief weighted bi-prediction luma. +* +* @par Description +* This function performs the weighted biprediction as described in +* sec 8.4.2.3.2 titled "weighted sample prediction process" for luma. +* The function gets two ht x wd blocks, weights them, adds them, rounds off +* the sum, offsets it, saturates it to unsigned 8-bit and stores it in the +* destination block. (ht,wd) can be (4,4), (8,4), (4,8), (8,8), (16,8), (8,16) +* or (16,16) +* +* @param[in] pu1_src1 +* Pointer to source 1 +* +* @param[in] pu1_src2 +* Pointer to source 2 +* +* @param[in] pu1_dst +* Pointer to destination +* +* @param[in] src_strd1 +* stride for source 1 +* +* @param[in] src_strd2 +* stride for source 2 +* +* @param[in] dst_strd +* stride for destination +* +* @param[in] log_wd +* number of bits to be rounded off +* +* @param[in] wt1 +* weight value for source 1 +* +* @param[in] wt2 +* weight value for source 2 +* +* @param[in] ofst1 +* offset value for source 1 +* +* @param[in] ofst2 +* offset value for source 2 +* +* @param[in] ht +* height of the block +* +* @param[in] wd +* width of the block +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_weighted_bi_pred_luma(UWORD8 *pu1_src1, UWORD8 *pu1_src2, UWORD8 *pu1_dst, @@ -404,41 +485,64 @@ void ih264_weighted_bi_pred_luma(UWORD8 *pu1_src1, } } -/*****************************************************************************/ -/* */ -/* Function Name : ih264_weighted_bi_pred_chroma */ -/* */ -/* Description : This function performs the weighted biprediction as */ -/* described in sec 8.4.2.3.2 titled "Weighted sample */ -/* prediction process" for chroma. The function gets two */ -/* ht x wd blocks, weights them, adds them, rounds off the */ -/* sum, offsets it, saturates it to unsigned 8-bit and */ -/* stores it in the destination block. (ht,wd) can be */ -/* (2,2), (4,2), (2,4), (4,4), (8,4), (4,8) or (8,8). */ -/* */ -/* Inputs : puc_src1 - Pointer to source 1 */ -/* puc_src2 - Pointer to source 2 */ -/* puc_dst - Pointer to destination */ -/* src_strd1 - stride for source 1 */ -/* src_strd2 - stride for source 2 */ -/* dst_strd2 - stride for destination */ -/* log_wd - number of bits to be rounded off */ -/* wt1 - weight values for u and v in source 1 */ -/* wt2 - weight values for u and v in source 2 */ -/* ofst1 - offset value for u and v in source 1 */ -/* ofst2 - offset value for u and v in source 2 */ -/* ht - height of the block */ -/* wd - width of the block */ -/* */ -/* Issues : None */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 01 2015 Kaushik Initial Version */ -/* Senthoor */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief weighted bi-prediction chroma. +* +* @par Description +* This function performs the weighted biprediction as described in +* sec 8.4.2.3.2 titled "weighted sample prediction process" for chroma. +* The function gets two ht x wd blocks, weights them, adds them, rounds off +* the sum, offsets it, saturates it to unsigned 8-bit and stores it in the +* destination block. (ht,wd) can be (2,2), (4,2), (2,4), (4,4), (8,4), (4,8) +* or (8,8) +* +* @param[in] pu1_src1 +* Pointer to source 1 +* +* @param[in] pu1_src2 +* Pointer to source 2 +* +* @param[in] pu1_dst +* Pointer to destination +* +* @param[in] src_strd1 +* stride for source 1 +* +* @param[in] src_strd2 +* stride for source 2 +* +* @param[in] dst_strd +* stride for destination +* +* @param[in] log_wd +* number of bits to be rounded off +* +* @param[in] wt1 +* weight value for source 1 +* +* @param[in] wt2 +* weight value for source 2 +* +* @param[in] ofst1 +* offset value for source 1 +* +* @param[in] ofst2 +* offset value for source 2 +* +* @param[in] ht +* height of the block +* +* @param[in] wd +* width of the block +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264_weighted_bi_pred_chroma(UWORD8 *pu1_src1, UWORD8 *pu1_src2, UWORD8 *pu1_dst, diff --git a/common/ih264_weighted_pred.h b/common/ih264_weighted_pred.h index f9b93b0..44a7aa6 100644 --- a/common/ih264_weighted_pred.h +++ b/common/ih264_weighted_pred.h @@ -27,43 +27,16 @@ * Declarations of functions used for weighted prediction * * @author -* Ittiam -* -* @par List of Functions: -* -ih264_default_weighted_pred_luma -* -ih264_default_weighted_pred_chroma -* -ih264_weighted_pred_luma -* -ih264_weighted_pred_chroma -* -ih264_weighted_bi_pred_luma -* -ih264_weighted_bi_pred_chroma -* -ih264_default_weighted_pred_luma_a9q -* -ih264_default_weighted_pred_chroma_a9q -* -ih264_weighted_pred_luma_a9q -* -ih264_weighted_pred_luma_a9q -* -ih264_weighted_bi_pred_luma_a9q -* -ih264_weighted_bi_pred_chroma_a9q -* -ih264_default_weighted_pred_luma_av8 -* -ih264_default_weighted_pred_chroma_av8 -* -ih264_weighted_pred_luma_av8 -* -ih264_weighted_pred_chroma_av8 -* -ih264_weighted_bi_pred_luma_av8 -* -ih264_weighted_bi_pred_chroma_av8 -* -ih264_default_weighted_pred_luma_sse42 -* -ih264_default_weighted_pred_chroma_sse42 -* -ih264_weighted_pred_luma_sse42 -* -ih264_weighted_pred_chroma_sse42 -* -ih264_weighted_bi_pred_luma_sse42 -* -ih264_weighted_bi_pred_chroma_sse42 -* +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264_WEIGHTED_PRED_H_ -#define IH264_WEIGHTED_PRED_H_ +#ifndef _IH264_WEIGHTED_PRED_H_ +#define _IH264_WEIGHTED_PRED_H_ /*****************************************************************************/ /* Extern Function Declarations */ @@ -101,64 +74,37 @@ typedef void ih264_weighted_bi_pred_ft(UWORD8 *puc_src1, WORD32 ht, WORD32 wd); -/* No NEON Declarations */ - +/* C Declarations */ ih264_default_weighted_pred_ft ih264_default_weighted_pred_luma; - ih264_default_weighted_pred_ft ih264_default_weighted_pred_chroma; - ih264_weighted_pred_ft ih264_weighted_pred_luma; - ih264_weighted_pred_ft ih264_weighted_pred_chroma; - ih264_weighted_bi_pred_ft ih264_weighted_bi_pred_luma; - ih264_weighted_bi_pred_ft ih264_weighted_bi_pred_chroma; /* A9 NEON Declarations */ - ih264_default_weighted_pred_ft ih264_default_weighted_pred_luma_a9q; - ih264_default_weighted_pred_ft ih264_default_weighted_pred_chroma_a9q; - ih264_weighted_pred_ft ih264_weighted_pred_luma_a9q; - ih264_weighted_pred_ft ih264_weighted_pred_chroma_a9q; - ih264_weighted_bi_pred_ft ih264_weighted_bi_pred_luma_a9q; - ih264_weighted_bi_pred_ft ih264_weighted_bi_pred_chroma_a9q; - /* AV8 NEON Declarations */ - ih264_default_weighted_pred_ft ih264_default_weighted_pred_luma_av8; - ih264_default_weighted_pred_ft ih264_default_weighted_pred_chroma_av8; - ih264_weighted_pred_ft ih264_weighted_pred_luma_av8; - ih264_weighted_pred_ft ih264_weighted_pred_chroma_av8; - ih264_weighted_bi_pred_ft ih264_weighted_bi_pred_luma_av8; - ih264_weighted_bi_pred_ft ih264_weighted_bi_pred_chroma_av8; - /* SSE42 Intrinsic Declarations */ - ih264_default_weighted_pred_ft ih264_default_weighted_pred_luma_sse42; - ih264_default_weighted_pred_ft ih264_default_weighted_pred_chroma_sse42; - ih264_weighted_pred_ft ih264_weighted_pred_luma_sse42; - ih264_weighted_pred_ft ih264_weighted_pred_chroma_sse42; - ih264_weighted_bi_pred_ft ih264_weighted_bi_pred_luma_sse42; - ih264_weighted_bi_pred_ft ih264_weighted_bi_pred_chroma_sse42; -#endif /* IH264_WEIGHTED_PRED_H_ */ +#endif /* _IH264_WEIGHTED_PRED_H_ */ -/** Nothing past this point */ diff --git a/common/ithread.h b/common/ithread.h index 45e755f..e5b1355 100644 --- a/common/ithread.h +++ b/common/ithread.h @@ -17,53 +17,40 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ -/*****************************************************************************/ -/* */ -/* File Name : ithread.h */ -/* */ -/* Description : This file contains all the necessary structure and */ -/* enumeration definitions needed for the Application */ -/* Program Interface(API) of the */ -/* Thread Abstraction Layer */ -/* */ -/* List of Functions : ithread_get_handle_size */ -/* ithread_get_mutex_lock_size */ -/* ithread_create */ -/* ithread_join */ -/* ithread_get_mutex_struct_size */ -/* ithread_mutex_init */ -/* ithread_mutex_destroy */ -/* ithread_mutex_lock */ -/* ithread_mutex_unlock */ -/* ithread_yield */ -/* ithread_sleep */ -/* ithread_msleep */ -/* ithread_usleep */ -/* ithread_get_sem_struct_size */ -/* ithread_sem_init */ -/* ithread_sem_post */ -/* ithread_sem_wait */ -/* ithread_sem_destroy */ -/* ithread_set_affinity */ -/* */ -/* Issues / Problems : None */ -/* */ -/* Revision History : */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 06 09 2012 Harish Initial Version */ -/* */ -/*****************************************************************************/ + +/** +******************************************************************************* +* @file +* ithread.h +* +* @brief +* Wrapper functions for thread operations. Library uses these functions during +* multi-thread execution. These calls can be mapped to POSIX, win threads, ... +* basing on platform +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ #ifndef _ITHREAD_H_ #define _ITHREAD_H_ +/*****************************************************************************/ +/* Function Declarations */ +/*****************************************************************************/ UWORD32 ithread_get_handle_size(void); UWORD32 ithread_get_mutex_lock_size(void); WORD32 ithread_create(void *thread_handle, void *attribute, void *strt, void *argument); +void ithread_exit(void *val_ptr); + WORD32 ithread_join(void *thread_id, void ** val_ptr); WORD32 ithread_get_mutex_struct_size(void); diff --git a/common/x86/svc/isvc_mem_fns_ssse3.c b/common/x86/svc/isvc_mem_fns_ssse3.c index 6467b8d..f6fb257 100644 --- a/common/x86/svc/isvc_mem_fns_ssse3.c +++ b/common/x86/svc/isvc_mem_fns_ssse3.c @@ -76,6 +76,13 @@ void isvc_copy_2d_ssse3(UWORD8 *pu1_dst, WORD32 i4_dst_stride, UWORD8 *pu1_src, /* all 128 bit registers are named with a suffix mxnb, where m is the */ /* number of n bits packed in the register */ + if(((i4_blk_wd % 4) != 0) || ((i4_blk_ht % 4) != 0)) + { + isvc_copy_2d(pu1_dst, i4_dst_stride, pu1_src, i4_src_stride, i4_blk_wd, i4_blk_ht); + + return; + } + if(0 == (i4_blk_wd & 31)) /* wd multiple of 32 case */ { __m128i src0_16x8b, src1_16x8b, src2_16x8b, src3_16x8b; diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c index 315f701..16944f4 100644 --- a/decoder/ih264d_api.c +++ b/decoder/ih264d_api.c @@ -3165,6 +3165,7 @@ WORD32 ih264d_set_flush_mode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op ps_ctl_op->u4_error_code = 0; ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); + ih264d_join_threads(ps_dec); UNUSED(pv_api_ip); /* ! */ /* Signal flush frame control call */ diff --git a/decoder/mvc/imvcd_nalu_parser.c b/decoder/mvc/imvcd_nalu_parser.c index 2699912..db09138 100644 --- a/decoder/mvc/imvcd_nalu_parser.c +++ b/decoder/mvc/imvcd_nalu_parser.c @@ -217,14 +217,17 @@ static WORD32 imvcd_parse_subset_sps(mvc_dec_ctxt_t *ps_mvcd_ctxt, dec_bit_strea if(ps_subset_sps->s_sps_data.u1_pic_order_cnt_type == 0) { - ps_subset_sps->s_sps_data.u1_log2_max_pic_order_cnt_lsb_minus = - 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + UWORD32 u1_log2_max_pic_order_cnt_lsb_minus4 = + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(ps_subset_sps->s_sps_data.u1_log2_max_pic_order_cnt_lsb_minus > MAX_BITS_IN_POC_LSB) + if(u1_log2_max_pic_order_cnt_lsb_minus4 > (MAX_BITS_IN_POC_LSB - 4)) { return ERROR_INV_SPS_PPS_T; } + ps_subset_sps->s_sps_data.u1_log2_max_pic_order_cnt_lsb_minus = + 4 + u1_log2_max_pic_order_cnt_lsb_minus4; + ps_subset_sps->s_sps_data.i4_max_pic_order_cntLsb = (1 << ps_subset_sps->s_sps_data.u1_log2_max_pic_order_cnt_lsb_minus); } diff --git a/encoder/arm/ih264e_function_selector.c b/encoder/arm/ih264e_function_selector.c index 0486200..2b155ca 100644 --- a/encoder/arm/ih264e_function_selector.c +++ b/encoder/arm/ih264e_function_selector.c @@ -27,12 +27,14 @@ * Contains functions to initialize function pointers used in h264 * * @author -* Ittiam +* ittiam * * @par List of Functions: +* - ih264e_init_function_ptr +* - ih264e_default_arch * * @remarks -* None +* none * ******************************************************************************* */ @@ -52,38 +54,46 @@ #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264_defs.h" -#include "ih264_size_defs.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" + +#include "ih264_macros.h" #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" +#include "ih264_size_defs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" #include "ih264_cabac_tables.h" -#include "ih264_macros.h" #include "ih264_platform_macros.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" #include "ih264e_cabac.h" #include "ih264e_platform_macros.h" + +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ + /** ******************************************************************************* * -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context +* @brief Initialize the intra/inter/transform/deblk/entropy function pointers * * @par Description: the current routine initializes the function pointers of * codec context basing on the architecture in use @@ -100,6 +110,7 @@ void ih264e_init_function_ptr(void *pv_codec) { codec_t *ps_codec = (codec_t *)pv_codec; + ih264e_init_function_ptr_generic(ps_codec); switch(ps_codec->s_cfg.e_arch) { diff --git a/encoder/arm/ih264e_function_selector_a9q.c b/encoder/arm/ih264e_function_selector_a9q.c index 30d7795..1806350 100644 --- a/encoder/arm/ih264e_function_selector_a9q.c +++ b/encoder/arm/ih264e_function_selector_a9q.c @@ -20,19 +20,19 @@ /** ******************************************************************************* * @file -* ih264e_function_selector_generic.c +* ih264e_function_selector_a9q.c * * @brief * Contains functions to initialize function pointers of codec context * * @author -* Ittiam +* ittiam * * @par List of Functions: -* - ih264e_init_function_ptr_generic +* - ih264e_init_function_ptr_neon_a9q * * @remarks -* None +* none * ******************************************************************************* */ @@ -42,52 +42,59 @@ /* File Includes */ /*****************************************************************************/ -/* System Include files */ +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <string.h> -/* User Include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264_defs.h" -#include "ih264_size_defs.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" + #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_cavlc_tables.h" #include "ih264_cabac_tables.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_platform_macros.h" -#include "ih264e_cabac.h" +#include "ih264e_half_pel.h" +#include "ih264e_intra_modes_eval.h" #include "ih264e_core_coding.h" -#include "ih264_cavlc_tables.h" #include "ih264e_cavlc.h" -#include "ih264e_intra_modes_eval.h" +#include "ih264e_cabac.h" #include "ih264e_fmt_conv.h" -#include "ih264e_half_pel.h" +#include "ih264e_platform_macros.h" + + +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ /** ******************************************************************************* * -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context +* @brief Initialize the intra/inter/transform/deblk/entropy function pointers * * @par Description: the current routine initializes the function pointers of * codec context basing on the architecture in use @@ -104,9 +111,6 @@ void ih264e_init_function_ptr_neon_a9q(codec_t *ps_codec) { WORD32 i= 0; - /* curr proc ctxt */ - process_ctxt_t *ps_proc = NULL; - me_ctxt_t *ps_me_ctxt = NULL; /* Init function pointers for intra pred leaf level functions luma * Intra 16x16 */ @@ -146,21 +150,21 @@ void ih264e_init_function_ptr_neon_a9q(codec_t *ps_codec) ps_codec->apf_intra_pred_c[3] = ih264_intra_pred_chroma_8x8_mode_plane_a9q; /* Init forward transform fn ptr */ - ps_codec->pf_resi_trans_quant_8x8 = ih264_resi_trans_quant_8x8; - ps_codec->pf_resi_trans_quant_4x4 = ih264_resi_trans_quant_4x4_a9; - ps_codec->pf_resi_trans_quant_chroma_4x4 = ih264_resi_trans_quant_chroma_4x4_a9; - ps_codec->pf_hadamard_quant_4x4 = ih264_hadamard_quant_4x4_a9; - ps_codec->pf_hadamard_quant_2x2_uv = ih264_hadamard_quant_2x2_uv_a9; + ps_codec->pf_resi_trans_quant_8x8 = ih264_resi_trans_quant_8x8; + ps_codec->pf_resi_trans_quant_4x4 = ih264_resi_trans_quant_4x4_a9; + ps_codec->pf_resi_trans_quant_chroma_4x4 = ih264_resi_trans_quant_chroma_4x4_a9; + ps_codec->pf_hadamard_quant_4x4 = ih264_hadamard_quant_4x4_a9; + ps_codec->pf_hadamard_quant_2x2_uv = ih264_hadamard_quant_2x2_uv_a9; /* Init inverse transform fn ptr */ - ps_codec->pf_iquant_itrans_recon_8x8 = ih264_iquant_itrans_recon_8x8; - ps_codec->pf_iquant_itrans_recon_4x4 = ih264_iquant_itrans_recon_4x4_a9; - ps_codec->pf_iquant_itrans_recon_4x4_dc = ih264_iquant_itrans_recon_4x4_dc_a9; - ps_codec->pf_iquant_itrans_recon_chroma_4x4 = ih264_iquant_itrans_recon_chroma_4x4_a9; - ps_codec->pf_iquant_itrans_recon_chroma_4x4_dc = ih264_iquant_itrans_recon_chroma_4x4_dc_a9; - ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_a9; - ps_codec->pf_ihadamard_scaling_2x2_uv = ih264_ihadamard_scaling_2x2_uv_a9; - ps_codec->pf_interleave_copy = ih264_interleave_copy_a9; + ps_codec->pf_iquant_itrans_recon_8x8 = ih264_iquant_itrans_recon_8x8; + ps_codec->pf_iquant_itrans_recon_4x4 = ih264_iquant_itrans_recon_4x4_a9; + ps_codec->pf_iquant_itrans_recon_4x4_dc = ih264_iquant_itrans_recon_4x4_dc_a9; + ps_codec->pf_iquant_itrans_recon_chroma_4x4 = ih264_iquant_itrans_recon_chroma_4x4_a9; + ps_codec->pf_iquant_itrans_recon_chroma_4x4_dc = ih264_iquant_itrans_recon_chroma_4x4_dc_a9; + ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_a9; + ps_codec->pf_ihadamard_scaling_2x2_uv = ih264_ihadamard_scaling_2x2_uv_a9; + ps_codec->pf_interleave_copy = ih264_interleave_copy_a9; /* Init fn ptr luma core coding */ ps_codec->luma_energy_compaction[0] = ih264e_code_luma_intra_macroblock_16x16; @@ -218,8 +222,9 @@ void ih264e_init_function_ptr_neon_a9q(codec_t *ps_codec) /* sad me level functions */ for (i = 0; i < (MAX_PROCESS_CTXT); i++) { - ps_proc = &ps_codec->as_process[i]; - ps_me_ctxt = &ps_proc->s_me_ctxt; + process_ctxt_t *ps_proc = &ps_codec->as_process[i]; + me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt; + ps_me_ctxt->pf_ime_compute_sad_16x16[0] = ime_compute_sad_16x16_a9q; ps_me_ctxt->pf_ime_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_a9q; ps_me_ctxt->pf_ime_compute_sad_16x8 = ime_compute_sad_16x8_a9q; @@ -242,6 +247,5 @@ void ih264e_init_function_ptr_neon_a9q(codec_t *ps_codec) /* Halp pel generation function - encoder level */ ps_codec->pf_ih264e_sixtapfilter_horz = ih264e_sixtapfilter_horz_a9q; ps_codec->pf_ih264e_sixtap_filter_2dvh_vert = ih264e_sixtap_filter_2dvh_vert_a9q; - } diff --git a/encoder/arm/ih264e_function_selector_av8.c b/encoder/arm/ih264e_function_selector_av8.c index 1679af3..5ecd982 100644 --- a/encoder/arm/ih264e_function_selector_av8.c +++ b/encoder/arm/ih264e_function_selector_av8.c @@ -20,79 +20,80 @@ /** ******************************************************************************* * @file -* ih264e_function_selector_generic.c +* ih264e_function_selector_av8.c * * @brief * Contains functions to initialize function pointers of codec context * * @author -* Ittiam +* ittiam * * @par List of Functions: -* - ih264e_init_function_ptr_generic +* - ih264e_init_function_ptr_neon_av8 * * @remarks -* None +* none * ******************************************************************************* */ - -/*****************************************************************************/ -/* File Includes */ -/*****************************************************************************/ - /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* System Include files */ +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <string.h> -/* User Include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264_defs.h" -#include "ih264_size_defs.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" + #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_cavlc_tables.h" #include "ih264_cabac_tables.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_platform_macros.h" -#include "ih264e_cabac.h" +#include "ih264e_half_pel.h" +#include "ih264e_intra_modes_eval.h" #include "ih264e_core_coding.h" -#include "ih264_cavlc_tables.h" #include "ih264e_cavlc.h" -#include "ih264e_intra_modes_eval.h" +#include "ih264e_cabac.h" #include "ih264e_fmt_conv.h" -#include "ih264e_half_pel.h" +#include "ih264e_platform_macros.h" +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ + /** ******************************************************************************* * -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context +* @brief Initialize the intra/inter/transform/deblk/entropy function pointers * * @par Description: the current routine initializes the function pointers of * codec context basing on the architecture in use @@ -108,151 +109,146 @@ */ void ih264e_init_function_ptr_neon_av8(codec_t *ps_codec) { - WORD32 i= 0; - /* curr proc ctxt */ - process_ctxt_t *ps_proc = NULL; - me_ctxt_t *ps_me_ctxt = NULL; - - /* Init function pointers for intra pred leaf level functions luma - * Intra 16x16 */ - ps_codec->apf_intra_pred_16_l[0] = ih264_intra_pred_luma_16x16_mode_vert_av8; - ps_codec->apf_intra_pred_16_l[1] = ih264_intra_pred_luma_16x16_mode_horz_av8; - ps_codec->apf_intra_pred_16_l[2] = ih264_intra_pred_luma_16x16_mode_dc_av8; - ps_codec->apf_intra_pred_16_l[3] = ih264_intra_pred_luma_16x16_mode_plane_av8; - - /* Init function pointers for intra pred leaf level functions luma - * Intra 4x4 */ - ps_codec->apf_intra_pred_4_l[0] = ih264_intra_pred_luma_4x4_mode_vert_av8; - ps_codec->apf_intra_pred_4_l[1] = ih264_intra_pred_luma_4x4_mode_horz_av8; - ps_codec->apf_intra_pred_4_l[2] = ih264_intra_pred_luma_4x4_mode_dc_av8; - ps_codec->apf_intra_pred_4_l[3] = ih264_intra_pred_luma_4x4_mode_diag_dl_av8; - ps_codec->apf_intra_pred_4_l[4] = ih264_intra_pred_luma_4x4_mode_diag_dr_av8; - ps_codec->apf_intra_pred_4_l[5] = ih264_intra_pred_luma_4x4_mode_vert_r_av8; - ps_codec->apf_intra_pred_4_l[6] = ih264_intra_pred_luma_4x4_mode_horz_d_av8; - ps_codec->apf_intra_pred_4_l[7] = ih264_intra_pred_luma_4x4_mode_vert_l_av8; - ps_codec->apf_intra_pred_4_l[8] = ih264_intra_pred_luma_4x4_mode_horz_u_av8; - - /* Init function pointers for intra pred leaf level functions luma - * Intra 8x8 */ - ps_codec->apf_intra_pred_8_l[0] = ih264_intra_pred_luma_8x8_mode_vert_av8; - ps_codec->apf_intra_pred_8_l[2] = ih264_intra_pred_luma_8x8_mode_dc_av8; - ps_codec->apf_intra_pred_8_l[3] = ih264_intra_pred_luma_8x8_mode_diag_dl_av8; - ps_codec->apf_intra_pred_8_l[4] = ih264_intra_pred_luma_8x8_mode_diag_dr_av8; - ps_codec->apf_intra_pred_8_l[5] = ih264_intra_pred_luma_8x8_mode_vert_r_av8; - ps_codec->apf_intra_pred_8_l[6] = ih264_intra_pred_luma_8x8_mode_horz_d_av8; - ps_codec->apf_intra_pred_8_l[7] = ih264_intra_pred_luma_8x8_mode_vert_l_av8; - ps_codec->apf_intra_pred_8_l[8] = ih264_intra_pred_luma_8x8_mode_horz_u_av8; - - /* Init function pointers for intra pred leaf level functions chroma - * Intra 8x8 */ - ps_codec->apf_intra_pred_c[0] = ih264_intra_pred_chroma_8x8_mode_dc_av8; - ps_codec->apf_intra_pred_c[1] = ih264_intra_pred_chroma_8x8_mode_horz_av8; - ps_codec->apf_intra_pred_c[2] = ih264_intra_pred_chroma_8x8_mode_vert_av8; - ps_codec->apf_intra_pred_c[3] = ih264_intra_pred_chroma_8x8_mode_plane_av8; - - - /* Init forward transform fn ptr */ - ps_codec->pf_resi_trans_quant_8x8 = ih264_resi_trans_quant_8x8; - ps_codec->pf_resi_trans_quant_4x4 = ih264_resi_trans_quant_4x4_av8; - ps_codec->pf_resi_trans_quant_chroma_4x4 = ih264_resi_trans_quant_chroma_4x4_av8; - ps_codec->pf_hadamard_quant_4x4 = ih264_hadamard_quant_4x4_av8; - ps_codec->pf_hadamard_quant_2x2_uv = ih264_hadamard_quant_2x2_uv_av8; - - /* Init inverse transform fn ptr */ - ps_codec->pf_iquant_itrans_recon_8x8 = ih264_iquant_itrans_recon_8x8_av8; - ps_codec->pf_iquant_itrans_recon_4x4 = ih264_iquant_itrans_recon_4x4_av8; - ps_codec->pf_iquant_itrans_recon_4x4_dc = ih264_iquant_itrans_recon_4x4_dc_av8; - ps_codec->pf_iquant_itrans_recon_chroma_4x4 = ih264_iquant_itrans_recon_chroma_4x4_av8; - ps_codec->pf_iquant_itrans_recon_chroma_4x4_dc = ih264_iquant_itrans_recon_chroma_4x4_dc_av8; - ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_av8; - ps_codec->pf_ihadamard_scaling_2x2_uv = ih264_ihadamard_scaling_2x2_uv_av8; - ps_codec->pf_interleave_copy = ih264_interleave_copy_av8; - - /* Init fn ptr luma core coding */ - ps_codec->luma_energy_compaction[0] = ih264e_code_luma_intra_macroblock_16x16; - ps_codec->luma_energy_compaction[1] = ih264e_code_luma_intra_macroblock_4x4; - ps_codec->luma_energy_compaction[3] = ih264e_code_luma_inter_macroblock_16x16; - - /* Init fn ptr chroma core coding */ - ps_codec->chroma_energy_compaction[0] = ih264e_code_chroma_intra_macroblock_8x8; - ps_codec->chroma_energy_compaction[1] = ih264e_code_chroma_inter_macroblock_8x8; - - /* Init fn ptr luma deblocking */ - ps_codec->pf_deblk_luma_vert_bs4 = ih264_deblk_luma_vert_bs4_av8; - ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4_av8; - ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4_av8; - ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4_av8; - - /* Init fn ptr chroma deblocking */ - ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4_av8; - ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4_av8; - ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4_av8; - ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4_av8; - - /* write mb syntax layer */ - /* write mb syntax layer */ - ps_codec->pf_write_mb_syntax_layer[CAVLC][ISLICE] = ih264e_write_islice_mb_cavlc; - ps_codec->pf_write_mb_syntax_layer[CAVLC][PSLICE] = ih264e_write_pslice_mb_cavlc; - ps_codec->pf_write_mb_syntax_layer[CAVLC][BSLICE] = ih264e_write_bslice_mb_cavlc; - ps_codec->pf_write_mb_syntax_layer[CABAC][ISLICE] = ih264e_write_islice_mb_cabac; - ps_codec->pf_write_mb_syntax_layer[CABAC][PSLICE] = ih264e_write_pslice_mb_cabac; - - /* Padding Functions */ - ps_codec->pf_pad_top = ih264_pad_top_av8; - ps_codec->pf_pad_bottom = ih264_pad_bottom; - ps_codec->pf_pad_left_luma = ih264_pad_left_luma_av8; - ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma_av8; - ps_codec->pf_pad_right_luma = ih264_pad_right_luma_av8; - ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma_av8; - - /* Inter pred leaf level functions */ - ps_codec->pf_inter_pred_luma_copy = ih264_inter_pred_luma_copy_av8; - ps_codec->pf_inter_pred_luma_horz = ih264_inter_pred_luma_horz_av8; - ps_codec->pf_inter_pred_luma_vert = ih264_inter_pred_luma_vert_av8; - ps_codec->pf_inter_pred_luma_bilinear = ih264_inter_pred_luma_bilinear; - ps_codec->pf_inter_pred_chroma = ih264_inter_pred_chroma_av8; - - /* sad me level functions */ - ps_codec->apf_compute_sad_16x16[0] = ime_compute_sad_16x16_av8; - ps_codec->apf_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_av8; - ps_codec->pf_compute_sad_16x8 = ime_compute_sad_16x8_av8; - - /* memor handling operations */ - ps_codec->pf_mem_cpy = ih264_memcpy_av8; - ps_codec->pf_mem_cpy_mul8 = ih264_memcpy_mul_8_av8; - ps_codec->pf_mem_set = ih264_memset_av8; - ps_codec->pf_mem_set_mul8 = ih264_memset_mul_8_av8; - - /* sad me level functions */ - for(i = 0; i < (MAX_PROCESS_CTXT); i++) - { - ps_proc = &ps_codec->as_process[i]; - ps_me_ctxt = &ps_proc->s_me_ctxt; - ps_me_ctxt->pf_ime_compute_sad_16x16[0] = ime_compute_sad_16x16_av8; - ps_me_ctxt->pf_ime_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_av8; - ps_me_ctxt->pf_ime_compute_sad_16x8 = ime_compute_sad_16x8_av8; - ps_me_ctxt->pf_ime_compute_sad4_diamond = ime_calculate_sad4_prog_av8; - ps_me_ctxt->pf_ime_compute_sad3_diamond = ime_calculate_sad3_prog_av8; - ps_me_ctxt->pf_ime_compute_sad2_diamond = ime_calculate_sad2_prog_av8; - ps_me_ctxt->pf_ime_sub_pel_compute_sad_16x16 = ime_sub_pel_compute_sad_16x16_av8; - ps_me_ctxt->pf_ime_compute_sad_stat_luma_16x16 = ime_compute_satqd_16x16_lumainter_av8; - } - - /* intra mode eval -encoder level function */ - ps_codec->pf_ih264e_evaluate_intra16x16_modes = ih264e_evaluate_intra16x16_modes_av8; - ps_codec->pf_ih264e_evaluate_intra_chroma_modes = ih264e_evaluate_intra_chroma_modes_av8; - ps_codec->pf_ih264e_evaluate_intra_4x4_modes = ih264e_evaluate_intra_4x4_modes; - - /* csc */ - ps_codec->pf_ih264e_conv_420p_to_420sp = ih264e_fmt_conv_420p_to_420sp; - ps_codec->pf_ih264e_fmt_conv_422i_to_420sp = ih264e_fmt_conv_422i_to_420sp; - - /* Halp pel generation function - encoder level*/ - ps_codec->pf_ih264e_sixtapfilter_horz = ih264e_sixtapfilter_horz_av8; - ps_codec->pf_ih264e_sixtap_filter_2dvh_vert = ih264e_sixtap_filter_2dvh_vert_av8; - - return ; + /* Init function pointers for intra pred leaf level functions luma + * Intra 16x16 */ + ps_codec->apf_intra_pred_16_l[0] = ih264_intra_pred_luma_16x16_mode_vert_av8; + ps_codec->apf_intra_pred_16_l[1] = ih264_intra_pred_luma_16x16_mode_horz_av8; + ps_codec->apf_intra_pred_16_l[2] = ih264_intra_pred_luma_16x16_mode_dc_av8; + ps_codec->apf_intra_pred_16_l[3] = ih264_intra_pred_luma_16x16_mode_plane_av8; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 4x4 */ + ps_codec->apf_intra_pred_4_l[0] = ih264_intra_pred_luma_4x4_mode_vert_av8; + ps_codec->apf_intra_pred_4_l[1] = ih264_intra_pred_luma_4x4_mode_horz_av8; + ps_codec->apf_intra_pred_4_l[2] = ih264_intra_pred_luma_4x4_mode_dc_av8; + ps_codec->apf_intra_pred_4_l[3] = ih264_intra_pred_luma_4x4_mode_diag_dl_av8; + ps_codec->apf_intra_pred_4_l[4] = ih264_intra_pred_luma_4x4_mode_diag_dr_av8; + ps_codec->apf_intra_pred_4_l[5] = ih264_intra_pred_luma_4x4_mode_vert_r_av8; + ps_codec->apf_intra_pred_4_l[6] = ih264_intra_pred_luma_4x4_mode_horz_d_av8; + ps_codec->apf_intra_pred_4_l[7] = ih264_intra_pred_luma_4x4_mode_vert_l_av8; + ps_codec->apf_intra_pred_4_l[8] = ih264_intra_pred_luma_4x4_mode_horz_u_av8; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 8x8 */ + ps_codec->apf_intra_pred_8_l[0] = ih264_intra_pred_luma_8x8_mode_vert_av8; + ps_codec->apf_intra_pred_8_l[2] = ih264_intra_pred_luma_8x8_mode_dc_av8; + ps_codec->apf_intra_pred_8_l[3] = ih264_intra_pred_luma_8x8_mode_diag_dl_av8; + ps_codec->apf_intra_pred_8_l[4] = ih264_intra_pred_luma_8x8_mode_diag_dr_av8; + ps_codec->apf_intra_pred_8_l[5] = ih264_intra_pred_luma_8x8_mode_vert_r_av8; + ps_codec->apf_intra_pred_8_l[6] = ih264_intra_pred_luma_8x8_mode_horz_d_av8; + ps_codec->apf_intra_pred_8_l[7] = ih264_intra_pred_luma_8x8_mode_vert_l_av8; + ps_codec->apf_intra_pred_8_l[8] = ih264_intra_pred_luma_8x8_mode_horz_u_av8; + + /* Init function pointers for intra pred leaf level functions chroma + * Intra 8x8 */ + ps_codec->apf_intra_pred_c[0] = ih264_intra_pred_chroma_8x8_mode_dc_av8; + ps_codec->apf_intra_pred_c[1] = ih264_intra_pred_chroma_8x8_mode_horz_av8; + ps_codec->apf_intra_pred_c[2] = ih264_intra_pred_chroma_8x8_mode_vert_av8; + ps_codec->apf_intra_pred_c[3] = ih264_intra_pred_chroma_8x8_mode_plane_av8; + + /* Init forward transform fn ptr */ + ps_codec->pf_resi_trans_quant_8x8 = ih264_resi_trans_quant_8x8; + ps_codec->pf_resi_trans_quant_4x4 = ih264_resi_trans_quant_4x4_av8; + ps_codec->pf_resi_trans_quant_chroma_4x4 = ih264_resi_trans_quant_chroma_4x4_av8; + ps_codec->pf_hadamard_quant_4x4 = ih264_hadamard_quant_4x4_av8; + ps_codec->pf_hadamard_quant_2x2_uv = ih264_hadamard_quant_2x2_uv_av8; + + /* Init inverse transform fn ptr */ + ps_codec->pf_iquant_itrans_recon_8x8 = ih264_iquant_itrans_recon_8x8_av8; + ps_codec->pf_iquant_itrans_recon_4x4 = ih264_iquant_itrans_recon_4x4_av8; + ps_codec->pf_iquant_itrans_recon_4x4_dc = ih264_iquant_itrans_recon_4x4_dc_av8; + ps_codec->pf_iquant_itrans_recon_chroma_4x4 = ih264_iquant_itrans_recon_chroma_4x4_av8; + ps_codec->pf_iquant_itrans_recon_chroma_4x4_dc = ih264_iquant_itrans_recon_chroma_4x4_dc_av8; + ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_av8; + ps_codec->pf_ihadamard_scaling_2x2_uv = ih264_ihadamard_scaling_2x2_uv_av8; + ps_codec->pf_interleave_copy = ih264_interleave_copy_av8; + + /* Init fn ptr luma core coding */ + ps_codec->luma_energy_compaction[0] = ih264e_code_luma_intra_macroblock_16x16; + ps_codec->luma_energy_compaction[1] = ih264e_code_luma_intra_macroblock_4x4; + ps_codec->luma_energy_compaction[3] = ih264e_code_luma_inter_macroblock_16x16; + + /* Init fn ptr chroma core coding */ + ps_codec->chroma_energy_compaction[0] = ih264e_code_chroma_intra_macroblock_8x8; + ps_codec->chroma_energy_compaction[1] = ih264e_code_chroma_inter_macroblock_8x8; + + /* Init fn ptr luma deblocking */ + ps_codec->pf_deblk_luma_vert_bs4 = ih264_deblk_luma_vert_bs4_av8; + ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4_av8; + ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4_av8; + ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4_av8; + + /* Init fn ptr chroma deblocking */ + ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4_av8; + ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4_av8; + ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4_av8; + ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4_av8; + + /* write mb syntax layer */ + /* write mb syntax layer */ + ps_codec->pf_write_mb_syntax_layer[CAVLC][ISLICE] = ih264e_write_islice_mb_cavlc; + ps_codec->pf_write_mb_syntax_layer[CAVLC][PSLICE] = ih264e_write_pslice_mb_cavlc; + ps_codec->pf_write_mb_syntax_layer[CAVLC][BSLICE] = ih264e_write_bslice_mb_cavlc; + ps_codec->pf_write_mb_syntax_layer[CABAC][ISLICE] = ih264e_write_islice_mb_cabac; + ps_codec->pf_write_mb_syntax_layer[CABAC][PSLICE] = ih264e_write_pslice_mb_cabac; + + /* Padding Functions */ + ps_codec->pf_pad_top = ih264_pad_top_av8; + ps_codec->pf_pad_bottom = ih264_pad_bottom; + ps_codec->pf_pad_left_luma = ih264_pad_left_luma_av8; + ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma_av8; + ps_codec->pf_pad_right_luma = ih264_pad_right_luma_av8; + ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma_av8; + + /* Inter pred leaf level functions */ + ps_codec->pf_inter_pred_luma_copy = ih264_inter_pred_luma_copy_av8; + ps_codec->pf_inter_pred_luma_horz = ih264_inter_pred_luma_horz_av8; + ps_codec->pf_inter_pred_luma_vert = ih264_inter_pred_luma_vert_av8; + ps_codec->pf_inter_pred_luma_bilinear = ih264_inter_pred_luma_bilinear; + ps_codec->pf_inter_pred_chroma = ih264_inter_pred_chroma_av8; + + /* sad me level functions */ + ps_codec->apf_compute_sad_16x16[0] = ime_compute_sad_16x16_av8; + ps_codec->apf_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_av8; + ps_codec->pf_compute_sad_16x8 = ime_compute_sad_16x8_av8; + + /* memor handling operations */ + ps_codec->pf_mem_cpy = ih264_memcpy_av8; + ps_codec->pf_mem_cpy_mul8 = ih264_memcpy_mul_8_av8; + ps_codec->pf_mem_set = ih264_memset_av8; + ps_codec->pf_mem_set_mul8 = ih264_memset_mul_8_av8; + + /* sad me level functions */ + for(i = 0; i < (MAX_PROCESS_CTXT); i++) + { + process_ctxt_t *ps_proc = &ps_codec->as_process[i]; + me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt; + + ps_me_ctxt->pf_ime_compute_sad_16x16[0] = ime_compute_sad_16x16_av8; + ps_me_ctxt->pf_ime_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_av8; + ps_me_ctxt->pf_ime_compute_sad_16x8 = ime_compute_sad_16x8_av8; + ps_me_ctxt->pf_ime_compute_sad4_diamond = ime_calculate_sad4_prog_av8; + ps_me_ctxt->pf_ime_compute_sad3_diamond = ime_calculate_sad3_prog_av8; + ps_me_ctxt->pf_ime_compute_sad2_diamond = ime_calculate_sad2_prog_av8; + ps_me_ctxt->pf_ime_sub_pel_compute_sad_16x16 = ime_sub_pel_compute_sad_16x16_av8; + ps_me_ctxt->pf_ime_compute_sad_stat_luma_16x16 = ime_compute_satqd_16x16_lumainter_av8; } + /* intra mode eval -encoder level function */ + ps_codec->pf_ih264e_evaluate_intra16x16_modes = ih264e_evaluate_intra16x16_modes_av8; + ps_codec->pf_ih264e_evaluate_intra_chroma_modes = ih264e_evaluate_intra_chroma_modes_av8; + ps_codec->pf_ih264e_evaluate_intra_4x4_modes = ih264e_evaluate_intra_4x4_modes; + + /* csc */ + ps_codec->pf_ih264e_conv_420p_to_420sp = ih264e_fmt_conv_420p_to_420sp; + ps_codec->pf_ih264e_fmt_conv_422i_to_420sp = ih264e_fmt_conv_422i_to_420sp; + + /* Halp pel generation function - encoder level*/ + ps_codec->pf_ih264e_sixtapfilter_horz = ih264e_sixtapfilter_horz_av8; + ps_codec->pf_ih264e_sixtap_filter_2dvh_vert = ih264e_sixtap_filter_2dvh_vert_av8; + + return ; +} + diff --git a/encoder/arm/ih264e_platform_macros.h b/encoder/arm/ih264e_platform_macros.h index 39cac96..7fdba26 100644 --- a/encoder/arm/ih264e_platform_macros.h +++ b/encoder/arm/ih264e_platform_macros.h @@ -34,110 +34,17 @@ ******************************************************************************* */ -#ifndef IH264E_PLATFORM_MACROS_H_ -#define IH264E_PLATFORM_MACROS_H_ +#ifndef _IH264E_PLATFORM_MACROS_H_ +#define _IH264E_PLATFORM_MACROS_H_ /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ -/** -******************************************************************************* -* -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context -* -* @par Description: the current routine initializes the function pointers of -* codec context basing on the architecture in use -* -* @param[in] ps_codec -* Codec context pointer -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ void ih264e_init_function_ptr_neon_a9q(codec_t *ps_codec); - -/** -******************************************************************************* -* -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context -* -* @par Description: the current routine initializes the function pointers of -* codec context basing on the architecture in use -* -* @param[in] ps_codec -* Codec context pointer -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ void ih264e_init_function_ptr_neon_av8(codec_t *ps_codec); - -/** -******************************************************************************* -* -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context -* -* @par Description: the current routine initializes the function pointers of -* codec context basing on the architecture in use -* -* @param[in] ps_codec -* Codec context pointer -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ void ih264e_init_function_ptr_generic(codec_t *ps_codec); - -/** -******************************************************************************* -* -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context -* -* @par Description: the current routine initializes the function pointers of -* codec context basing on the architecture in use -* -* @param[in] ps_codec -* Codec context pointer -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ void ih264e_init_function_ptr(void *pv_codec); - -/** -******************************************************************************* -* -* @brief Determine the architecture of the encoder executing environment -* -* @par Description: This routine returns the architecture of the enviro- -* ment in which the current encoder is being tested -* -* @param[in] void -* -* @returns IV_ARCH_T -* architecture -* -* @remarks none -* -******************************************************************************* -*/ IV_ARCH_T ih264e_default_arch(void); -#endif /* IH264E_PLATFORM_MACROS_H_ */ +#endif /* _IH264E_PLATFORM_MACROS_H_ */ diff --git a/encoder/arm/ime_platform_macros.h b/encoder/arm/ime_platform_macros.h index 0f5b2f2..fc3b1a3 100644 --- a/encoder/arm/ime_platform_macros.h +++ b/encoder/arm/ime_platform_macros.h @@ -48,4 +48,4 @@ ABS(src[3]-est[3]) -#endif /* _IH264_PLATFORM_MACROS_H_ */ +#endif /* _IME_PLATFORM_MACROS_H_ */ diff --git a/encoder/armv8/ih264e_platform_macros.h b/encoder/armv8/ih264e_platform_macros.h index 39cac96..7fdba26 100644 --- a/encoder/armv8/ih264e_platform_macros.h +++ b/encoder/armv8/ih264e_platform_macros.h @@ -34,110 +34,17 @@ ******************************************************************************* */ -#ifndef IH264E_PLATFORM_MACROS_H_ -#define IH264E_PLATFORM_MACROS_H_ +#ifndef _IH264E_PLATFORM_MACROS_H_ +#define _IH264E_PLATFORM_MACROS_H_ /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ -/** -******************************************************************************* -* -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context -* -* @par Description: the current routine initializes the function pointers of -* codec context basing on the architecture in use -* -* @param[in] ps_codec -* Codec context pointer -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ void ih264e_init_function_ptr_neon_a9q(codec_t *ps_codec); - -/** -******************************************************************************* -* -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context -* -* @par Description: the current routine initializes the function pointers of -* codec context basing on the architecture in use -* -* @param[in] ps_codec -* Codec context pointer -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ void ih264e_init_function_ptr_neon_av8(codec_t *ps_codec); - -/** -******************************************************************************* -* -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context -* -* @par Description: the current routine initializes the function pointers of -* codec context basing on the architecture in use -* -* @param[in] ps_codec -* Codec context pointer -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ void ih264e_init_function_ptr_generic(codec_t *ps_codec); - -/** -******************************************************************************* -* -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context -* -* @par Description: the current routine initializes the function pointers of -* codec context basing on the architecture in use -* -* @param[in] ps_codec -* Codec context pointer -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ void ih264e_init_function_ptr(void *pv_codec); - -/** -******************************************************************************* -* -* @brief Determine the architecture of the encoder executing environment -* -* @par Description: This routine returns the architecture of the enviro- -* ment in which the current encoder is being tested -* -* @param[in] void -* -* @returns IV_ARCH_T -* architecture -* -* @remarks none -* -******************************************************************************* -*/ IV_ARCH_T ih264e_default_arch(void); -#endif /* IH264E_PLATFORM_MACROS_H_ */ +#endif /* _IH264E_PLATFORM_MACROS_H_ */ diff --git a/encoder/armv8/ime_platform_macros.h b/encoder/armv8/ime_platform_macros.h index 0f5b2f2..fc3b1a3 100644 --- a/encoder/armv8/ime_platform_macros.h +++ b/encoder/armv8/ime_platform_macros.h @@ -48,4 +48,4 @@ ABS(src[3]-est[3]) -#endif /* _IH264_PLATFORM_MACROS_H_ */ +#endif /* _IME_PLATFORM_MACROS_H_ */ diff --git a/encoder/ih264e.h b/encoder/ih264e.h index bf874eb..65f23b0 100644 --- a/encoder/ih264e.h +++ b/encoder/ih264e.h @@ -17,25 +17,23 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ -/*****************************************************************************/ -/* */ -/* File Name : ih264e.h */ -/* */ -/* Description : This file contains all the necessary structure and */ -/* enumeration definitions needed for the Application */ -/* Program Interface(API) of the Ittiam MPEG4 */ -/* Encoder on Cortex A8 - Neon platform */ -/* */ -/* List of Functions : ih264e_api_function */ -/* */ -/* Issues / Problems : None */ -/* */ -/* Revision History : */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 26 08 2010 100239(RCY) Draft */ -/* */ -/*****************************************************************************/ + +/** +****************************************************************************** +* @file +* ih264e.h +* +* @brief +* This file contains all the necessary structure and enumeration definitions +* needed for the Application Program Interface(API) of the Ittiam H264 Encoder +* +* @author +* ittiam +* +* @remarks +* none +****************************************************************************** +*/ #ifndef _IH264E_H_ #define _IH264E_H_ @@ -46,10 +44,17 @@ extern "C" { #include "iv2.h" #include "ive2.h" + +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ + + /*****************************************************************************/ -/* API Function Prototype */ +/* Function Declarations */ /*****************************************************************************/ -IV_STATUS_T ih264e_api_function(iv_obj_t *ps_handle, void *pv_api_ip,void *pv_api_op); +IV_STATUS_T ih264e_api_function(iv_obj_t *ps_handle, void *pv_api_ip, + void *pv_api_op); /*****************************************************************************/ /* Enums */ @@ -59,6 +64,14 @@ typedef enum IH264E_CMD_CTL_SET_ME_INFO_ENABLE, }IH264E_CMD_CTL_SUB_CMDS; +/* NOTE: Ensure this enum values are not greater than 8 bits as this is being + * assigned to WORD8 */ +typedef enum +{ + INTRA16x16 = 0, + INTRA4x4, + INTER16x16, +}IV_MB_TYPE_T; /*****************************************************************************/ /* Extended Structures */ @@ -67,31 +80,24 @@ typedef enum /*****************************************************************************/ /* Get Number of Memory Records */ /*****************************************************************************/ - - typedef struct { iv_num_mem_rec_ip_t s_ive_ip; }ih264e_num_mem_rec_ip_t; - typedef struct { iv_num_mem_rec_op_t s_ive_op; }ih264e_num_mem_rec_op_t; - /*****************************************************************************/ /* Fill Memory Records */ /*****************************************************************************/ - - typedef struct { iv_fill_mem_rec_ip_t s_ive_ip; }ih264e_fill_mem_rec_ip_t; - typedef struct { iv_fill_mem_rec_op_t s_ive_op; @@ -100,36 +106,29 @@ typedef struct /*****************************************************************************/ /* Retrieve Memory Records */ /*****************************************************************************/ - - typedef struct { iv_retrieve_mem_rec_ip_t s_ive_ip; }ih264e_retrieve_mem_rec_ip_t; - typedef struct { iv_retrieve_mem_rec_op_t s_ive_op; }ih264e_retrieve_mem_rec_op_t; - /*****************************************************************************/ /* Initialize encoder */ /*****************************************************************************/ - typedef struct { ive_init_ip_t s_ive_ip; }ih264e_init_ip_t; - typedef struct { ive_init_op_t s_ive_op; }ih264e_init_op_t; - /*****************************************************************************/ /* Queue Input raw buffer - Send the YUV buffer to be encoded */ /*****************************************************************************/ @@ -156,7 +155,6 @@ typedef struct ive_dequeue_inp_op_t s_ive_op; }ih264e_dequeue_inp_op_t; - /*****************************************************************************/ /* Queue Output bitstream buffer - Send the bistream buffer to be filled */ /*****************************************************************************/ @@ -183,7 +181,6 @@ typedef struct ive_dequeue_out_op_t s_ive_op; }ih264e_dequeue_out_op_t; - /*****************************************************************************/ /* Get Recon data - Get the reconstructed data from encoder */ /*****************************************************************************/ @@ -196,17 +193,15 @@ typedef struct { ive_get_recon_op_t s_ive_op; }ih264e_get_recon_op_t; + /*****************************************************************************/ /* Video control Flush */ /*****************************************************************************/ - - typedef struct { ive_ctl_flush_ip_t s_ive_ip; }ih264e_ctl_flush_ip_t; - typedef struct { ive_ctl_flush_op_t s_ive_op; @@ -215,68 +210,50 @@ typedef struct /*****************************************************************************/ /* Video control reset */ /*****************************************************************************/ - - typedef struct { ive_ctl_reset_ip_t s_ive_ip; }ih264e_ctl_reset_ip_t; - typedef struct { ive_ctl_reset_op_t s_ive_op; }ih264e_ctl_reset_op_t; - /*****************************************************************************/ /* Video control:Get Buf Info */ /*****************************************************************************/ - - typedef struct { ive_ctl_getbufinfo_ip_t s_ive_ip; }ih264e_ctl_getbufinfo_ip_t; - - typedef struct { ive_ctl_getbufinfo_op_t s_ive_op; }ih264e_ctl_getbufinfo_op_t; - - /*****************************************************************************/ /* Video control:Get Version Info */ /*****************************************************************************/ - - typedef struct { ive_ctl_getversioninfo_ip_t s_ive_ip; }ih264e_ctl_getversioninfo_ip_t; - - typedef struct { ive_ctl_getversioninfo_op_t s_ive_op; }ih264e_ctl_getversioninfo_op_t; /*****************************************************************************/ -/* Video control:Set default params */ +/* Video control:Set default params */ /*****************************************************************************/ - - typedef struct { ive_ctl_setdefault_ip_t s_ive_ip; }ih264e_ctl_setdefault_ip_t; - - typedef struct { ive_ctl_setdefault_op_t s_ive_op; @@ -315,12 +292,12 @@ typedef struct { ive_ctl_set_frame_rate_ip_t s_ive_ip; }ih264e_ctl_set_frame_rate_ip_t; + typedef struct { ive_ctl_set_frame_rate_op_t s_ive_op; }ih264e_ctl_set_frame_rate_op_t; - /*****************************************************************************/ /* Video control Set Bitrate */ /*****************************************************************************/ @@ -334,7 +311,6 @@ typedef struct ive_ctl_set_bitrate_op_t s_ive_op; }ih264e_ctl_set_bitrate_op_t; - /*****************************************************************************/ /* Video control Set Frame type */ /*****************************************************************************/ @@ -478,7 +454,6 @@ typedef struct ive_video_encode_op_t s_ive_op; }ih264e_video_encode_op_t; - /*****************************************************************************/ /* Video usability information */ /*****************************************************************************/ @@ -910,14 +885,6 @@ typedef struct } ih264e_ctl_set_sei_sii_params_op_t; -/* The enum values should not have greater than 8 bits as this is assigned to WORD8 */ -typedef enum -{ - INTRA16x16 = 0, - INTRA4x4, - INTER16x16 -}IV_MB_TYPE_T; - /*****************************************************************************/ /* Pic info structures */ /*****************************************************************************/ @@ -1024,11 +991,10 @@ typedef struct WORD8 ai1_intra_mode[16]; }; - - }ih264e_mb_info4_t; -/* Add any new structures to the following union. It is used to calculate the max size needed for allocation of memory */ +/* Add any new structures to the following union. It is used to calculate the + * max size needed for allocation of memory */ typedef struct { union @@ -1042,5 +1008,6 @@ typedef struct #ifdef __cplusplus } /* closing brace for extern "C" */ + #endif #endif /* _IH264E_H_ */ diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c index c4c6050..f76fbd1 100644 --- a/encoder/ih264e_api.c +++ b/encoder/ih264e_api.c @@ -30,36 +30,36 @@ * ittiam * * @par List of Functions: -* - api_check_struct_sanity() -* - ih264e_codec_update_config() -* - ih264e_set_default_params() -* - ih264e_init() -* - ih264e_get_num_rec() -* - ih264e_fill_num_mem_rec() -* - ih264e_init_mem_rec() -* - ih264e_retrieve_memrec() -* - ih264e_set_flush_mode() -* - ih264e_get_buf_info() -* - ih264e_set_dimensions() -* - ih264e_set_frame_rate() -* - ih264e_set_bit_rate() -* - ih264e_set_frame_type() -* - ih264e_set_qp() -* - ih264e_set_enc_mode() -* - ih264e_set_vbv_params() -* - ih264_set_air_params() -* - ih264_set_me_params() -* - ih264_set_ipe_params() -* - ih264_set_gop_params() -* - ih264_set_profile_params() -* - ih264_set_deblock_params() -* - ih264e_set_num_cores() -* - ih264e_reset() -* - ih264e_ctl() -* - ih264e_api_function() +* - api_check_struct_sanity +* - ih264e_codec_update_config +* - ih264e_set_default_params +* - ih264e_init +* - ih264e_get_num_rec +* - ih264e_fill_num_mem_rec +* - ih264e_init_mem_rec +* - ih264e_retrieve_memrec +* - ih264e_set_flush_mode +* - ih264e_get_buf_info +* - ih264e_set_dimensions +* - ih264e_set_frame_rate +* - ih264e_set_bit_rate +* - ih264e_set_frame_type +* - ih264e_set_qp +* - ih264e_set_enc_mode +* - ih264e_set_vbv_params +* - ih264_set_air_params +* - ih264_set_me_params +* - ih264_set_ipe_params +* - ih264_set_gop_params +* - ih264_set_profile_params +* - ih264_set_deblock_params +* - ih264e_set_num_cores +* - ih264e_reset +* - ih264e_ctl +* - ih264e_api_function * * @remarks -* None +* none * ******************************************************************************* */ @@ -78,60 +78,57 @@ /* User Include Files */ #include "ih264e_config.h" #include "ih264_typedefs.h" -#include "ih264_size_defs.h" #include "iv2.h" #include "ive2.h" -#include "ih264e.h" #include "ithread.h" + #include "ih264_debug.h" -#include "ih264_defs.h" +#include "ih264_macros.h" #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" +#include "ih264_size_defs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_common_tables.h" +#include "ih264_cavlc_tables.h" #include "ih264_cabac_tables.h" -#include "ih264_macros.h" -#include "ih264e_defs.h" -#include "ih264e_globals.h" #include "ih264_buf_mgr.h" +#include "ih264_list.h" +#include "ih264_dpb_mgr.h" +#include "ih264_platform_macros.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_mem_req_and_acq.h" #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" #include "irc_rate_control_api.h" + +#include "ih264e.h" +#include "ih264e_error.h" +#include "ih264e_version.h" +#include "ih264e_defs.h" +#include "ih264e_globals.h" #include "ih264e_time_stamp.h" #include "ih264e_modify_frm_rate.h" #include "ih264e_rate_control.h" -#include "ih264e_error.h" +#include "ih264e_rc_mem_interface.h" #include "ih264e_bitstream.h" -#include "ime_defs.h" -#include "ime_distortion_metrics.h" -#include "ime_structs.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" #include "ih264e_utils.h" #include "ih264e_core_coding.h" -#include "ih264_platform_macros.h" -#include "ih264e_platform_macros.h" -#include "ih264_list.h" -#include "ih264_dpb_mgr.h" -#include "ih264_cavlc_tables.h" #include "ih264e_cavlc.h" -#include "ih264_common_tables.h" #include "ih264e_master.h" #include "ih264e_fmt_conv.h" -#include "ih264e_version.h" - - -/*****************************************************************************/ -/* Function Declarations */ -/*****************************************************************************/ -WORD32 ih264e_get_rate_control_mem_tab(void *pv_rate_control, - iv_mem_rec_t *ps_mem, - ITT_FUNC_TYPE_E e_func_type); +#include "ih264e_platform_macros.h" /*****************************************************************************/ @@ -1613,6 +1610,16 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, return IV_FAIL; } + if((ps_ip->s_ive_ip.u4_idr_frm_interval > ps_ip->s_ive_ip.u4_i_frm_interval) && + (ps_ip->s_ive_ip.u4_idr_frm_interval % ps_ip->s_ive_ip.u4_i_frm_interval != 0)) + { + ps_op->s_ive_op.u4_error_code |= 1 + << IVE_UNSUPPORTEDPARAM; + ps_op->s_ive_op.u4_error_code |= + IH264E_INVALID_INTRA_FRAME_INTERVAL; + return IV_FAIL; + } + break; } @@ -1709,15 +1716,8 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, if ((ps_ip->s_ive_ip.u4_i_qp > ps_ip->s_ive_ip.u4_i_qp_max) || (ps_ip->s_ive_ip.u4_p_qp > ps_ip->s_ive_ip.u4_p_qp_max) - || (ps_ip->s_ive_ip.u4_b_qp > ps_ip->s_ive_ip.u4_b_qp_max)) - { - ps_op->s_ive_op.u4_error_code |= 1 - << IVE_UNSUPPORTEDPARAM; - ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INIT_QP; - return IV_FAIL; - } - - if ((ps_ip->s_ive_ip.u4_i_qp < ps_ip->s_ive_ip.u4_i_qp_min) + || (ps_ip->s_ive_ip.u4_b_qp > ps_ip->s_ive_ip.u4_b_qp_max) + || (ps_ip->s_ive_ip.u4_i_qp < ps_ip->s_ive_ip.u4_i_qp_min) || (ps_ip->s_ive_ip.u4_p_qp < ps_ip->s_ive_ip.u4_p_qp_min) || (ps_ip->s_ive_ip.u4_b_qp < ps_ip->s_ive_ip.u4_b_qp_min)) { @@ -2301,7 +2301,8 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, return IV_FAIL; } - if (ps_ip->s_ive_ip.u4_air_refresh_period == 0) + if (ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_NONE && + ps_ip->s_ive_ip.u4_air_refresh_period == 0) { ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; @@ -2569,100 +2570,14 @@ IH264E_ERROR_T ih264e_codec_update_config(codec_t *ps_codec, else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_IPE_PARAMS) { ps_curr_cfg->u4_enc_speed_preset = ps_cfg->u4_enc_speed_preset; - ps_curr_cfg->u4_constrained_intra_pred = ps_cfg->u4_constrained_intra_pred; - if (ps_curr_cfg->u4_enc_speed_preset == IVE_SLOWEST) - {/* high quality */ - /* enable diamond search */ - ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; - ps_curr_cfg->u4_enable_fast_sad = 0; - - /* disable intra 4x4 */ - ps_curr_cfg->u4_enable_intra_4x4 = 1; - ps_codec->luma_energy_compaction[1] = - ih264e_code_luma_intra_macroblock_4x4_rdopt_on; - - /* sub pel off */ - ps_curr_cfg->u4_enable_hpel = 1; - - /* deblocking off */ - ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; - - /* disabled intra inter gating in Inter slices */ - ps_codec->u4_inter_gate = 0; - } - else if (ps_curr_cfg->u4_enc_speed_preset == IVE_NORMAL) - {/* normal */ - /* enable diamond search */ - ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; - ps_curr_cfg->u4_enable_fast_sad = 0; - - /* disable intra 4x4 */ - ps_curr_cfg->u4_enable_intra_4x4 = 1; - - /* sub pel off */ - ps_curr_cfg->u4_enable_hpel = 1; - - /* deblocking off */ - ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; - - /* disabled intra inter gating in Inter slices */ - ps_codec->u4_inter_gate = 0; - } - else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FAST) - {/* normal */ - /* enable diamond search */ - ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; - ps_curr_cfg->u4_enable_fast_sad = 0; - - /* disable intra 4x4 */ - ps_curr_cfg->u4_enable_intra_4x4 = 0; - - /* sub pel off */ - ps_curr_cfg->u4_enable_hpel = 1; - - /* deblocking off */ - ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; - - /* disabled intra inter gating in Inter slices */ - ps_codec->u4_inter_gate = 1; - } - else if (ps_curr_cfg->u4_enc_speed_preset == IVE_HIGH_SPEED) - {/* fast */ - /* enable diamond search */ - ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; - ps_curr_cfg->u4_enable_fast_sad = 0; - - /* disable intra 4x4 */ - ps_curr_cfg->u4_enable_intra_4x4 = 0; - - /* sub pel off */ - ps_curr_cfg->u4_enable_hpel = 0; - /* deblocking off */ - ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4; - - /* disabled intra inter gating in Inter slices */ - ps_codec->u4_inter_gate = 0; - } - else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST) - {/* fastest */ - /* enable diamond search */ - ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; - //u4_num_layers = 4; - - /* disable intra 4x4 */ - ps_curr_cfg->u4_enable_intra_4x4 = 0; - - /* sub pel off */ - ps_curr_cfg->u4_enable_hpel = 0; - - /* deblocking off */ - ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4; + ps_curr_cfg->u4_constrained_intra_pred = ps_cfg->u4_constrained_intra_pred; - /* disabled intra inter gating in Inter slices */ - ps_codec->u4_inter_gate = 1; + if (ps_curr_cfg->u4_enc_speed_preset != IVE_CONFIG) + { + ih264e_speed_preset_side_effects(ps_codec); } - else if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG) + else { ps_curr_cfg->u4_enable_intra_4x4 = ps_cfg->u4_enable_intra_4x4; } @@ -2679,8 +2594,7 @@ IH264E_ERROR_T ih264e_codec_update_config(codec_t *ps_codec, /* re-init air map */ ih264e_init_air_map(ps_codec); - /*Effect intra frame interval change*/ - + /* Effect intra frame interval change */ irc_change_intra_frm_int_call( ps_codec->s_rate_control.pps_rate_control_api, ps_curr_cfg->u4_i_frm_interval); @@ -2991,9 +2905,9 @@ static WORD32 ih264e_set_default_params(cfg_params_t *ps_cfg) ps_cfg->e_cmd = IVE_CMD_CT_NA; ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4; ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4; - ps_cfg->u4_entropy_coding_mode = CAVLC; + ps_cfg->u4_entropy_coding_mode = DEFAULT_ENTROPY_CODING_MODE; ps_cfg->u4_weighted_prediction = 0; - ps_cfg->u4_constrained_intra_pred = 0; + ps_cfg->u4_constrained_intra_pred = DEFAULT_CONSTRAINED_INTRAPRED; ps_cfg->u4_pic_info_type = 0; ps_cfg->u4_mb_info_type = 0; ps_cfg->s_vui.u1_video_signal_type_present_flag = 0; @@ -3101,7 +3015,8 @@ static WORD32 ih264e_init(codec_t *ps_codec) ps_codec->i4_pps_id = 0; /* Process thread created status */ - memset(ps_codec->ai4_process_thread_created, 0, MAX_PROCESS_THREADS); + memset(ps_codec->ai4_process_thread_created, 0, + sizeof(ps_codec->ai4_process_thread_created)); memset(&ps_codec->s_global_quality_stats, 0, sizeof(ps_codec->s_global_quality_stats)); @@ -3328,7 +3243,7 @@ static WORD32 ih264e_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op) max_mb_cnt = max_mb_rows * max_mb_cols; /* profile / level info */ - level = ih264e_get_min_level(max_ht_luma, max_wd_luma); + level = ih264e_get_min_level(max_wd_luma, max_ht_luma); /* validate params */ if ((level < MIN_LEVEL) || (level > MAX_LEVEL)) @@ -3592,6 +3507,25 @@ static WORD32 ih264e_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op) DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBITS, ps_mem_rec->u4_mem_size); /************************************************************************ + * Frame level Intra Cost Map. During intra/inter analysis preserve the* + * intra mb cost for future complexity estimation. * + * NOTE: The cost map is a overlay on the previous frame. In case if an* + * mb is not intra analyzed, the cost here represents its collocated mb* + * intra cost. This traversal can go till the latest I frame at worse * + ************************************************************************/ + ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_COST]; + { + /* total size of the mem record */ + WORD32 total_size = 0; + + /* size in bytes to mb core coding status of an entire frame */ + total_size = max_mb_cnt * sizeof(WORD32); + + ps_mem_rec->u4_mem_size = total_size; + } + DEBUG("\nMemory record Id %d = %d \n", MEM_REC_INTRA_COST, ps_mem_rec->u4_mem_size); + + /************************************************************************ * Request memory for SPS * ***********************************************************************/ ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS]; @@ -4508,6 +4442,11 @@ static WORD32 ih264e_init_mem_rec(iv_obj_t *ps_codec_obj, } } + ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_COST]; + { + ps_codec->pi4_mb_intra_cost = ps_mem_rec->pv_base; + } + ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS]; { ps_codec->ps_sps_base = (sps_t *) ps_mem_rec->pv_base; @@ -5710,7 +5649,6 @@ static IV_STATUS_T ih264_set_ipe_params(void *pv_api_ip, ps_cfg->u4_enable_intra_4x4 = ps_ip->s_ive_ip.u4_enable_intra_4x4; ps_cfg->u4_enc_speed_preset = ps_ip->s_ive_ip.u4_enc_speed_preset; - ps_cfg->u4_constrained_intra_pred = ps_ip->s_ive_ip.u4_constrained_intra_pred; ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; @@ -5755,6 +5693,8 @@ static IV_STATUS_T ih264_set_gop_params(void *pv_api_ip, ps_cfg->u4_i_frm_interval = ps_ip->s_ive_ip.u4_i_frm_interval; ps_cfg->u4_idr_frm_interval = ps_ip->s_ive_ip.u4_idr_frm_interval; + if (ps_cfg->u4_idr_frm_interval < ps_cfg->u4_i_frm_interval) + ps_cfg->u4_i_frm_interval = ps_cfg->u4_idr_frm_interval; ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; @@ -5797,7 +5737,6 @@ static IV_STATUS_T ih264_set_profile_params(void *pv_api_ip, ps_op->s_ive_op.u4_error_code = 0; ps_cfg->e_profile = ps_ip->s_ive_ip.e_profile; - ps_cfg->u4_entropy_coding_mode = ps_ip->s_ive_ip.u4_entropy_coding_mode; ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; @@ -5884,50 +5823,36 @@ static WORD32 ih264e_set_vui_params(void *pv_api_ip, ps_op->u4_error_code = 0; - ps_vui->u1_aspect_ratio_info_present_flag = - ps_ip->u1_aspect_ratio_info_present_flag; + ps_vui->u1_aspect_ratio_info_present_flag = ps_ip->u1_aspect_ratio_info_present_flag; ps_vui->u1_aspect_ratio_idc = ps_ip->u1_aspect_ratio_idc; ps_vui->u2_sar_width = ps_ip->u2_sar_width; ps_vui->u2_sar_height = ps_ip->u2_sar_height; - ps_vui->u1_overscan_info_present_flag = - ps_ip->u1_overscan_info_present_flag; + ps_vui->u1_overscan_info_present_flag = ps_ip->u1_overscan_info_present_flag; ps_vui->u1_overscan_appropriate_flag = ps_ip->u1_overscan_appropriate_flag; - ps_vui->u1_video_signal_type_present_flag = - ps_ip->u1_video_signal_type_present_flag; + ps_vui->u1_video_signal_type_present_flag = ps_ip->u1_video_signal_type_present_flag; ps_vui->u1_video_format = ps_ip->u1_video_format; ps_vui->u1_video_full_range_flag = ps_ip->u1_video_full_range_flag; - ps_vui->u1_colour_description_present_flag = - ps_ip->u1_colour_description_present_flag; + ps_vui->u1_colour_description_present_flag = ps_ip->u1_colour_description_present_flag; ps_vui->u1_colour_primaries = ps_ip->u1_colour_primaries; ps_vui->u1_transfer_characteristics = ps_ip->u1_transfer_characteristics; ps_vui->u1_matrix_coefficients = ps_ip->u1_matrix_coefficients; - ps_vui->u1_chroma_loc_info_present_flag = - ps_ip->u1_chroma_loc_info_present_flag; - ps_vui->u1_chroma_sample_loc_type_top_field = - ps_ip->u1_chroma_sample_loc_type_top_field; - ps_vui->u1_chroma_sample_loc_type_bottom_field = - ps_ip->u1_chroma_sample_loc_type_bottom_field; - ps_vui->u1_vui_timing_info_present_flag = - ps_ip->u1_vui_timing_info_present_flag; + ps_vui->u1_chroma_loc_info_present_flag = ps_ip->u1_chroma_loc_info_present_flag; + ps_vui->u1_chroma_sample_loc_type_top_field = ps_ip->u1_chroma_sample_loc_type_top_field; + ps_vui->u1_chroma_sample_loc_type_bottom_field = ps_ip->u1_chroma_sample_loc_type_bottom_field; + ps_vui->u1_vui_timing_info_present_flag = ps_ip->u1_vui_timing_info_present_flag; ps_vui->u4_vui_num_units_in_tick = ps_ip->u4_vui_num_units_in_tick; ps_vui->u4_vui_time_scale = ps_ip->u4_vui_time_scale; ps_vui->u1_fixed_frame_rate_flag = ps_ip->u1_fixed_frame_rate_flag; - ps_vui->u1_nal_hrd_parameters_present_flag = - ps_ip->u1_nal_hrd_parameters_present_flag; - ps_vui->u1_vcl_hrd_parameters_present_flag = - ps_ip->u1_vcl_hrd_parameters_present_flag; + ps_vui->u1_nal_hrd_parameters_present_flag = ps_ip->u1_nal_hrd_parameters_present_flag; + ps_vui->u1_vcl_hrd_parameters_present_flag = ps_ip->u1_vcl_hrd_parameters_present_flag; ps_vui->u1_low_delay_hrd_flag = ps_ip->u1_low_delay_hrd_flag; ps_vui->u1_pic_struct_present_flag = ps_ip->u1_pic_struct_present_flag; - ps_vui->u1_bitstream_restriction_flag = - ps_ip->u1_bitstream_restriction_flag; - ps_vui->u1_motion_vectors_over_pic_boundaries_flag = - ps_ip->u1_motion_vectors_over_pic_boundaries_flag; + ps_vui->u1_bitstream_restriction_flag = ps_ip->u1_bitstream_restriction_flag; + ps_vui->u1_motion_vectors_over_pic_boundaries_flag = ps_ip->u1_motion_vectors_over_pic_boundaries_flag; ps_vui->u1_max_bytes_per_pic_denom = ps_ip->u1_max_bytes_per_pic_denom; ps_vui->u1_max_bits_per_mb_denom = ps_ip->u1_max_bits_per_mb_denom; - ps_vui->u1_log2_max_mv_length_horizontal = - ps_ip->u1_log2_max_mv_length_horizontal; - ps_vui->u1_log2_max_mv_length_vertical = - ps_ip->u1_log2_max_mv_length_vertical; + ps_vui->u1_log2_max_mv_length_horizontal = ps_ip->u1_log2_max_mv_length_horizontal; + ps_vui->u1_log2_max_mv_length_vertical = ps_ip->u1_log2_max_mv_length_vertical; ps_vui->u1_num_reorder_frames = ps_ip->u1_num_reorder_frames; ps_vui->u1_max_dec_frame_buffering = ps_ip->u1_max_dec_frame_buffering; diff --git a/encoder/ih264e_bitstream.c b/encoder/ih264e_bitstream.c index 9f73f69..dfdacff 100644 --- a/encoder/ih264e_bitstream.c +++ b/encoder/ih264e_bitstream.c @@ -30,13 +30,13 @@ * ittiam * * @par List of Functions: -* - ih264e_bitstrm_init() -* - ih264e_put_bits() -* - ih264e_put_bit() -* - ih264e_put_rbsp_trailing_bits() -* - ih264e_put_uev() -* - ih264e_put_sev() -* - ih264e_put_nal_start_code_prefix() +* - ih264e_bitstrm_init +* - ih264e_put_bits +* - ih264e_put_bit +* - ih264e_put_rbsp_trailing_bits +* - ih264e_put_uev +* - ih264e_put_sev +* - ih264e_put_nal_start_code_prefix * ****************************************************************************** */ @@ -45,7 +45,7 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -53,16 +53,17 @@ #include <stdarg.h> #include <math.h> -/* User include files */ +/* User Include Files */ #include "ih264e_config.h" #include "ih264_typedefs.h" -#include "ih264_platform_macros.h" + #include "ih264_debug.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ih264_defs.h" #include "ih264_macros.h" +#include "ih264_defs.h" +#include "ih264_platform_macros.h" +#include "ih264e_error.h" +#include "ih264e_bitstream.h" /*****************************************************************************/ /* Function Definitions */ @@ -182,7 +183,6 @@ IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm, /* 4. insert remaining bits of code starting from msb of cur word */ /* 5. update bitsleft in current word and stream buffer offset */ /********************************************************************/ - IH264E_ERROR_T status = IH264E_SUCCESS; WORD32 i, rem_bits = (code_len - bits_left_in_cw); /* insert parital code corresponding to bits left in cur word */ @@ -193,7 +193,8 @@ IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm, /* flush the bits in cur word byte by byte and copy to stream */ UWORD8 u1_next_byte = (u4_cur_word >> (i-8)) & 0xFF; - status |= ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); + IH264E_ERROR_T status = ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); + if (status != IH264E_SUCCESS) return status; } /* insert the remaining bits from code val into current word */ @@ -202,7 +203,7 @@ IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm, /* update the state variables and return success */ ps_bitstrm->u4_cur_word = u4_cur_word; ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE - rem_bits; - return (status); + return (IH264E_SUCCESS); } } @@ -262,7 +263,6 @@ IH264E_ERROR_T ih264e_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm) UWORD32 u4_cur_word = ps_bitstrm->u4_cur_word; WORD32 bits_left_in_cw = ps_bitstrm->i4_bits_left_in_cw; WORD32 bytes_left_in_cw = (bits_left_in_cw - 1) >> 3; - IH264E_ERROR_T status = IH264E_SUCCESS; /* insert a 1 at the end of current word and flush all the bits */ u4_cur_word |= (1 << (bits_left_in_cw - 1)); @@ -275,7 +275,8 @@ IH264E_ERROR_T ih264e_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm) /* flush the bits in cur word byte by byte and copy to stream */ UWORD8 u1_next_byte = (u4_cur_word >> (i-8)) & 0xFF; - status |= ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); + IH264E_ERROR_T status = ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); + if (status != IH264E_SUCCESS) return status; } /* Default init values for scratch variables of bitstream context */ @@ -283,7 +284,7 @@ IH264E_ERROR_T ih264e_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm) ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; ps_bitstrm->i4_zero_bytes_run = 0; - return (status); + return (IH264E_SUCCESS); } /** diff --git a/encoder/ih264e_bitstream.h b/encoder/ih264e_bitstream.h index 4f592f3..aee049b 100644 --- a/encoder/ih264e_bitstream.h +++ b/encoder/ih264e_bitstream.h @@ -36,8 +36,8 @@ ******************************************************************************* */ -#ifndef IH264E_BITSTREAM_H_ -#define IH264E_BITSTREAM_H_ +#ifndef _IH264E_BITSTREAM_H_ +#define _IH264E_BITSTREAM_H_ /*****************************************************************************/ /* Constant Macros */ @@ -265,216 +265,33 @@ static inline IH264E_ERROR_T ih264e_put_byte_epb(bitstrm_t *ps_bitstrm, UWORD8 b UWORD8 u1_next_byte = (ps_bitstrm->u4_cur_word >> (i - 8)) & 0xFF; \ err |= ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); \ } \ - ps_bitstrm->u4_cur_word = 0; \ - ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; \ -} \ - + if (err == IH264E_SUCCESS) { \ + ps_bitstrm->u4_cur_word = 0; \ + ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; \ + } \ +} /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ -/** -****************************************************************************** -* -* @brief Initializes the encoder bitstream engine -* -* @par Description -* This routine needs to be called at start of slice/frame encode -* -* @param[in] ps_bitstrm -* pointer to bitstream context (handle) -* -* @param[in] p1_bitstrm_buf -* bitstream buffer pointer where the encoded stream is generated in byte order -* -* @param[in] u4_max_bitstrm_size -* indicates maximum bitstream buffer size. (in bytes) -* If actual stream size exceeds the maximum size, encoder should -* 1. Not corrupt data beyond u4_max_bitstrm_size bytes -* 2. Report an error back to application indicating overflow -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_bitstrm_init - ( - bitstrm_t *ps_bitstrm, - UWORD8 *pu1_bitstrm_buf, - UWORD32 u4_max_bitstrm_size - ); +IH264E_ERROR_T ih264e_bitstrm_init(bitstrm_t *ps_bitstrm, + UWORD8 *pu1_bitstrm_buf, + UWORD32 u4_max_bitstrm_size); -/** -****************************************************************************** -* -* @brief puts a code with specified number of bits into the bitstream -* -* @par Description -* inserts code_len number of bits from lsb of code_val into the -* bitstream. If the total bytes (u4_strm_buf_offset) exceeds max -* available size (u4_max_strm_size), returns error without corrupting data -* beyond it -* -* @param[in] ps_bitstrm -* pointer to bitstream context (handle) -* -* @param[in] u4_code_val -* code value that needs to be inserted in the stream. -* -* @param[in] code_len -* indicates code length (in bits) of code_val that would be inserted in -* bitstream buffer size. -* -* @remarks Assumptions: all bits from bit position code_len to msb of -* code_val shall be zero -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_put_bits - ( - bitstrm_t *ps_bitstrm, - UWORD32 u4_code_val, - WORD32 code_len - ); +IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm, UWORD32 u4_code_val, + WORD32 code_len); -/** -****************************************************************************** -* -* @brief inserts a 1-bit code into the bitstream -* -* @par Description -* inserts 1bit lsb of code_val into the bitstream -* updates context members like u4_cur_word, u4_strm_buf_offset and -* i4_bits_left_in_cw. If the total words (u4_strm_buf_offset) exceeds max -* available size (u4_max_strm_size), returns error without corrupting data -* beyond it -* -* @param[in] ps_bitstrm -* pointer to bitstream context (handle) -* -* @param[in] u4_code_val -* code value that needs to be inserted in the stream. -* -* @remarks Assumptions: all bits from bit position 1 to msb of code_val -* shall be zero -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_put_bit - ( - bitstrm_t *ps_bitstrm, - UWORD32 u4_code_val - ); +IH264E_ERROR_T ih264e_put_bit(bitstrm_t *ps_bitstrm, UWORD32 u4_code_val); -/** -****************************************************************************** -* -* @brief inserts rbsp trailing bits at the end of stream buffer (NAL) -* -* @par Description -* inserts rbsp trailing bits, updates context members like u4_cur_word and -* i4_bits_left_in_cw and flushes the same in the bitstream buffer. If the -* total words (u4_strm_buf_offset) exceeds max available size -* (u4_max_strm_size), returns error without corrupting data beyond it -* -* @param[in] ps_bitstrm -* pointer to bitstream context (handle) -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_put_rbsp_trailing_bits - ( - bitstrm_t *ps_bitstrm - ); +IH264E_ERROR_T ih264e_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm); -/** -****************************************************************************** -* -* @brief puts exponential golomb code of a unsigned integer into bitstream -* -* @par Description -* computes uev code for given syntax element and inserts the same into -* bitstream by calling ih264e_put_bits() interface. -* -* @param[in] ps_bitstrm -* pointer to bitstream context (handle) -* -* @param[in] u4_code_num -* unsigned integer input whose golomb code is written in stream -* -* @remarks Assumptions: code value can be represented in less than 16bits -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_put_uev - ( - bitstrm_t *ps_bitstrm, - UWORD32 u4_code_num - ); +IH264E_ERROR_T ih264e_put_uev(bitstrm_t *ps_bitstrm, UWORD32 u4_code_num); -/** -****************************************************************************** -* -* @brief puts exponential golomb code of a signed integer into bitstream -* -* @par Description -* computes sev code for given syntax element and inserts the same into -* bitstream by calling ih264e_put_bits() interface. -* -* @param[in] ps_bitstrm -* pointer to bitstream context (handle) -* -* @param[in] syntax_elem -* signed integer input whose golomb code is written in stream -* -* @remarks Assumptions: code value can be represented in less than 16bits -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_put_sev - ( - bitstrm_t *ps_bitstrm, - WORD32 syntax_elem - ); +IH264E_ERROR_T ih264e_put_sev(bitstrm_t *ps_bitstrm, WORD32 syntax_elem); -/** -****************************************************************************** -* -* @brief insert NAL start code prefix (0x000001) into bitstream with an option -* of inserting leading_zero_8bits (which makes startcode prefix as 0x00000001) -* -* @par Description -* Although start code prefix could have been put by calling ih264e_put_bits(), -* ih264e_put_nal_start_code_prefix() is specially added to make sure emulation -* prevention insertion is not done for the NAL start code prefix which will -* surely happen otherwise by calling ih264e_put_bits() interface. -* -* @param[in] ps_bitstrm -* pointer to bitstream context (handle) -* -* @param[in] insert_leading_zero_8bits -* flag indicating if one more zero bytes needs to prefixed before start code -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_put_nal_start_code_prefix - ( - bitstrm_t *ps_bitstrm, - WORD32 insert_leading_zero_8bits - ); +IH264E_ERROR_T ih264e_put_nal_start_code_prefix(bitstrm_t *ps_bitstrm, + WORD32 insert_leading_zero_8bits); -#endif /* IH264E_BITSTREAM_H_ */ +#endif /* _IH264E_BITSTREAM_H_ */ diff --git a/encoder/ih264e_cabac.c b/encoder/ih264e_cabac.c index 2d91058..9e9add9 100644 --- a/encoder/ih264e_cabac.c +++ b/encoder/ih264e_cabac.c @@ -26,15 +26,21 @@ * @brief * Contains all leaf level functions for CABAC entropy coding. * -* * @author -* Doney Alex +* ittiam * * @par List of Functions: -* +* - ih264e_cabac_UEGk0_binarization +* - ih264e_get_cabac_context +* - ih264e_cabac_put_byte +* - ih264e_cabac_encode_bin +* - ih264e_encode_decision_bins +* - ih264e_cabac_encode_terminate +* - ih264e_cabac_encode_bypass_bin +* - ih264e_cabac_encode_bypass_bins * * @remarks -* None +* none * ******************************************************************************* */ @@ -43,44 +49,47 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <assert.h> #include <limits.h> #include <string.h> -/* User include files */ +/* User Include Files */ #include "ih264e_config.h" #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" + #include "ih264_debug.h" -#include "ih264_defs.h" -#include "ih264e_defs.h" #include "ih264_macros.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" -#include "ih264_platform_macros.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_cavlc_tables.h" #include "ih264_cabac_tables.h" +#include "ih264_platform_macros.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" -#include "ih264e_rate_control.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_cabac.h" #include "ih264e_encode_header.h" -#include "ih264_cavlc_tables.h" +#include "ih264e_cabac.h" #include "ih264e_statistics.h" #include "ih264e_trace.h" @@ -89,29 +98,26 @@ /* Function Definitions */ /*****************************************************************************/ - /** - ******************************************************************************* - * - * @brief - * k-th order Exp-Golomb (UEGk) binarization process: Implements concatenated - * unary/ k-th order Exp-Golomb (UEGk) binarization process, - * where k = 0 as defined in 9.3.2.3 of ITU_T_H264-201402 - * - * @param[in] i2_sufs - * Suffix bit string - * - * @param[in] pi1_bins_len - * Pointer to length of tthe string - * - * @returns Binarized value - * - * @remarks - * None - * - ******************************************************************************* - */ - +******************************************************************************* +* +* @brief +* k-th order Exp-Golomb (UEGk) binarization process: Implements concatenated +* unary/ k-th order Exp-Golomb (UEGk) binarization process, where k = 0 as +* defined in 9.3.2.3 of ITU_T_H264-201402 +* +* @param[in] i2_sufs +* Suffix bit string +* +* @param[in] pi1_bins_len +* Pointer to length of tthe string +* +* @returns Binarized value +* +* @remarks none +* +******************************************************************************* +*/ UWORD32 ih264e_cabac_UEGk0_binarization(WORD16 i2_sufs, WORD8 *pi1_bins_len) { WORD32 unary_length; @@ -135,33 +141,29 @@ UWORD32 ih264e_cabac_UEGk0_binarization(WORD16 i2_sufs, WORD8 *pi1_bins_len) } /** - ******************************************************************************* - * - * @brief - * Get cabac context for the MB :calculates the pointers to Top and left - * cabac neighbor context depending upon neighbor availability. - * - * @param[in] ps_ent_ctxt - * Pointer to entropy context structure - * - * @param[in] u4_mb_type - * Type of MB - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Get cabac context for the MB :calculates the pointers to Top and left +* cabac neighbor context depending upon neighbor availability. +* +* @param[in] ps_ent_ctxt +* Pointer to entropy context structure +* +* @param[in] u4_mb_type +* Type of MB +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264e_get_cabac_context(entropy_ctxt_t *ps_ent_ctxt, WORD32 u4_mb_type) { - - /* CABAC context */ cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac; mb_info_ctxt_t *ps_ctx_inc_mb_map; cab_csbp_t *ps_lft_csbp; - WORD32 i4_lft_avail, i4_top_avail, i4_is_intra; WORD32 i4_mb_x, i4_mb_y; UWORD8 *pu1_slice_idx = ps_ent_ctxt->pu1_slice_idx; @@ -222,29 +224,25 @@ void ih264e_get_cabac_context(entropy_ctxt_t *ps_ent_ctxt, WORD32 u4_mb_type) ps_cabac_ctxt->ps_curr_ctxt_mb_info->i1_ref_idx[3] = 0; memset(ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_mv, 0, 16); } - } - - /** - ******************************************************************************* - * @brief - * flushing at termination: Explained in flowchart 9-12(ITU_T_H264-201402). - * - * @param[in] ps_cabac_ctxt - * pointer to cabac context (handle) - * - * @returns none - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* flushing at termination: Explained in flowchart 9-12(ITU_T_H264-201402). +* +* @param[in] ps_cabac_ctxt +* pointer to cabac context (handle) +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ IH264E_ERROR_T ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) { - /* bit stream ptr */ bitstrm_t *ps_stream = ps_cabac_ctxt->ps_bitstrm; encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env); UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low; @@ -315,41 +313,41 @@ IH264E_ERROR_T ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) last_byte &= 0xFF; status |= ih264e_put_byte_epb(ps_stream, last_byte); - /* update the state variables and return success */ - ps_stream->i4_zero_bytes_run = 0; - /* Default init values for scratch variables of bitstream context */ - ps_stream->u4_cur_word = 0; - ps_stream->i4_bits_left_in_cw = WORD_SIZE; + if (status == IH264E_SUCCESS) { + /* update the state variables and return success */ + ps_stream->i4_zero_bytes_run = 0; + /* Default init values for scratch variables of bitstream context */ + ps_stream->u4_cur_word = 0; + ps_stream->i4_bits_left_in_cw = WORD_SIZE; + } } return status; } /** - ****************************************************************************** - * - * @brief Puts new byte (and outstanding bytes) into bitstream after cabac - * renormalization - * - * @par Description - * 1. Extract the leading byte of low(L) - * 2. If leading byte=0xff increment outstanding bytes and return - * (as the actual bits depend on carry propogation later) - * 3. If leading byte is not 0xff check for any carry propogation - * 4. Insert the carry (propogated in previous byte) along with outstanding - * bytes (if any) and leading byte - * - * - * @param[in] ps_cabac_ctxt - * pointer to cabac context (handle) - * - * @return - * - ****************************************************************************** - */ +****************************************************************************** +* +* @brief Puts new byte (and outstanding bytes) into bitstream after cabac +* renormalization +* +* @par Description +* 1. Extract the leading byte of low(L) +* 2. If leading byte=0xff increment outstanding bytes and return +* (as the actual bits depend on carry propogation later) +* 3. If leading byte is not 0xff check for any carry propogation +* 4. Insert the carry (propogated in previous byte) along with outstanding +* bytes (if any) and leading byte +* +* @param[in] ps_cabac_ctxt +* pointer to cabac context (handle) +* +* @returns none +* +****************************************************************************** +*/ IH264E_ERROR_T ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) { - /* bit stream ptr */ bitstrm_t *ps_stream = ps_cabac_ctxt->ps_bitstrm; encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env); UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low; @@ -433,36 +431,32 @@ IH264E_ERROR_T ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) return status; } - - - - /** - ****************************************************************************** - * - * @brief Codes a bin based on probablilty and mps packed context model - * - * @par Description - * 1. Apart from encoding bin, context model is updated as per state transition - * 2. Range and Low renormalization is done based on bin and original state - * 3. After renorm bistream is updated (if required) - * - * @param[in] ps_cabac - * pointer to cabac context (handle) - * - * @param[in] bin - * bin(boolean) to be encoded - * - * @param[in] pu1_bin_ctxts - * index of cabac context model containing pState[bits 5-0] | MPS[bit6] - * - * @return - * - ****************************************************************************** - */ +/** +****************************************************************************** +* +* @brief Codes a bin based on probablilty and mps packed context model +* +* @par Description +* 1. Apart from encoding bin, context model is updated as per state transition +* 2. Range and Low renormalization is done based on bin and original state +* 3. After renorm bistream is updated (if required) +* +* @param[in] ps_cabac +* pointer to cabac context (handle) +* +* @param[in] bin +* bin(boolean) to be encoded +* +* @param[in] pu1_bin_ctxts +* index of cabac context model containing pState[bits 5-0] | MPS[bit6] +* +* @return none +* +****************************************************************************** +*/ void ih264e_cabac_encode_bin(cabac_ctxt_t *ps_cabac, WORD32 bin, bin_ctxt_model *pu1_bin_ctxts) { - encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env); UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range; UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low; @@ -471,6 +465,7 @@ void ih264e_cabac_encode_bin(cabac_ctxt_t *ps_cabac, WORD32 bin, UWORD8 u1_mps = !!((*pu1_bin_ctxts) & (0x40)); WORD32 shift; UWORD32 u4_table_val; + /* Sanity checks */ ASSERT((bin == 0) || (bin == 1)); ASSERT((u4_range >= 256) && (u4_range < 512)); @@ -501,64 +496,58 @@ void ih264e_cabac_encode_bin(cabac_ctxt_t *ps_cabac, WORD32 bin, (*pu1_bin_ctxts) = (u1_mps << 6) | state_mps; - /*****************************************************************/ - /* Renormalization; calculate bits generated based on range(R) */ - /* Note : 6 <= R < 512; R is 2 only for terminating encode */ - /*****************************************************************/ - GETRANGE(shift, u4_range); - shift = 9 - shift; - u4_low <<= shift; - u4_range <<= shift; - - /* bits to be inserted in the bitstream */ - ps_cab_enc_env->u4_bits_gen += shift; - ps_cab_enc_env->u4_code_int_range = u4_range; - ps_cab_enc_env->u4_code_int_low = u4_low; - - /* generate stream when a byte is ready */ - if (ps_cab_enc_env->u4_bits_gen > CABAC_BITS) - { - ih264e_cabac_put_byte(ps_cabac); - } - -} - - + /*****************************************************************/ + /* Renormalization; calculate bits generated based on range(R) */ + /* Note : 6 <= R < 512; R is 2 only for terminating encode */ + /*****************************************************************/ + GETRANGE(shift, u4_range); + shift = 9 - shift; + u4_low <<= shift; + u4_range <<= shift; + /* bits to be inserted in the bitstream */ + ps_cab_enc_env->u4_bits_gen += shift; + ps_cab_enc_env->u4_code_int_range = u4_range; + ps_cab_enc_env->u4_code_int_low = u4_low; - /** - ******************************************************************************* - * - * @brief - * Encoding process for a binary decision :implements encoding process of a decision - * as defined in 9.3.4.2 . This function encodes multiple bins, of a symbol. Implements - * flowchart Figure 9-7( ITU_T_H264-201402) - * - * @param[in] u4_bins - * array of bin values - * - * @param[in] i1_bins_len - * Length of bins, maximum 32 - * - * @param[in] u4_ctx_inc - * CtxInc, byte0- bin0, byte1-bin1 .. - * - * @param[in] i1_valid_len - * valid length of bins, after that CtxInc is constant - * - * @param[in] pu1_bin_ctxt_type - * Pointer to binary contexts + /* generate stream when a byte is ready */ + if (ps_cab_enc_env->u4_bits_gen > CABAC_BITS) + { + ih264e_cabac_put_byte(ps_cabac); + } +} - * @param[in] ps_cabac - * Pointer to cabac_context_structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +/** +******************************************************************************* +* +* @brief Encoding process for a binary decision: implements encoding process of +* a decision as defined in 9.3.4.2. This function encodes multiple bins, of a +* symbol. Implements flowchart Figure 9-7( ITU_T_H264-201402) +* +* @param[in] u4_bins +* array of bin values +* +* @param[in] i1_bins_len +* Length of bins, maximum 32 +* +* @param[in] u4_ctx_inc +* CtxInc, byte0- bin0, byte1-bin1 .. +* +* @param[in] i1_valid_len +* valid length of bins, after that CtxInc is constant +* +* @param[in] pu1_bin_ctxt_type +* Pointer to binary contexts +* +* @param[in] ps_cabac +* Pointer to cabac_context_structure +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264e_encode_decision_bins(UWORD32 u4_bins, WORD8 i1_bins_len, UWORD32 u4_ctx_inc, WORD8 i1_valid_len, bin_ctxt_model *pu1_bin_ctxt_type, @@ -578,38 +567,29 @@ void ih264e_encode_decision_bins(UWORD32 u4_bins, WORD8 i1_bins_len, ih264e_cabac_encode_bin(ps_cabac, u1_bin, pu1_bin_ctxt_type + u1_ctx_inc); } - } - - - - - /** - ******************************************************************************* - * @brief - * Encoding process for a binary decision before termination:Encoding process - * of a termination(9.3.4.5 :ITU_T_H264-201402) . Explained in flowchart 9-11. - * - * @param[in] ps_cabac - * Pointer to cabac structure - * - * @param[in] term_bin - * Symbol value, end of slice or not, term_bin is binary - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @brief +* Encoding process for a binary decision before termination:Encoding process +* of a termination(9.3.4.5:ITU_T_H264-201402). Explained in flowchart 9-11. +* +* @param[in] ps_cabac +* Pointer to cabac structure +* +* @param[in] term_bin +* Symbol value, end of slice or not, term_bin is binary +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264e_cabac_encode_terminate(cabac_ctxt_t *ps_cabac, WORD32 term_bin) { - encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env); - UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range; UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low; UWORD32 u4_rlps; @@ -655,33 +635,28 @@ void ih264e_cabac_encode_terminate(cabac_ctxt_t *ps_cabac, WORD32 term_bin) { ih264e_cabac_flush(ps_cabac); } - } - /** - ******************************************************************************* - * @brief - * Bypass encoding process for binary decisions: Explained (9.3.4.4 :ITU_T_H264-201402) - * , flowchart 9-10. - * - * @param[ino] ps_cabac : pointer to cabac context (handle) - * - * @param[in] bin : bypass bin(0/1) to be encoded - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ - +******************************************************************************* +* @brief Bypass encoding process for binary decisions. +* Explained (9.3.4.4 :ITU_T_H264-201402), flowchart 9-10. +* +* @param[ino] ps_cabac +* pointer to cabac context (handle) +* +* @param[in] bin +* bypass bin(0/1) to be encoded +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264e_cabac_encode_bypass_bin(cabac_ctxt_t *ps_cabac, WORD32 bin) { - encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env); - UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range; UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low; @@ -705,40 +680,35 @@ void ih264e_cabac_encode_bypass_bin(cabac_ctxt_t *ps_cabac, WORD32 bin) { ih264e_cabac_put_byte(ps_cabac); } - } - - /** - ****************************************************************************** - * - * @brief Encodes a series of bypass bins (FLC bypass bins) - * - * @par Description - * This function is more optimal than calling ih264e_cabac_encode_bypass_bin() - * in a loop as cabac low, renorm and generating the stream (8bins at a time) - * can be done in one operation - * - * @param[inout]ps_cabac - * pointer to cabac context (handle) - * - * @param[in] u4_bins - * syntax element to be coded (as FLC bins) - * - * @param[in] num_bins - * This is the FLC length for u4_sym - * - * @return - * - ****************************************************************************** - */ - +/** +****************************************************************************** +* +* @brief Encodes a series of bypass bins (FLC bypass bins) +* +* @par Description +* This function is more optimal than calling ih264e_cabac_encode_bypass_bin() +* in a loop as cabac low, renorm and generating the stream (8bins at a time) +* can be done in one operation +* +* @param[inout]ps_cabac +* pointer to cabac context (handle) +* +* @param[in] u4_bins +* syntax element to be coded (as FLC bins) +* +* @param[in] num_bins +* This is the FLC length for u4_sym +* +* @return none +* +****************************************************************************** +*/ void ih264e_cabac_encode_bypass_bins(cabac_ctxt_t *ps_cabac, UWORD32 u4_bins, WORD32 num_bins) { - encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env); - UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range; WORD32 next_byte; @@ -780,5 +750,4 @@ void ih264e_cabac_encode_bypass_bins(cabac_ctxt_t *ps_cabac, UWORD32 u4_bins, /* insert the leading byte of low into stream */ ih264e_cabac_put_byte(ps_cabac); } - } diff --git a/encoder/ih264e_cabac.h b/encoder/ih264e_cabac.h index bc4b07c..c8492df 100644 --- a/encoder/ih264e_cabac.h +++ b/encoder/ih264e_cabac.h @@ -19,38 +19,40 @@ */ /** - ******************************************************************************* - * @file - * ih264e_cabac_structs.h - * - * @brief - * This file contains cabac related macros, enums, tables and function declarations. - * - * @author - * Doney Alex - * - * @remarks - * none - * - ******************************************************************************* - */ - -#ifndef IH264E_CABAC_H_ -#define IH264E_CABAC_H_ +******************************************************************************* +* @file +* ih264e_cabac.h +* +* @brief +* This file contains declarations necessary for cabac encoding +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ +#ifndef _IH264E_CABAC_H_ +#define _IH264E_CABAC_H_ +/*****************************************************************************/ +/* Macros */ +/*****************************************************************************/ -/******************************************************************************* -@brief Bit precision of cabac engine; +/** +******************************************************************************* +* @brief Bit precision of cabac engine; ******************************************************************************* */ #define CABAC_BITS 9 - /** -****************************************************************************** - * @macro Reverse bits in an unsigned integer -****************************************************************************** +******************************************************************************* +* @macro Reverse bits in an unsigned integer +******************************************************************************* */ #define REV(u4_input, u4_output) \ { \ @@ -65,370 +67,57 @@ } /** -****************************************************************************** +******************************************************************************* *! Bit manipulation macros -****************************************************************************** +******************************************************************************* */ #define SETBIT(a, i) ((a) |= (1 << (i))) #define CLEARBIT(a, i) ((a) &= ~(1 << (i))) - /** -****************************************************************************** +******************************************************************************* *! Cabac module expect atlesat MIN_STREAM_SIZE_MB bytes left in stream buffer *! for encoding an MB -****************************************************************************** +******************************************************************************* */ #define MIN_STREAM_SIZE_MB 1024 - /*****************************************************************************/ -/* Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ - -/** - ******************************************************************************* - * - * @brief - * Initialize default context values and pointers. - * - * @param[in] ps_ent_ctxt - * Pointer to entropy context structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ void ih264e_init_cabac_table(entropy_ctxt_t *ps_ent_ctxt); - -/** - ******************************************************************************* - * - * @brief - * Initialize cabac context: Intitalize all contest with init values given in the spec. - * Called at the beginning of entropy coding of each slice for CABAC encoding. - * - * @param[in] ps_ent_ctxt - * Pointer to entropy context structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ void ih264e_init_cabac_ctxt(entropy_ctxt_t *ps_ent_ctxt); - - -/** - ******************************************************************************* - * - * @brief - * k-th order Exp-Golomb (UEGk) binarization process: Implements concatenated - * unary/ k-th order Exp-Golomb (UEGk) binarization process, - * where k = 0 as defined in 9.3.2.3 of ITU_T_H264-201402 - * - * @param[in] i2_sufs - * Suffix bit string - * - * @param[in] pi1_bins_len - * Pointer to length of the string - * - * @returns Binarized value - * - * @remarks - * None - * - ******************************************************************************* - */ UWORD32 ih264e_cabac_UEGk0_binarization(WORD16 i2_sufs, WORD8 *pi1_bins_len); - -/** - ******************************************************************************* - * - * @brief - * Get cabac context for the MB :calculates the pointers to Top and left - * cabac neighbor context depending upon neighbor availability. - * - * @param[in] ps_ent_ctxt - * Pointer to entropy context structure - * - * @param[in] u4_mb_type - * Type of MB - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ void ih264e_get_cabac_context(entropy_ctxt_t *ps_ent_ctxt, WORD32 u4_mb_type); - -/** - ******************************************************************************* - * @brief - * flushing at termination: Explained in flowchart 9-12(ITU_T_H264-201402). - * - * @param[in] ps_cabac_ctxt - * pointer to cabac context (handle) - * - * @returns none - * - * @remarks - * None - * - ******************************************************************************* - */ IH264E_ERROR_T ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt); - -/** - ****************************************************************************** - * - * @brief Puts new byte (and outstanding bytes) into bitstream after cabac - * renormalization - * - * @par Description - * 1. Extract the leading byte of low(L) - * 2. If leading byte=0xff increment outstanding bytes and return - * (as the actual bits depend on carry propogation later) - * 3. If leading byte is not 0xff check for any carry propogation - * 4. Insert the carry (propogated in previous byte) along with outstanding - * bytes (if any) and leading byte - * - * - * @param[inout] ps_cabac_ctxt - * pointer to cabac context (handle) - * - * @return - * - ****************************************************************************** - */ IH264E_ERROR_T ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt); - -/** - ****************************************************************************** - * - * @brief Codes a bin based on probablilty and mps packed context model - * - * @par Description - * 1. Apart from encoding bin, context model is updated as per state transition - * 2. Range and Low renormalization is done based on bin and original state - * 3. After renorm bistream is updated (if required) - * - * @param[inout] ps_cabac - * pointer to cabac context (handle) - * - * @param[in] bin - * bin(boolean) to be encoded - * - * @param[in] pu1_bin_ctxts - * index of cabac context model containing pState[bits 5-0] | MPS[bit6] - * - * @return - * - ****************************************************************************** - */ void ih264e_cabac_encode_bin(cabac_ctxt_t *ps_cabac, WORD32 bin, bin_ctxt_model *pu1_bin_ctxts); - - -/** - ******************************************************************************* - * - * @brief - * Encoding process for a binary decision :implements encoding process of a decision - * as defined in 9.3.4.2 . This function encodes multiple bins, of a symbol. Implements - * flowchart Figure 9-7( ITU_T_H264-201402) - * - * @param[in] u4_bins - * array of bin values - * - * @param[in] i1_bins_len - * Length of bins, maximum 32 - * - * @param[in] u4_ctx_inc - * CtxInc, byte0- bin0, byte1-bin1 .. - * - * @param[in] i1_valid_len - * valid length of bins, after that CtxInc is constant - * - * @param[in] pu1_bin_ctxt_type - * Pointer to binary contexts - - * @param[in] ps_cabac - * Pointer to cabac_context_structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ void ih264e_encode_decision_bins(UWORD32 u4_bins, WORD8 i1_bins_len, UWORD32 u4_ctx_inc, WORD8 i1_valid_len, bin_ctxt_model *pu1_bin_ctxt_type, cabac_ctxt_t *ps_cabac); -/** - ******************************************************************************* - * @brief - * Encoding process for a binary decision before termination:Encoding process - * of a termination(9.3.4.5 :ITU_T_H264-201402) . Explained in flowchart 9-11. - * - * @param[in] ps_cabac - * Pointer to cabac structure - * - * @param[in] term_bin - * Symbol value, end of slice or not, term_bin is binary - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ void ih264e_cabac_encode_terminate(cabac_ctxt_t *ps_cabac, WORD32 term_bin); - -/** - ******************************************************************************* - * @brief - * Bypass encoding process for binary decisions: Explained (9.3.4.4 :ITU_T_H264-201402) - * , flowchart 9-10. - * - * @param[in] ps_cabac : pointer to cabac context (handle) - * - * @param[in] bin : bypass bin(0/1) to be encoded - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ - void ih264e_cabac_encode_bypass_bin(cabac_ctxt_t *ps_cabac, WORD32 bin); - - -/** - ****************************************************************************** - * - * @brief Encodes a series of bypass bins (FLC bypass bins) - * - * @par Description - * This function is more optimal than calling ih264e_cabac_encode_bypass_bin() - * in a loop as cabac low, renorm and generating the stream (8bins at a time) - * can be done in one operation - * - * @param[inout]ps_cabac - * pointer to cabac context (handle) - * - * @param[in] u4_bins - * syntax element to be coded (as FLC bins) - * - * @param[in] num_bins - * This is the FLC length for u4_sym - * - * @return - * - ****************************************************************************** - */ - void ih264e_cabac_encode_bypass_bins(cabac_ctxt_t *ps_cabac, UWORD32 u4_bins, WORD32 num_bins); - - - - -/** - ******************************************************************************* - * - * @brief - * This function generates CABAC coded bit stream for an Intra Slice. - * - * @description - * The mb syntax layer for intra slices constitutes luma mb mode, luma sub modes - * (if present), mb qp delta, coded block pattern, chroma mb mode and - * luma/chroma residue. These syntax elements are written as directed by table - * 7.3.5 of h264 specification. - * - * @param[in] ps_ent_ctxt - * pointer to entropy context - * - * @returns error code - * - * @remarks none - * - ******************************************************************************* - */ IH264E_ERROR_T ih264e_write_islice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt); - -/** - ******************************************************************************* - * - * @brief - * This function generates CABAC coded bit stream for Inter slices - * - * @description - * The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes - * (if present), mb qp delta, coded block pattern, chroma mb mode and - * luma/chroma residue. These syntax elements are written as directed by table - * 7.3.5 of h264 specification - * - * @param[in] ps_ent_ctxt - * pointer to entropy context - * - * @returns error code - * - * @remarks none - * - ******************************************************************************* - */ IH264E_ERROR_T ih264e_write_pslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt); - -/** - ******************************************************************************* - * - * @brief - * This function generates CABAC coded bit stream for B slices - * - * @description - * The mb syntax layer for inter slices constitutes luma mb mode, - * mb qp delta, coded block pattern, chroma mb mode and - * luma/chroma residue. These syntax elements are written as directed by table - * 7.3.5 of h264 specification - * - * @param[in] ps_ent_ctxt - * pointer to entropy context - * - * @returns error code - * - * @remarks none - * - ******************************************************************************* - */ IH264E_ERROR_T ih264e_write_bslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt); - -#endif /* IH264E_CABAC_H_ */ +#endif /* _IH264E_CABAC_H_ */ diff --git a/encoder/ih264e_cabac_encode.c b/encoder/ih264e_cabac_encode.c index e49ab58..156632c 100644 --- a/encoder/ih264e_cabac_encode.c +++ b/encoder/ih264e_cabac_encode.c @@ -21,20 +21,34 @@ /** ******************************************************************************* * @file -* ih264e_cabac.c +* ih264e_cabac_encode.c * * @brief * Contains all functions to encode in CABAC entropy mode * -* * @author -* Doney Alex -* -* @par List of Functions: +* ittiam * +* @par List of Functions +* - ih264e_cabac_enc_mb_skip +* - ih264e_cabac_enc_intra_mb_type +* - ih264e_cabac_enc_4x4mb_modes +* - ih264e_cabac_enc_chroma_predmode +* - ih264e_cabac_enc_cbp +* - ih264e_cabac_enc_mb_qp_delta +* - ih264e_cabac_write_coeff4x4 +* - ih264e_cabac_encode_residue_luma_dc +* - ih264e_cabac_write_chroma_residue +* - ih264e_cabac_encode_residue +* - ih264e_cabac_enc_ctx_mvd +* - ih264e_cabac_enc_mvds_p16x16 +* - ih264e_cabac_enc_mvds_b16x16 +* - ih264e_write_islice_mb_cabac +* - ih264e_write_pslice_mb_cabac +* - ih264e_write_bslice_mb_cabac * * @remarks -* None +* none * ******************************************************************************* */ @@ -43,100 +57,55 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <assert.h> #include <limits.h> #include <string.h> -/* User include files */ +/* User Include Files */ #include "ih264e_config.h" #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" + #include "ih264_debug.h" -#include "ih264_defs.h" -#include "ih264e_defs.h" #include "ih264_macros.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" -#include "ih264_platform_macros.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_cavlc_tables.h" #include "ih264_cabac_tables.h" +#include "ih264_platform_macros.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" -#include "ih264e_rate_control.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_cabac.h" #include "ih264e_encode_header.h" -#include "ih264_cavlc_tables.h" -#include "ih264e_cavlc.h" +#include "ih264e_cabac.h" #include "ih264e_statistics.h" #include "ih264e_trace.h" /*****************************************************************************/ -/* Function Definitions */ +/* Global Definitions */ /*****************************************************************************/ - - - -/** - ******************************************************************************* - * - * @brief - * Encodes mb_skip_flag using CABAC entropy coding mode. - * - * @param[in] u1_mb_skip_flag - * mb_skip_flag - * - * @param[in] ps_cabac_ctxt - * Pointer to cabac context structure - * - * @param[in] u4_ctxidx_offset - * ctxIdxOffset for mb_skip_flag context - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ -static void ih264e_cabac_enc_mb_skip(UWORD8 u1_mb_skip_flag, - cabac_ctxt_t *ps_cabac_ctxt, - UWORD32 u4_ctxidx_offset) -{ - - UWORD8 u4_ctx_inc; - WORD8 a, b; - a = ((ps_cabac_ctxt->ps_left_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK) ? - 0 : 1); - b = ((ps_cabac_ctxt->ps_top_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK) ? - 0 : 1); - - u4_ctx_inc = a + b; - /* Encode the bin */ - ih264e_cabac_encode_bin(ps_cabac_ctxt, - (UWORD32) u1_mb_skip_flag, - ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctxidx_offset - + u4_ctx_inc); - -} - - -/* ! < Table 9-36 – Binarization for macroblock types in I slices in ITU_T_H264-201402 +/* ! < Table 9-36 : Binarization for macroblock types in I slices in ITU_T_H264 * Bits 0-7 : binarised value * Bits 8-15: length of binary sequence */ @@ -145,7 +114,6 @@ static const UWORD32 u4_mb_type_intra[26] = 0x074c, 0x074d, 0x074e, 0x074f, 0x0628, 0x0629, 0x062a, 0x062b, 0x0758, 0x0759, 0x075a, 0x075b, 0x075c, 0x075d, 0x075e, 0x075f, 0x0203 }; - /* CtxInc for mb types */ static const UWORD32 u4_mb_ctxinc[2][26] = { @@ -163,39 +131,97 @@ static const UWORD32 u4_mb_ctxinc[2][26] = 0x0012233, 0x0012233, 0x0012233, 0x00} }; +/* ! < Table 9-37 : Binarization for macroblock types in B slices in ITU_T_H264-201402 + * Bits 0-7 : binarised value + * Bits 8-15: length of binary sequence */ +static const UWORD32 u4_b_mb_type[27] = + { 0x0100, 0x0301, 0x0305, 0x0603, 0x0623, 0x0613, 0x0633, 0x060b, 0x062b, + 0x061b, 0x063b, 0x061f, 0x0707, 0x0747, 0x0727, 0x0767, 0x0717, 0x0757, + 0x0737, 0x0777, 0x070f, 0x074f, 0x063f }; + +/* CtxInc for mb types in B slices */ +static const UWORD32 ui_b_mb_type_ctx_inc[27] = + { 0x00, 0x0530, 0x0530, 0x0555430, 0x0555430, 0x0555430, 0x0555430, + 0x0555430, 0x0555430, 0x0555430, 0x0555430, 0x0555430, 0x05555430, + 0x05555430, 0x05555430, 0x05555430, 0x05555430, 0x05555430, 0x05555430, + 0x05555430, 0x05555430, 0x05555430, 0x0555430 }; + + +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ /** - ******************************************************************************* - * - * @brief - * Encodes mb_type for an intra MB. - * - * @param[in] u4_slice_type - * slice type - * - * @param[in] u4_intra_mb_type - * MB type (Table 7-11) - * - * @param[in] ps_cabac_ctxt - * Pointer to cabac context structure - * - ** @param[in] u4_ctxidx_offset - * ctxIdxOffset for mb_type context - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Encodes mb_skip_flag using CABAC entropy coding mode. +* +* @param[in] u1_mb_skip_flag +* mb_skip_flag +* +* @param[in] ps_cabac_ctxt +* Pointer to cabac context structure +* +* @param[in] u4_ctxidx_offset +* ctxIdxOffset for mb_skip_flag context +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ +static void ih264e_cabac_enc_mb_skip(UWORD8 u1_mb_skip_flag, + cabac_ctxt_t *ps_cabac_ctxt, + UWORD32 u4_ctxidx_offset) +{ + UWORD8 u4_ctx_inc; + WORD8 a, b; + + a = ((ps_cabac_ctxt->ps_left_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK) ? + 0 : 1); + b = ((ps_cabac_ctxt->ps_top_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK) ? + 0 : 1); + + u4_ctx_inc = a + b; + + /* Encode the bin */ + ih264e_cabac_encode_bin(ps_cabac_ctxt, + (UWORD32) u1_mb_skip_flag, + ps_cabac_ctxt->au1_cabac_ctxt_table + + u4_ctxidx_offset + u4_ctx_inc); +} +/** +******************************************************************************* +* +* @brief +* Encodes mb_type for an intra MB. +* +* @param[in] u4_slice_type +* slice type +* +* @param[in] u4_intra_mb_type +* MB type (Table 7-11) +* +* @param[in] ps_cabac_ctxt +* Pointer to cabac context structure +* +* @param[in] u4_ctxidx_offset +* ctxIdxOffset for mb_type context +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_enc_intra_mb_type(UWORD32 u4_slice_type, UWORD32 u4_intra_mb_type, cabac_ctxt_t *ps_cabac_ctxt, UWORD32 u4_ctx_idx_offset) { - encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env); bin_ctxt_model *pu1_mb_bin_ctxt, *pu1_bin_ctxt; UWORD8 u1_bin; @@ -252,8 +278,7 @@ static void ih264e_cabac_enc_intra_mb_type(UWORD32 u4_slice_type, WORD8 i1_state = (*pu1_bin_ctxt) & 0x3F; u2_quant_code_int_range = ((u4_code_int_range >> 6) & 0x03); - u4_table_val = - gau4_ih264_cabac_table[i1_state][u2_quant_code_int_range]; + u4_table_val = gau4_ih264_cabac_table[i1_state][u2_quant_code_int_range]; u4_code_int_range_lps = u4_table_val & 0xFF; u4_code_int_range -= u4_code_int_range_lps; @@ -303,39 +328,36 @@ static void ih264e_cabac_enc_intra_mb_type(UWORD32 u4_slice_type, ih264e_cabac_put_byte(ps_cabac_ctxt); u4_code_int_range = ps_cab_enc_env->u4_code_int_range; u4_code_int_low = ps_cab_enc_env->u4_code_int_low; - } } } - - /** - ******************************************************************************* - * - * @brief - * Encodes prev_intra4x4_pred_mode_flag and - * rem_intra4x4_pred_mode using CABAC entropy coding mode - * - * @param[in] ps_cabac_ctxt - * Pointer to cabac context structure - * - * @param[in] pu1_intra_4x4_modes - * Pointer to array containing prev_intra4x4_pred_mode_flag and - * rem_intra4x4_pred_mode - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Encodes prev_intra4x4_pred_mode_flag and rem_intra4x4_pred_mode using +* CABAC entropy coding mode +* +* @param[in] ps_cabac_ctxt +* Pointer to cabac context structure +* +* @param[in] pu1_intra_4x4_modes +* Pointer to array containing prev_intra4x4_pred_mode_flag and +* rem_intra4x4_pred_mode +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_enc_4x4mb_modes(cabac_ctxt_t *ps_cabac_ctxt, UWORD8 *pu1_intra_4x4_modes) { WORD32 i; WORD8 byte; + for (i = 0; i < 16; i += 2) { /* sub blk idx 1 */ @@ -380,31 +402,27 @@ static void ih264e_cabac_enc_4x4mb_modes(cabac_ctxt_t *ps_cabac_ctxt, } } - - /** - ******************************************************************************* - * - * @brief - * Encodes chroma intrapred mode for the MB. - * - * @param[in] u1_chroma_pred_mode - * Chroma intr prediction mode - * - * @param[in] ps_cabac_ctxt - * Pointer to cabac context structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Encodes chroma intra pred mode for the MB. +* +* @param[in] u1_chroma_pred_mode +* Chroma intra prediction mode +* +* @param[in] ps_cabac_ctxt +* Pointer to cabac context structure +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_enc_chroma_predmode(UWORD8 u1_chroma_pred_mode, cabac_ctxt_t *ps_cabac_ctxt) { - WORD8 i1_temp; mb_info_ctxt_t *ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info; mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info; @@ -413,6 +431,7 @@ static void ih264e_cabac_enc_chroma_predmode(UWORD8 u1_chroma_pred_mode, WORD8 i1_bins_len = 1; UWORD32 u4_ctx_inc = 0; UWORD8 a, b; + a = ((ps_left_ctxt->u1_intrapred_chroma_mode != 0) ? 1 : 0); b = ((ps_top_ctxt->u1_intrapred_chroma_mode != 0) ? 1 : 0); @@ -447,29 +466,25 @@ static void ih264e_cabac_enc_chroma_predmode(UWORD8 u1_chroma_pred_mode, ps_cabac_ctxt->au1_cabac_ctxt_table + INTRA_CHROMA_PRED_MODE, ps_cabac_ctxt); - } - /** - ******************************************************************************* - * - * @brief - * Encodes CBP for the MB. - * - * @param[in] u1_cbp - * CBP for the MB - * - * @param[in] ps_cabac_ctxt - * Pointer to cabac context structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief Encodes CBP for the MB. +* +* @param[in] u1_cbp +* CBP for the MB +* +* @param[in] ps_cabac_ctxt +* Pointer to cabac context structure +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_enc_cbp(UWORD32 u4_cbp, cabac_ctxt_t *ps_cabac_ctxt) { mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info; @@ -555,38 +570,36 @@ static void ih264e_cabac_enc_cbp(UWORD32 u4_cbp, cabac_ctxt_t *ps_cabac_ctxt) ps_cabac_ctxt); } - /** - ******************************************************************************* - * - * @brief - * Encodes mb_qp_delta for the MB. - * - * @param[in] i1_mb_qp_delta - * mb_qp_delta - * - * @param[in] ps_cabac_ctxt - * Pointer to cabac context structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief Encodes mb_qp_delta for the MB. +* +* @param[in] i1_mb_qp_delta +* mb_qp_delta +* +* @param[in] ps_cabac_ctxt +* Pointer to cabac context structure +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_enc_mb_qp_delta(WORD8 i1_mb_qp_delta, cabac_ctxt_t *ps_cabac_ctxt) { UWORD8 u1_code_num; UWORD8 u1_ctxt_inc; - UWORD32 u4_ctx_inc; UWORD32 u4_bins; WORD8 i1_bins_len; UWORD8 u1_ctx_inc, u1_bin; + /* Range of ps_mb_qp_delta_ctxt= -26 to +25 inclusive */ - ASSERT((i1_mb_qp_delta < 26) && (i1_mb_qp_delta > -27)); + ASSERT((i1_mb_qp_delta < 26) && (i1_mb_qp_delta > -27)); + /* if ps_mb_qp_delta_ctxt=0, then codeNum=0 */ u1_code_num = 0; if (i1_mb_qp_delta > 0) @@ -598,8 +611,8 @@ static void ih264e_cabac_enc_mb_qp_delta(WORD8 i1_mb_qp_delta, u4_bins = 0; i1_bins_len = 1; /* calculate ctxtInc, depending on neighbour availability */ - u1_ctxt_inc = (!(!(ps_cabac_ctxt->i1_prevps_mb_qp_delta_ctxt))); - ps_cabac_ctxt->i1_prevps_mb_qp_delta_ctxt = i1_mb_qp_delta; + u1_ctxt_inc = (!(!(ps_cabac_ctxt->i1_prev_mb_qp_delta_ctxt))); + ps_cabac_ctxt->i1_prev_mb_qp_delta_ctxt = i1_mb_qp_delta; if (u1_code_num == 0) { @@ -692,42 +705,38 @@ static void ih264e_cabac_enc_mb_qp_delta(WORD8 i1_mb_qp_delta, } } - - - /** - ******************************************************************************* - * @brief - * Encodes 4residual_block_cabac as defined in 7.3.5.3.3. - * - * @param[in] pi2_res_block - * pointer to the array of residues - * - * @param[in] u1_nnz - * Number of non zero coeffs in the block - * - * @param[in] u1_max_num_coeffs - * Max number of coeffs that can be there in the block - * - * @param[in] u2_sig_coeff_map - * Significant coeff map - * - * @param[in] u4_ctx_cat_offset - * ctxIdxOffset for absolute value contexts - * - * @param[in] pu1_ctxt_sig_coeff - * Pointer to residual state variables - * - * @param[in] ps_cabac_ctxt - * Pointer to cabac context structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @brief +* Encodes 4x4 residual_block_cabac as defined in 7.3.5.3.3. +* +* @param[in] pi2_res_block +* pointer to the array of residues +* +* @param[in] u1_nnz +* Number of non zero coeffs in the block +* +* @param[in] u1_max_num_coeffs +* Max number of coeffs that can be there in the block +* +* @param[in] u2_sig_coeff_map +* Significant coeff map +* +* @param[in] u4_ctx_cat_offset +* ctxIdxOffset for absolute value contexts +* +* @param[in] pu1_ctxt_sig_coeff +* Pointer to residual state variables +* +* @param[in] ps_cabac_ctxt +* Pointer to cabac context structure +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_write_coeff4x4(WORD16 *pi2_res_block, UWORD8 u1_nnz, UWORD8 u1_max_num_coeffs, UWORD16 u2_sig_coeff_map, @@ -735,7 +744,6 @@ static void ih264e_cabac_write_coeff4x4(WORD16 *pi2_res_block, UWORD8 u1_nnz, bin_ctxt_model *pu1_ctxt_sig_coeff, cabac_ctxt_t *ps_cabac_ctxt) { - WORD8 i; WORD16 *pi16_coeffs; UWORD32 u4_sig_coeff, u4_bins; @@ -743,152 +751,151 @@ static void ih264e_cabac_write_coeff4x4(WORD16 *pi2_res_block, UWORD8 u1_nnz, UWORD8 u1_last_sig_coef_index = (31 - CLZ(u2_sig_coeff_map)); /* Always put Coded Block Flag as 1 */ + pi16_coeffs = pi2_res_block; + { + bin_ctxt_model *pu1_bin_ctxt; + UWORD8 u1_bin, uc_last; + + i = 0; + pu1_bin_ctxt = pu1_ctxt_sig_coeff; + u4_sig_coeff = 0; + u1_bin = 1; + if ((u1_last_sig_coef_index)) + { + u1_bin = !!(u2_sig_coeff_map & 01); + } + uc_last = 1; - pi16_coeffs = pi2_res_block; + do { - bin_ctxt_model *pu1_bin_ctxt; - UWORD8 u1_bin, uc_last; - - i = 0; - pu1_bin_ctxt = pu1_ctxt_sig_coeff; - u4_sig_coeff = 0; - u1_bin = 1; - if ((u1_last_sig_coef_index)) + /* Encode Decision */ + ih264e_cabac_encode_bin(ps_cabac_ctxt, u1_bin, pu1_bin_ctxt); + + if (u1_bin & uc_last) { - u1_bin = !!(u2_sig_coeff_map & 01); + u4_sig_coeff = (u4_sig_coeff | (1 << i)); + pu1_bin_ctxt = pu1_ctxt_sig_coeff + i + + LAST_SIGNIFICANT_COEFF_FLAG_FRAME + - SIGNIFICANT_COEFF_FLAG_FRAME; + u1_bin = (i == u1_last_sig_coef_index); + uc_last = 0; } - uc_last = 1; - - do + else { - /* Encode Decision */ - ih264e_cabac_encode_bin(ps_cabac_ctxt, u1_bin, pu1_bin_ctxt); - - if (u1_bin & uc_last) + i = i + 1; + pu1_bin_ctxt = pu1_ctxt_sig_coeff + i; + u1_bin = (i == u1_last_sig_coef_index); + uc_last = 1; + if ((i != u1_last_sig_coef_index)) { - u4_sig_coeff = (u4_sig_coeff | (1 << i)); - pu1_bin_ctxt = pu1_ctxt_sig_coeff + i - + LAST_SIGNIFICANT_COEFF_FLAG_FRAME - - SIGNIFICANT_COEFF_FLAG_FRAME; - u1_bin = (i == u1_last_sig_coef_index); - uc_last = 0; + u1_bin = !!((u2_sig_coeff_map >> i) & 01); } - else - { - i = i + 1; - pu1_bin_ctxt = pu1_ctxt_sig_coeff + i; - u1_bin = (i == u1_last_sig_coef_index); - uc_last = 1; - if ((i != u1_last_sig_coef_index)) - { - u1_bin = !!((u2_sig_coeff_map >> i) & 01); - } - } - }while (!((i > u1_last_sig_coef_index) - || (i > (u1_max_num_coeffs - 1)))); - } + } + } while (!((i > u1_last_sig_coef_index) || (i > (u1_max_num_coeffs - 1)))); + } - /* Encode coeff_abs_level_minus1 and coeff_sign_flag */ + /* Encode coeff_abs_level_minus1 and coeff_sign_flag */ + { + UWORD8 u1_sign; + UWORD16 u2_abs_level; + UWORD8 u1_abs_level_equal1 = 1, u1_abs_level_gt1 = 0; + UWORD8 u1_ctx_inc; + UWORD8 u1_coff; + WORD16 i2_sufs; + WORD8 i1_bins_len; + + i = u1_last_sig_coef_index; + pi16_coeffs = pi2_res_block + u1_nnz - 1; + do { - UWORD8 u1_sign; - UWORD16 u2_abs_level; - UWORD8 u1_abs_level_equal1 = 1, u1_abs_level_gt1 = 0; - UWORD8 u1_ctx_inc; - UWORD8 u1_coff; - WORD16 i2_sufs; - WORD8 i1_bins_len; - i = u1_last_sig_coef_index; - pi16_coeffs = pi2_res_block + u1_nnz - 1; - do { + u4_sig_coeff = u4_sig_coeff & ((1 << i) - 1); + u4_bins = 0; + u4_ctx_inc = 0; + i1_bins_len = 1; + /* Encode the AbsLevelMinus1 */ + u2_abs_level = ABS(*(pi16_coeffs)) - 1; + /* CtxInc for bin0 */ + u4_ctx_inc = MIN(u1_abs_level_equal1, 4); + /* CtxInc for remaining */ + u1_ctx_inc = 5 + MIN(u1_abs_level_gt1, 4); + u4_ctx_inc = u4_ctx_inc + (u1_ctx_inc << 4); + if (u2_abs_level) { - u4_sig_coeff = u4_sig_coeff & ((1 << i) - 1); - u4_bins = 0; - u4_ctx_inc = 0; - i1_bins_len = 1; - /* Encode the AbsLevelMinus1 */ - u2_abs_level = ABS(*(pi16_coeffs)) - 1; - /* CtxInc for bin0 */ - u4_ctx_inc = MIN(u1_abs_level_equal1, 4); - /* CtxInc for remaining */ - u1_ctx_inc = 5 + MIN(u1_abs_level_gt1, 4); - u4_ctx_inc = u4_ctx_inc + (u1_ctx_inc << 4); - if (u2_abs_level) - { - u1_abs_level_gt1++; - u1_abs_level_equal1 = 0; - } - if (!u1_abs_level_gt1) - u1_abs_level_equal1++; + u1_abs_level_gt1++; + u1_abs_level_equal1 = 0; + } + if (!u1_abs_level_gt1) + u1_abs_level_equal1++; - u1_coff = 14; - if (u2_abs_level >= u1_coff) - { - /* Prefix TU i.e string of 14 1's */ - u4_bins = 0x3fff; - i1_bins_len = 14; - ih264e_encode_decision_bins(u4_bins, i1_bins_len, - u4_ctx_inc, 1, ps_cabac_ctxt->au1_cabac_ctxt_table + u1_coff = 14; + if (u2_abs_level >= u1_coff) + { + /* Prefix TU i.e string of 14 1's */ + u4_bins = 0x3fff; + i1_bins_len = 14; + ih264e_encode_decision_bins( + u4_bins, + i1_bins_len, + u4_ctx_inc, + 1, + ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctx_cat_offset, - ps_cabac_ctxt); - - /* Suffix, uses EncodeBypass */ - i2_sufs = u2_abs_level - u1_coff; + ps_cabac_ctxt); - u4_bins = ih264e_cabac_UEGk0_binarization(i2_sufs, - &i1_bins_len); + /* Suffix, uses EncodeBypass */ + i2_sufs = u2_abs_level - u1_coff; - ih264e_cabac_encode_bypass_bins(ps_cabac_ctxt, u4_bins, - i1_bins_len); + u4_bins = ih264e_cabac_UEGk0_binarization(i2_sufs, + &i1_bins_len); - } - else - { - /* Prefix only */ - u4_bins = (1 << u2_abs_level) - 1; - i1_bins_len = u2_abs_level + 1; - /* Encode Terminating bit */ - ih264e_encode_decision_bins(u4_bins, i1_bins_len, - u4_ctx_inc, 1, ps_cabac_ctxt->au1_cabac_ctxt_table + ih264e_cabac_encode_bypass_bins(ps_cabac_ctxt, u4_bins, + i1_bins_len); + } + else + { + /* Prefix only */ + u4_bins = (1 << u2_abs_level) - 1; + i1_bins_len = u2_abs_level + 1; + /* Encode Terminating bit */ + ih264e_encode_decision_bins( + u4_bins, + i1_bins_len, + u4_ctx_inc, + 1, + ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctx_cat_offset, - ps_cabac_ctxt); - } + ps_cabac_ctxt); } - /* encode coeff_sign_flag[i] */ - u1_sign = ((*pi16_coeffs) < 0) ? 1 : 0; - ih264e_cabac_encode_bypass_bin(ps_cabac_ctxt, u1_sign); - i = CLZ(u4_sig_coeff); - i = 31 - i; - pi16_coeffs--; - }while (u4_sig_coeff); - } - + } + /* encode coeff_sign_flag[i] */ + u1_sign = ((*pi16_coeffs) < 0) ? 1 : 0; + ih264e_cabac_encode_bypass_bin(ps_cabac_ctxt, u1_sign); + i = CLZ(u4_sig_coeff); + i = 31 - i; + pi16_coeffs--; + } while (u4_sig_coeff); + } } - /** - ******************************************************************************* - * @brief - * Write DC coeffs for intra predicted luma block - * - * @param[in] ps_ent_ctxt - * Pointer to entropy context structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @brief +* Write DC coeffs for intra predicted luma block +* +* @param[in] ps_ent_ctxt +* Pointer to entropy context structure +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_encode_residue_luma_dc(entropy_ctxt_t *ps_ent_ctxt) { - - /* CABAC context */ cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac; tu_sblk_coeff_data_t *ps_mb_coeff_data; - - /* packed residue */ void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data; UWORD16 u2_sig_coeff_map; WORD16 *pi2_res_block; @@ -941,34 +948,28 @@ static void ih264e_cabac_encode_residue_luma_dc(entropy_ctxt_t *ps_ent_ctxt) ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data; } - - - /** - ******************************************************************************* - * @brief - * Write chroma residues to the bitstream - * - * @param[in] ps_ent_ctxt - * Pointer to entropy context structure - * - * @param[in] u1_chroma_cbp - * coded block pattern, chroma - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @brief +* Write chroma residues to the bitstream +* +* @param[in] ps_ent_ctxt +* Pointer to entropy context structure +* +* @param[in] u1_chroma_cbp +* coded block pattern, chroma +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_write_chroma_residue(entropy_ctxt_t *ps_ent_ctxt, UWORD8 u1_chroma_cbp) { - /* CABAC context */ cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac; tu_sblk_coeff_data_t *ps_mb_coeff_data; - /* packed residue */ void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data; UWORD16 u2_sig_coeff_map; UWORD8 u1_nnz; @@ -1114,38 +1115,31 @@ static void ih264e_cabac_write_chroma_residue(entropy_ctxt_t *ps_ent_ctxt, ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data; } - - - /** - ******************************************************************************* - * @brief - * Encodes Residues for the MB as defined in 7.3.5.3 - * - * @param[in] ps_ent_ctxt - * Pointer to entropy context structure - * - * @param[in] u1_cbp - * coded block pattern - * - * @param[in] u1_ctx_cat - * Context category, LUMA_AC_CTXCAT or LUMA_4x4_CTXCAT - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @brief +* Encodes Residues for the MB as defined in 7.3.5.3 +* +* @param[in] ps_ent_ctxt +* Pointer to entropy context structure +* +* @param[in] u1_cbp +* coded block pattern +* +* @param[in] u1_ctx_cat +* Context category, LUMA_AC_CTXCAT or LUMA_4x4_CTXCAT +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_encode_residue(entropy_ctxt_t *ps_ent_ctxt, UWORD32 u4_cbp, UWORD8 u1_ctx_cat) { - /* CABAC context */ cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac; - tu_sblk_coeff_data_t *ps_mb_coeff_data; - /* packed residue */ void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data; UWORD16 u2_sig_coeff_map; UWORD8 u1_nnz; @@ -1154,6 +1148,7 @@ static void ih264e_cabac_encode_residue(entropy_ctxt_t *ps_ent_ctxt, UWORD8 u1_left_ac_csbp; UWORD8 u1_top_ac_csbp; UWORD32 u4_ctx_idx_offset_sig_coef, u4_ctx_idx_offset_abs_lvl; + ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info; ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info; u1_left_ac_csbp = ps_cabac_ctxt->pu1_left_y_ac_csbp[0]; @@ -1193,10 +1188,10 @@ static void ih264e_cabac_encode_residue(entropy_ctxt_t *ps_ent_ctxt, if (!((u4_cbp >> u1_b3b2) & 0x1)) { - /* ---------------------------------------------------------- */ + /************************************************************/ /* The current block is not coded so skip all the sub block */ /* and set the pointer of scan level, csbp accrodingly */ - /* ---------------------------------------------------------- */ + /************************************************************/ CLEARBIT(u1_top_ac_csbp, u1_b2b0); CLEARBIT(u1_top_ac_csbp, (u1_b2b0 + 1)); CLEARBIT(u1_left_ac_csbp, u1_b3b1); @@ -1267,7 +1262,6 @@ static void ih264e_cabac_encode_residue(entropy_ctxt_t *ps_ent_ctxt, } /* Write chroma residue */ - ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data; { UWORD8 u1_cbp_chroma; @@ -1287,34 +1281,32 @@ static void ih264e_cabac_encode_residue(entropy_ctxt_t *ps_ent_ctxt, } /** - ******************************************************************************* - * @brief - * Encodes a Motion vector (9.3.3.1.1.7 ) - * - * @param[in] u1_mvd - * Motion vector to be encoded - * - * @param[in] u4_ctx_idx_offset - * * ctxIdxOffset for MV_X or MV_Ycontext - * - * @param[in] ui2_abs_mvd - * sum of absolute value of corresponding neighboring motion vectors - * - * @param[in] ps_cabac_ctxt - * Pointer to cabac context structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @brief +* Encodes a Motion vector (Sec. 9.3.3.1.1.7 ITU T. H264) +* +* @param[in] u1_mvd +* Motion vector to be encoded +* +* @param[in] u4_ctx_idx_offset +* ctxIdxOffset for MV_X or MV_Ycontext +* +* @param[in] ui2_abs_mvd +* sum of absolute value of corresponding neighboring motion vectors +* +* @param[in] ps_cabac_ctxt +* Pointer to cabac context structure +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_enc_ctx_mvd(WORD16 u1_mvd, UWORD32 u4_ctx_idx_offset, UWORD16 ui2_abs_mvd, cabac_ctxt_t *ps_cabac_ctxt) { - UWORD8 u1_bin, u1_ctxt_inc; WORD8 k = 3, u1_coff = 9; WORD16 i2_abs_mvd, i2_sufs; @@ -1322,16 +1314,6 @@ static void ih264e_cabac_enc_ctx_mvd(WORD16 u1_mvd, UWORD32 u4_ctx_idx_offset, UWORD32 u4_bins; WORD8 i1_bins_len; - /* if mvd < u1_coff - only Prefix - else - Prefix + Suffix - - encode sign bit - - Prefix TU encoding Cmax =u1_coff and Suffix 3rd order Exp-Golomb - */ - if (ui2_abs_mvd < 3) u4_ctx_inc = 0; else if (ui2_abs_mvd > 32) @@ -1436,34 +1418,31 @@ static void ih264e_cabac_enc_ctx_mvd(WORD16 u1_mvd, UWORD32 u4_ctx_idx_offset, } /** - ******************************************************************************* - * @brief - * Encodes all motion vectors for a P16x16 MB - * - * @param[in] ps_cabac_ctxt - * Pointer to cabac context structure - * - * @param[in] pi2_mv_ptr - * Pointer to array of motion vectors - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @brief +* Encodes all motion vectors for a P16x16 MB +* +* @param[in] ps_cabac_ctxt +* Pointer to cabac context structure +* +* @param[in] pi2_mv_ptr +* Pointer to array of motion vectors +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_enc_mvds_p16x16(cabac_ctxt_t *ps_cabac_ctxt, WORD16 *pi2_mv_ptr) { - - /* Encode the differential component of the motion vectors */ - { UWORD8 u1_abs_mvd_x, u1_abs_mvd_y; UWORD8 *pu1_top_mv_ctxt, *pu1_lft_mv_ctxt; WORD16 u2_mv; + u1_abs_mvd_x = 0; u1_abs_mvd_y = 0; pu1_top_mv_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_mv[0]; @@ -1498,36 +1477,34 @@ static void ih264e_cabac_enc_mvds_p16x16(cabac_ctxt_t *ps_cabac_ctxt, } } - /** - ******************************************************************************* - * @brief - * Encodes all motion vectors for a B MB (Assues that mbype is B_L0_16x16, B_L1_16x16 or B_Bi_16x16 - * - * @param[in] ps_cabac_ctxt - * Pointer to cabac context structure - * - * @param[in] pi2_mv_ptr - * Pointer to array of motion vectors - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @brief +* Encodes all motion vectors for a B MB (Assumes that mbype is B_L0_16x16, +* B_L1_16x16 or B_Bi_16x16 +* +* @param[in] ps_cabac_ctxt +* Pointer to cabac context structure +* +* @param[in] pi2_mv_ptr +* Pointer to array of motion vectors +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ static void ih264e_cabac_enc_mvds_b16x16(cabac_ctxt_t *ps_cabac_ctxt, WORD16 *pi2_mv_ptr, WORD32 i4_mb_part_pred_mode ) { - /* Encode the differential component of the motion vectors */ - { UWORD8 u1_abs_mvd_x, u1_abs_mvd_y; UWORD8 *pu1_top_mv_ctxt, *pu1_lft_mv_ctxt; WORD16 u2_mv; + u1_abs_mvd_x = 0; u1_abs_mvd_y = 0; pu1_top_mv_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_mv[0]; @@ -1595,35 +1572,30 @@ static void ih264e_cabac_enc_mvds_b16x16(cabac_ctxt_t *ps_cabac_ctxt, } } - - /** - ******************************************************************************* - * - * @brief - * This function generates CABAC coded bit stream for an Intra Slice. - * - * @description - * The mb syntax layer for intra slices constitutes luma mb mode, mb qp delta, coded block pattern, chroma mb mode and - * luma/chroma residue. These syntax elements are written as directed by table - * 7.3.5 of h264 specification. - * - * @param[in] ps_ent_ctxt - * pointer to entropy context - * - * @returns error code - * - * @remarks none - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* This function generates CABAC coded bit stream for an Intra Slice. +* +* @description +* The mb syntax layer for intra slices constitutes luma mb mode, mb qp delta, +* coded block pattern, chroma mb mode and luma/chroma residue. These syntax +* elements are written as directed by table 7.3.5 of h264 specification. +* +* @param[in] ps_ent_ctxt +* pointer to entropy context +* +* @returns error code +* +* @remarks none +* +******************************************************************************* +*/ IH264E_ERROR_T ih264e_write_islice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) { - /* bit stream ptr */ bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm; - /* CABAC context */ cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac; - /* packed header data */ UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data; mb_hdr_common_t *ps_mb_hdr = (mb_hdr_common_t *)ps_ent_ctxt->pv_mb_header_data; mb_info_ctxt_t *ps_curr_ctxt; @@ -1721,6 +1693,7 @@ IH264E_ERROR_T ih264e_write_islice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) *(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = 0; *(ps_cabac_ctxt->pu1_left_y_ac_csbp) = 0; *(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = 0; + ps_cabac_ctxt->i1_prev_mb_qp_delta_ctxt = 0; /* Ending bitstream offset for header in bits */ bitstream_end_offset = GET_NUM_BITS(ps_bitstream); ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset @@ -1747,34 +1720,30 @@ IH264E_ERROR_T ih264e_write_islice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) } /** - ******************************************************************************* - * - * @brief - * This function generates CABAC coded bit stream for Inter slices - * - * @description - * The mb syntax layer for inter slices constitutes luma mb mode, mb qp delta, coded block pattern, chroma mb mode and - * luma/chroma residue. These syntax elements are written as directed by table - * 7.3.5 of h264 specification - * - * @param[in] ps_ent_ctxt - * pointer to entropy context - * - * @returns error code - * - * @remarks none - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* This function generates CABAC coded bit stream for Inter slices +* +* @description +* The mb syntax layer for inter slices constitutes luma mb mode, mb qp delta, +* coded block pattern, chroma mb mode and luma/chroma residue. These syntax +* elements are written as directed by table 7.3.5 of h264 specification +* +* @param[in] ps_ent_ctxt +* pointer to entropy context +* +* @returns error code +* +* @remarks none +* +******************************************************************************* +*/ IH264E_ERROR_T ih264e_write_pslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) { - /* bit stream ptr */ bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm; - /* CABAC context */ cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac; - mb_info_ctxt_t *ps_curr_ctxt; - WORD32 bitstream_start_offset, bitstream_end_offset; WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode; WORD8 mb_qp_delta; @@ -1887,6 +1856,7 @@ IH264E_ERROR_T ih264e_write_pslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) *(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = 0; *(ps_cabac_ctxt->pu1_left_y_ac_csbp) = 0; *(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = 0; + ps_cabac_ctxt->i1_prev_mb_qp_delta_ctxt = 0; /* Ending bitstream offset for header in bits */ bitstream_end_offset = GET_NUM_BITS(ps_bitstream); ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset @@ -2002,6 +1972,7 @@ IH264E_ERROR_T ih264e_write_pslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) *(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = 0; *(ps_cabac_ctxt->pu1_left_y_ac_csbp) = 0; *(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = 0; + ps_cabac_ctxt->i1_prev_mb_qp_delta_ctxt = 0; } ps_curr_ctxt->u1_intrapred_chroma_mode = 0; ps_curr_ctxt->u1_cbp = cbp; @@ -2011,61 +1982,31 @@ IH264E_ERROR_T ih264e_write_pslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) } } - -/* ! < Table 9-37 – Binarization for macroblock types in B slices in ITU_T_H264-201402 - * Bits 0-7 : binarised value - * Bits 8-15: length of binary sequence */ - - -static const UWORD32 u4_b_mb_type[27] = { 0x0100, 0x0301, 0x0305, 0x0603, - 0x0623, 0x0613, 0x0633, 0x060b, - 0x062b, 0x061b, 0x063b, 0x061f, - 0x0707, 0x0747, 0x0727, 0x0767, - 0x0717, 0x0757, 0x0737, 0x0777, - 0x070f, 0x074f, 0x063f }; -/* CtxInc for mb types in B slices */ -static const UWORD32 ui_b_mb_type_ctx_inc[27] = { 0x00, 0x0530, 0x0530, - 0x0555430, 0x0555430, - 0x0555430, 0x0555430, - 0x0555430, 0x0555430, - 0x0555430, 0x0555430, - 0x0555430, 0x05555430, - 0x05555430, 0x05555430, - 0x05555430, 0x05555430, - 0x05555430, 0x05555430, - 0x05555430, 0x05555430, - 0x05555430, 0x0555430 }; - /** - ******************************************************************************* - * - * @brief - * This function generates CABAC coded bit stream for B slices - * - * @description - * The mb syntax layer for inter slices constitutes luma mb mode, - * mb qp delta, coded block pattern, chroma mb mode and - * luma/chroma residue. These syntax elements are written as directed by table - * 7.3.5 of h264 specification - * - * @param[in] ps_ent_ctxt - * pointer to entropy context - * - * @returns error code - * - * @remarks none - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* This function generates CABAC coded bit stream for B slices +* +* @description +* The mb syntax layer for inter slices constitutes luma mb mode, mb qp delta, +* coded block pattern, chroma mb mode and luma/chroma residue. These syntax +* elements are written as directed by table 7.3.5 of h264 specification +* +* @param[in] ps_ent_ctxt +* pointer to entropy context +* +* @returns error code +* +* @remarks none +* +******************************************************************************* +*/ IH264E_ERROR_T ih264e_write_bslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) { - /* bit stream ptr */ bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm; - /* CABAC context */ cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac; - mb_info_ctxt_t *ps_curr_ctxt; - WORD32 bitstream_start_offset, bitstream_end_offset; WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode; WORD8 mb_qp_delta; @@ -2195,6 +2136,7 @@ IH264E_ERROR_T ih264e_write_bslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) *(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = 0; *(ps_cabac_ctxt->pu1_left_y_ac_csbp) = 0; *(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = 0; + ps_cabac_ctxt->i1_prev_mb_qp_delta_ctxt = 0; /* Ending bitstream offset for header in bits */ bitstream_end_offset = GET_NUM_BITS(ps_bitstream); ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset @@ -2220,7 +2162,6 @@ IH264E_ERROR_T ih264e_write_bslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) return IH264E_SUCCESS; } - else /* Inter MB */ { /* Starting bitstream offset for header in bits */ @@ -2280,7 +2221,6 @@ IH264E_ERROR_T ih264e_write_bslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) pu1_byte += sizeof(mb_hdr_bdirect_t); } - else if (mb_type == BSKIP)/* MB = BSKIP */ { ih264e_cabac_enc_mb_skip(1, ps_cabac_ctxt, MB_SKIP_FLAG_B_SLICE); @@ -2299,7 +2239,6 @@ IH264E_ERROR_T ih264e_write_bslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) pu1_byte += sizeof(mb_hdr_bskip_t); } - else /* mbype is B_L0_16x16, B_L1_16x16 or B_Bi_16x16 */ { mb_hdr_b16x16_t *ps_mb_hdr_b16x16 = (mb_hdr_b16x16_t *)ps_ent_ctxt->pv_mb_header_data; @@ -2390,6 +2329,7 @@ IH264E_ERROR_T ih264e_write_bslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt) *(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = 0; *(ps_cabac_ctxt->pu1_left_y_ac_csbp) = 0; *(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = 0; + ps_cabac_ctxt->i1_prev_mb_qp_delta_ctxt = 0; } ps_curr_ctxt->u1_intrapred_chroma_mode = 0; ps_curr_ctxt->u1_cbp = cbp; diff --git a/encoder/ih264e_cabac_init.c b/encoder/ih264e_cabac_init.c index 7407dcc..6eb2e34 100644 --- a/encoder/ih264e_cabac_init.c +++ b/encoder/ih264e_cabac_init.c @@ -21,19 +21,21 @@ /** ******************************************************************************* * @file -* ih264e_cabac_init.c +* ih264e_cabac_init.c * * @brief * Contains all initialization functions for cabac contexts * * @author -* Doney Alex -* -* @par List of Functions: +* ittiam * +* @par List of Functions +* - ih264e_init_cabac_enc_envirnoment +* - ih264e_init_cabac_table +* - ih264e_init_cabac_ctxt * * @remarks -* None +* none * ******************************************************************************* */ @@ -42,7 +44,7 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> @@ -50,57 +52,43 @@ #include <limits.h> #include <assert.h> -/* User include files */ +/* User Include Files */ +#include "ih264e_config.h" #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264_defs.h" + #include "ih264_debug.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" +#include "ih264_macros.h" #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" -#include "ih264_platform_macros.h" -#include "ih264_macros.h" -#include "ih264_buf_mgr.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ih264_common_tables.h" +#include "ih264_cavlc_tables.h" #include "ih264_cabac_tables.h" -#include "ih264_list.h" -#include "ih264e_defs.h" +#include "ih264_platform_macros.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" -#include "ih264e_rate_control.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_cabac.h" -#include "ih264e_process.h" -#include "ithread.h" -#include "ih264e_intra_modes_eval.h" #include "ih264e_encode_header.h" -#include "ih264e_globals.h" -#include "ih264e_config.h" -#include "ih264e_trace.h" +#include "ih264e_cabac.h" #include "ih264e_statistics.h" -#include "ih264_cavlc_tables.h" -#include "ih264e_deblk.h" -#include "ih264e_me.h" -#include "ih264e_debug.h" -#include "ih264e_master.h" -#include "ih264e_utils.h" -#include "irc_mem_req_and_acq.h" -#include "irc_rate_control_api.h" -#include "ih264e_platform_macros.h" -#include "ime_statistics.h" - +#include "ih264e_trace.h" /*****************************************************************************/ @@ -108,20 +96,18 @@ /*****************************************************************************/ /** - ******************************************************************************* - * - * @brief - * Initialize cabac encoding environment - * - * @param[in] ps_cab_enc_env - * Pointer to encoding_envirnoment_t structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* +******************************************************************************* +* +* @brief Initialize cabac encoding environment +* +* @param[in] ps_cab_enc_env +* Pointer to encoding_envirnoment_t structure +* +* @returns none +* +* @remarks none +* +******************************************************************************* */ static void ih264e_init_cabac_enc_envirnoment(encoding_envirnoment_t *ps_cab_enc_env) { @@ -131,26 +117,23 @@ static void ih264e_init_cabac_enc_envirnoment(encoding_envirnoment_t *ps_cab_enc ps_cab_enc_env->u4_bits_gen = 0; } - /** - ******************************************************************************* - * - * @brief - * Initialize default context values and pointers (Called once at the beginning of encoding). - * - * @param[in] ps_ent_ctxt - * Pointer to entropy context structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* +******************************************************************************* +* +* @brief Initialize default context values and pointers. Called once at the +* beginning of encoding. +* +* @param[in] ps_ent_ctxt +* Pointer to entropy context structure +* +* @returns none +* +* @remarks none +* +******************************************************************************* */ void ih264e_init_cabac_table(entropy_ctxt_t *ps_ent_ctxt) { - /* CABAC context */ cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac; ps_cabac_ctxt->ps_mb_map_ctxt_inc = ps_cabac_ctxt->ps_mb_map_ctxt_inc_base + 1; ps_cabac_ctxt->ps_lft_csbp = &ps_cabac_ctxt->s_lft_csbp; @@ -158,7 +141,7 @@ void ih264e_init_cabac_table(entropy_ctxt_t *ps_ent_ctxt) { /* 0th entry of mb_map_ctxt_inc will be always be containing default values */ - /* for CABAC context representing MB not available */ + /* for CABAC context representing MB not available */ mb_info_ctxt_t *ps_def_ctxt = ps_cabac_ctxt->ps_mb_map_ctxt_inc - 1; ps_def_ctxt->u1_mb_type = CAB_SKIP; @@ -171,30 +154,25 @@ void ih264e_init_cabac_table(entropy_ctxt_t *ps_ent_ctxt) } } - /** - ******************************************************************************* - * - * @brief - * Initialize cabac context: Initialize all contest with init values given in the spec. - * Called at the beginning of entropy coding of each slice for CABAC encoding. - * - * @param[in] ps_ent_ctxt - * Pointer to entropy context structure - * - * @returns - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief Initialize cabac context: Initialize all contest with init values given +* in the spec. Called at the beginning of entropy coding of each slice for +* CABAC encoding. +* +* @param[in] ps_ent_ctxt +* Pointer to entropy context structure +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264e_init_cabac_ctxt(entropy_ctxt_t *ps_ent_ctxt) { - /* CABAC context */ cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac; - - /* slice header */ slice_header_t *ps_slice_hdr = ps_ent_ctxt->ps_slice_hdr_base; const UWORD8 u1_slice_type = ps_slice_hdr->u1_slice_type; WORD8 i1_cabac_init_idc = 0; @@ -203,7 +181,7 @@ void ih264e_init_cabac_ctxt(entropy_ctxt_t *ps_ent_ctxt) ih264e_init_cabac_enc_envirnoment(&ps_cabac_ctxt->s_cab_enc_env); - ps_cabac_ctxt->i1_prevps_mb_qp_delta_ctxt = 0; + ps_cabac_ctxt->i1_prev_mb_qp_delta_ctxt = 0; if (ISLICE != u1_slice_type) { @@ -212,11 +190,9 @@ void ih264e_init_cabac_ctxt(entropy_ctxt_t *ps_ent_ctxt) else { i1_cabac_init_idc = 3; - } memcpy(au1_cabac_ctxt_table, gau1_ih264_cabac_ctxt_init_table[i1_cabac_init_idc][u1_qp_y], NUM_CABAC_CTXTS * sizeof(bin_ctxt_model)); - } diff --git a/encoder/ih264e_cabac_structs.h b/encoder/ih264e_cabac_structs.h index 82938ca..bc6ba98 100644 --- a/encoder/ih264e_cabac_structs.h +++ b/encoder/ih264e_cabac_structs.h @@ -19,45 +19,52 @@ */ /** - ******************************************************************************* - * @file - * ih264e_cabac_structs.h - * - * @brief - * This file contains cabac related structure definitions. - * - * @author - * Doney Alex - * - * @remarks - * none - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264e_cabac_structs.h +* +* @brief +* This file contains structure definitions necessary for cabac encoding +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ -#ifndef IH264E_CABAC_STRUCTS_H_ -#define IH264E_CABAC_STRUCTS_H_ +#ifndef _IH264E_CABAC_STRUCTS_H_ +#define _IH264E_CABAC_STRUCTS_H_ +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ #define CABAC_INIT_IDC 2 +/*****************************************************************************/ +/* Structures */ +/*****************************************************************************/ + /** - ****************************************************************************** - * @brief typedef for context model - ****************************************************************************** - */ +******************************************************************************* +* @brief typedef for context model +******************************************************************************* +*/ /* bits 0 to 5 :state bit 6 :mps */ typedef UWORD8 bin_ctxt_model; /** - ****************************************************************************** - * @brief MB info for cabac - ****************************************************************************** - */ +******************************************************************************* +* @brief MB info for cabac +******************************************************************************* +*/ typedef struct { /* Neighbour availability Variables needed to get CtxtInc, for CABAC */ @@ -72,6 +79,7 @@ typedef struct /* CSBP: V1 V0 U1 U0 Y3 Y2 Y1 Y0 */ /*************************************************************************/ UWORD8 u1_yuv_ac_csbp; + /*************************************************************************/ /* Arrangnment of DC CSBP */ /* bits: b7 b6 b5 b4 b3 b2 b1 b0 */ @@ -81,14 +89,15 @@ typedef struct WORD8 i1_ref_idx[4]; UWORD8 u1_mv[4][4]; + } mb_info_ctxt_t; /** - ****************************************************************************** - * @brief CSBP info for CABAC - ****************************************************************************** - */ +******************************************************************************* +* @brief CSBP info for CABAC +******************************************************************************* +*/ typedef struct { /*************************************************************************/ @@ -123,47 +132,56 @@ typedef struct /*************************************************************************/ UWORD8 u1_yuv_dc_csbp_top_mb; UWORD8 u1_yuv_dc_csbp_bot_mb; + } cab_csbp_t; /** - ****************************************************************************** - * @brief CABAC Encoding Environment - ****************************************************************************** - */ - +******************************************************************************* +* @brief CABAC Encoding Environment +******************************************************************************* +*/ typedef struct { - /** cabac interval start L */ + /** + * cabac interval start L + */ UWORD32 u4_code_int_low; - /** cabac interval range R */ + /** + * cabac interval range R + */ UWORD32 u4_code_int_range; /** bytes_outsanding; number of 0xFF bits that occur during renorm - * These will be accumulated till the carry bit is knwon - */ + * These will be accumulated till the carry bit is knwon + */ UWORD32 u4_out_standing_bytes; /** bits generated during renormalization - * A byte is put to stream/u4_out_standing_bytes from u4_low(L) when - * u4_bits_gen exceeds 8 - */ + * A byte is put to stream/u4_out_standing_bytes from u4_low(L) when + * u4_bits_gen exceeds 8 + */ UWORD32 u4_bits_gen; + } encoding_envirnoment_t; /** - ****************************************************************************** - * @brief CABAC Context structure : Variables to handle Cabac - ****************************************************************************** - */ +******************************************************************************* +* @brief CABAC Context structure : Variables to handle Cabac +******************************************************************************* +*/ typedef struct { - /* Base pointer to all the cabac contexts */ + /** + * Base pointer to all the cabac contexts + */ bin_ctxt_model au1_cabac_ctxt_table[NUM_CABAC_CTXTS]; - + /** + * left csbp + */ cab_csbp_t s_lft_csbp; /** @@ -171,51 +189,72 @@ typedef struct */ bitstrm_t *ps_bitstrm; - /* Pointer to mb_info_ctxt_t map_base */ + /** + * Pointer to mb_info_ctxt_t map_base + */ mb_info_ctxt_t *ps_mb_map_ctxt_inc_base; - /* Pointer to encoding_envirnoment_t */ + /** + * Pointer to encoding_envirnoment_t + */ encoding_envirnoment_t s_cab_enc_env; /* These things need to be updated at each MbLevel */ + /** + * Prev mb_qp_delta_ctxt + */ + WORD8 i1_prev_mb_qp_delta_ctxt; - /* Prev ps_mb_qp_delta_ctxt */ - WORD8 i1_prevps_mb_qp_delta_ctxt; - - /* Pointer to mb_info_ctxt_t map */ + /** + * Pointer to mb_info_ctxt_t map + */ mb_info_ctxt_t *ps_mb_map_ctxt_inc; - /* Pointer to default mb_info_ctxt_t */ + /** + * Pointer to default mb_info_ctxt_t + */ mb_info_ctxt_t *ps_def_ctxt_mb_info; - /* Pointer to current mb_info_ctxt_t */ + /** + * Pointer to current mb_info_ctxt_t + */ mb_info_ctxt_t *ps_curr_ctxt_mb_info; - /* Pointer to left mb_info_ctxt_t */ + /** + * Pointer to left mb_info_ctxt_t + */ mb_info_ctxt_t *ps_left_ctxt_mb_info; - /* Pointer to top mb_info_ctxt_t */ + /** + * Pointer to top mb_info_ctxt_t + */ mb_info_ctxt_t *ps_top_ctxt_mb_info; - /* Poniter to left csbp structure */ + /** + * Pointer to csbp structures + */ cab_csbp_t *ps_lft_csbp; UWORD8 *pu1_left_y_ac_csbp; UWORD8 *pu1_left_uv_ac_csbp; UWORD8 *pu1_left_yuv_dc_csbp; - /***************************************************************************/ - /* Ref_idx contexts are stored in the following way */ - /* Array Idx 0,1 for reference indices in Forward direction */ - /* Array Idx 2,3 for reference indices in backward direction */ - /***************************************************************************/ - /* Dimensions for u1_left_ref_ctxt_inc_arr is [2][4] for Mbaff:Top and Bot */ + /**************************************************************************/ + /* Ref_idx contexts are stored in the following way */ + /* Array Idx 0,1 for reference indices in Forward direction */ + /* Array Idx 2,3 for reference indices in backward direction */ + /**************************************************************************/ + /** + * Dimensions for u1_left_ref_ctxt_inc_arr is [2][4] for Mbaff:Top and Bot + */ WORD8 i1_left_ref_idx_ctx_inc_arr[2][4]; WORD8 *pi1_left_ref_idx_ctxt_inc; - /* Dimensions for u1_left_mv_ctxt_inc_arr is [2][4][4] for Mbaff case */ + /** + * Dimensions for u1_left_mv_ctxt_inc_arr is [2][4][4] for Mbaff case + */ UWORD8 u1_left_mv_ctxt_inc_arr[2][4][4]; UWORD8 (*pu1_left_mv_ctxt_inc)[4]; } cabac_ctxt_t; -#endif /* IH264E_CABAC_STRUCTS_H_ */ +#endif /* _IH264E_CABAC_STRUCTS_H_ */ diff --git a/encoder/ih264e_cavlc.c b/encoder/ih264e_cavlc.c index ed34a43..f142717 100644 --- a/encoder/ih264e_cavlc.c +++ b/encoder/ih264e_cavlc.c @@ -31,15 +31,16 @@ * ittiam * * @par List of Functions: -* - ih264e_compute_zeroruns_and_trailingones() -* - ih264e_write_coeff4x4_cavlc() -* - ih264e_write_coeff8x8_cavlc() -* - ih264e_encode_residue() -* - ih264e_write_islice_mb_cavlc() -* - ih264e_write_pslice_mb_cavlc() +* - ih264e_compute_zeroruns_and_trailingones +* - ih264e_write_coeff4x4_cavlc +* - ih264e_write_coeff8x8_cavlc +* - ih264e_encode_residue +* - ih264e_write_islice_mb_cavlc +* - ih264e_write_pslice_mb_cavlc +* - ih264e_write_bslice_mb_cavlc * * @remarks -* None +* none * ******************************************************************************* */ @@ -48,41 +49,44 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <assert.h> #include <limits.h> -/* User include files */ +/* User Include Files */ #include "ih264e_config.h" #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" + #include "ih264_debug.h" #include "ih264_macros.h" -#include "ih264_defs.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_cavlc_tables.h" #include "ih264_cabac_tables.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" -#include "ih264e_rate_control.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" #include "ih264e_encode_header.h" -#include "ih264_cavlc_tables.h" #include "ih264e_cavlc.h" #include "ih264e_statistics.h" #include "ih264e_trace.h" @@ -117,7 +121,7 @@ * Bits 16-24 contains total number of zeros. * * @remarks -* None +* none * ******************************************************************************* */ @@ -421,44 +425,44 @@ static IH264E_ERROR_T ih264e_write_coeff4x4_cavlc(WORD16 *pi2_res_block, while (1) { - UWORD32 u4_codesize; - UWORD32 u4_codeword; - UWORD32 u4_codeval; + WORD32 i4_codesize; + WORD32 i4_codeword; + WORD32 i4_codeval; u4_remaining_coeff--; GATHER_CAVLC_STATS1(); { - u4_codeval = u4_abs_level << 1; - u4_codeval = u4_codeval - 2 - i4_sign; + i4_codeval = u4_abs_level << 1; + i4_codeval = i4_codeval - 2 - i4_sign; if ((!u4_suffix_length) && (u4_escape > 7) && (u4_abs_level < 16)) { - u4_codeword = (1 << 4) + (u4_codeval - 14); - u4_codesize = 19; + i4_codeword = (1 << 4) + (i4_codeval - 14); + i4_codesize = 19; } else if (u4_escape > 7) { - u4_codeword = (1 << 12) + (u4_codeval - (15 << u4_suffix_length)); - u4_codesize = 28; + i4_codeword = (1 << 12) + (i4_codeval - (15 << u4_suffix_length)); + i4_codesize = 28; if (!u4_suffix_length) { - u4_codeword -= 15; + i4_codeword -= 15; } } else { - u4_codeword = (1 << u4_suffix_length) + (u4_codeval & ((1 << u4_suffix_length)-1)); - u4_codesize = (u4_codeval >> u4_suffix_length) + 1 + u4_suffix_length; + i4_codeword = (1 << u4_suffix_length) + (i4_codeval & ((1 << u4_suffix_length)-1)); + i4_codesize = (i4_codeval >> u4_suffix_length) + 1 + u4_suffix_length; } } /*put the level code in bitstream*/ - DEBUG("\nLEVEL: %d u4_codeword, %d u4_codesize",u4_codeword, u4_codesize); - ENTROPY_TRACE("\tcodeword ",u4_codeword); - ENTROPY_TRACE("\tcodesize ",u4_codesize); - error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize); + DEBUG("\nLEVEL: %d i4_codeword, %d i4_codesize",i4_codeword, i4_codesize); + ENTROPY_TRACE("\tcodeword ",i4_codeword); + ENTROPY_TRACE("\tcodesize ",i4_codesize); + error_status = ih264e_put_bits(ps_bit_stream, i4_codeword, i4_codesize); if (u4_remaining_coeff == 0) break; diff --git a/encoder/ih264e_cavlc.h b/encoder/ih264e_cavlc.h index 8da2cea..4d5c401 100644 --- a/encoder/ih264e_cavlc.h +++ b/encoder/ih264e_cavlc.h @@ -24,8 +24,7 @@ * ih264e_cavlc.h * * @brief -* This file contains enumerations, macros and extern declarations of H264 -* cavlc tables +* This file contains declarations necessary for cavlc encoding * * @author * ittiam @@ -35,84 +34,17 @@ ****************************************************************************** */ -#ifndef IH264E_CAVLC_H_ -#define IH264E_CAVLC_H_ +#ifndef _IH264E_CAVLC_H_ +#define _IH264E_CAVLC_H_ /*****************************************************************************/ -/* Function macro definitions */ +/* Function Declarations */ /*****************************************************************************/ -/*****************************************************************************/ -/* Extern Function Declarations */ -/*****************************************************************************/ - -/** -******************************************************************************* -* -* @brief -* This function generates CAVLC coded bit stream for an Intra Slice. -* -* @description -* The mb syntax layer for intra slices constitutes luma mb mode, luma sub modes -* (if present), mb qp delta, coded block pattern, chroma mb mode and -* luma/chroma residue. These syntax elements are written as directed by table -* 7.3.5 of h264 specification. -* -* @param[in] ps_ent_ctxt -* pointer to entropy context -* -* @returns error code -* -* @remarks none -* -******************************************************************************* -*/ IH264E_ERROR_T ih264e_write_islice_mb_cavlc(entropy_ctxt_t *ps_ent_ctxt); -/** -******************************************************************************* -* -* @brief -* This function generates CAVLC coded bit stream for Inter slices -* -* @description -* The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes -* (if present), mb qp delta, coded block pattern, chroma mb mode and -* luma/chroma residue. These syntax elements are written as directed by table -* 7.3.5 of h264 specification -* -* @param[in] ps_ent_ctxt -* pointer to entropy context -* -* @returns error code -* -* @remarks none -* -******************************************************************************* -*/ IH264E_ERROR_T ih264e_write_pslice_mb_cavlc(entropy_ctxt_t *ps_ent_ctxt); -/** -******************************************************************************* -* -* @brief -* This function generates CAVLC coded bit stream for Inter(B) slices -* -* @description -* The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes -* (if present), mb qp delta, coded block pattern, chroma mb mode and -* luma/chroma residue. These syntax elements are written as directed by table -* 7.3.5 of h264 specification -* -* @param[in] ps_ent_ctxt -* pointer to entropy context -* -* @returns error code -* -* @remarks none -* -******************************************************************************* -*/ IH264E_ERROR_T ih264e_write_bslice_mb_cavlc(entropy_ctxt_t *ps_ent_ctxt); -#endif /* IH264E_CAVLC_H_ */ +#endif /* _IH264E_CAVLC_H_ */ diff --git a/encoder/ih264e_config.h b/encoder/ih264e_config.h index 2446cdb..5251a57 100644 --- a/encoder/ih264e_config.h +++ b/encoder/ih264e_config.h @@ -24,8 +24,7 @@ * ih264e_config.h * * @brief -* contains any necessary declarations/definitions that are used during codec -* build +* h264 library configuration definitions * * @author * ittiam @@ -35,8 +34,8 @@ ****************************************************************************** */ -#ifndef IH264E_CONFIG_H_ -#define IH264E_CONFIG_H_ +#ifndef _IH264E_CONFIG_H_ +#define _IH264E_CONFIG_H_ /*****************************************************************************/ /* Constant Macros */ @@ -49,4 +48,4 @@ #define DEBUG_RC 0 #define TRACE_SUPPORT 0 -#endif /* IH264E_CONFIG_H_ */ +#endif /* _IH264E_CONFIG_H_ */ diff --git a/encoder/ih264e_core_coding.c b/encoder/ih264e_core_coding.c index 5b36aef..3d0806f 100644 --- a/encoder/ih264e_core_coding.c +++ b/encoder/ih264e_core_coding.c @@ -19,70 +19,82 @@ */ /** - ******************************************************************************* - * @file - * ih264e_core_coding.c - * - * @brief - * This file contains routines that perform luma and chroma core coding for - * intra macroblocks - * - * @author - * ittiam - * - * @par List of Functions: - * - ih264e_pack_l_mb_i16() - * - ih264e_pack_c_mb_i8() - * - ih264e_code_luma_intra_macroblock_16x16() - * - ih264e_code_luma_intra_macroblock_4x4() - * - ih264e_code_chroma_intra_macroblock_8x8() - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264e_core_coding.c +* +* @brief +* This file contains routines that perform luma and chroma core coding of +* H264 macroblocks +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264e_luma_16x16_resi_trans_dctrans_quant +* - ih264e_luma_16x16_idctrans_iquant_itrans_recon +* - ih264e_chroma_8x8_resi_trans_dctrans_quant +* - ih264e_chroma_8x8_idctrans_iquant_itrans_recon +* - ih264e_pack_l_mb_i16 +* - ih264e_pack_l_mb +* - ih264e_pack_c_mb_i8 +* - ih264e_code_luma_intra_macroblock_16x16 +* - ih264e_code_luma_intra_macroblock_4x4 +* - ih264e_code_luma_intra_macroblock_4x4_rdopt_on +* - ih264e_code_chroma_intra_macroblock_8x8 +* - ih264e_code_luma_inter_macroblock_16x16 +* - ih264e_code_chroma_inter_macroblock_8x8 +* +* @remarks +* none +* +******************************************************************************* +*/ /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <string.h> #include <assert.h> -/* User include files */ +/* User Include Files */ #include "ih264e_config.h" #include "ih264_typedefs.h" -#include "ih264_platform_macros.h" #include "iv2.h" #include "ive2.h" + #include "ih264_macros.h" #include "ih264_defs.h" -#include "ih264e_defs.h" -#include "ih264_trans_data.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_trans_data.h" #include "ih264_cabac_tables.h" +#include "ih264_platform_macros.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" +#include "ih264e_globals.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_globals.h" -#include "ih264e_core_coding.h" #include "ih264e_mc.h" +#include "ih264e_core_coding.h" /*****************************************************************************/ @@ -222,8 +234,8 @@ void ih264e_luma_16x16_resi_trans_dctrans_quant(codec_t *ps_codec, * * @param[in] pi2_src * Input data, 16x16 size -* First 16 mem locations will have the Dc coffs in rater scan order in linear fashion -* after a stride 1st AC clock will be present again in raster can order +* First 16 mem locations will have the Dc coffs in raster scan order in linear +* fashion after a stride 1st AC clock will be present again in raster can order * Then each AC block of the 16x16 block will follow in raster scan order * * @param[in] pu1_pred @@ -252,17 +264,17 @@ void ih264e_luma_16x16_resi_trans_dctrans_quant(codec_t *ps_codec, * @param[in] qp_div * QP/6 * -* @param[in] pi4_tmp -* Input temporary buffer -* needs to be at least 20 in size -* -* @param[in] pu4_cntrl +* @param[in] u4_cntrl * Controls the transform path * total Last 17 bits are used * the 16th th bit will correspond to DC block * and 32-17 will correspond to the ac blocks in raster scan order * bit equaling zero indicates that the entire 4x4 block is zero for DC -* For AC blocks a bit equaling zero will mean that all 15 AC coffs of the block is nonzero +* For AC blocks a bit equaling zero will mean that all 15 AC coffs of the block +* is nonzero +* +* @param[in] u4_dc_trans_flag +* Differentiates intra vs inter * * @param[in] pi4_tmp * Input temporary buffer @@ -457,7 +469,7 @@ void ih264e_luma_16x16_idctrans_iquant_itrans_recon(codec_t *ps_codec, * @param[in] pred_strd * Prediction stride * -* @param[in] dst_strd +* @param[in] out_strd * Destination stride * * @param[in] pu2_scale_matrix @@ -472,18 +484,13 @@ void ih264e_luma_16x16_idctrans_iquant_itrans_recon(codec_t *ps_codec, * @param[in] u4_round_factor * Round factor for quant * -* @param[out] pu1_nnz +* @param[out] pu1_nnz_c * Memory to store the non-zeros after transform * The first byte will be the nnz od DC block for U plane * From the next byte the AC nnzs will be storerd in raster scan order * The fifth byte will be nnz of Dc block of V plane * Then Ac blocks will follow * -* @param u4_dc_flag -* Signals if Dc transform is to be done or not -* 1 -> Dc transform will be done -* 0 -> Dc transform will not be done -* * @remarks * ******************************************************************************* @@ -547,11 +554,12 @@ void ih264e_chroma_8x8_resi_trans_dctrans_quant(codec_t *ps_codec, /** ******************************************************************************* -* @brief -* This function performs the inverse transform with process for chroma MB of H264 +* @brief Does inverse DC transform, inverse quantization inverse transform for +* chroma MB * * @par Description: -* Does inverse DC transform ,inverse quantization inverse transform +* Does inverse DC transform, inverse quantization inverse transform for +* chroma MB * * @param[in] pi2_src * Input data, 16x16 size @@ -585,22 +593,23 @@ void ih264e_chroma_8x8_resi_trans_dctrans_quant(codec_t *ps_codec, * @param[in] qp_div * QP/6 * -* @param[in] pi4_tmp -* Input temporary buffer -* needs to be at least COFF_CNT_SUB_BLK_4x4 + Number of Dc cofss for chroma * number of planes -* in size -* -* @param[in] pu4_cntrl +* @param[in] u4_cntrl * Controls the transform path -* the 15 th bit will correspond to DC block of U plane , 14th will indicate the V plane Dc block -* 32-28 bits will indicate AC blocks of U plane in raster scan order -* 27-23 bits will indicate AC blocks of V plane in rater scan order +* the 15 th bit will correspond to DC block of U plane, 14th will indicate the +* V plane Dc block. 32-28 bits will indicate AC blocks of U plane in raster +* scan order. 27-23 bits will indicate AC blocks of V plane in rater scan order. * The bit 1 implies that there is at least one non zero coeff in a block * +* @param[in] pi4_tmp +* Input temporary buffer +* needs to be at least COFF_CNT_SUB_BLK_4x4 + (Number of Dc coeffs for chroma * +* number of planes) in size +* * @returns * none * * @remarks +* ******************************************************************************* */ void ih264e_chroma_8x8_idctrans_iquant_itrans_recon(codec_t *ps_codec, @@ -649,8 +658,8 @@ void ih264e_chroma_8x8_idctrans_iquant_itrans_recon(codec_t *ps_codec, if (u4_cntrl & CNTRL_FLAG_DCBLK_MASK_CHROMA) { UWORD32 cntr, u4_dc_cntrl; - /* Do inv hadamard for u an v block */ + /* Do inv hadamard for u an v block */ ps_codec->pf_ihadamard_scaling_2x2_uv(pi2_src, pi2_src, pu2_iscale_mat, pu2_weigh_mat, qp_div, NULL); /* @@ -1085,11 +1094,9 @@ void ih264e_pack_l_mb(WORD16 *pi2_res_mb, /* Decide if the 8x8 unit has to be sent for entropy coding? */ if ((b4+1) % 4 == 0) { - if ( u4_thres_resi && (u4_b8_coeff_cost <= LUMA_SUB_BLOCK_SKIP_THRESHOLD) && - (*u1_cbp_l & (1 << b8)) ) + if (u4_thres_resi && (u4_b8_coeff_cost <= LUMA_SUB_BLOCK_SKIP_THRESHOLD) && + (*u1_cbp_l & (1 << b8))) { - - /* * When we want to reset the full 8x8 block, we have to reset * both the dc and ac coeff bits hence we have the symmetric @@ -1479,7 +1486,6 @@ void ih264e_pack_c_mb(WORD16 *pi2_res_mb, * ******************************************************************************* */ - UWORD8 ih264e_code_luma_intra_macroblock_16x16(process_ctxt_t *ps_proc) { /* Codec Context */ @@ -2091,7 +2097,7 @@ UWORD8 ih264e_code_chroma_intra_macroblock_8x8(process_ctxt_t *ps_proc) /** ******************************************************************************* * -* @brief performs luma core coding when mode is inter +* @brief performs luma core coding when mode is inter * * @par Description: * If the current mb is to be coded as inter the mb is predicted based on the @@ -2103,14 +2109,12 @@ UWORD8 ih264e_code_chroma_intra_macroblock_8x8(process_ctxt_t *ps_proc) * @param[in] ps_proc_ctxt * pointer to the current macro block context * -* @returns u1_cbp_l -* coded block pattern luma +* @returns coded block pattern luma * * @remarks none * ******************************************************************************* */ - UWORD8 ih264e_code_luma_inter_macroblock_16x16(process_ctxt_t *ps_proc) { /* Codec Context */ @@ -2241,18 +2245,16 @@ UWORD8 ih264e_code_luma_inter_macroblock_16x16(process_ctxt_t *ps_proc) * @brief performs chroma core coding for inter macro blocks * * @par Description: -* If the current mb is to be coded as inter predicted mb,based on the sub mb partitions -* and corresponding motion vectors generated by ME ,prediction is done. +* If the current mb is to be coded as inter predicted mb, based on the sub mb +* partitions and corresponding motion vectors generated by ME, prediction is done. * Then, error is computed between the input blk and the estimated blk. -* This error is transformed , quantized. The quantized coefficients -* are packed in scan order for -* entropy coding. +* This error is transformed, quantized. The quantized coefficients +* are packed in scan order for entropy coding. * * @param[in] ps_proc_ctxt * pointer to the current macro block context * -* @returns u1_cbp_l -* coded block pattern chroma +* @returns coded block pattern chroma * * @remarks none * diff --git a/encoder/ih264e_core_coding.h b/encoder/ih264e_core_coding.h index 1237d25..7087ec6 100644 --- a/encoder/ih264e_core_coding.h +++ b/encoder/ih264e_core_coding.h @@ -24,7 +24,8 @@ * ih264e_core_coding.h * * @brief -* This file contains extern declarations of core coding routines +* This file contains declarations necessary for core coding of luma and chroma +* blocks * * @author * ittiam @@ -34,11 +35,11 @@ ****************************************************************************** */ -#ifndef IH264E_CORE_CODING_H_ -#define IH264E_CORE_CODING_H_ +#ifndef _IH264E_CORE_CODING_H_ +#define _IH264E_CORE_CODING_H_ /*****************************************************************************/ -/* Constant Macros */ +/* Macros */ /*****************************************************************************/ /** @@ -84,14 +85,14 @@ */ #define DEQUEUE_BLKID_FROM_CONTROL( u4_cntrl, blk_lin_id) \ { \ - blk_lin_id = CLZ(u4_cntrl); \ - u4_cntrl &= (0x7FFFFFFF >> blk_lin_id); \ + blk_lin_id = CLZ(u4_cntrl); \ + u4_cntrl &= (0x7FFFFFFF >> blk_lin_id); \ }; -#define IND2SUB_LUMA_MB(u4_blk_id,i4_offset_x,i4_offset_y) \ -{ \ - i4_offset_x = (u4_blk_id % 4) << 2; \ - i4_offset_y = (u4_blk_id / 4) << 2; \ +#define IND2SUB_LUMA_MB(u4_blk_id,i4_offset_x,i4_offset_y) \ +{ \ + i4_offset_x = (u4_blk_id % 4) << 2; \ + i4_offset_y = (u4_blk_id / 4) << 2; \ } #define IND2SUB_CHROMA_MB(u4_blk_id,i4_offset_x,i4_offset_y) \ @@ -105,67 +106,6 @@ /* Function Declarations */ /*****************************************************************************/ -/** -******************************************************************************* -* -* @brief -* This function performs does the DCT transform then Hadamard transform -* and quantization for a macroblock when the mb mode is intra 16x16 mode -* -* @par Description: -* First cf4 is done on all 16 4x4 blocks of the 16x16 input block. -* Then hadamard transform is done on the DC coefficients -* Quantization is then performed on the 16x16 block, 4x4 wise -* -* @param[in] pu1_src -* Pointer to source sub-block -* -* @param[in] pu1_pred -* Pointer to prediction sub-block -* -* @param[in] pi2_out -* Pointer to residual sub-block -* The output will be in linear format -* The first 16 continuous locations will contain the values of Dc block -* After DC block and a stride 1st AC block will follow -* After one more stride next AC block will follow -* The blocks will be in raster scan order -* -* @param[in] src_strd -* Source stride -* -* @param[in] pred_strd -* Prediction stride -* -* @param[in] dst_strd -* Destination stride -* -* @param[in] pu2_scale_matrix -* The quantization matrix for 4x4 transform -* -* @param[in] pu2_threshold_matrix -* Threshold matrix -* -* @param[in] u4_qbits -* 15+QP/6 -* -* @param[in] u4_round_factor -* Round factor for quant -* -* @param[out] pu1_nnz -* Memory to store the non-zeros after transform -* The first byte will be the nnz of DC block -* From the next byte the AC nnzs will be stored in raster scan order -* -* @param u4_dc_flag -* Signals if Dc transform is to be done or not -* 1 -> Dc transform will be done -* 0 -> Dc transform will not be done -* -* @remarks -* -******************************************************************************* -*/ void ih264e_luma_16x16_resi_trans_dctrans_quant( codec_t *ps_codec, UWORD8 *pu1_src, UWORD8 *pu1_pred, WORD16 *pi2_out, WORD32 src_strd, WORD32 pred_strd, @@ -173,71 +113,6 @@ void ih264e_luma_16x16_resi_trans_dctrans_quant( const UWORD16 *pu2_threshold_matrix, UWORD32 u4_qbits, UWORD32 u4_round_factor, UWORD8 *pu1_nnz, UWORD32 u4_dc_flag); -/** -******************************************************************************* -* -* @brief -* This function performs the intra 16x16 inverse transform process for H264 -* it includes inverse Dc transform, inverse quant and then inverse transform -* -* @par Description: -* -* @param[in] pi2_src -* Input data, 16x16 size -* First 16 mem locations will have the Dc coffs in rater scan order in linear fashion -* after a stride 1st AC clock will be present again in raster can order -* Then each AC block of the 16x16 block will follow in raster scan order -* -* @param[in] pu1_pred -* The predicted data, 16x16 size -* Block by block form -* -* @param[in] pu1_out -* Output 16x16 -* In block by block form -* -* @param[in] src_strd -* Source stride -* -* @param[in] pred_strd -* input stride for prediction buffer -* -* @param[in] out_strd -* input stride for output buffer -* -* @param[in] pu2_iscale_mat -* Inverse quantization matrix for 4x4 transform -* -* @param[in] pu2_weigh_mat -* weight matrix of 4x4 transform -* -* @param[in] qp_div -* QP/6 -* -* @param[in] pi4_tmp -* Input temporary buffer -* needs to be at least 20 in size -* -* @param[in] pu4_cntrl -* Controls the transform path -* total Last 17 bits are used -* the 16th th bit will correspond to DC block -* and 32-17 will correspond to the ac blocks in raster scan order -* bit equaling zero indicates that the entire 4x4 block is zero for DC -* For AC blocks a bit equaling zero will mean that all 15 AC coffs of the block is nonzero -* -* @param[in] pi4_tmp -* Input temporary buffer -* needs to be at least COFF_CNT_SUB_BLK_4x4+COFF_CNT_SUB_BLK_4x4 size -* -* @returns -* none -* -* @remarks -* The all zero case must be taken care outside -* -******************************************************************************* -*/ void ih264e_luma_16x16_idctrans_iquant_itrans_recon( codec_t *ps_codec, WORD16 *pi2_src, UWORD8 *pu1_pred, UWORD8 *pu1_out, WORD32 src_strd, WORD32 pred_strd, @@ -245,75 +120,6 @@ void ih264e_luma_16x16_idctrans_iquant_itrans_recon( const UWORD16 *pu2_weigh_mat, UWORD32 qp_div, UWORD32 u4_cntrl, UWORD32 u4_dc_trans_flag, WORD32 *pi4_tmp); -/** -******************************************************************************* -* -* @brief -* This function performs does the DCT transform then Hadamard transform -* and quantization for a chroma macroblock -* -* @par Description: -* First cf4 is done on all 16 4x4 blocks of the 8x8input block -* Then hadamard transform is done on the DC coefficients -* Quantization is then performed on the 8x8 block, 4x4 wise -* -* @param[in] pu1_src -* Pointer to source sub-block -* The input is in interleaved format for two chroma planes -* -* @param[in] pu1_pred -* Pointer to prediction sub-block -* Prediction is in inter leaved format -* -* @param[in] pi2_out -* Pointer to residual sub-block -* The output will be in linear format -* The first 4 continuous locations will contain the values of DC block for U -* and then next 4 will contain for V. -* After DC block and a stride 1st AC block of U plane will follow -* After one more stride next AC block of V plane will follow -* The blocks will be in raster scan order -* -* After all the AC blocks of U plane AC blocks of V plane will follow in exact -* same way -* -* @param[in] src_strd -* Source stride -* -* @param[in] pred_strd -* Prediction stride -* -* @param[in] dst_strd -* Destination stride -* -* @param[in] pu2_scale_matrix -* The quantization matrix for 4x4 transform -* -* @param[in] pu2_threshold_matrix -* Threshold matrix -* -* @param[in] u4_qbits -* 15+QP/6 -* -* @param[in] u4_round_factor -* Round factor for quant -* -* @param[out] pu1_nnz -* Memory to store the non-zeros after transform -* The first byte will be the nnz od DC block for U plane -* From the next byte the AC nnzs will be storerd in raster scan order -* The fifth byte will be nnz of Dc block of V plane -* Then Ac blocks will follow -* -* @param u4_dc_flag -* Signals if Dc transform is to be done or not -* 1 -> Dc transform will be done -* 0 -> Dc transform will not be done -* -* @remarks -* -******************************************************************************* -*/ void ih264e_chroma_8x8_resi_trans_dctrans_quant( codec_t *ps_codec, UWORD8 *pu1_src, UWORD8 *pu1_pred, WORD16 *pi2_out, WORD32 src_strd, WORD32 pred_strd, @@ -321,64 +127,6 @@ void ih264e_chroma_8x8_resi_trans_dctrans_quant( const UWORD16 *pu2_threshold_matrix, UWORD32 u4_qbits, UWORD32 u4_round_factor, UWORD8 *pu1_nnz_c); -/** -******************************************************************************* -* @brief -* This function performs the inverse transform with process for chroma MB of H264 -* -* @par Description: -* Does inverse DC transform ,inverse quantization inverse transform -* -* @param[in] pi2_src -* Input data, 16x16 size -* The input is in the form of, first 4 locations will contain DC coeffs of -* U plane, next 4 will contain DC coeffs of V plane, then AC blocks of U plane -* in raster scan order will follow, each block as linear array in raster scan order. -* After a stride next AC block will follow. After all AC blocks of U plane -* V plane AC blocks will follow in exact same order. -* -* @param[in] pu1_pred -* The predicted data, 8x16 size, U and V interleaved -* -* @param[in] pu1_out -* Output 8x16, U and V interleaved -* -* @param[in] src_strd -* Source stride -* -* @param[in] pred_strd -* input stride for prediction buffer -* -* @param[in] out_strd -* input stride for output buffer -* -* @param[in] pu2_iscale_mat -* Inverse quantization martix for 4x4 transform -* -* @param[in] pu2_weigh_mat -* weight matrix of 4x4 transform -* -* @param[in] qp_div -* QP/6 -* -* @param[in] pi4_tmp -* Input temporary buffer -* needs to be at least COFF_CNT_SUB_BLK_4x4 + Number of Dc cofss for chroma * number of planes -* in size -* -* @param[in] pu4_cntrl -* Controls the transform path -* the 15 th bit will correspond to DC block of U plane , 14th will indicate the V plane Dc block -* 32-28 bits will indicate AC blocks of U plane in raster scan order -* 27-23 bits will indicate AC blocks of V plane in rater scan order -* The bit 1 implies that there is at least one non zero coff in a block -* -* @returns -* none -* -* @remarks -******************************************************************************* -*/ void ih264e_chroma_8x8_idctrans_iquant_itrans_recon( codec_t *ps_codec, WORD16 *pi2_src, UWORD8 *pu1_pred, UWORD8 *pu1_out, WORD32 src_strd, WORD32 pred_strd, @@ -386,268 +134,25 @@ void ih264e_chroma_8x8_idctrans_iquant_itrans_recon( const UWORD16 *pu2_weigh_mat, UWORD32 qp_div, UWORD32 u4_cntrl, WORD32 *pi4_tmp); -/** -****************************************************************************** -* -* @brief This function packs residue of an i16x16 luma mb for entropy coding -* -* @par Description -* An i16 macro block contains two classes of units, dc 4x4 block and -* 4x4 ac blocks. while packing the mb, the dc block is sent first, and -* the 16 ac blocks are sent next in scan order. Each and every block is -* represented by 3 parameters (nnz, significant coefficient map and the -* residue coefficients itself). If a 4x4 unit does not have any coefficients -* then only nnz is sent. Inside a 4x4 block the individual coefficients are -* sent in scan order. -* -* The first byte of each block will be nnz of the block, if it is non zero, -* a 2 byte significance map is sent. This is followed by nonzero coefficients. -* This is repeated for 1 dc + 16 ac blocks. -* -* @param[in] pi2_res_mb -* pointer to residue mb -* -* @param[in, out] pv_mb_coeff_data -* buffer pointing to packed residue coefficients -* -* @param[in] u4_res_strd -* residual block stride -* -* @param[out] u1_cbp_l -* coded block pattern luma -* -* @param[in] pu1_nnz -* number of non zero coefficients in each 4x4 unit -* -* @param[out] -* Control signal for inverse transform of 16x16 blocks -* -* @return none -* -* @ remarks -* -****************************************************************************** -*/ void ih264e_pack_l_mb_i16(WORD16 *pi2_res_mb, void **pv_mb_coeff_data, WORD32 i4_res_strd, UWORD8 *u1_cbp_l, UWORD8 *pu1_nnz, UWORD32 *pu4_cntrl); -/** -****************************************************************************** -* -* @brief This function packs residue of an i8x8 chroma mb for entropy coding -* -* @par Description -* An i8 chroma macro block contains two classes of units, dc 2x2 block and -* 4x4 ac blocks. while packing the mb, the dc block is sent first, and -* the 4 ac blocks are sent next in scan order. Each and every block is -* represented by 3 parameters (nnz, significant coefficient map and the -* residue coefficients itself). If a 4x4 unit does not have any coefficients -* then only nnz is sent. Inside a 4x4 block the individual coefficients are -* sent in scan order. -* -* The first byte of each block will be nnz of the block, if it is non zero, -* a 2 byte significance map is sent. This is followed by nonzero coefficients. -* This is repeated for 1 dc + 4 ac blocks. -* -* @param[in] pi2_res_mb -* pointer to residue mb -* -* @param[in, out] pv_mb_coeff_data -* buffer pointing to packed residue coefficients -* -* @param[in] u4_res_strd -* residual block stride -* -* @param[out] u1_cbp_c -* coded block pattern chroma -* -* @param[in] pu1_nnz -* number of non zero coefficients in each 4x4 unit -* -* @param[out] pu1_nnz -* Control signal for inverse transform -* -* @param[in] u4_swap_uv -* Swaps the order of U and V planes in entropy bitstream -* -* @return none -* -* @ remarks -* -****************************************************************************** -*/ void ih264e_pack_c_mb(WORD16 *pi2_res_mb, void **pv_mb_coeff_data, WORD32 i4_res_strd, UWORD8 *u1_cbp_c, UWORD8 *pu1_nnz, UWORD32 u4_kill_coffs_flag, UWORD32 *pu4_cntrl, UWORD32 u4_swap_uv); -/** -******************************************************************************* -* -* @brief performs luma core coding when intra mode is i16x16 -* -* @par Description: -* If the current mb is to be coded as intra of mb type i16x16, the mb is first -* predicted using one of i16x16 prediction filters, basing on the intra mode -* chosen. Then, error is computed between the input blk and the estimated blk. -* This error is transformed (hierarchical transform i.e., dct followed by hada- -* -mard), quantized. The quantized coefficients are packed in scan order for -* entropy coding. -* -* @param[in] ps_proc_ctxt -* pointer to the current macro block context -* -* @returns u1_cbp_l -* coded block pattern luma -* -* @remarks none -* -******************************************************************************* -*/ -UWORD8 ih264e_code_luma_intra_macroblock_16x16 - ( - process_ctxt_t *ps_proc - ); +UWORD8 ih264e_code_luma_intra_macroblock_16x16(process_ctxt_t *ps_proc); -/** -******************************************************************************* -* -* @brief performs luma core coding when intra mode is i4x4 -* -* @par Description: -* If the current mb is to be coded as intra of mb type i4x4, the mb is first -* predicted using one of i4x4 prediction filters, basing on the intra mode -* chosen. Then, error is computed between the input blk and the estimated blk. -* This error is dct transformed and quantized. The quantized coefficients are -* packed in scan order for entropy coding. -* -* @param[in] ps_proc_ctxt -* pointer to the current macro block context -* -* @returns u1_cbp_l -* coded block pattern luma -* -* @remarks -* The traversal of 4x4 subblocks in the 16x16 macroblock is as per the scan order -* mentioned in h.264 specification -* -******************************************************************************* -*/ -UWORD8 ih264e_code_luma_intra_macroblock_4x4 - ( - process_ctxt_t *ps_proc - ); +UWORD8 ih264e_code_luma_intra_macroblock_4x4(process_ctxt_t *ps_proc); -/** -******************************************************************************* -* -* @brief performs luma core coding when intra mode is i4x4 -* -* @par Description: -* If the current mb is to be coded as intra of mb type i4x4, the mb is first -* predicted using one of i4x4 prediction filters, basing on the intra mode -* chosen. Then, error is computed between the input blk and the estimated blk. -* This error is dct transformed and quantized. The quantized coefficients are -* packed in scan order for entropy coding. -* -* @param[in] ps_proc_ctxt -* pointer to the current macro block context -* -* @returns u1_cbp_l -* coded block pattern luma -* -* @remarks -* The traversal of 4x4 subblocks in the 16x16 macroblock is as per the scan order -* mentioned in h.264 specification -* -******************************************************************************* -*/ -UWORD8 ih264e_code_luma_intra_macroblock_4x4_rdopt_on - ( - process_ctxt_t *ps_proc - ); +UWORD8 ih264e_code_luma_intra_macroblock_4x4_rdopt_on(process_ctxt_t *ps_proc); -/** -******************************************************************************* -* -* @brief performs chroma core coding for intra macro blocks -* -* @par Description: -* If the current MB is to be intra coded with mb type chroma I8x8, the MB is -* first predicted using intra 8x8 prediction filters. The predicted data is -* compared with the input for error and the error is transformed. The DC -* coefficients of each transformed sub blocks are further transformed using -* Hadamard transform. The resulting coefficients are quantized, packed and sent -* for entropy coding. -* -* @param[in] ps_proc_ctxt -* pointer to the current macro block context -* -* @returns u1_cbp_c -* coded block pattern chroma -* -* @remarks -* The traversal of 4x4 subblocks in the 8x8 macroblock is as per the scan order -* mentioned in h.264 specification -* -******************************************************************************* -*/ -UWORD8 ih264e_code_chroma_intra_macroblock_8x8 - ( - process_ctxt_t *ps_proc - ); +UWORD8 ih264e_code_chroma_intra_macroblock_8x8(process_ctxt_t *ps_proc); -/** -******************************************************************************* -* @brief performs luma core coding when mode is inter -* -* @par Description: -* If the current mb is to be coded as inter predicted mb,based on the sub mb -* partitions and corresponding motion vectors generated by ME, prediction is done. -* Then, error is computed between the input blk and the estimated blk. -* This error is transformed ( dct and with out hadamard), quantized. The -* quantized coefficients are packed in scan order for entropy coding. -* -* @param[in] ps_proc_ctxt -* pointer to the current macro block context -* -* @returns u1_cbp_l -* coded block pattern luma -* -* @remarks none -* -******************************************************************************* -*/ -UWORD8 ih264e_code_luma_inter_macroblock_16x16 - ( - process_ctxt_t *ps_proc - ); +UWORD8 ih264e_code_luma_inter_macroblock_16x16(process_ctxt_t *ps_proc); -/** -******************************************************************************* -* @brief performs chroma core coding for inter macro blocks -* -* @par Description: -* If the current mb is to be coded as inter predicted mb, based on the sub mb -* partitions and corresponding motion vectors generated by ME, prediction is done. -* Then, error is computed between the input blk and the estimated blk. -* This error is transformed, quantized. The quantized coefficients -* are packed in scan order for entropy coding. -* -* @param[in] ps_proc_ctxt -* pointer to the current macro block context -* -* @returns u1_cbp_l -* coded block pattern luma -* -* @remarks none -* -******************************************************************************* -*/ -UWORD8 ih264e_code_chroma_inter_macroblock_8x8 - ( - process_ctxt_t *ps_proc - ); +UWORD8 ih264e_code_chroma_inter_macroblock_8x8(process_ctxt_t *ps_proc); -#endif /* IH264E_CORE_CODING_H_ */ +#endif /* _IH264E_CORE_CODING_H_ */ diff --git a/encoder/ih264e_deblk.c b/encoder/ih264e_deblk.c index db176ac..8766604 100644 --- a/encoder/ih264e_deblk.c +++ b/encoder/ih264e_deblk.c @@ -19,72 +19,76 @@ */ /** - ******************************************************************************* - * @file - * ih264e_deblk.c - * - * @brief - * This file contains functions that are associated with deblocking - * - * @author - * ittiam - * - * @par List of Functions: - * - ih264e_fill_bs_1mv_1ref_non_mbaff - * - ih264e_calculate_csbp - * - ih264e_compute_bs - * - ih264e_filter_top_edge - * - ih264e_filter_left_edge - * - ih264e_deblock_mb - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264e_deblk.c +* +* @brief +* This file contains functions that are associated with deblocking +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264e_fill_bs_1mv_1ref_non_mbaff +* - ih264e_calculate_csbp +* - ih264e_compute_bs +* - ih264e_filter_top_edge +* - ih264e_filter_left_edge +* - ih264e_deblock_mb +* +* @remarks +* none +* +******************************************************************************* +*/ /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <string.h> #include <assert.h> -/* User include files */ +/* User Include Files */ #include "ih264e_config.h" #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" + #include "ih264_macros.h" #include "ih264_defs.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_trans_data.h" #include "ih264_cabac_tables.h" +#include "ih264_deblk_tables.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264_trans_data.h" -#include "ih264_deblk_tables.h" #include "ih264e_deblk.h" /*****************************************************************************/ -/* Extern global definitions */ +/* global definitions */ /*****************************************************************************/ /** @@ -161,7 +165,6 @@ static const UWORD16 ih264e_gu2_4x4_v2h_reorder[16] = * @param[in] ps_curr_pu * PU for current MB * -* * @returns none * * @remarks none @@ -296,7 +299,7 @@ static void ih264e_fill_bs_1mv_1ref_non_mbaff(UWORD32 *pu4_horz_bs, { u4_left_flag = 1; } - else if(ps_curr_pu->b2_pred_mode != 2)/* Not bipred */ + else if (ps_curr_pu->b2_pred_mode != 2)/* Not bipred */ { i16_pMvl0_x = ps_left_pu->s_me_info[ps_left_pu->b2_pred_mode].s_mv.i2_mvx; i16_pMvl0_y = ps_left_pu->s_me_info[ps_left_pu->b2_pred_mode].s_mv.i2_mvy; @@ -310,7 +313,6 @@ static void ih264e_fill_bs_1mv_1ref_non_mbaff(UWORD32 *pu4_horz_bs, } else { - i16_pMvl0_x = ps_left_pu->s_me_info[PRED_L0].s_mv.i2_mvx; i16_pMvl0_y = ps_left_pu->s_me_info[PRED_L0].s_mv.i2_mvy; i16_pMvl1_x = ps_left_pu->s_me_info[PRED_L1].s_mv.i2_mvx; diff --git a/encoder/ih264e_deblk.h b/encoder/ih264e_deblk.h index 9b3b67b..35be2fb 100644 --- a/encoder/ih264e_deblk.h +++ b/encoder/ih264e_deblk.h @@ -24,7 +24,7 @@ * ih264e_deblk.h * * @brief -* This file contains extern declarations of deblocking routines +* This file contains declarations of deblocking routines * * @author * ittiam @@ -34,8 +34,8 @@ ****************************************************************************** */ -#ifndef IH264E_DEBLK_H_ -#define IH264E_DEBLK_H_ +#ifndef _IH264E_DEBLK_H_ +#define _IH264E_DEBLK_H_ /*****************************************************************************/ /* Constant Macros */ @@ -43,9 +43,9 @@ /** ****************************************************************************** - * @brief masks to extract csbp +* @brief masks to extract csbp ****************************************************************************** - */ +*/ #define CSBP_LEFT_BLOCK_MASK 0x1111 #define CSBP_RIGHT_BLOCK_MASK 0x8888 @@ -54,46 +54,8 @@ /* Function Declarations */ /*****************************************************************************/ -/** -******************************************************************************* -* -* @brief This function computes blocking strength for an mb -* -* @par Description: -* This function computes blocking strength for an mb -* -* @param[in] ps_proc -* process context -* -* @returns none -* -* @remarks In this module it is assumed that their is only single reference -* frame and is always the most recently used anchor frame -* -******************************************************************************* -*/ void ih264e_compute_bs(process_ctxt_t * ps_proc); -/** -******************************************************************************* -* -* @brief This function performs deblocking on an mb -* -* @par Description: -* This function performs deblocking on an mb -* -* @param[in] ps_proc -* process context corresponding to the job -* -* @param[in] ps_deblk -* pointer to deblock context -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ void ih264e_deblock_mb(process_ctxt_t *ps_proc, deblk_ctxt_t * ps_deblk); -#endif /* IH264E_DEBLK_H_ */ +#endif /* _IH264E_DEBLK_H_ */ diff --git a/encoder/ih264e_defs.h b/encoder/ih264e_defs.h index 7f69554..317e306 100644 --- a/encoder/ih264e_defs.h +++ b/encoder/ih264e_defs.h @@ -23,21 +23,29 @@ * ih264e_defs.h * * @brief -* Definitions used in the encoder +* Declarations of common definitions used in the encoder library * * @author * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_DEFS_H_ -#define IH264E_DEFS_H_ +#ifndef _IH264E_DEFS_H_ +#define _IH264E_DEFS_H_ +/*****************************************************************************/ +/* Function Macros */ +/*****************************************************************************/ +/** + ***************************************************************************** + * Macro to extract residue, nnz, significant coefficient map for a 4x4 blk + ***************************************************************************** + */ #define PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, u4_nnz, u4_sig_coeff_map, pi2_res_block) \ { \ ps_mb_coeff_data = pv_mb_coeff_data; \ @@ -54,6 +62,33 @@ } \ } +/** + ***************************************************************************** + * Macro to compute total size required to hold on set of scaling matrices + ***************************************************************************** + */ +#define SCALING_MAT_SIZE(m_scaling_mat_size) \ +{ \ + m_scaling_mat_size = 6 * TRANS_SIZE_4 * TRANS_SIZE_4; \ + m_scaling_mat_size += 6 * TRANS_SIZE_8 * TRANS_SIZE_8; \ + m_scaling_mat_size += 6 * TRANS_SIZE_16 * TRANS_SIZE_16; \ + m_scaling_mat_size += 2 * TRANS_SIZE_32 * TRANS_SIZE_32; \ +} + +/** + ****************************************************************************** + * @brief Macros to get raster scan position of a block[8x8] / sub block[4x4] + ****************************************************************************** + */ +#define GET_BLK_RASTER_POS_X(x) ((x & 0x01)) +#define GET_BLK_RASTER_POS_Y(y) ((y >> 1)) +#define GET_SUB_BLK_RASTER_POS_X(x) ((x & 0x01)) +#define GET_SUB_BLK_RASTER_POS_Y(y) ((y >> 1)) + +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ + /*****************************************************************************/ /* Width and height restrictions */ /*****************************************************************************/ @@ -202,19 +237,21 @@ #define LOG2_MAX_SLICE_HDR_CNT 8 #define MAX_SLICE_HDR_CNT (1 << LOG2_MAX_SLICE_HDR_CNT) -/* Generic declarations */ +/** + * Generic declarations + */ #define DEFAULT_MAX_LEVEL 40 #define DEFAULT_RECON_ENABLE 0 #define DEFAULT_QUALITY_METRICS_ENABLE 0 #define DEFAULT_RC IVE_RC_STORAGE -#define DEFAULT_MAX_FRAMERATE 120000 +#define DEFAULT_MAX_FRAMERATE 120000 /* in ticks (1000 ticks = 1s) */ #define DEFAULT_MAX_BITRATE 240000000 #define DEFAULT_MAX_NUM_BFRAMES 0 #define DEFAULT_MAX_SRCH_RANGE_X 256 #define DEFAULT_MAX_SRCH_RANGE_Y 256 #define DEFAULT_SLICE_PARAM 256 -#define DEFAULT_SRC_FRAME_RATE 30000 -#define DEFAULT_TGT_FRAME_RATE 30000 +#define DEFAULT_SRC_FRAME_RATE 30000 /* in ticks (1000 ticks = 1s) */ +#define DEFAULT_TGT_FRAME_RATE 30000 /* in ticks (1000 ticks = 1s) */ #define DEFAULT_BITRATE 6000000 #define DEFAULT_QP_MIN 10 #define DEFAULT_QP_MAX 51 @@ -237,10 +274,9 @@ #define DEFAULT_MIN_SAD_ENABLE 0 #define DEFAULT_MIN_SAD_DISABLE -1 #define DEFAULT_SRCH_RNG_X 64 -#define DEFAULT_SRCH_RNG_Y 48 +#define DEFAULT_SRCH_RNG_Y 64 #define DEFAULT_I_INTERVAL 30 -#define DEFAULT_IDR_INTERVAL 1000 -#define DEFAULT_B_FRAMES 0 +#define DEFAULT_IDR_INTERVAL 1200 #define DEFAULT_DISABLE_DEBLK_LEVEL 0 #define DEFAULT_PROFILE IV_PROFILE_BASE #define DEFAULT_MIN_INTRA_FRAME_RATE 1 @@ -248,10 +284,10 @@ #define DEFAULT_MIN_BUFFER_DELAY 30 #define DEFAULT_MAX_BUFFER_DELAY 20000 #define DEFAULT_STRIDE 0 -#define DEFAULT_ENC_SPEED_PRESET IVE_USER_DEFINED #define DEFAULT_PRE_ENC_ME 0 #define DEFAULT_PRE_ENC_IPE 0 #define DEFAULT_ENTROPY_CODING_MODE 0 +#define DEFAULT_CONSTRAINED_INTRAPRED 0 /** Maximum number of entries in input buffer list */ #define MAX_INP_BUF_LIST_ENTRIES 32 @@ -268,32 +304,88 @@ /** Number of buffers Needed for SUBPEL and BIPRED computation */ #define SUBPEL_BUFF_CNT 4 +#define NUM_RC_MEMTABS 17 + +#define DISABLE_DEBLOCK_INTERVAL 8 + /** Mask value for PSNR. Needed when quality metrics is enabled */ #define QUALITY_MASK_PSNR 0x1 + /** - ***************************************************************************** - * Macro to compute total size required to hold on set of scaling matrices - ***************************************************************************** + **************************************************************************** + * Number of buffers for I/O based on format + **************************************************************************** */ -#define SCALING_MAT_SIZE(m_scaling_mat_size) \ -{ \ - m_scaling_mat_size = 6 * TRANS_SIZE_4 * TRANS_SIZE_4; \ - m_scaling_mat_size += 6 * TRANS_SIZE_8 * TRANS_SIZE_8; \ - m_scaling_mat_size += 6 * TRANS_SIZE_16 * TRANS_SIZE_16; \ - m_scaling_mat_size += 2 * TRANS_SIZE_32 * TRANS_SIZE_32; \ -} + +/** Minimum number of input buffers */ +#define MIN_INP_BUFS 2 + +/** Minimum number of output buffers */ +#define MIN_OUT_BUFS 1 + +/** Minimum number of components in bitstream buffer */ +#define MIN_BITS_BUFS_COMP 1 + +/** Minimum number of components in raw buffer */ +#define MIN_RAW_BUFS_420_COMP 3 +#define MIN_RAW_BUFS_422ILE_COMP 1 +#define MIN_RAW_BUFS_RGB565_COMP 1 +#define MIN_RAW_BUFS_RGBA8888_COMP 1 +#define MIN_RAW_BUFS_420SP_COMP 2 + +/** Maximum number of active config paramter sets */ +#define MAX_ACTIVE_CONFIG_PARAMS 32 /** - ****************************************************************************** - * @brief Macros to get raster scan position of a block[8x8] / sub block[4x4] - ****************************************************************************** - */ -#define GET_BLK_RASTER_POS_X(x) ((x & 0x01)) -#define GET_BLK_RASTER_POS_Y(y) ((y >> 1)) -#define GET_SUB_BLK_RASTER_POS_X(x) ((x & 0x01)) -#define GET_SUB_BLK_RASTER_POS_Y(y) ((y >> 1)) +****************************************************************************** + * @brief Thresholds for luma & chroma to determine if the 8x8 subblock needs + * to be encoded or skipped +****************************************************************************** +*/ +#define LUMA_SUB_BLOCK_SKIP_THRESHOLD 4 +#define LUMA_BLOCK_SKIP_THRESHOLD 5 +#define CHROMA_BLOCK_SKIP_THRESHOLD 4 -#define NUM_RC_MEMTABS 17 +/** +****************************************************************************** + * @brief defines the first byte of a NAL unit + * forbidden zero bit - nal_ref_idc - nal_unit_type +****************************************************************************** +*/ +/* [0 - 11 - 00111] */ +#define NAL_SPS_FIRST_BYTE 0x67 + +/* [0 - 11 - 01000] */ +#define NAL_PPS_FIRST_BYTE 0x68 + +/* [0 - 11 - 00001] */ +#define NAL_SLICE_FIRST_BYTE 0x61 + +/* [0 - 00 - 00001] */ +#define NAL_NON_REF_SLICE_FIRST_BYTE 0x01 + +/* [0 - 11 - 00101] */ +#define NAL_IDR_SLICE_FIRST_BYTE 0x65 + +/* [0 - 00 - 01100] */ +#define NAL_FILLER_FIRST_BYTE 0x0C + +/* [0 - 00 - 00110] */ +#define NAL_SEI_FIRST_BYTE 0x06 + +/** +****************************************************************************** + * @brief h264qp and linear qp map +****************************************************************************** +*/ +#define H264_MPEG_QP_MAP 255 +#define MPEG2_QP_ELEM (H264_MPEG_QP_MAP + 1) +#define H264_QP_ELEM (MAX_H264_QP + 1) + + +/*****************************************************************************/ +/* Enums */ +/*****************************************************************************/ /** *************************************************************************** @@ -348,6 +440,11 @@ enum MEM_REC_MVBITS, /** + * Overlay Intra Cost Map + */ + MEM_REC_INTRA_COST, + + /** * Holds mem records passed to the codec. */ MEM_REC_BACKUP, @@ -484,8 +581,6 @@ enum */ }; -#define DISABLE_DEBLOCK_INTERVAL 8 - /** **************************************************************************** * Disable deblock levels @@ -522,76 +617,4 @@ enum DISABLE_DEBLK_LEVEL_4 }; -/** - **************************************************************************** - * Number of buffers for I/O based on format - **************************************************************************** - */ - -/** Minimum number of input buffers */ -#define MIN_INP_BUFS 2 - -/** Minimum number of output buffers */ -#define MIN_OUT_BUFS 1 - -/** Minimum number of components in bitstream buffer */ -#define MIN_BITS_BUFS_COMP 1 - -/** Minimum number of components in raw buffer */ -#define MIN_RAW_BUFS_420_COMP 3 -#define MIN_RAW_BUFS_422ILE_COMP 1 -#define MIN_RAW_BUFS_RGB565_COMP 1 -#define MIN_RAW_BUFS_RGBA8888_COMP 1 -#define MIN_RAW_BUFS_420SP_COMP 2 - -/** Maximum number of active config paramter sets */ -#define MAX_ACTIVE_CONFIG_PARAMS 32 - -/** -****************************************************************************** - * @brief Thresholds for luma & chroma to determine if the 8x8 subblock needs - * to be encoded or skipped -****************************************************************************** -*/ -#define LUMA_SUB_BLOCK_SKIP_THRESHOLD 4 -#define LUMA_BLOCK_SKIP_THRESHOLD 5 -#define CHROMA_BLOCK_SKIP_THRESHOLD 4 - -/** -****************************************************************************** - * @brief defines the first byte of a NAL unit - * forbidden zero bit - nal_ref_idc - nal_unit_type -****************************************************************************** -*/ -/* [0 - 11 - 00111] */ -#define NAL_SPS_FIRST_BYTE 0x67 - -/* [0 - 11 - 01000] */ -#define NAL_PPS_FIRST_BYTE 0x68 - -/* [0 - 11 - 00001] */ -#define NAL_SLICE_FIRST_BYTE 0x61 - -/* [0 - 00 - 00001] */ -#define NAL_NON_REF_SLICE_FIRST_BYTE 0x01 - -/* [0 - 11 - 00101] */ -#define NAL_IDR_SLICE_FIRST_BYTE 0x65 - -/* [0 - 00 - 01100] */ -#define NAL_FILLER_FIRST_BYTE 0x0C - -/* [0 - 00 - 00110] */ -#define NAL_SEI_FIRST_BYTE 0x06 - -#define H264_ALLOC_INTER_FRM_INTV 2 - -#define H264_MPEG_QP_MAP 255 - -#define MPEG2_QP_ELEM (H264_MPEG_QP_MAP + 1) -#define H264_QP_ELEM (MAX_H264_QP + 1) - -#define H264_INIT_QUANT_I 26 -#define H264_INIT_QUANT_P 34 - -#endif /*IH264E_DEFS_H_*/ +#endif /*_IH264E_DEFS_H_ */ diff --git a/encoder/ih264e_encode.c b/encoder/ih264e_encode.c index 1db0850..f5d14d2 100644 --- a/encoder/ih264e_encode.c +++ b/encoder/ih264e_encode.c @@ -31,9 +31,9 @@ * ittiam * * List of Functions -* - ih264e_join_threads() -* - ih264e_wait_for_thread() -* - ih264e_encode() +* - ih264e_join_threads +* - ih264e_wait_for_thread +* - ih264e_encode * ****************************************************************************** */ @@ -50,49 +50,54 @@ #include <assert.h> #include <limits.h> #include <stdbool.h> -/* User Include files */ + +/* User Include Files */ #include "ih264e_config.h" #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264e.h" #include "ithread.h" -#include "ih264_defs.h" -#include "ih264_macros.h" + #include "ih264_debug.h" -#include "ih264_structs.h" -#include "ih264_platform_macros.h" +#include "ih264_macros.h" #include "ih264_error.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" -#include "ih264_trans_quant_itrans_iquant.h" -#include "ih264_inter_pred_filters.h" +#include "ih264_defs.h" #include "ih264_mem_fns.h" #include "ih264_padding.h" +#include "ih264_structs.h" +#include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_inter_pred_filters.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" #include "ih264_cabac_tables.h" +#include "ih264_buf_mgr.h" #include "ih264_list.h" -#include "ih264e_error.h" -#include "ih264e_defs.h" -#include "ih264e_bitstream.h" +#include "ih264_dpb_mgr.h" +#include "ih264_platform_macros.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_mem_req_and_acq.h" #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" -#include "ih264e_rate_control.h" + +#include "ih264e.h" +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_time_stamp.h" +#include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" +#include "ih264e_utils.h" +#include "ih264e_encode_header.h" #include "ih264e_master.h" #include "ih264e_process.h" -#include "ih264_buf_mgr.h" -#include "ih264_dpb_mgr.h" -#include "ih264e_utils.h" #include "ih264e_fmt_conv.h" #include "ih264e_statistics.h" #include "ih264e_trace.h" -#include "ih264e_debug.h" #ifdef LOGO_EN #include "ih264e_ittiam_logo.h" #endif @@ -522,7 +527,7 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) } /* curr pic cnt */ - ps_codec->i4_pic_cnt += 1; + ps_codec->i4_pic_cnt += 1; i4_rc_pre_enc_skip = 0; i4_rc_pre_enc_skip = ih264e_input_queue_update( @@ -586,6 +591,12 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) ih264_list_reset(ps_codec->pv_entropy_jobq); + error_status = ih264e_update_rc_post_enc(ps_codec, ctxt_sel, (ps_codec->i4_poc == 0)); + SET_ERROR_ON_RETURN(error_status, + ((error_status == IH264E_BITSTREAM_BUFFER_OVERFLOW) ? + IVE_UNSUPPORTEDPARAM : IVE_FATALERROR), + ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL); + if (ps_codec->s_cfg.u4_enable_quality_metrics & QUALITY_MASK_PSNR) { ih264e_compute_quality_stats(ps_proc); @@ -593,7 +604,6 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) } - /**************************************************************************** * RECON * Since we have forward dependent frames, we cannot return recon in encoding @@ -709,7 +719,6 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) } } - /*************************************************************************** * Free reference buffers: * In case of a post enc skip, we have to ensure that those pics will not @@ -788,7 +797,6 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) } } - /************************************************************************** * Signaling to APP * 1) If we valid a valid output mark it so @@ -817,7 +825,6 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) ps_video_encode_op->s_ive_op.u4_timestamp_low = s_inp_buf.u4_timestamp_low; ps_video_encode_op->s_ive_op.u4_timestamp_high = s_inp_buf.u4_timestamp_high; - switch (ps_codec->pic_type) { case PIC_IDR: diff --git a/encoder/ih264e_encode_header.c b/encoder/ih264e_encode_header.c index 4eb0017..aa2aa27 100644 --- a/encoder/ih264e_encode_header.c +++ b/encoder/ih264e_encode_header.c @@ -30,19 +30,20 @@ * ittiam * * @par List of Functions: -* - ih264e_generate_nal_unit_header() -* - ih264e_generate_sps() -* - ih264e_generate_pps() -* - ih264e_generate_sei() -* - ih264e_generate_slice_header() -* - ih264e_get_level() -* - ih264e_populate_sps() -* - ih264e_populate_pps() -* - ih264e_populate_slice_header() -* - ih264e_add_filler_nal_unit() +* - ih264e_generate_nal_unit_header +* - ih264e_generate_vui +* - ih264e_generate_aud +* - ih264e_generate_sps +* - ih264e_generate_pps +* - ih264e_generate_slice_header +* - ih264e_populate_vui +* - ih264e_populate_sps +* - ih264e_populate_pps +* - ih264e_populate_slice_header +* - ih264e_add_filler_nal_unit * * @remarks -* None +* none * ******************************************************************************* */ @@ -51,7 +52,7 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> @@ -59,40 +60,44 @@ #include <assert.h> /* User Include Files */ +#include "ih264e_config.h" #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264e.h" #include "ithread.h" -#include "ih264e_config.h" -#include "ih264e_trace.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" + #include "ih264_debug.h" -#include "ih264_defs.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" +#include "ih264_macros.h" #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_common_tables.h" #include "ih264_cabac_tables.h" -#include "ih264e_defs.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e.h" +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" +#include "ih264e_utils.h" #include "ih264e_sei.h" #include "ih264e_encode_header.h" -#include "ih264_common_tables.h" -#include "ih264_macros.h" -#include "ih264e_utils.h" +#include "ih264e_trace.h" /*****************************************************************************/ @@ -1056,22 +1061,29 @@ WORD32 ih264e_generate_slice_header(bitstrm_t *ps_bitstrm, */ IH264E_ERROR_T ih264e_populate_vui(codec_t *ps_codec) { - + /* vui params */ vui_t *ps_vui = &ps_codec->s_cfg.s_vui; - sps_t *ps_sps = ps_codec->ps_sps_base + ps_codec->i4_sps_id; + /* active sps params */ + sps_t *ps_sps = ps_codec->ps_sps_base + ps_codec->i4_sps_id; ps_vui->u1_nal_hrd_parameters_present_flag = 0; + ps_vui->u1_vcl_hrd_parameters_present_flag = 0; ps_vui->u1_bitstream_restriction_flag = 1; + ps_vui->u1_motion_vectors_over_pic_boundaries_flag = 1; + ps_vui->u1_max_bytes_per_pic_denom = 0; + ps_vui->u1_max_bits_per_mb_denom = 0; + ps_vui->u1_log2_max_mv_length_horizontal = 16; + ps_vui->u1_log2_max_mv_length_vertical = 16; - if(ps_codec->s_cfg.u4_num_bframes == 0) + if (ps_codec->s_cfg.u4_num_bframes == 0) { ps_vui->u1_num_reorder_frames = 0; } @@ -1082,12 +1094,9 @@ IH264E_ERROR_T ih264e_populate_vui(codec_t *ps_codec) ps_vui->u1_max_dec_frame_buffering = ps_sps->u1_max_num_ref_frames; - - return 0; + return IH264E_SUCCESS; } - - /** ****************************************************************************** * @@ -1259,6 +1268,7 @@ IH264E_ERROR_T ih264e_populate_sps(codec_t *ps_codec, sps_t *ps_sps) ps_sps->i1_direct_8x8_inference_flag = 1; } + /* cropping params */ /*NOTE : Cropping values depend on the chroma format * For our case ,decoder interprets the cropping values as 2*num pixels @@ -1365,6 +1375,7 @@ IH264E_ERROR_T ih264e_populate_pps(codec_t *ps_codec, pps_t *ps_pps) ps_pps->i1_redundant_pic_cnt_present_flag = 0; ps_pps->u1_slice_group_map_type = 0; + return IH264E_SUCCESS; } diff --git a/encoder/ih264e_encode_header.h b/encoder/ih264e_encode_header.h index c4876b3..3f480b4 100644 --- a/encoder/ih264e_encode_header.h +++ b/encoder/ih264e_encode_header.h @@ -31,13 +31,13 @@ * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_ENCODE_HEADER_H_ -#define IH264E_ENCODE_HEADER_H_ +#ifndef _IH264E_ENCODE_HEADER_H_ +#define _IH264E_ENCODE_HEADER_H_ /*****************************************************************************/ /* Function Macros */ @@ -106,228 +106,33 @@ } /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ -/** -****************************************************************************** -* -* @brief Generates SPS (Sequence Parameter Set) -* -* @par Description -* This function generates Sequence Parameter Set header as per the spec -* -* @param[in] ps_bitstrm -* pointer to bitstream context (handle) -* -* @param[in] ps_sps -* pointer to structure containing SPS data -* -* @return success or failure error code -* -****************************************************************************** -*/ -WORD32 ih264e_generate_sps - ( - bitstrm_t *ps_bitstrm, - sps_t *ps_sps, - vui_t *ps_vui - ); - -/** -****************************************************************************** -* -* @brief Generates PPS (Picture Parameter Set) -* -* @par Description -* Generate Picture Parameter Set as per Section 7.3.2.2 -* -* @param[in] ps_bitstrm -* pointer to bitstream context (handle) -* -* @param[in] ps_pps -* pointer to structure containing PPS data -* -* @return success or failure error code -* -****************************************************************************** -*/ -WORD32 ih264e_generate_pps - ( - bitstrm_t *ps_bitstrm, - pps_t *ps_pps, - sps_t *ps_sps - ); - -/** -****************************************************************************** -* -* @brief Generates SEI (Supplemental Enhancement Information) -* -* @par Description -* This function generates Supplemental Enhancement Information header as per the spec -* -* @param[in] ps_bitstrm -* pointer to bitstream context (handle) -* -* @param[in] ps_sei -* pointer to structure containing SEI data -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_generate_sei - ( - bitstrm_t *ps_bitstrm, - sei_params_t *ps_sei, - UWORD32 u4_insert_per_idr - ); +WORD32 ih264e_generate_sps(bitstrm_t *ps_bitstrm, sps_t *ps_sps, vui_t *ps_vui); -/** -****************************************************************************** -* -* @brief Generates Slice Header -* -* @par Description -* Generate Slice Header as per Section 7.3.5.1 -* -* @param[inout] ps_bitstrm -* pointer to bitstream context for generating slice header -* -* @param[in] ps_slice_hdr -* pointer to slice header params -* -* @param[in] ps_pps -* pointer to pps params referred by slice -* -* @param[in] ps_sps -* pointer to sps params referred by slice -* -* @param[out] ps_dup_bit_strm_ent_offset -* Bitstream struct to store bitstream state -* -* @param[out] pu4_first_slice_start_offset -* first slice offset is returned -* -* @return success or failure error code -* -****************************************************************************** -*/ -WORD32 ih264e_generate_slice_header - ( - bitstrm_t *ps_bitstrm, - slice_header_t *ps_slice_hdr, - pps_t *ps_pps, - sps_t *ps_sps - ); +WORD32 ih264e_generate_pps(bitstrm_t *ps_bitstrm, pps_t *ps_pps, sps_t *ps_sps); -/** -****************************************************************************** -* -* @brief Populates sps structure -* -* @par Description -* Populates sps structure for its use in header generation -* -* @param[in] ps_codec -* pointer to encoder context -* -* @param[out] ps_sps -* pointer to sps params that needs to be populated -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_populate_sps - ( - codec_t *ps_codec, - sps_t *ps_sps - ); +IH264E_ERROR_T ih264e_generate_sei(bitstrm_t *ps_bitstrm, + sei_params_t *ps_sei, + UWORD32 u4_insert_per_idr); -/** -****************************************************************************** -* -* @brief Populates pps structure -* -* @par Description -* Populates pps structure for its use in header generation -* -* @param[in] ps_codec -* pointer to encoder context -* -* @param[out] ps_pps -* pointer to pps params that needs to be populated -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_populate_pps - ( - codec_t *ps_codec, - pps_t *ps_pps - ); +WORD32 ih264e_generate_slice_header(bitstrm_t *ps_bitstrm, + slice_header_t *ps_slice_hdr, + pps_t *ps_pps, + sps_t *ps_sps); +IH264E_ERROR_T ih264e_populate_sps(codec_t *ps_codec, sps_t *ps_sps); -/** -****************************************************************************** -* -* @brief Populates slice header structure -* -* @par Description -* Populates slice header structure for its use in header generation -* -* @param[in] ps_proc -* pointer to proc context -* -* @param[out] ps_slice_hdr -* pointer to slice header structure that needs to be populated -* -* @param[in] ps_pps -* pointer to pps params structure referred by the slice -* -* @param[in] ps_sps -* pointer to sps params referred by the pps -* -* @return success or failure error code -* -****************************************************************************** -*/ -WORD32 ih264e_populate_slice_header - ( - process_ctxt_t *ps_proc, - slice_header_t *ps_slice_hdr, - pps_t *ps_pps, - sps_t *ps_sps - ); +IH264E_ERROR_T ih264e_populate_pps(codec_t *ps_codec, pps_t *ps_pps); +WORD32 ih264e_populate_slice_header(process_ctxt_t *ps_proc, + slice_header_t *ps_slice_hdr, + pps_t *ps_pps, + sps_t *ps_sps); -/** -****************************************************************************** -* -* @brief inserts FILLER Nal Unit. -* -* @par Description -* In constant bit rate rc mode, when the bits generated by the codec is -* underflowing the target bit rate, the encoder library inserts filler nal unit. -* -* @param[in] ps_bitstrm -* pointer to bitstream context (handle) -* -* @param[in] insert_fill_bytes -* Number of fill bytes to be inserted -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_add_filler_nal_unit - ( - bitstrm_t *ps_bitstrm, - WORD32 insert_fill_bytes - ); +IH264E_ERROR_T ih264e_add_filler_nal_unit(bitstrm_t *ps_bitstrm, + WORD32 insert_fill_bytes); -#endif //IH264E_ENCODE_HEADER_H_ +#endif /* _IH264E_ENCODE_HEADER_H_ */ diff --git a/encoder/ih264e_error.h b/encoder/ih264e_error.h index 05e8920..d0fd294 100644 --- a/encoder/ih264e_error.h +++ b/encoder/ih264e_error.h @@ -30,13 +30,17 @@ * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_ERROR_H_ -#define IH264E_ERROR_H_ +#ifndef _IH264E_ERROR_H_ +#define _IH264E_ERROR_H_ + +/*****************************************************************************/ +/* Function Macros */ +/*****************************************************************************/ /** ****************************************************************************** @@ -48,9 +52,12 @@ {\ out_status = ((1 << severity) | error);\ ps_codec->i4_error_code = out_status;\ - return (ret_code);\ + if (severity == IVE_FATALERROR) return (ret_code);\ } +/*****************************************************************************/ +/* Enums */ +/*****************************************************************************/ /** ****************************************************************************** @@ -254,4 +261,4 @@ typedef enum }IH264E_ERROR_T; -#endif /* IH264E_ERROR_H_ */ +#endif /* _IH264E_ERROR_H_ */ diff --git a/encoder/ih264e_fmt_conv.c b/encoder/ih264e_fmt_conv.c index e06aea1..4269572 100644 --- a/encoder/ih264e_fmt_conv.c +++ b/encoder/ih264e_fmt_conv.c @@ -30,17 +30,17 @@ * ittiam * * @par List of Functions: -* - ih264e_fmt_conv_420sp_to_rgb565() -* - ih264e_fmt_conv_420sp_to_rgba8888() -* - ih264e_fmt_conv_420sp_to_420sp() -* - ih264e_fmt_conv_420sp_to_420sp_swap_uv() -* - ih264e_fmt_conv_420sp_to_420p() -* - ih264e_fmt_conv_420p_to_420sp() -* - ih264e_fmt_conv_422i_to_420sp() -* - ih264e_fmt_conv() +* - ih264e_fmt_conv_420sp_to_rgb565 +* - ih264e_fmt_conv_420sp_to_rgba8888 +* - ih264e_fmt_conv_420sp_to_420sp +* - ih264e_fmt_conv_420sp_to_420sp_swap_uv +* - ih264e_fmt_conv_420sp_to_420p +* - ih264e_fmt_conv_420p_to_420sp +* - ih264e_fmt_conv_422i_to_420sp +* - ih264e_fmt_conv * * @remarks -* None +* none * ******************************************************************************* */ @@ -49,42 +49,45 @@ /* File Includes */ /*****************************************************************************/ -/* System Include files */ +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <string.h> #include <assert.h> -/* User Include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264e.h" #include "ithread.h" -#include "ih264_defs.h" + #include "ih264_debug.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" +#include "ih264_macros.h" #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" #include "ih264_cabac_tables.h" -#include "ih264_macros.h" #include "ih264_platform_macros.h" -#include "ih264_buf_mgr.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e.h" +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" #include "ih264e_fmt_conv.h" @@ -94,6 +97,45 @@ /* Function Definitions */ /*****************************************************************************/ +/** +******************************************************************************* +* +* @brief Function used to perform color space conversion from 420SP to RGB565 +* +* @par Description +* Function used to perform color space conversion from 420SP to RGB565 +* +* @param[in] pu1_y_src +* Input Y pointer +* +* @param[in] pu1_uv_src +* Input UV pointer +* +* @param[in] pu2_rgb_dst +* Output RGB pointer +* +* @param[in] wd +* Width +* +* @param[in] ht +* Height +* +* @param[in] src_y_strd +* Input Y Stride +* +* @param[in] src_uv_strd +* Input UV stride +* +* @param[in] dst_strd +* Output stride +* +* @param[in] is_u_first +* Flag to indicate chroma ordering +* +* @returns none +* +******************************************************************************* +*/ void ih264e_fmt_conv_420sp_to_rgb565(UWORD8 *pu1_y_src, UWORD8 *pu1_uv_src, UWORD16 *pu2_rgb_dst, @@ -207,6 +249,45 @@ void ih264e_fmt_conv_420sp_to_rgb565(UWORD8 *pu1_y_src, } +/** +******************************************************************************* +* +* @brief Function used to perform color space conversion from 420SP to RGBA888 +* +* @par Description +* Function used to perform color space conversion from 420SP to RGBA888 +* +* @param[in] pu1_y_src +* Input Y pointer +* +* @param[in] pu1_uv_src +* Input UV pointer +* +* @param[in] pu4_rgba_dst +* Output RGB pointer +* +* @param[in] wd +* Width +* +* @param[in] ht +* Height +* +* @param[in] src_y_strd +* Input Y Stride +* +* @param[in] src_uv_strd +* Input UV stride +* +* @param[in] dst_strd +* Output stride +* +* @param[in] is_u_first +* Flag to indicate chroma ordering +* +* @returns none +* +******************************************************************************* +*/ void ih264e_fmt_conv_420sp_to_rgba8888(UWORD8 *pu1_y_src, UWORD8 *pu1_uv_src, UWORD32 *pu4_rgba_dst, @@ -350,10 +431,6 @@ void ih264e_fmt_conv_420sp_to_rgba8888(UWORD8 *pu1_y_src, * * @returns None * -* @remarks In case there is a need to perform partial frame copy then -* by passion appropriate source and destination pointers and appropriate -* values for wd and ht it can be done -* ******************************************************************************* */ void ih264e_fmt_conv_420sp_to_420sp(UWORD8 *pu1_y_src, @@ -407,7 +484,48 @@ void ih264e_fmt_conv_420sp_to_420sp(UWORD8 *pu1_y_src, return; } - +/** +******************************************************************************* +* +* @brief Function used for copying a 420SP buffer and interchange chroma planes +* +* @par Description +* Function used for copying a 420SP buffer and interchange chroma planes +* +* @param[in] pu1_y_src +* Input Y pointer +* +* @param[in] pu1_uv_src +* Input UV pointer (UV is interleaved either in UV or VU format) +* +* @param[in] pu1_y_dst +* Output Y pointer +* +* @param[in] pu1_uv_dst +* Output UV pointer (UV is interleaved in the opp. format as that of input) +* +* @param[in] wd +* Width +* +* @param[in] ht +* Height +* +* @param[in] src_y_strd +* Input Y Stride +* +* @param[in] src_uv_strd +* Input UV stride +* +* @param[in] dst_y_strd +* Output Y stride +* +* @param[in] dst_uv_strd +* Output UV stride +* +* @returns None +* +******************************************************************************* +*/ void ih264e_fmt_conv_420sp_to_420sp_swap_uv(UWORD8 *pu1_y_src, UWORD8 *pu1_uv_src, UWORD8 *pu1_y_dst, @@ -464,6 +582,59 @@ void ih264e_fmt_conv_420sp_to_420sp_swap_uv(UWORD8 *pu1_y_src, return; } +/** +******************************************************************************* +* +* @brief Function used to perform color space conversion from 420SP to 420P +* +* @par Description +* Function used to perform color space conversion from 420SP to 420P +* +* @param[in] pu1_y_src +* Input Y pointer +* +* @param[in] pu1_uv_src +* Input UV pointer (UV is interleaved either in UV or VU format) +* +* @param[in] pu1_y_dst +* Output Y pointer +* +* @param[in] pu1_u_dst +* Output U pointer +* +* @param[in] pu1_v_dst +* Output V pointer +* +* @param[in] wd +* Width +* +* @param[in] ht +* Height +* +* @param[in] src_y_strd +* Input Y Stride +* +* @param[in] src_uv_strd +* Input UV stride +* +* @param[in] dst_y_strd +* Output Y stride +* +* @param[in] dst_uv_strd +* Output UV stride +* +* @param[in] is_u_first +* Flag to indicate chroma ordering +* +* @param[in] disable_luma_copy +* Flag to indicate if only UV copy needs to be done +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void ih264e_fmt_conv_420sp_to_420p(UWORD8 *pu1_y_src, UWORD8 *pu1_uv_src, UWORD8 *pu1_y_dst, @@ -585,9 +756,7 @@ void ih264e_fmt_conv_420sp_to_420p(UWORD8 *pu1_y_src, * * @returns none * -* @remarks In case there is a need to perform partial frame copy then -* by passion appropriate source and destination pointers and appropriate -* values for wd and ht it can be done +* @remarks none * ******************************************************************************* */ @@ -615,7 +784,6 @@ void ih264e_fmt_conv_420p_to_420sp(UWORD8 *pu1_y_src, if (0 == convert_uv_only) { - /* Copy Y buffer */ pu1_dst = (UWORD8 *) pu1_y_dst; pu1_src = (UWORD8 *) pu1_y_src; @@ -693,8 +861,8 @@ void ih264e_fmt_conv_420p_to_420sp(UWORD8 *pu1_y_src, * @returns None * * @remarks For conversion -* pu1_v_buf = pu1_u_buf+1 -* u4_u_stride = u4_v_stride +* pu1_v_buf = pu1_u_buf+1 +* u4_u_stride = u4_v_stride * * The extra parameters are for maintaining API with assembly function * @@ -752,12 +920,18 @@ void ih264e_fmt_conv_422i_to_420sp(UWORD8 *pu1_y_buf, /** ******************************************************************************* * -* @brief Function used from format conversion or frame copy +* @brief Function used for format conversion or frame copy * * @par Description * Function used from copying or converting a reference frame to display buffer * in non shared mode * +* @param[in] ps_codec +* Codec ctxt +* +* @param[in] ps_pic +* Reference pic ctxt +* * @param[in] pu1_y_dst * Output Y pointer * @@ -773,19 +947,15 @@ void ih264e_fmt_conv_422i_to_420sp(UWORD8 *pu1_y_buf, * @param[in] u4_dst_u_strd * Stride of destination U/V buffer * -* @param[in] blocking -* To indicate whether format conversion should wait till frame is reconstructed -* and then return after complete copy is done. To be set to 1 when called at the -* end of frame processing and set to 0 when called between frame processing modules -* in order to utilize available MCPS +* @param[in] cur_row +* Start row of fmt conversion +* +* @param[in] num_rows +* number of rows to process * * @returns error status * -* @remarks -* Assumes that the stride of U and V buffers are same. -* This is correct in most cases -* If a case comes where this is not true we need to modify the fmt conversion -* functions called inside also +* @remarks Assumes that the stride of U and V buffers are same. * ******************************************************************************* */ @@ -810,14 +980,12 @@ IH264E_ERROR_T ih264e_fmt_conv(codec_t *ps_codec, UWORD8 *pu1_chroma; WORD32 dst_stride, wd; - if (0 == num_rows) return ret; pu1_luma = ps_pic->pu1_luma; pu1_chroma = ps_pic->pu1_chroma; - dst_stride = ps_codec->s_cfg.u4_wd; wd = ps_codec->s_cfg.u4_disp_wd; is_u_first = (IV_YUV_420SP_UV == ps_codec->e_codec_color_format) ? 1 : 0; diff --git a/encoder/ih264e_fmt_conv.h b/encoder/ih264e_fmt_conv.h index 6b33bf0..b183cea 100644 --- a/encoder/ih264e_fmt_conv.h +++ b/encoder/ih264e_fmt_conv.h @@ -24,25 +24,33 @@ * ih264e_fmt_conv.h * * @brief -* The file contains extern declarations of color space conversion routines +* The file contains declarations of color space conversion routines * * @author * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_FMT_CONV_H_ -#define IH264E_FMT_CONV_H_ +#ifndef _IH264E_FMT_CONV_H_ +#define _IH264E_FMT_CONV_H_ + +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ #define COEFF1 13073 #define COEFF2 -3207 #define COEFF3 -6664 #define COEFF4 16530 +/*****************************************************************************/ +/* Function Declarations */ +/*****************************************************************************/ + IH264E_ERROR_T ih264e_fmt_conv(codec_t *ps_codec, pic_buf_t *ps_pic, UWORD8 *pu1_y_dst, @@ -113,20 +121,19 @@ typedef void ih264e_fmt_conv_422i_to_420sp_ft(UWORD8 *pu1_y_buf,UWORD8 *pu1_u_bu /* C function declarations */ -ih264e_fmt_conv_420sp_to_rgba8888_ft ih264e_fmt_conv_420sp_to_rgba8888; -ih264e_fmt_conv_420sp_to_rgb565_ft ih264e_fmt_conv_420sp_to_rgb565; -ih264e_fmt_conv_420sp_to_420sp_ft ih264e_fmt_conv_420sp_to_420sp; -ih264e_fmt_conv_420sp_to_420p_ft ih264e_fmt_conv_420sp_to_420p; -ih264e_fmt_conv_420p_to_420sp_ft ih264e_fmt_conv_420p_to_420sp; -ih264e_fmt_conv_422i_to_420sp_ft ih264e_fmt_conv_422i_to_420sp; +ih264e_fmt_conv_420sp_to_rgba8888_ft ih264e_fmt_conv_420sp_to_rgba8888; +ih264e_fmt_conv_420sp_to_rgb565_ft ih264e_fmt_conv_420sp_to_rgb565; +ih264e_fmt_conv_420sp_to_420sp_ft ih264e_fmt_conv_420sp_to_420sp; +ih264e_fmt_conv_420sp_to_420p_ft ih264e_fmt_conv_420sp_to_420p; +ih264e_fmt_conv_420p_to_420sp_ft ih264e_fmt_conv_420p_to_420sp; +ih264e_fmt_conv_422i_to_420sp_ft ih264e_fmt_conv_422i_to_420sp; /* A9Q function declarations */ -ih264e_fmt_conv_420sp_to_rgba8888_ft ih264e_fmt_conv_420sp_to_rgba8888_a9q; -ih264e_fmt_conv_420sp_to_420sp_ft ih264e_fmt_conv_420sp_to_420sp_a9q; -ih264e_fmt_conv_420sp_to_420p_ft ih264e_fmt_conv_420sp_to_420p_a9q; -ih264e_fmt_conv_420p_to_420sp_ft ih264e_fmt_conv_420p_to_420sp_a9q; -ih264e_fmt_conv_422i_to_420sp_ft ih264e_fmt_conv_422i_to_420sp_a9q; - +ih264e_fmt_conv_420sp_to_rgba8888_ft ih264e_fmt_conv_420sp_to_rgba8888_a9q; +ih264e_fmt_conv_420sp_to_420sp_ft ih264e_fmt_conv_420sp_to_420sp_a9q; +ih264e_fmt_conv_420sp_to_420p_ft ih264e_fmt_conv_420sp_to_420p_a9q; +ih264e_fmt_conv_420p_to_420sp_ft ih264e_fmt_conv_420p_to_420sp_a9q; +ih264e_fmt_conv_422i_to_420sp_ft ih264e_fmt_conv_422i_to_420sp_a9q; /* A9A function declarations */ ih264e_fmt_conv_420sp_to_rgba8888_ft ih264e_fmt_conv_420sp_to_rgba8888_a9a; @@ -139,4 +146,4 @@ ih264e_fmt_conv_420sp_to_420p_ft ih264e_fmt_conv_420sp_to_420p_ssse31; /* SSE4 function declarations */ ih264e_fmt_conv_420sp_to_420p_ft ih264e_fmt_conv_420sp_to_420p_sse42; -#endif /* IH264E_FMT_CONV_H_ */ +#endif /* _IH264E_FMT_CONV_H_ */ diff --git a/encoder/ih264e_function_selector_generic.c b/encoder/ih264e_function_selector_generic.c index 8305fd2..2730900 100644 --- a/encoder/ih264e_function_selector_generic.c +++ b/encoder/ih264e_function_selector_generic.c @@ -33,7 +33,7 @@ * - ih264e_init_function_ptr_generic * * @remarks -* None +* none * ******************************************************************************* */ @@ -43,48 +43,50 @@ /* File Includes */ /*****************************************************************************/ - -/* System Include files */ +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <string.h> -/* User Include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264_defs.h" -#include "ih264_size_defs.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" + #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_cavlc_tables.h" #include "ih264_cabac_tables.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_platform_macros.h" -#include "ih264e_cabac.h" +#include "ih264e_me.h" +#include "ih264e_half_pel.h" +#include "ih264e_intra_modes_eval.h" #include "ih264e_core_coding.h" -#include "ih264_cavlc_tables.h" #include "ih264e_cavlc.h" -#include "ih264e_intra_modes_eval.h" +#include "ih264e_cabac.h" #include "ih264e_fmt_conv.h" -#include "ih264e_half_pel.h" -#include "ih264e_me.h" +#include "ih264e_platform_macros.h" /*****************************************************************************/ @@ -94,8 +96,7 @@ /** ******************************************************************************* * -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context +* @brief Initialize the intra/inter/transform/deblk/entropy function pointers * * @par Description: the current routine initializes the function pointers of * codec context basing on the architecture in use @@ -113,10 +114,6 @@ void ih264e_init_function_ptr_generic(codec_t *ps_codec) { WORD32 i = 0; - /* curr proc ctxt */ - process_ctxt_t *ps_proc = NULL; - me_ctxt_t *ps_me_ctxt = NULL; - /* Init function pointers for intra pred leaf level functions luma * Intra 16x16 */ ps_codec->apf_intra_pred_16_l[0] = ih264_intra_pred_luma_16x16_mode_vert; @@ -155,22 +152,22 @@ void ih264e_init_function_ptr_generic(codec_t *ps_codec) ps_codec->apf_intra_pred_c[3] = ih264_intra_pred_chroma_8x8_mode_plane; /* Init luma forward transform fn ptr */ - ps_codec->pf_resi_trans_quant_8x8 = ih264_resi_trans_quant_8x8; - ps_codec->pf_resi_trans_quant_4x4 = ih264_resi_trans_quant_4x4; - ps_codec->pf_resi_trans_quant_chroma_4x4 = ih264_resi_trans_quant_chroma_4x4; - ps_codec->pf_hadamard_quant_4x4 = ih264_hadamard_quant_4x4; - ps_codec->pf_hadamard_quant_2x2_uv = ih264_hadamard_quant_2x2_uv; + ps_codec->pf_resi_trans_quant_8x8 = ih264_resi_trans_quant_8x8; + ps_codec->pf_resi_trans_quant_4x4 = ih264_resi_trans_quant_4x4; + ps_codec->pf_resi_trans_quant_chroma_4x4 = ih264_resi_trans_quant_chroma_4x4; + ps_codec->pf_hadamard_quant_4x4 = ih264_hadamard_quant_4x4; + ps_codec->pf_hadamard_quant_2x2_uv = ih264_hadamard_quant_2x2_uv; /* Init inverse transform fn ptr */ - ps_codec->pf_iquant_itrans_recon_8x8 = ih264_iquant_itrans_recon_8x8; - ps_codec->pf_iquant_itrans_recon_4x4 = ih264_iquant_itrans_recon_4x4; - ps_codec->pf_iquant_itrans_recon_4x4_dc = ih264_iquant_itrans_recon_4x4_dc; - ps_codec->pf_iquant_itrans_recon_chroma_4x4 = ih264_iquant_itrans_recon_chroma_4x4; + ps_codec->pf_iquant_itrans_recon_8x8 = ih264_iquant_itrans_recon_8x8; + ps_codec->pf_iquant_itrans_recon_4x4 = ih264_iquant_itrans_recon_4x4; + ps_codec->pf_iquant_itrans_recon_4x4_dc = ih264_iquant_itrans_recon_4x4_dc; + ps_codec->pf_iquant_itrans_recon_chroma_4x4 = ih264_iquant_itrans_recon_chroma_4x4; ps_codec->pf_iquant_itrans_recon_chroma_4x4_dc = ih264_iquant_itrans_recon_chroma_4x4_dc; - ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4; - ps_codec->pf_ihadamard_scaling_2x2_uv = ih264_ihadamard_scaling_2x2_uv; - ps_codec->pf_interleave_copy = ih264_interleave_copy; + ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4; + ps_codec->pf_ihadamard_scaling_2x2_uv = ih264_ihadamard_scaling_2x2_uv; + ps_codec->pf_interleave_copy = ih264_interleave_copy; /* Init fn ptr luma core coding */ ps_codec->luma_energy_compaction[0] = ih264e_code_luma_intra_macroblock_16x16; @@ -230,9 +227,9 @@ void ih264e_init_function_ptr_generic(codec_t *ps_codec) /* sad me level functions */ for (i = 0; i < (MAX_PROCESS_CTXT); i++) { - ps_proc = &ps_codec->as_process[i]; + process_ctxt_t *ps_proc = &ps_codec->as_process[i]; + me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt; - ps_me_ctxt = &ps_proc->s_me_ctxt; ps_me_ctxt->pf_ime_compute_sad_16x16[0] = ime_compute_sad_16x16; ps_me_ctxt->pf_ime_compute_sad_16x16[1] = ime_compute_sad_16x16_fast; ps_me_ctxt->pf_ime_compute_sad_16x8 = ime_compute_sad_16x8; @@ -263,7 +260,4 @@ void ih264e_init_function_ptr_generic(codec_t *ps_codec) /* skip decision */ ps_codec->apf_find_skip_params_me[PSLICE] = &ih264e_find_pskip_params_me; ps_codec->apf_find_skip_params_me[BSLICE] = &ih264e_find_bskip_params_me; - - - return; } diff --git a/encoder/ih264e_globals.c b/encoder/ih264e_globals.c index 6719c5f..9499782 100644 --- a/encoder/ih264e_globals.c +++ b/encoder/ih264e_globals.c @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file @@ -28,9 +29,6 @@ * @author * ittiam * -* @par List of functions -* -* * @remarks * ******************************************************************************* @@ -40,19 +38,19 @@ /* File Includes */ /*****************************************************************************/ -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "ih264_defs.h" #include "ih264e_defs.h" #include "ih264e_globals.h" /*****************************************************************************/ -/* Extern global definitions */ +/* Global definitions */ /*****************************************************************************/ /** ****************************************************************************** -* @brief lamda for varying quantizer scales that would be used to +* @brief lambda for varying quantizer scales that would be used to * compute the RD cost while deciding on the MB modes. * input : qp * output : lambda @@ -64,7 +62,7 @@ * (from rate distortion optimization for video compression by sullivan). ****************************************************************************** */ -const UWORD16 gu2_qp_lambda[52]= +const UWORD8 gu1_qp_lambdaIP[52]= { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -77,6 +75,26 @@ const UWORD16 gu2_qp_lambda[52]= /** ****************************************************************************** +* @brief lambda for varying quantizer scales that would be used to +* compute the RD cost while deciding on the MB modes. +* input : qp +* output : lambda +* @remarks lambda = max(2, min(4, pow(2, (qp - 12)/6))) * gu1_qp_lambdaIP[] +****************************************************************************** +*/ +const UWORD8 gu1_qp_lambdaB[52]= +{ + 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 3, 3, 3, 4, 4, 5, + 5, 6, 7, 8, 10, 11, 13, 15, + 17, 20, 22, 26, 30, 33, 37, 42, + 47, 53, 59, 66, 74, 83, 94, 105, + 118, 132, 149, 167, +}; + +/** +****************************************************************************** * @brief Lamda for varying quantizer scales that would be used to * compute the RD cost while deciding on the MB modes. * input : qp @@ -112,7 +130,6 @@ const UWORD8 u1_uev_codelength[32] = 9, 9, 9, 9, 9, 9, 9, 11, }; - /** ****************************************************************************** * @brief Look up table to assign cost to a coefficient of a residual block @@ -196,138 +213,57 @@ const WORD8 gi1_mv_pred_condition[8] = -1, 0, 1, -1, 2, -1, -1, -1 }; - -/******************************************************************************* - * Translation of MPEG QP to H264 QP - ******************************************************************************/ -/* - * Note : RC library models QP and bits assuming the QP to be MPEG2. - * Since MPEG qp varies linearly, when the relationship is computed, - * it learns that delta(qp) => delta(bits). Now what we are doing by the - * transation of qp is that - * QPrc = a + b*2^(QPen) - * By not considering the weight matrix in both MPEG and H264 we in effect - * only changing the relation to - * QPrc = c + d*2^(QPen) - * This will only entatil changin the RC model parameters, and this will - * not affect rc relation at all - * - * - * We have MPEG qp which varies from 0-228. The quantization factor has a linear - * relation ship with the size of quantized values - * - * We also have H264 Qp, which varies such that for a change in QP of 6 , we - * double the corresponding scaling factor. Hence the scaling is linear in terms - * of 2^(QPh/6) - * - * Now we want to have translation between QPm and QPh. Hence we can write - * - * QPm = a + b*2^(QPh/6) - * - * Appling boundary condition that - * 1) QPm = 0.625 if QPh = 0 - * 2) QPm = 224 if QPh = 51, - * - * we will have - * a = 0.0063, b = 0.6187 - * - * Hence the relatiohship is - * QPm = a + b*2^(Qph/6) - * QPh = 6*log((Qpm - a)/b) - * - * - * Unrounded values for gau1_h264_to_mpeg2_qmap[H264_QP_ELEM] = - * - * 0.625 0.70077 0.78581 0.88127 0.98843 1.10870 - * 1.24370 1.39523 1.56533 1.75625 1.97055 2.21110 - * 2.48110 2.78417 3.12435 3.50620 3.93480 4.41589 - * 4.95590 5.56204 6.24241 7.00609 7.86330 8.82548 - * 9.90550 11.11778 12.47851 14.00588 15.72030 17.64467 - * 19.80470 22.22925 24.95072 28.00547 31.43430 35.28304 - * 39.60310 44.45221 49.89514 56.00463 62.86230 70.55978 - * 79.19990 88.89811 99.78398 112.00296 125.71830 141.11325 - * 158.39350 177.78992 199.56167 223.99963 - * - * - * - * Unrounded values for gau1_mpeg2_to_h264_qmap[MPEG2_QP_ELEM] - * - * 0 4.1014 10.1288 13.6477 16.1425 18.0768 19.6568 - * 20.9925 22.1493 23.1696 24.0822 24.9078 25.6614 26.3546 - * 26.9964 27.5938 28.1527 28.6777 29.1726 29.6408 30.0850 - * 30.5074 30.9102 31.2951 31.6636 32.0171 32.3567 32.6834 - * 32.9983 33.3021 33.5957 33.8795 34.1544 34.4208 34.6793 - * 34.9303 35.1742 35.4114 35.6423 35.8671 36.0863 36.3001 - * 36.5087 36.7124 36.9115 37.1060 37.2963 37.4825 37.6648 - * 37.8433 38.0182 38.1896 38.3577 38.5226 38.6844 38.8433 - * 38.9993 39.1525 39.3031 39.4511 39.5966 39.7397 39.8804 - * 40.0189 40.1553 40.2895 40.4217 40.5518 40.6801 40.8065 - * 40.9310 41.0538 41.1749 41.2943 41.4121 41.5283 41.6430 - * 41.7561 41.8678 41.9781 42.0870 42.1946 42.3008 42.4057 - * 42.5094 42.6118 42.7131 42.8132 42.9121 43.0099 43.1066 - * 43.2023 43.2969 43.3905 43.4831 43.5747 43.6653 43.7550 - * 43.8438 43.9317 44.0187 44.1049 44.1901 44.2746 44.3582 - * 44.4411 44.5231 44.6044 44.6849 44.7647 44.8438 44.9221 - * 44.9998 45.0767 45.1530 45.2286 45.3035 45.3779 45.4515 - * 45.5246 45.5970 45.6689 45.7401 45.8108 45.8809 45.9504 - * 46.0194 46.0878 46.1557 46.2231 46.2899 46.3563 46.4221 - * 46.4874 46.5523 46.6166 46.6805 46.7439 46.8069 46.8694 - * 46.9314 46.9930 47.0542 47.1150 47.1753 47.2352 47.2947 - * 47.3538 47.4125 47.4708 47.5287 47.5862 47.6433 47.7001 - * 47.7565 47.8125 47.8682 47.9235 47.9785 48.0331 48.0874 - * 48.1413 48.1949 48.2482 48.3011 48.3537 48.4060 48.4580 - * 48.5097 48.5611 48.6122 48.6629 48.7134 48.7636 48.8135 - * 48.8631 48.9124 48.9615 49.0102 49.0587 49.1069 49.1549 - * 49.2026 49.2500 49.2972 49.3441 49.3908 49.4372 49.4834 - * 49.5293 49.5750 49.6204 49.6656 49.7106 49.7553 49.7998 - * 49.8441 49.8882 49.9320 49.9756 50.0190 50.0622 50.1051 - * 50.1479 50.1904 50.2327 50.2749 50.3168 50.3585 50.4000 - * 50.4413 50.4825 50.5234 50.5641 50.6047 50.6450 50.6852 - * 50.7252 50.7650 50.8046 50.8440 50.8833 50.9224 50.9613 - * 51.0000 - */ - +/** +****************************************************************************** +* @brief Translation of Qstep <-> QP +* Qstep(QP) = Qstep(QP%6) * (2 ^ floor(QP/6)) +* Qstep(QP, n = 0) {0.625, 0.6875, 0.8125, 0.875, 1.0, 1.125} for QP[0-5] +* @remarks QPRange[0-51] & QstepRange[1 - 224]. +****************************************************************************** +*/ const UWORD8 gau1_h264_to_mpeg2_qmap[H264_QP_ELEM] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 3, 3, 4, - 4, 4, 5, 6, 6, 7, 8, 9, - 10, 11, 12, 14, 16, 18, 20, 22, - 25, 28, 31, 35, 40, 44, 50, 56, - 63, 71, 79, 89, 100, 112, 126, 141, - 158, 178, 200, 224 + 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 3, 3, 3, 4, + 4, 5, 5, 6, 7, 7, 8, 9, + 10, 11, 13, 14, 16, 18, 20, 22, + 26, 28, 32, 36, 40, 44, 52, 56, + 64, 72, 80, 88, 104, 112, 128, 144, + 160, 176, 208, 224, }; - const UWORD8 gau1_mpeg2_to_h264_qmap[MPEG2_QP_ELEM] = { - 0, 4, 10, 14, 16, 18, 20, 21, - 22, 23, 24, 25, 26, 26, 27, 28, - 28, 29, 29, 30, 30, 31, 31, 31, - 32, 32, 32, 33, 33, 33, 34, 34, - 34, 34, 35, 35, 35, 35, 36, 36, - 36, 36, 37, 37, 37, 37, 37, 37, - 38, 38, 38, 38, 38, 39, 39, 39, - 39, 39, 39, 39, 40, 40, 40, 40, - 40, 40, 40, 41, 41, 41, 41, 41, - 41, 41, 41, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, - 51 + 0, 4, 10, 13, 16, 18, 19, 21, + 22, 23, 24, 25, 25, 26, 27, 27, + 28, 28, 29, 30, 30, 30, 31, 31, + 31, 32, 32, 32, 33, 33, 33, 34, + 34, 34, 34, 35, 35, 36, 36, 36, + 36, 36, 36, 37, 37, 37, 37, 37, + 37, 38, 38, 38, 38, 38, 38, 39, + 39, 39, 39, 39, 39, 40, 40, 40, + 40, 40, 40, 40, 40, 41, 41, 41, + 41, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 47, 47, 47, 47, 47, 47, 47, + 47, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, }; diff --git a/encoder/ih264e_globals.h b/encoder/ih264e_globals.h index 4c3de23..3c9ea1f 100644 --- a/encoder/ih264e_globals.h +++ b/encoder/ih264e_globals.h @@ -24,169 +24,37 @@ * ih264e_globals.h * * @brief -* Contains declarations of global variables for H264 encoder +* Contains declarations of global variables used in the encoder * * @author -* Ittiam +* ittiam * * @remarks +* none * ******************************************************************************* */ -#ifndef IH264E_GLOBALS_H_ -#define IH264E_GLOBALS_H_ +#ifndef _IH264E_GLOBALS_H_ +#define _IH264E_GLOBALS_H_ /*****************************************************************************/ -/* Extern global declarations */ +/* Global Declarations */ /*****************************************************************************/ -/** -****************************************************************************** -* @brief Computes the lamda for varying quantizer scales that would be used to -* compute the RD cost while deciding on the MB modes. -* input : qp -* output : lambda -* @remarks lambda = 0.85 * pow(2, (qp - 12)/3), when SSD is used as metric -* for computing distortion (Bit rate estimation for cost function of H.264/ -* AVC by Mohd Golam Sarwer et. al.) If the use of distortion metric is SAD -* rather than SSD in the stage of encoding, consider sqrt(lambda) simply to -* adjust lambda for the lack of squaring operation in the error computation -* (from rate distortion optimization for video compression by sullivan). -****************************************************************************** -*/ -extern const UWORD16 gu2_qp_lambda[52]; - -/** -****************************************************************************** -* @brief Computes the lamda for varying quantizer scales that would be used to -* compute the RD cost while deciding on the MB modes. -* input : qp -* output : lambda -* @remarks lambda = pow(2, (qp - 12)/6). When Lagrangian multiplier is disabled -* the same constant is used across mode decision and mv decisions. -****************************************************************************** -*/ +extern const UWORD8 gu1_qp_lambdaIP[52]; +extern const UWORD8 gu1_qp_lambdaB[52]; extern const UWORD8 gu1_qp0[52]; - -/** -****************************************************************************** -* @brief unsigned exp. goulumb codelengths to assign cost to a coefficient of -* mb types. -* input : Integer -* output : codelength -* @remarks Refer sec. 9-1 in h264 specification -****************************************************************************** -*/ extern const UWORD8 u1_uev_codelength[32]; - -/** -****************************************************************************** -* @brief Look up table to assign cost to a coefficient of a residual block -* basing on its surrounding coefficients -* input : Numbers of T1's -* output : coeff_cost -* @remarks Refer Section 2.3 Elimination of single coefficients in inter -* macroblocks in document JVT-O079 -****************************************************************************** -*/ extern const UWORD8 gu1_coeff_cost[6]; - -/** -****************************************************************************** -* @brief Indices map to raster scan for luma 4x4 block -* input : scan index -* output : scan location -* @remarks The scan order assumes the stride to access the next row is 16 -****************************************************************************** -*/ extern const UWORD8 gu1_luma_scan_order[16]; - -/** -****************************************************************************** -* @brief Indices map to raster scan for chroma AC block -* input : scan index -* output : scan location -* @remarks The scan order assumes the stride to access the next row is 32 -****************************************************************************** -*/ extern const UWORD8 gu1_chroma_scan_order[15]; - -/** -****************************************************************************** -* @brief Indices map to raster scan for luma 4x4 dc block -* input : scan index -* output : scan location -* @remarks The scan order assumes the stride to access the next row is 16 -****************************************************************************** -*/ extern const UWORD8 gu1_luma_scan_order_dc[16]; - -/** -****************************************************************************** -* @brief Indices map to raster scan for chroma 2x2 dc block -* input : scan index -* output : scan location -* @remarks The scan order assumes the stride to access the next row is 16 -****************************************************************************** -*/ extern const UWORD8 gu1_chroma_scan_order_dc[4]; - - -/** -****************************************************************************** -* @brief choice of motion vectors to be used during mv prediction -* input : formatted reference idx comparison metric -* output : mv prediction has to be median or a simple straight forward selec -* tion from neighbors. -* @remarks If only one of the candidate blocks has a reference frame equal to - the current block then use the same block as the final predictor. A simple - look up table to assist this mv prediction condition -****************************************************************************** -*/ extern const WORD8 gi1_mv_pred_condition[8]; - - -/** -****************************************************************************** -* @brief maps the h264 quantizer to the mpeg2 quantizer scale -* input : h264 qp -* output : eqvivalent mpeg 2 qp -* @remarks mpeg2qscale = 2 ^ [((h264qp - 12) / 6) + 1] -****************************************************************************** -*/ extern const UWORD8 gau1_h264_to_mpeg2_qmap[H264_QP_ELEM]; - -/** -****************************************************************************** -* @brief maps the mpeg2 quantizer to the h264 quantizer scale -* input : mpeg2 qp -* output : eqvivalent h264q p -* @remarks MPEG-2 dequantization: (2*QFij + k)*Wij*qscale/32 -* k = 0 (for intra) k = sign(QFij) -* H.264 dequantization: (QFij*R(QP%6,i,j))>>(6 - QP/6) -* -* Excluding the portion of R(QP%6,i,j) that is due to -* the DCT scale factors, the 6 entries after dividing by 64 (2^6) -* correspond to dequant values of -* 2.5, 2.8125, 3.125, 3.5625, 3.9375, 4.4375. -* (a=0.5 b=sqrt(2/5) - refer to JVT-B038.doc) -* -* Assuming that h264Qp=12 corresponds to MPEG2 qscale of 2 -* (the actual mapping seems to be to MPEG2 qscale of 2.5), -* and the fact that the effective h264 quantizer changes by -* a factor of 2 for every 6 steps, the following mapping is -* obtained: -* h264qp = 6*(log2(mpeg2qscale/2)) + 12. -* -* Note that the quant matrix entry assumed for the above -* equality is 16. Hence when the mpeg2 quant matrix entries -* are all 16, this lookup can be used as is (which is the -* default inter quant matrix in mpeg-2). -****************************************************************************** -*/ extern const UWORD8 gau1_mpeg2_to_h264_qmap[MPEG2_QP_ELEM]; -#endif /* IH264E_GLOBALS_H_ */ +#endif /* _IH264E_GLOBALS_H_ */ diff --git a/encoder/ih264e_half_pel.c b/encoder/ih264e_half_pel.c index 4871f40..b19e765 100644 --- a/encoder/ih264e_half_pel.c +++ b/encoder/ih264e_half_pel.c @@ -34,7 +34,7 @@ * - ih264e_sixtap_filter_2dvh_vert * * @remarks -* None +* none * ******************************************************************************* */ @@ -43,24 +43,24 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <assert.h> #include <limits.h> -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" -#include "ithread.h" -#include "ih264_platform_macros.h" -#include "ih264_defs.h" -#include "ih264e_half_pel.h" + #include "ih264_macros.h" -#include "ih264e_debug.h" -#include "ih264_inter_pred_filters.h" +#include "ih264_defs.h" #include "ih264_mem_fns.h" #include "ih264_padding.h" #include "ih264_intra_pred_filters.h" +#include "ih264_inter_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_platform_macros.h" + +#include "ih264e_half_pel.h" /*****************************************************************************/ @@ -93,7 +93,7 @@ * @returns * * @remarks -* None +* none * ******************************************************************************* */ @@ -172,7 +172,7 @@ void ih264e_sixtapfilter_horz(UWORD8 *pu1_src, * @returns * * @remarks -* None +* none * ******************************************************************************* */ diff --git a/encoder/ih264e_half_pel.h b/encoder/ih264e_half_pel.h index 92bd37f..5b66ec0 100644 --- a/encoder/ih264e_half_pel.h +++ b/encoder/ih264e_half_pel.h @@ -19,27 +19,27 @@ */ /** - ******************************************************************************* - * @file - * ih264e_half_pel.h - * - * @brief - * Contains extern declarations of subpel functions used by the encoder - * - * @author - * ittiam - * - * @remarks - * none - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264e_half_pel.h +* +* @brief +* Contains declarations of subpel functions used by the encoder +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ -#ifndef IH264E_HALF_PEL_H_ -#define IH264E_HALF_PEL_H_ +#ifndef _IH264E_HALF_PEL_H_ +#define _IH264E_HALF_PEL_H_ /*****************************************************************************/ -/* Global constants */ +/* Constant Macros */ /*****************************************************************************/ /* * Dimensions of subpel plane buffers @@ -48,99 +48,14 @@ #define HP_PL_HT MB_SIZE + 1 /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ -/** -******************************************************************************* -* -* @brief -* Interprediction luma filter for horizontal input (Filter run for width = 17 -* and height =16) -* -* @par Description: -* Applies a 6 tap horizontal filter .The output is clipped to 8 bits -* sec 8.4.2.2.1 titled "Luma sample interpolation process" -* -* @param[in] pu1_src -* UWORD8 pointer to the source -* -* @param[out] pu1_dst -* UWORD8 pointer to the destination -* -* @param[in] src_strd -* integer source stride -* -* @param[in] dst_strd -* integer destination stride -* -* @returns -* -* @remarks -* None -* -******************************************************************************* -*/ typedef void ih264e_sixtapfilter_horz_ft(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, WORD32 dst_strd); -ih264e_sixtapfilter_horz_ft ih264e_sixtapfilter_horz; - -/* arm assembly */ -ih264e_sixtapfilter_horz_ft ih264e_sixtapfilter_horz_a9q; -ih264e_sixtapfilter_horz_ft ih264e_sixtapfilter_horz_av8; - -/* x86 intrinsics*/ -ih264e_sixtapfilter_horz_ft ih264e_sixtapfilter_horz_ssse3; - -/** -******************************************************************************* -* -* @brief -* This function implements a two stage cascaded six tap filter. It applies -* the six tap filter in the vertical direction on the predictor values, -* followed by applying the same filter in the horizontal direction on the -* output of the first stage. The six tap filtering operation is described in -* sec 8.4.2.2.1 titled "Luma sample interpolation process" (Filter run for -* width = 17 and height = 17) -* -* @par Description: -* The function interpolates the predictors first in the vertical direction and -* then in the horizontal direction to output the (1/2,1/2). The output of the -* first stage of the filter is stored in the buffer pointed to by -* pi16_pred1(only in C) in 16 bit precision. -* -* @param[in] pu1_src -* UWORD8 pointer to the source -* -* @param[out] pu1_dst1 -* UWORD8 pointer to the destination (Horizontal filtered output) -* -* @param[out] pu1_dst2 -* UWORD8 pointer to the destination (output after applying vertical filter to -* the intermediate horizontal output) -* -* @param[in] src_strd -* integer source stride - -* @param[in] dst_strd -* integer destination stride of pu1_dst -* -* @param[in] pi4_pred -* Pointer to 16bit intermediate buffer (used only in c) -* -* @param[in] i4_pred_strd -* integer destination stride of pi16_pred1 -* -* @returns -* -* @remarks -* None -* -******************************************************************************* -*/ typedef void ih264e_sixtap_filter_2dvh_vert_ft(UWORD8 *pu1_src, UWORD8 *pu1_dst1, UWORD8 *pu1_dst2, @@ -149,14 +64,20 @@ typedef void ih264e_sixtap_filter_2dvh_vert_ft(UWORD8 *pu1_src, WORD32 *pi4_pred, WORD32 i4_pred_strd); +/* C Declarations */ +ih264e_sixtapfilter_horz_ft ih264e_sixtapfilter_horz; ih264e_sixtap_filter_2dvh_vert_ft ih264e_sixtap_filter_2dvh_vert; -/* assembly */ +/* A9 Declarations */ +ih264e_sixtapfilter_horz_ft ih264e_sixtapfilter_horz_a9q; ih264e_sixtap_filter_2dvh_vert_ft ih264e_sixtap_filter_2dvh_vert_a9q; +/* AV8 Declarations */ +ih264e_sixtapfilter_horz_ft ih264e_sixtapfilter_horz_av8; ih264e_sixtap_filter_2dvh_vert_ft ih264e_sixtap_filter_2dvh_vert_av8; -/* x86 intrinsics */ +/* SSSE3 Declarations */ +ih264e_sixtapfilter_horz_ft ih264e_sixtapfilter_horz_ssse3; ih264e_sixtap_filter_2dvh_vert_ft ih264e_sixtap_filter_2dvh_vert_ssse3; -#endif /* IH264E_HALF_PEL_H_ */ +#endif /* _IH264E_HALF_PEL_H_ */ diff --git a/encoder/ih264e_intra_modes_eval.c b/encoder/ih264e_intra_modes_eval.c index 3edf98f..a0e447e 100644 --- a/encoder/ih264e_intra_modes_eval.c +++ b/encoder/ih264e_intra_modes_eval.c @@ -31,19 +31,19 @@ * ittiam * * @par List of Functions: -* - ih264e_derive_neighbor_availability_of_mbs() -* - ih264e_derive_ngbr_avbl_of_mb_partitions() -* - ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff() -* - ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff() -* - ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff() -* - ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton() -* - ih264e_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff() -* - ih264e_evaluate_intra16x16_modes() -* - ih264e_evaluate_intra4x4_modes() -* - ih264e_evaluate_intra_chroma_modes() +* - ih264e_derive_neighbor_availability_of_mbs +* - ih264e_derive_ngbr_avbl_of_mb_partitions +* - ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff +* - ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff +* - ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff +* - ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton +* - ih264e_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff +* - ih264e_evaluate_intra16x16_modes +* - ih264e_evaluate_intra4x4_modes +* - ih264e_evaluate_intra_chroma_modes * * @remarks -* None +* none * ******************************************************************************* */ @@ -52,43 +52,47 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <string.h> #include <limits.h> #include <assert.h> -/* User include files */ +/* User Include Files */ #include "ih264e_config.h" #include "ih264_typedefs.h" -#include "ih264e_defs.h" #include "iv2.h" #include "ive2.h" + #include "ih264_debug.h" -#include "ih264_defs.h" #include "ih264_macros.h" -#include "ih264_intra_pred_filters.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" -#include "ih264_common_tables.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" +#include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_common_tables.h" #include "ih264_cabac_tables.h" -#include "ime_distortion_metrics.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" + #include "ime_defs.h" +#include "ime_distortion_metrics.h" #include "ime_structs.h" +#include "ime_platform_macros.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" +#include "ih264e_globals.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" #include "ih264e_intra_modes_eval.h" -#include "ih264e_globals.h" -#include "ime_platform_macros.h" /*****************************************************************************/ @@ -322,7 +326,6 @@ UWORD8 ih264e_derive_ngbr_avbl_of_mb_partitions(block_neighbors_t *ps_ngbr_avbl, * ****************************************************************************** */ - void ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_proc) { /* Codec Context */ @@ -364,6 +367,7 @@ void ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff(process_ctxt_t *ps UWORD8 *pu1_mb_b = pu1_ref_mb - i4_rec_strd; UWORD8 *pu1_mb_d = pu1_mb_b - 1; UWORD8 u1_mb_a, u1_mb_b, u1_mb_d; + /* valid intra modes map */ UWORD32 u4_valid_intra_modes; @@ -479,6 +483,10 @@ void ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff(process_ctxt_t *ps ps_proc->i4_mb_distortion = i4_mb_distortion_least; ps_proc->u4_mb_type = I16x16; } + if (i4_mb_cost_least < ps_proc->i4_mb_intra_cost) + { + ps_proc->i4_mb_intra_cost = i4_mb_cost_least; + } return ; } @@ -566,6 +574,7 @@ void ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_p UWORD8 *pu1_top_mb_intra_modes = ps_proc->pu1_top_mb_intra_modes + (ps_proc->i4_mb_x << 4); mb_info_t *ps_top_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x; mb_info_t *ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x; + /* valid intra modes map */ UWORD32 u4_valid_intra_modes; @@ -590,7 +599,7 @@ void ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_p && (u4_constrained_intra_pred ? ps_top_right_mb_syn_ele->u2_is_intra : 1)); - for(b8 = 0; b8 < 4; b8++) + for (b8 = 0; b8 < 4; b8++) { u4_pix_x = (b8 & 0x01) << 3; u4_pix_y = (b8 >> 1) << 3; @@ -727,6 +736,10 @@ void ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_p ps_proc->i4_mb_distortion = i4_total_distortion; ps_proc->u4_mb_type = I8x8; } + if (i4_total_cost < ps_proc->i4_mb_intra_cost) + { + ps_proc->i4_mb_intra_cost = i4_total_cost; + } return ; } @@ -827,6 +840,7 @@ void ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_p UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred; UWORD8 u1_mb_a, u1_mb_b, u1_mb_c, u1_mb_d; + if (ps_proc->ps_ngbr_avbl->u1_mb_c) { ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x + 1; @@ -998,6 +1012,10 @@ void ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_p ps_proc->i4_mb_distortion = i4_total_distortion; ps_proc->u4_mb_type = I4x4; } + if (i4_total_cost < ps_proc->i4_mb_intra_cost) + { + ps_proc->i4_mb_intra_cost = i4_total_cost; + } return ; } @@ -1082,7 +1100,7 @@ void ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton(process_ctxt_t *ps_pr UWORD8 *pu1_mb_d; /* number of non zero coeffs*/ - UWORD8 *pu1_nnz = (UWORD8 *)ps_proc->au4_nnz_intra_4x4; + UWORD8 *pu1_nnz = (UWORD8 *)ps_proc->au4_nnz_intra_4x4; /* quantization parameters */ quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0]; @@ -1136,11 +1154,11 @@ void ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton(process_ctxt_t *ps_pr i4_ngbr_avbl = (u1_mb_a) + (u1_mb_d << 1) + (u1_mb_b << 2) + (u1_mb_c << 3); memcpy(ps_proc->au1_ngbr_avbl_4x4_subblks, gau1_ih264_4x4_ngbr_avbl[i4_ngbr_avbl], 16); - for(b8 = 0; b8 < 4; b8++) + for (b8 = 0; b8 < 4; b8++) { u4_blk_x = (b8 & 0x01) << 3; u4_blk_y = (b8 >> 1) << 3; - for(b4 = 0; b4 < 4; b4++, pu1_nnz++, pi2_res_mb += MB_SIZE) + for (b4 = 0; b4 < 4; b4++, pu1_nnz++, pi2_res_mb += MB_SIZE) { u4_pix_x = u4_blk_x + ((b4 & 0x01) << 2); u4_pix_y = u4_blk_y + ((b4 >> 1) << 2); @@ -1336,6 +1354,10 @@ void ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton(process_ctxt_t *ps_pr ps_proc->i4_mb_distortion = i4_total_distortion; ps_proc->u4_mb_type = I4x4; } + if (i4_total_cost < ps_proc->i4_mb_intra_cost) + { + ps_proc->i4_mb_intra_cost = i4_total_cost; + } return ; } @@ -1361,7 +1383,6 @@ void ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton(process_ctxt_t *ps_pr * ****************************************************************************** */ - void ih264e_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_proc) { /* Codec Context */ @@ -1406,8 +1427,8 @@ void ih264e_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_ UWORD8 i; UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred; UWORD8 u1_mb_a, u1_mb_b, u1_mb_d; - /* locating neighbors that are available for prediction */ + /* locating neighbors that are available for prediction */ /* gather prediction pels from the neighbors */ /* left pels */ u1_mb_a = ((ps_proc->ps_ngbr_avbl->u1_mb_a) @@ -2038,7 +2059,6 @@ void ih264e_evaluate_intra_4x4_modes(UWORD8 *pu1_src, pu1_dst += dst_strd; memset(pu1_dst, u4_dcval, 4); } - else if (i4_min_cost == i4_cost[3]) { *u4_intra_mode = DIAG_DL_I4x4; @@ -2064,7 +2084,6 @@ void ih264e_evaluate_intra_4x4_modes(UWORD8 *pu1_src, pu1_dst += dst_strd; memcpy(pu1_dst, (pu1_pred_val - 3), 4); } - else if (i4_min_cost == i4_cost[5]) { *u4_intra_mode = VERT_R_I4x4; diff --git a/encoder/ih264e_intra_modes_eval.h b/encoder/ih264e_intra_modes_eval.h index c8402e5..f6cad82 100644 --- a/encoder/ih264e_intra_modes_eval.h +++ b/encoder/ih264e_intra_modes_eval.h @@ -36,293 +36,31 @@ ******************************************************************************* */ -#ifndef IH264E_INTRA_MODES_EVAL_H_ -#define IH264E_INTRA_MODES_EVAL_H_ +#ifndef _IH264E_INTRA_MODES_EVAL_H_ +#define _IH264E_INTRA_MODES_EVAL_H_ /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ -/** -****************************************************************************** -* -* @brief -* derivation process for macroblock availability -* -* @par Description -* Calculates the availability of the left, top, topright and topleft macroblocks. -* -* @param[in] ps_proc_ctxt -* pointer to proc context (handle) -* -* @remarks Based on section 6.4.5 in H264 spec -* -* @return none -* -****************************************************************************** -*/ -void ih264e_derive_nghbr_avbl_of_mbs - ( - process_ctxt_t *ps_proc_ctxt - ); +void ih264e_derive_nghbr_avbl_of_mbs(process_ctxt_t *ps_proc_ctxt); -/** -****************************************************************************** -* -* @brief -* derivation process for subblock/partition availability -* -* @par Description -* Calculates the availability of the left, top, topright and topleft subblock -* or partitions. -* -* @param[in] ps_proc_ctxt -* pointer to macroblock context (handle) -* -* @param[in] i1_pel_pos_x -* column position of the pel wrt the current block -* -* @param[in] i1_pel_pos_y -* row position of the pel in wrt current block -* -* @remarks Assumptions: before calling this function it is assumed that -* the neighbor availability of the current macroblock is already derived. -* Based on table 6-3 of H264 specification -* -* @return availability status (yes or no) -* -****************************************************************************** -*/ -UWORD8 ih264e_derive_ngbr_avbl_of_mb_partitions - ( - block_neighbors_t *s_ngbr_avbl, - WORD8 i1_pel_pos_x, - WORD8 i1_pel_pos_y - ); +UWORD8 ih264e_derive_ngbr_avbl_of_mb_partitions(block_neighbors_t *s_ngbr_avbl, + WORD8 i1_pel_pos_x, + WORD8 i1_pel_pos_y); -/** -****************************************************************************** -* -* @brief -* evaluate best intra 16x16 mode (rate distortion opt off) -* -* @par Description -* This function evaluates all the possible intra 16x16 modes and finds the mode -* that best represents the macro-block (least distortion) and occupies fewer -* bits in the bit-stream. -* -* @param[in] ps_proc_ctxt -* pointer to process context (handle) -* -* @remarks -* Ideally the cost of encoding a macroblock is calculated as -* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the -* input block and the reconstructed block and rate is the number of bits taken -* to place the macroblock in the bit-stream. In this routine the rate does not -* exactly point to the total number of bits it takes, rather it points to header -* bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits -* and residual bits fall in to texture bits the number of bits taken to encoding -* mbtype is considered as rate, we compute cost. Further we will approximate -* the distortion as the deviation b/w input and the predicted block as opposed -* to input and reconstructed block. -* -* NOTE: As per the Document JVT-O079, for intra 16x16 macroblock, -* the SAD and cost are one and the same. -* -* @return none -* -****************************************************************************** -*/ -void ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff - ( - process_ctxt_t *ps_proc_ctxt - ); +void ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_proc); -/** -****************************************************************************** -* -* @brief -* evaluate best intra 8x8 mode (rate distortion opt on) -* -* @par Description -* This function evaluates all the possible intra 8x8 modes and finds the mode -* that best represents the macro-block (least distortion) and occupies fewer -* bits in the bit-stream. -* -* @param[in] ps_proc_ctxt -* pointer to proc ctxt -* -* @remarks Ideally the cost of encoding a macroblock is calculated as -* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the -* input block and the reconstructed block and rate is the number of bits taken -* to place the macroblock in the bit-stream. In this routine the rate does not -* exactly point to the total number of bits it takes, rather it points to header -* bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits -* and residual bits fall in to texture bits the number of bits taken to encoding -* mbtype is considered as rate, we compute cost. Further we will approximate -* the distortion as the deviation b/w input and the predicted block as opposed -* to input and reconstructed block. -* -* NOTE: TODO: This function needs to be tested -* -* @return none -* -****************************************************************************** -*/ -void ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff - ( - process_ctxt_t *ps_proc_ctxt - ); +void ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_proc); -/** -****************************************************************************** -* -* @brief -* evaluate best intra 4x4 mode (rate distortion opt on) -* -* @par Description -* This function evaluates all the possible intra 4x4 modes and finds the mode -* that best represents the macro-block (least distortion) and occupies fewer -* bits in the bit-stream. -* -* @param[in] ps_proc_ctxt -* pointer to proc ctxt -* -* @remarks -* Ideally the cost of encoding a macroblock is calculated as -* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the -* input block and the reconstructed block and rate is the number of bits taken -* to place the macroblock in the bit-stream. In this routine the rate does not -* exactly point to the total number of bits it takes, rather it points to header -* bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits -* and residual bits fall in to texture bits the number of bits taken to encoding -* mbtype is considered as rate, we compute cost. Further we will approximate -* the distortion as the deviation b/w input and the predicted block as opposed -* to input and reconstructed block. -* -* NOTE: As per the Document JVT-O079, for the whole intra 4x4 macroblock, -* 24*lambda is added to the SAD before comparison with the best SAD for -* inter prediction. This is an empirical value to prevent using too many intra -* blocks. -* -* @return none -* -****************************************************************************** -*/ -void ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton - ( - process_ctxt_t *ps_proc_ctxt - ); +void ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_proc); -/** -****************************************************************************** -* -* @brief -* evaluate best intra 4x4 mode (rate distortion opt off) -* -* @par Description -* This function evaluates all the possible intra 4x4 modes and finds the mode -* that best represents the macro-block (least distortion) and occupies fewer -* bits in the bit-stream. -* -* @param[in] ps_proc_ctxt -* pointer to proc ctxt -* -* @remarks -* Ideally the cost of encoding a macroblock is calculated as -* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the -* input block and the reconstructed block and rate is the number of bits taken -* to place the macroblock in the bit-stream. In this routine the rate does not -* exactly point to the total number of bits it takes, rather it points to header -* bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits -* and residual bits fall in to texture bits the number of bits taken to encoding -* mbtype is considered as rate, we compute cost. Further we will approximate -* the distortion as the deviation b/w input and the predicted block as opposed -* to input and reconstructed block. -* -* NOTE: As per the Document JVT-O079, for the whole intra 4x4 macroblock, -* 24*lambda is added to the SAD before comparison with the best SAD for -* inter prediction. This is an empirical value to prevent using too many intra -* blocks. -* -* @return none -* -****************************************************************************** -*/ -void ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff - ( - process_ctxt_t *ps_proc_ctxt - ); +void ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton(process_ctxt_t *ps_proc); -/** -****************************************************************************** -* -* @brief -* evaluate best chroma intra 8x8 mode (rate distortion opt off) -* -* @par Description -* This function evaluates all the possible chroma intra 8x8 modes and finds -* the mode that best represents the macroblock (least distortion) and occupies -* fewer bits in the bitstream. -* -* @param[in] ps_proc_ctxt -* pointer to macroblock context (handle) -* -* @remarks -* For chroma best intra pred mode is calculated based only on SAD -* -* @returns none -* -****************************************************************************** -*/ -void ih264e_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff - ( - process_ctxt_t *ps_proc_ctxt - ); +void ih264e_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_proc); +void ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_proc_ctxt); -/** -****************************************************************************** -* -* @brief -* Evaluate best intra 16x16 mode (among VERT, HORZ and DC) and do the -* prediction. -* -* @par Description -* This function evaluates first three 16x16 modes and compute corresponding sad -* and return the buffer predicted with best mode. -* -* @param[in] pu1_src -* UWORD8 pointer to the source -* -* @param[in] pu1_ngbr_pels_i16 -* UWORD8 pointer to neighbouring pels -* -* @param[out] pu1_dst -* UWORD8 pointer to the destination -* -* @param[in] src_strd -* integer source stride -* -* @param[in] dst_strd -* integer destination stride -* -* @param[in] u4_n_avblty -* availability of neighbouring pixels -* -* @param[in] u4_intra_mode -* Pointer to the variable in which best mode is returned -* -* @param[in] pu4_sadmin -* Pointer to the variable in which minimum sad is returned -* -* @param[in] u4_valid_intra_modes -* Says what all modes are valid -* -* @returns none -* -****************************************************************************** -*/ typedef void ih264e_evaluate_intra_modes_ft(UWORD8 *pu1_src, UWORD8 *pu1_ngbr_pels_i16, UWORD8 *pu1_dst, @@ -333,67 +71,6 @@ typedef void ih264e_evaluate_intra_modes_ft(UWORD8 *pu1_src, WORD32 *pu4_sadmin, UWORD32 u4_valid_intra_modes); -ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra16x16_modes; -ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra_chroma_modes; - -/* assembly */ -ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra16x16_modes_a9q; -ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra_chroma_modes_a9q; - -ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra16x16_modes_av8; -ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra_chroma_modes_av8; - -/* x86 intrinsics */ -ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra16x16_modes_ssse3; -ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra_chroma_modes_ssse3; - -/** -****************************************************************************** -* -* @brief -* Evaluate best intra 4x4 mode and perform prediction. -* -* @par Description -* This function evaluates 4x4 modes and compute corresponding sad -* and return the buffer predicted with best mode. -* -* @param[in] pu1_src -* UWORD8 pointer to the source -* -* @param[in] pu1_ngbr_pels -* UWORD8 pointer to neighbouring pels -* -* @param[out] pu1_dst -* UWORD8 pointer to the destination -* -* @param[in] src_strd -* integer source stride -* -* @param[in] dst_strd -* integer destination stride -* -* @param[in] u4_n_avblty -* availability of neighbouring pixels -* -* @param[in] u4_intra_mode -* Pointer to the variable in which best mode is returned -* -* @param[in] pu4_sadmin -* Pointer to the variable in which minimum cost is returned -* -* @param[in] u4_valid_intra_modes -* Says what all modes are valid -* -* @param[in] u4_lambda -* Lamda value for computing cost from SAD -* -* @param[in] u4_predictd_mode -* Predicted mode for cost computation -* -* @returns none -* -****************************************************************************** -*/ typedef void ih264e_evaluate_intra_4x4_modes_ft(UWORD8 *pu1_src, UWORD8 *pu1_ngbr_pels, UWORD8 *pu1_dst, @@ -403,16 +80,27 @@ typedef void ih264e_evaluate_intra_4x4_modes_ft(UWORD8 *pu1_src, UWORD32 *u4_intra_mode, WORD32 *pu4_sadmin, UWORD32 u4_valid_intra_modes, - UWORD32 u4_lambda, + UWORD32 u4_lambda, UWORD32 u4_predictd_mode); +/* C Declarations */ +ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra16x16_modes; +ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra_chroma_modes; ih264e_evaluate_intra_4x4_modes_ft ih264e_evaluate_intra_4x4_modes; -/* x86 intrinsics */ -ih264e_evaluate_intra_4x4_modes_ft ih264e_evaluate_intra_4x4_modes_ssse3; - -/* assembly */ +/* A9 Declarations */ +ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra16x16_modes_a9q; +ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra_chroma_modes_a9q; ih264e_evaluate_intra_4x4_modes_ft ih264e_evaluate_intra_4x4_modes_a9q; + +/* AV8 Declarations */ +ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra16x16_modes_av8; +ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra_chroma_modes_av8; ih264e_evaluate_intra_4x4_modes_ft ih264e_evaluate_intra_4x4_modes_av8; -#endif /* IH264E_INTRA_MODES_EVAL_H_ */ +/* SSSE3 Declarations */ +ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra16x16_modes_ssse3; +ih264e_evaluate_intra_modes_ft ih264e_evaluate_intra_chroma_modes_ssse3; +ih264e_evaluate_intra_4x4_modes_ft ih264e_evaluate_intra_4x4_modes_ssse3; + +#endif /* _IH264E_INTRA_MODES_EVAL_H_ */ diff --git a/encoder/ih264e_master.h b/encoder/ih264e_master.h index 67354fd..94fb9b0 100644 --- a/encoder/ih264e_master.h +++ b/encoder/ih264e_master.h @@ -30,120 +30,26 @@ * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_MASTER_H_ -#define IH264E_MASTER_H_ +#ifndef _IH264E_MASTER_H_ +#define _IH264E_MASTER_H_ /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ -/** -****************************************************************************** -* -* @brief -* This function joins all the spawned threads after successful completion of -* their tasks -* -* @par Description -* -* @param[in] ps_codec -* pointer to codec context -* -* @returns none -* -****************************************************************************** -*/ void ih264e_join_threads(codec_t *ps_codec); -/** -****************************************************************************** -* -* @brief -* This function calculates various quality metrics; the initial one is PSNR. -* -* @par Description -* -* @param[in] ps_codec -* pointer to process context -* -* @returns none -* -****************************************************************************** -*/ void ih264e_compute_quality_stats(process_ctxt_t *ps_proc); -/** -****************************************************************************** -* -* @brief This function puts the current thread to sleep for a duration -* of sleep_us -* -* @par Description -* ithread_yield() method causes the calling thread to yield execution to another -* thread that is ready to run on the current processor. The operating system -* selects the thread to yield to. ithread_usleep blocks the current thread for -* the specified number of milliseconds. In other words, yield just says, -* end my timeslice prematurely, look around for other threads to run. If there -* is nothing better than me, continue. Sleep says I don't want to run for x -* milliseconds. Even if no other thread wants to run, don't make me run. -* -* @param[in] sleep_us -* thread sleep duration -* -* @returns error_status -* -****************************************************************************** -*/ IH264E_ERROR_T ih264e_wait_for_thread(UWORD32 sleep_us); -/** -****************************************************************************** -* -* @brief -* Encodes in synchronous api mode -* -* @par Description -* This routine processes input yuv, encodes it and outputs bitstream and recon -* -* @param[in] ps_codec_obj -* Pointer to codec object at API level -* -* @param[in] pv_api_ip -* Pointer to input argument structure -* -* @param[out] pv_api_op -* Pointer to output argument structure -* -* @returns Status -* -****************************************************************************** -*/ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op); -/** -******************************************************************************* -* -* @brief update encoder configuration parameters -* -* @par Description: -* updates encoder configuration parameters from the given config set. -* Initialize/reinitialize codec parameters according to new configurations. -* -* @param[in] ps_codec -* Pointer to codec context -* -* @param[in] ps_cfg -* Pointer to config param set -* -* @remarks none -* -******************************************************************************* -*/ IH264E_ERROR_T ih264e_codec_update_config(codec_t *ps_codec, cfg_params_t *ps_cfg); -#endif /* IH264E_MASTER_H_ */ +#endif /* _IH264E_MASTER_H_ */ diff --git a/encoder/ih264e_mc.c b/encoder/ih264e_mc.c index 2b19dd1..6d4a1df 100644 --- a/encoder/ih264e_mc.c +++ b/encoder/ih264e_mc.c @@ -19,93 +19,98 @@ */ /** - ******************************************************************************* - * @file - * ih264e_mc.c - * - * @brief - * Contains definition of functions for motion compensation - * - * @author - * ittiam - * - * @par List of Functions: - * - ih264e_motion_comp_luma() - * - ih264e_motion_comp_chroma() - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264e_mc.c +* +* @brief +* Contains definition of functions for motion compensation +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264e_motion_comp_luma +* - ih264e_motion_comp_chroma +* +* @remarks +* none +* +******************************************************************************* +*/ /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" -#include "ih264_defs.h" #include "iv2.h" #include "ive2.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" -#include "ih264_structs.h" -#include "ih264_inter_pred_filters.h" + +#include "ih264_defs.h" #include "ih264_mem_fns.h" #include "ih264_padding.h" +#include "ih264_structs.h" +#include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_inter_pred_filters.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" -#include "ih264_trans_quant_itrans_iquant.h" #include "ih264_cabac_tables.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" #include "ih264e_mc.h" #include "ih264e_half_pel.h" + /*****************************************************************************/ /* Function Definitions */ /*****************************************************************************/ /** - ****************************************************************************** - * - * @brief - * performs motion compensation for a luma mb for the given mv. - * - * @par Description - * This routine performs motion compensation of an inter mb. When the inter - * mb mode is P16x16, there is no need to copy 16x16 unit from reference buffer - * to pred buffer. In this case the function returns pointer and stride of the - * ref. buffer and this info is used in place of pred buffer else where. - * In other cases, the pred buffer is populated via copy / filtering + copy - * (q pel cases) and returned. - * - * @param[in] ps_proc - * pointer to current proc ctxt - * - * @param[out] pu1_pseudo_pred - * pseudo prediction buffer - * - * @param[out] u4_pseudo_pred_strd - * pseudo pred buffer stride - * - * @return none - * - * @remarks Assumes half pel buffers for the entire frame are populated. - * - ****************************************************************************** - */ +****************************************************************************** +* +* @brief +* performs motion compensation for a luma mb for the given mv. +* +* @par Description +* This routine performs motion compensation of an inter mb. When the inter +* mb mode is P16x16, there is no need to copy 16x16 unit from reference buffer +* to pred buffer. In this case the function returns pointer and stride of the +* ref. buffer and this info is used in place of pred buffer else where. +* In other cases, the pred buffer is populated via copy / filtering + copy +* (q pel cases) and returned. +* +* @param[in] ps_proc +* pointer to current proc ctxt +* +* @param[out] pu1_pseudo_pred +* pseudo prediction buffer +* +* @param[out] u4_pseudo_pred_strd +* pseudo pred buffer stride +* +* @return none +* +* @remarks Assumes half pel buffers for the entire frame are populated. +* +****************************************************************************** +*/ void ih264e_motion_comp_luma(process_ctxt_t *ps_proc, UWORD8 **pu1_pseudo_pred, WORD32 *pi4_pseudo_pred_strd) { @@ -161,7 +166,7 @@ void ih264e_motion_comp_luma(process_ctxt_t *ps_proc, UWORD8 **pu1_pseudo_pred, ps_me_ctxt->u4_subpel_buf_strd; for (u4_num_prtn = 0; u4_num_prtn < ps_proc->u4_num_sub_partitions; - u4_num_prtn++) + u4_num_prtn++) { mv_t *ps_curr_mv; @@ -255,7 +260,8 @@ void ih264e_motion_comp_luma(process_ctxt_t *ps_proc, UWORD8 **pu1_pseudo_pred, } /* * Copying half pel or full pel to prediction buffer - * Currently ps_proc->u4_num_sub_partitions will always be 1 as we only support 16x16 in P mbs + * Currently ps_proc->u4_num_sub_partitions will always be 1 as we + * only support 16x16 in P mbs */ else { @@ -265,30 +271,29 @@ void ih264e_motion_comp_luma(process_ctxt_t *ps_proc, UWORD8 **pu1_pseudo_pred, i4_pred_strd, ht, wd, NULL, 0); } - } } } /** - ****************************************************************************** - * - * @brief - * performs motion compensation for chroma mb - * - * @par Description - * Copies a MB of data from the reference buffer (Full pel, half pel or q pel) - * according to the motion vectors given - * - * @param[in] ps_proc - * pointer to current proc ctxt - * - * @return none - * - * @remarks Assumes half pel and quarter pel buffers for the entire frame are - * populated. - ****************************************************************************** - */ +****************************************************************************** +* +* @brief +* performs motion compensation for chroma mb +* +* @par Description +* Copies a MB of data from the reference buffer (Full pel, half pel or q pel) +* according to the motion vectors given +* +* @param[in] ps_proc +* pointer to current proc ctxt +* +* @return none +* +* @remarks Assumes half pel and quarter pel buffers for the entire frame are +* populated. +****************************************************************************** +*/ void ih264e_motion_comp_chroma(process_ctxt_t *ps_proc) { /* codec context */ @@ -329,7 +334,7 @@ void ih264e_motion_comp_chroma(process_ctxt_t *ps_proc) UWORD8 u1_dx, u1_dy; for (u4_num_prtn = 0; u4_num_prtn < ps_proc->u4_num_sub_partitions; - u4_num_prtn++) + u4_num_prtn++) { mv_t *ps_curr_mv; diff --git a/encoder/ih264e_mc.h b/encoder/ih264e_mc.h index 965e1d1..fb80272 100644 --- a/encoder/ih264e_mc.h +++ b/encoder/ih264e_mc.h @@ -36,69 +36,16 @@ ******************************************************************************* */ -#ifndef IH264E_MC_H_ -#define IH264E_MC_H_ +#ifndef _IH264E_MC_H_ +#define _IH264E_MC_H_ /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ -/** -****************************************************************************** -* -* @brief -* performs motion compensation for a luma mb for the given mv. -* -* @par Description -* This routine performs motion compensation of an inter mb. When the inter -* mb mode is P16x16, there is no need to copy 16x16 unit from reference buffer -* to pred buffer. In this case the function returns pointer and stride of the -* ref. buffer and this info is used in place of pred buffer else where. -* In other cases, the pred buffer is populated via copy / filtering + copy -* (q pel cases) and returned. -* -* @param[in] ps_proc -* pointer to current proc ctxt -* -* @param[out] pu1_pseudo_pred -* pseudo prediction buffer -* -* @param[out] u4_pseudo_pred_strd -* pseudo pred buffer stride -* -* @return none -* -* @remarks Assumes half pel buffers for the entire frame are populated. -* -****************************************************************************** -*/ -void ih264e_motion_comp_luma(process_ctxt_t *ps_proc, - UWORD8 **pu1_pseudo_pred, +void ih264e_motion_comp_luma(process_ctxt_t *ps_proc, UWORD8 **pu1_pseudo_pred, WORD32 *pi4_pseudo_pred_strd); -/** -****************************************************************************** -* -* @brief -* performs motion compensation for chroma mb -* -* @par Description -* Copies a MB of data from the reference buffer (Full pel, half pel or q pel) -* according to the motion vectors given -* -* @param[in] ps_proc -* pointer to current proc ctxt -* -* @return none -* -* @remarks Assumes half pel and quarter pel buffers for the entire frame are -* populated. -****************************************************************************** -*/ -void ih264e_motion_comp_chroma - ( - process_ctxt_t *ps_proc - ); - +void ih264e_motion_comp_chroma(process_ctxt_t *ps_proc); -#endif // IH264E_MC_H_ +#endif /* _IH264E_MC_H_ */ diff --git a/encoder/ih264e_me.c b/encoder/ih264e_me.c index 36182e4..7b1d5f3 100644 --- a/encoder/ih264e_me.c +++ b/encoder/ih264e_me.c @@ -19,82 +19,86 @@ */ /** - ******************************************************************************* - * @file - * ih264e_me.c - * - * @brief - * Contains definition of functions for motion estimation - * - * @author - * ittiam - * - * @par List of Functions: - * - ih264e_init_mv_bits() - * - ih264e_skip_analysis_chroma() - * - ih264e_skip_analysis_luma() - * - ih264e_analyse_skip() - * - ih264e_get_search_candidates() - * - ih264e_find_skip_motion_vector() - * - ih264e_get_mv_predictor() - * - ih264e_mv_pred() - * - ih264e_mv_pred_me() - * - ih264e_init_me() - * - ih264e_compute_me() - * - ih264e_compute_me_nmb() - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ih264e_me.c +* +* @brief +* Contains definition of functions for motion estimation +* +* @author +* ittiam +* +* @par List of Functions: +* - ih264e_init_mv_bits +* - ih264e_get_search_candidates +* - ih264e_find_pskip_params +* - ih264e_find_pskip_params_me +* - ih264e_get_mv_predictor +* - ih264e_mv_pred +* - ih264e_mv_pred_me +* - ih264e_compute_me_single_reflist +* - ih264e_compute_me_nmb +* - ih264e_find_bskip_params_me +* - ih264e_find_bskip_params +* - ih264e_evaluate_bipred +* - ih264e_compute_me_multi_reflist +* +* @remarks +* none +* +******************************************************************************* +*/ /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <assert.h> #include <limits.h> -/* User include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" #include "ithread.h" -#include "ih264_platform_macros.h" + +#include "ih264_debug.h" +#include "ih264_macros.h" #include "ih264_defs.h" -#include "ime_defs.h" -#include "ime_distortion_metrics.h" -#include "ime_structs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" #include "ih264_cabac_tables.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" +#include "ih264_platform_macros.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" +#include "ime.h" +#include "ime_statistics.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" +#include "ih264e_globals.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_globals.h" -#include "ih264_macros.h" +#include "ih264e_mc.h" #include "ih264e_me.h" -#include "ime.h" -#include "ih264_debug.h" +#include "ih264e_half_pel.h" #include "ih264e_intra_modes_eval.h" #include "ih264e_core_coding.h" -#include "ih264e_mc.h" -#include "ih264e_debug.h" -#include "ih264e_half_pel.h" -#include "ime_statistics.h" #include "ih264e_platform_macros.h" @@ -116,7 +120,7 @@ * length of the codeword for all mv's * * @remarks The length of the code words are derived from signed exponential -* goloumb codes. +* goloumb codes. * ******************************************************************************* */ @@ -164,44 +168,27 @@ void ih264e_init_mv_bits(me_ctxt_t *ps_me_ctxt) } } - - /** ******************************************************************************* * * @brief Determines the valid candidates for which the initial search shall happen. * The best of these candidates is used to center the diamond pixel search. * -* @par Description: The function sends the skip, (0,0), left, top and top-right +* @par Description The function sends the skip, (0,0), left, top and top-right * neighbouring MBs MVs. The left, top and top-right MBs MVs are used because * these are the same MVs that are used to form the MV predictor. This initial MV * search candidates need not take care of slice boundaries and hence neighbor * availability checks are not made here. * -* @param[in] ps_left_mb_pu -* pointer to left mb motion vector info -* -* @param[in] ps_top_mb_pu -* pointer to top & top right mb motion vector info -* -* @param[in] ps_top_left_mb_pu -* pointer to top left mb motion vector info -* -* @param[out] ps_skip_mv -* pointer to skip motion vectors for the curr mb -* -* @param[in] i4_mb_x -* mb index x -* -* @param[in] i4_mb_y -* mb index y -* -* @param[in] i4_wd_mbs -* pic width in mbs +* @param[in] ps_proc +* Pointer to process context * -* @param[in] ps_motionEst +* @param[in] ps_me_ctxt * pointer to me context * +* @param[in] i4_ref_list +* Current active reference list +* * @returns The list of MVs to be used of priming the full pel search and the * number of such MVs * @@ -319,7 +306,6 @@ static void ih264e_get_search_candidates(process_ctxt_t *ps_proc, } } - /********************************************************************/ /* MV Prediction */ /********************************************************************/ @@ -371,22 +357,16 @@ static void ih264e_get_search_candidates(process_ctxt_t *ps_proc, * * @par Description: * The function updates the skip motion vector and checks if the current -* MB can be a skip PSKIP mB or not +* MB can be a PSKIP MB or not * * @param[in] ps_proc * Pointer to process context * -* @param[in] u4_for_me -* Flag to indicate function is called for ME or not -* -* @param[out] i4_ref_list -* Current active refernce list +* @param[in] i4_ref_list +* Current active reference list * * @returns Flag indicating if the current MB can be marked as skip * -* @remarks The code implements the logic as described in sec 8.4.1.2.2 in H264 -* specification. -* ******************************************************************************* */ WORD32 ih264e_find_pskip_params(process_ctxt_t *ps_proc, WORD32 i4_reflist) @@ -402,7 +382,7 @@ WORD32 ih264e_find_pskip_params(process_ctxt_t *ps_proc, WORD32 i4_reflist) UNUSED(i4_reflist); - ps_left_mb_pu = &ps_proc->s_left_mb_pu ; + ps_left_mb_pu = &ps_proc->s_left_mb_pu; ps_top_mb_pu = ps_proc->ps_top_row_pu + ps_proc->i4_mb_x; if ((!ps_proc->ps_ngbr_avbl->u1_mb_a) || @@ -418,7 +398,6 @@ WORD32 ih264e_find_pskip_params(process_ctxt_t *ps_proc, WORD32 i4_reflist) (ps_top_mb_pu->s_me_info[PRED_L0].s_mv.i2_mvy == 0) ) ) - { ps_skip_mv->i2_mvx = 0; ps_skip_mv->i2_mvy = 0; @@ -429,7 +408,7 @@ WORD32 ih264e_find_pskip_params(process_ctxt_t *ps_proc, WORD32 i4_reflist) ps_skip_mv->i2_mvy = ps_proc->ps_pred_mv[PRED_L0].s_mv.i2_mvy; } - if ( (ps_proc->ps_pu->s_me_info[PRED_L0].s_mv.i2_mvx == ps_skip_mv->i2_mvx) + if ((ps_proc->ps_pu->s_me_info[PRED_L0].s_mv.i2_mvx == ps_skip_mv->i2_mvx) && (ps_proc->ps_pu->s_me_info[PRED_L0].s_mv.i2_mvy == ps_skip_mv->i2_mvy)) { return 1; @@ -445,22 +424,16 @@ WORD32 ih264e_find_pskip_params(process_ctxt_t *ps_proc, WORD32 i4_reflist) * * @par Description: * The function updates the skip motion vector and checks if the current -* MB can be a skip PSKIP mB or not +* MB can be a PSKIP MB or not * * @param[in] ps_proc * Pointer to process context * -* @param[in] u4_for_me -* Flag to dincate fucntion is called for ME or not -* -* @param[out] i4_ref_list -* Current active refernce list +* @param[in] i4_ref_list +* Current active reference list * * @returns Flag indicating if the current MB can be marked as skip * -* @remarks The code implements the logic as described in sec 8.4.1.2.2 in H264 -* specification. -* ******************************************************************************* */ WORD32 ih264e_find_pskip_params_me(process_ctxt_t *ps_proc, WORD32 i4_reflist) @@ -492,7 +465,6 @@ WORD32 ih264e_find_pskip_params_me(process_ctxt_t *ps_proc, WORD32 i4_reflist) (ps_top_mb_pu->s_me_info[PRED_L0].s_mv.i2_mvy == 0) ) ) - { ps_skip_mv->i2_mvx = 0; ps_skip_mv->i2_mvy = 0; @@ -506,7 +478,6 @@ WORD32 ih264e_find_pskip_params_me(process_ctxt_t *ps_proc, WORD32 i4_reflist) return PRED_L0; } - /** ******************************************************************************* * @@ -525,6 +496,9 @@ WORD32 ih264e_find_pskip_params_me(process_ctxt_t *ps_proc, WORD32 i4_reflist) * @param[out] ps_pred_mv * pointer to candidate predictors for the current block * +* @param[in] i4_ref_list +* Current active reference list +* * @returns The x & y components of the MV predictor. * * @remarks The code implements the logic as described in sec 8.4.1.3 in H264 @@ -539,7 +513,6 @@ void ih264e_get_mv_predictor(enc_pu_t *ps_left_mb_pu, enc_pu_mv_t *ps_pred_mv, WORD32 i4_ref_list) { - /* Indicated the current ref */ WORD8 i1_ref_idx; @@ -607,6 +580,9 @@ void ih264e_get_mv_predictor(enc_pu_t *ps_left_mb_pu, * @param[in] ps_proc * Process context corresponding to the job * +* @param[in] i4_slice_type +* slice type +* * @returns none * * @remarks none @@ -617,7 +593,6 @@ void ih264e_get_mv_predictor(enc_pu_t *ps_left_mb_pu, */ void ih264e_mv_pred(process_ctxt_t *ps_proc, WORD32 i4_slice_type) { - /* left mb motion vector */ enc_pu_t *ps_left_mb_pu; @@ -701,7 +676,6 @@ void ih264e_mv_pred(process_ctxt_t *ps_proc, WORD32 i4_slice_type) ih264e_get_mv_predictor(ps_left_mb_pu, ps_top_row_pu, &ps_pred_mv[i4_reflist], i4_reflist); } - } /** @@ -714,6 +688,9 @@ void ih264e_mv_pred(process_ctxt_t *ps_proc, WORD32 i4_slice_type) * @param[in] ps_proc * Process context corresponding to the job * +* @param[in] i4_ref_list +* Current active reference list +* * @returns none * * @remarks none @@ -758,7 +735,6 @@ void ih264e_mv_pred_me(process_ctxt_t *ps_proc, WORD32 i4_ref_list) * Before performing mv prediction prepare the ngbr information and * reset motion vectors basing on their availability */ - if (!ps_ngbr_avbl->u1_mb_a || (ps_left_mb_pu->b2_pred_mode == i4_cmpl_predmode)) { /* left mv */ @@ -841,6 +817,7 @@ void ih264e_init_me(process_ctxt_t *ps_proc) /* src ptr */ ps_me_ctxt->pu1_src_buf_luma = ps_proc->pu1_src_buf_luma; + /* src stride */ ps_me_ctxt->i4_src_strd = ps_proc->i4_src_strd; @@ -848,9 +825,14 @@ void ih264e_init_me(process_ctxt_t *ps_proc) ps_me_ctxt->apu1_ref_buf_luma[0] = ps_proc->apu1_ref_buf_luma[0]; ps_me_ctxt->apu1_ref_buf_luma[1] = ps_proc->apu1_ref_buf_luma[1]; - ps_me_ctxt->u4_lambda_motion = gu1_qp0[ps_me_ctxt->u1_mb_qp]; - - + if (ps_codec->pic_type == PIC_B) + { + ps_me_ctxt->u4_lambda_motion = gu1_qp_lambdaB[ps_me_ctxt->u1_mb_qp]; + } + else + { + ps_me_ctxt->u4_lambda_motion = gu1_qp_lambdaIP[ps_me_ctxt->u1_mb_qp]; + } } @@ -938,9 +920,9 @@ void ih264e_compute_me_single_reflist(process_ctxt_t *ps_proc) /* Get the seed motion vector candidates */ ih264e_get_search_candidates(ps_proc, ps_me_ctxt, PRED_L0); - /* **************************************************************** - *Evaluate the SKIP for current list - * ****************************************************************/ + /***************************************************************** + * Evaluate the SKIP for current list + *****************************************************************/ s_skip_mbpart.s_mv_curr.i2_mvx = 0; s_skip_mbpart.s_mv_curr.i2_mvy = 0; s_skip_mbpart.i4_mb_cost = INT_MAX; @@ -985,9 +967,9 @@ void ih264e_compute_me_single_reflist(process_ctxt_t *ps_proc) if (ps_me_ctxt->u4_enable_hpel) { /* moving src pointer to the converged motion vector location*/ - pu1_hpel_src = ps_me_ctxt->apu1_ref_buf_luma[PRED_L0] - + (ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvx >> 2) - + (ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvy >> 2)* i4_rec_strd; + pu1_hpel_src = ps_me_ctxt->apu1_ref_buf_luma[PRED_L0] + + (ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvx >> 2) + + (ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvy >> 2) * i4_rec_strd; ps_me_ctxt->apu1_subpel_buffs[0] = ps_proc->apu1_subpel_buffs[0]; ps_me_ctxt->apu1_subpel_buffs[1] = ps_proc->apu1_subpel_buffs[1]; @@ -1083,7 +1065,6 @@ void ih264e_compute_me_single_reflist(process_ctxt_t *ps_proc) ps_proc->ps_cur_mb->u4_min_sad_reached = 1; ps_proc->ps_cur_mb->u4_min_sad = ps_me_ctxt->i4_min_sad; } - } /** @@ -1092,12 +1073,15 @@ void ih264e_compute_me_single_reflist(process_ctxt_t *ps_proc) * @brief This function performs motion estimation for the current NMB * * @par Description: -* Intializes input and output pointers required by the function ih264e_compute_me -* and calls the function ih264e_compute_me in a loop to process NMBs. +* Intializes input and output pointers required by the function ih264e_compute_me +* and calls the function ih264e_compute_me in a loop to process NMBs. * * @param[in] ps_proc * Process context corresponding to the job * +* @param[in] u4_nmb_count +* Number of mb's to process +* * @returns * * @remarks none @@ -1221,7 +1205,6 @@ void ih264e_compute_me_nmb(process_ctxt_t *ps_proc, UWORD32 u4_nmb_count) ps_proc->pu4_mb_pu_cnt += 1; } - ps_proc->ps_pu = ps_pu_begin; ps_proc->i4_mb_x = ps_proc->i4_mb_x - u4_nmb_count; @@ -1240,7 +1223,6 @@ void ih264e_compute_me_nmb(process_ctxt_t *ps_proc, UWORD32 u4_nmb_count) ps_proc->apu1_ref_buf_chroma[0] -= MB_SIZE * u4_nmb_count; ps_proc->apu1_ref_buf_chroma[1] -= MB_SIZE * u4_nmb_count; - ps_proc->pu4_mb_pu_cnt -= u4_nmb_count; } @@ -1257,11 +1239,8 @@ void ih264e_compute_me_nmb(process_ctxt_t *ps_proc, UWORD32 u4_nmb_count) * @param[in] ps_proc * Pointer to process context * -* @param[in] u4_for_me -* Dummy -* * @param[in] i4_reflist -* Dummy +* Current active reference list * * @returns Flag indicating if the current Mb can be skip or not * @@ -1271,7 +1250,8 @@ void ih264e_compute_me_nmb(process_ctxt_t *ps_proc, UWORD32 u4_nmb_count) * * Need to add condition for this fucntion to be used in ME * -*******************************************************************************/ +******************************************************************************* +*/ WORD32 ih264e_find_bskip_params_me(process_ctxt_t *ps_proc, WORD32 i4_reflist) { /* Colzero for co-located MB */ @@ -1459,10 +1439,7 @@ WORD32 ih264e_find_bskip_params_me(process_ctxt_t *ps_proc, WORD32 i4_reflist) * @param[in] ps_proc * Pointer to process context * -* @param[in] u4_for_me -* Dummy -* -* @param[in] u4_for_me +* @param[in] i4_reflist * Dummy * * @returns Flag indicating if the current Mb can be skip or not @@ -1473,6 +1450,7 @@ WORD32 ih264e_find_bskip_params_me(process_ctxt_t *ps_proc, WORD32 i4_reflist) *******************************************************************************/ WORD32 ih264e_find_bskip_params(process_ctxt_t *ps_proc, WORD32 i4_reflist) { + /* Colzero for co-located MB */ WORD32 i4_colzeroflag; /* motion vectors */ @@ -1496,7 +1474,7 @@ WORD32 ih264e_find_bskip_params(process_ctxt_t *ps_proc, WORD32 i4_reflist) UNUSED(i4_reflist); /************************************************************************** - *Find co-locates parameters + * Find co-locates parameters * See sec 8.4.1.2.1 for reference **************************************************************************/ { @@ -1651,18 +1629,18 @@ WORD32 ih264e_find_bskip_params(process_ctxt_t *ps_proc, WORD32 i4_reflist) * This function determines the position in the search window at which the motion * estimation should begin in order to minimise the number of search iterations. * -* @param[in] ps_mb_part -* pointer to current mb partition ctxt with respect to ME +* @param[in] ps_me_ctxt +* pointer to me context * -* @param[in] u4_lambda_motion -* lambda motion +* @param[in] ps_proc +* process context * -* @param[in] u4_fast_flag -* enable/disable fast sad computation +* @param[in] ps_mb_ctxt_bi +* pointer to current mb partition ctxt with respect to ME * * @returns mv pair & corresponding distortion and cost * -* @remarks Currently onyl 4 search candiates are supported +* @remarks Currently only 4 search candiates are supported * ******************************************************************************* */ @@ -1688,6 +1666,7 @@ void ih264e_evaluate_bipred(me_ctxt_t *ps_me_ctxt, u4_fast_sad = ps_me_ctxt->u4_enable_fast_sad; i4_dest_buff = 0; + for (i = 0; i < ps_me_ctxt->u4_num_candidates[PRED_BI]; i += 2) { pu1_dst_buf = ps_me_ctxt->apu1_subpel_buffs[i4_dest_buff]; @@ -1902,10 +1881,10 @@ void ih264e_compute_me_multi_reflist(process_ctxt_t *ps_proc) /********************************************************************/ ime_full_pel_motion_estimation_16x16(ps_me_ctxt, i4_reflist); - DEBUG_MV_HISTOGRAM_ADD((ps_me_ctxt->s_mb_part.s_mv_curr.i2_mvx >> 2), - (ps_me_ctxt->s_mb_part.s_mv_curr.i2_mvy >> 2)); + DEBUG_MV_HISTOGRAM_ADD((ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx >> 2), + (ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvy >> 2)); - DEBUG_SAD_HISTOGRAM_ADD(ps_me_ctxt->s_mb_part.i4_mb_distortion, 1); + DEBUG_SAD_HISTOGRAM_ADD(ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_distortion, 1); /* Scale the MV to qpel resolution */ ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx <<= 2; diff --git a/encoder/ih264e_me.h b/encoder/ih264e_me.h index 2266e5a..8af8c8a 100644 --- a/encoder/ih264e_me.h +++ b/encoder/ih264e_me.h @@ -24,7 +24,7 @@ * ih264e_me.h * * @brief - * Contains declarations of global variables for H264 encoder + * Contains declarations of h264 me * * @author * ittiam @@ -34,8 +34,9 @@ ******************************************************************************* */ -#ifndef IH264E_ME_H_ -#define IH264E_ME_H_ +#ifndef _IH264E_ME_H_ +#define _IH264E_ME_H_ + /*****************************************************************************/ /* Constant Macros */ @@ -66,7 +67,6 @@ * in to result. This is used for mv prediction ****************************************************************************** */ - #define MEDIAN(a, b, c, result) if (a > b){\ if (b > c)\ result = b;\ @@ -89,284 +89,32 @@ } /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ -/** - ******************************************************************************* - * - * @brief - * This function populates the length of the codewords for motion vectors in the - * range (-search range, search range) in pixels - * - * @param[in] ps_me - * Pointer to me ctxt - * - * @param[out] pu1_mv_bits - * length of the codeword for all mv's - * - * @remarks The length of the code words are derived from signed exponential - * goloumb codes. - * - ******************************************************************************* - */ void ih264e_init_mv_bits(me_ctxt_t *ps_me); -/** - ******************************************************************************* - * - * @brief The function computes the parameters for a P skip MB - * - * @par Description: - * The function computes the parameters for a P skip MB - * - * @param[in] ps_proc - * Process context - * - * @param[in] u4_for_me - * Flag to indicate the purpose of computing skip - * - * @param[out] ps_pred_mv - * Flag to indicate the current active refernce list - * - * @returns - * 1) Updates skip MV in proc - * 2) Returns if the current MB can be coded as skip or not - * - * @remarks The code implements the logic as described in sec 8.4.1.1 in H264 - * specification. - * - ******************************************************************************* -*/ ih264e_skip_params_ft ih264e_find_pskip_params; -/** - ******************************************************************************* - * - * @brief The function computes the parameters for a P skip MB - * - * @par Description: - * The function computes the parameters for a P skip MB - * - * @param[in] ps_proc - * Process context - * - * @param[in] u4_for_me - * Flag to indicate the purpose of computing skip - * - * @param[out] ps_pred_mv - * Flag to indicate the current active refernce list - * - * @returns - * 1) Updates skip MV in proc - * 2) Returns if the current MB can be coded as skip or not - * - * @remarks The code implements the logic as described in sec 8.4.1.1 in H264 - * specification. - * - ******************************************************************************* -*/ ih264e_skip_params_ft ih264e_find_pskip_params_me; -/** - ******************************************************************************* - * - * @brief The function computes the parameters for a B skip MB - * - * @par Description: - * The function computes the parameters for a B skip MB - * - * @param[in] ps_proc - * Process context - * - * @param[in] u4_for_me - * Flag to indicate the purpose of computing skip - * - * @param[out] ps_pred_mv - * Flag to indicate the current active refernce list - * - * @returns - * 1) Updates skip MV in proc - * 2) Returns if the current MB can be coded as skip or not - * - * @remarks The code implements the logic as described in sec 8.4.1.1 in H264 - * specification. - * - ******************************************************************************* -*/ ih264e_skip_params_ft ih264e_find_bskip_params; -/** - ******************************************************************************* - * - * @brief The function computes the parameters for a B skip MB - * - * @par Description: - * The function computes the parameters for a B skip MB - * - * @param[in] ps_proc - * Process context - * - * @param[in] u4_for_me - * Flag to indicate the purpose of computing skip - * - * @param[out] ps_pred_mv - * Flag to indicate the current active refernce list - * - * @returns - * 1) Updates skip MV in proc - * 2) The type of SKIP [L0/L1/BI] - * - * @remarks - ******************************************************************************* -*/ ih264e_skip_params_ft ih264e_find_bskip_params_me; -/** - ******************************************************************************* - * - * @brief motion vector predictor - * - * @par Description: - * The routine calculates the motion vector predictor for a given block, - * given the candidate MV predictors. - * - * @param[in] ps_left_mb_pu - * pointer to left mb motion vector info - * - * @param[in] ps_top_row_pu - * pointer to top & top right mb motion vector info - * - * @param[out] ps_pred_mv - * pointer to candidate predictors for the current block - * - * @returns The x & y components of the MV predictor. - * - * @remarks The code implements the logic as described in sec 8.4.1.3 in H264 - * specification. - * Assumptions : 1. Assumes Only partition of size 16x16 - * - ******************************************************************************* - */ void ih264e_get_mv_predictor(enc_pu_t *ps_left_mb_pu, enc_pu_t *ps_top_row_pu, enc_pu_mv_t *ps_pred_mv, WORD32 i4_ref_list); -/** - ******************************************************************************* - * - * @brief This fucntion evalues ME for 2 reference lists - * - * @par Description: - * It evaluates skip, full-pel an half-pel and assigns the correct MV in proc - * - * @param[in] ps_proc - * Process context corresponding to the job - * - * @returns none - * - * @remarks none - * - ******************************************************************************* - */ ih264e_compute_me_ft ih264e_compute_me_multi_reflist; -/** - ******************************************************************************* - * - * @brief This fucntion evalues ME for single reflist [Pred L0] - * - * @par Description: - * It evaluates skip, full-pel an half-pel and assigns the correct MV in proc - * - * @param[in] ps_proc - * Process context corresponding to the job - * - * @returns none - * - * @remarks none - * - ******************************************************************************* - */ ih264e_compute_me_ft ih264e_compute_me_single_reflist; -/** - ******************************************************************************* - * - * @brief This function initializes me ctxt - * - * @par Description: - * Before dispatching the current job to me thread, the me context associated - * with the job is initialized. - * - * @param[in] ps_proc - * Process context corresponding to the job - * - * @returns none - * - * @remarks none - * - ******************************************************************************* - */ void ih264e_init_me(process_ctxt_t *ps_proc); -/** - ******************************************************************************* - * - * @brief This function performs motion estimation for the current NMB - * - * @par Description: - * Intializes input and output pointers required by the function ih264e_compute_me - * and calls the function ih264e_compute_me in a loop to process NMBs. - * - * @param[in] ps_proc - * Process context corresponding to the job - * - * @returns - * - * @remarks none - * - ******************************************************************************* - */ void ih264e_compute_me_nmb(process_ctxt_t *ps_proc, UWORD32 u4_nmb_count); -/** - ******************************************************************************* - * - * @brief This function performs MV prediction - * - * @par Description: - * - * @param[in] ps_proc - * Process context corresponding to the job - * - * @returns none - * - * @remarks none - * This function will update the MB availability since intra inter decision - * should be done before the call - * - ******************************************************************************* - */ void ih264e_mv_pred(process_ctxt_t *ps_proc, WORD32 i4_reflist); -/** - ******************************************************************************* - * - * @brief This function approximates Pred. MV - * - * @par Description: - * - * @param[in] ps_proc - * Process context corresponding to the job - * - * @returns none - * - * @remarks none - * Motion estimation happens at nmb level. For cost calculations, mv is appro - * ximated using this function - * - ******************************************************************************* - */ void ih264e_mv_pred_me(process_ctxt_t *ps_proc, WORD32 i4_ref_list); -#endif /* IH264E_ME_H_ */ +#endif /* _IH264E_ME_H_ */ diff --git a/encoder/ih264e_modify_frm_rate.c b/encoder/ih264e_modify_frm_rate.c index f1e6e61..8f93f64 100644 --- a/encoder/ih264e_modify_frm_rate.c +++ b/encoder/ih264e_modify_frm_rate.c @@ -24,19 +24,19 @@ * ih264e_modify_frm_rate.c * * @brief -* Functions used to modify frame rate +* Handle source frame rate pulldown * * @author * ittiam * * @par List of Functions: -* - ih264e_pd_frm_rate_get_init_free_memtab() -* - ih264e_init_pd_frm_rate() -* - ih264e_update_pd_frm_rate() -* - ih264e_get_pd_avg_frm_rate() +* - ih264e_pd_frm_rate_get_init_free_memtab +* - ih264e_init_pd_frm_rate +* - ih264e_update_pd_frm_rate +* - ih264e_get_pd_avg_frm_rate * * @remarks -* None +* none * ******************************************************************************* */ @@ -45,31 +45,35 @@ /* File Includes */ /*****************************************************************************/ -/* User include files */ -#include "irc_datatypes.h" +/* User Include Files */ +#include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" + #include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" #include "ih264_cabac_tables.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ih264e_defs.h" -#include "ime_distortion_metrics.h" + #include "ime_defs.h" +#include "ime_distortion_metrics.h" #include "ime_structs.h" + +#include "irc_mem_req_and_acq.h" #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_rc_mem_interface.h" #include "ih264e_time_stamp.h" #include "ih264e_modify_frm_rate.h" diff --git a/encoder/ih264e_modify_frm_rate.h b/encoder/ih264e_modify_frm_rate.h index c301e2c..1bcf73e 100644 --- a/encoder/ih264e_modify_frm_rate.h +++ b/encoder/ih264e_modify_frm_rate.h @@ -24,19 +24,19 @@ * ih264e_modify_frm_rate.h * * @brief -* Functions declarations used to modify frame rate +* Handle source frame rate pulldown * * @author * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_MODIFY_FRM_RATE_H_ -#define IH264E_MODIFY_FRM_RATE_H_ +#ifndef _IH264E_MODIFY_FRM_RATE_H_ +#define _IH264E_MODIFY_FRM_RATE_H_ /*****************************************************************************/ /* Constant Definitions */ @@ -80,103 +80,16 @@ typedef struct pd_frm_rate_t *pd_frm_rate_handle; /* Function Declarations */ /*****************************************************************************/ -/** -******************************************************************************* -* -* @brief Function to init pd frame rate memtab -* -* @par Description -* Function to init pull down frame rate memtab -* -* @param[in] pps_pd_frm_rate -* pull down frame rate context -* -* @param[in] ps_memtab -* Handle to memtab -* -* @param[in] e_func_type -* Function type (get memtab/ update memtab) -* -* @returns Number of memtabs used -* -* @remarks None -* -******************************************************************************* -*/ WORD32 ih264e_pd_frm_rate_get_init_free_memtab(pd_frm_rate_handle *pps_pd_frm_rate, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type); -/** -******************************************************************************* -* -* @brief Initializes the pull down frame rate state structure based on input -* frame rate -* -* @par Description -* Initializes the pull down frame rate state structure based on input frame rate -* -* @param[in] ps_pd_frm_rate -* Pull down frame rate context -* -* @param[in] u4_input_frm_rate -* Input frame rate in frame per 1000sec -* -* @returns none -* -* @remarks -* -******************************************************************************* -*/ + void ih264e_init_pd_frm_rate(pd_frm_rate_handle ps_pd_frm_rate, UWORD32 u4_input_frm_rate); -/** -******************************************************************************* -* -* @brief Function to update pull down frame rate -* -* @par Description -* For each frame a run time frame rate value is sent based on whether a frame -* is skipped or not. If it is skipped for pull down then the current frame -* rate for the pull down period is signaled as 4/5th of the original frame -* rate. Thus when this is averaged the frame rate gradually switches from the -* input frame rate to 4/5th of input frame rate as and when more 3:2 pull -* down patterns are detected -* -* @param[in] ps_pd_frm_rate -* Pull down frame rate context -* -* @param[in] u4_input_frm_rate -* Input frame rate in frame per 1000sec -* -* @returns none -* -* @remarks -* -******************************************************************************* -*/ void ih264e_update_pd_frm_rate(pd_frm_rate_handle ps_pd_frm_rate, UWORD32 u4_cur_frm_rate); -/** -******************************************************************************* -* -* @brief returns average frame rate in 1 sec duration -* -* @par Description -* Averages the last N frame in period(1 sec) and then gives that -* as the current frames frame rate. Thus this averages out the sudden -* variation in frame rate -* -* @param[in] ps_pd_frm_rate -* Handle to pull down frame rate context -* -* @returns average frame rate -* -* @remarks -* -******************************************************************************* -*/ UWORD32 ih264e_get_pd_avg_frm_rate(pd_frm_rate_handle ps_pd_frm_rate); -#endif /* IH264E_MODIFY_FRM_RATE_H_ */ +#endif /* _IH264E_MODIFY_FRM_RATE_H_ */ diff --git a/encoder/ih264e_process.c b/encoder/ih264e_process.c index a0a04e0..5e55a14 100644 --- a/encoder/ih264e_process.c +++ b/encoder/ih264e_process.c @@ -27,24 +27,23 @@ * Contains functions for codec thread * * @author -* Harish +* ittiam * * @par List of Functions: -* - ih264e_generate_sps_pps() -* - ih264e_init_entropy_ctxt() -* - ih264e_entropy() -* - ih264e_pack_header_data() -* - ih264e_update_proc_ctxt() -* - ih264e_init_proc_ctxt() -* - ih264e_pad_recon_buffer() -* - ih264e_dblk_pad_hpel_processing_n_mbs() -* - ih264e_process() -* - ih264e_set_rc_pic_params() -* - ih264e_update_rc_post_enc() -* - ih264e_process_thread() +* - ih264e_generate_sps_pps +* - ih264e_init_entropy_ctxt +* - ih264e_entropy +* - ih264e_pack_header_data +* - ih264e_update_proc_ctxt +* - ih264e_init_proc_ctxt +* - ih264e_pad_recon_buffer +* - ih264e_dblk_pad_hpel_processing_n_mbs +* - ih264e_process +* - ih264e_update_rc_post_enc +* - ih264e_process_thread * * @remarks -* None +* none * ******************************************************************************* */ @@ -53,7 +52,7 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> @@ -61,57 +60,60 @@ #include <limits.h> #include <assert.h> -/* User include files */ +/* User Include Files */ +#include "ih264e_config.h" #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264_defs.h" +#include "ithread.h" + #include "ih264_debug.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" +#include "ih264_macros.h" #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_common_tables.h" +#include "ih264_cavlc_tables.h" #include "ih264_cabac_tables.h" -#include "ih264_platform_macros.h" -#include "ih264_macros.h" #include "ih264_buf_mgr.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ih264_common_tables.h" #include "ih264_list.h" -#include "ih264e_defs.h" +#include "ih264_platform_macros.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" +#include "ime_statistics.h" + +#include "irc_mem_req_and_acq.h" #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" +#include "irc_rate_control_api.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" +#include "ih264e_globals.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" +#include "ih264e_deblk.h" +#include "ih264e_encode_header.h" +#include "ih264e_utils.h" +#include "ih264e_me.h" +#include "ih264e_intra_modes_eval.h" +#include "ih264e_cavlc.h" #include "ih264e_cabac.h" +#include "ih264e_master.h" #include "ih264e_process.h" -#include "ithread.h" -#include "ih264e_intra_modes_eval.h" -#include "ih264e_encode_header.h" -#include "ih264e_globals.h" -#include "ih264e_config.h" #include "ih264e_trace.h" #include "ih264e_statistics.h" -#include "ih264_cavlc_tables.h" -#include "ih264e_cavlc.h" -#include "ih264e_deblk.h" -#include "ih264e_me.h" -#include "ih264e_debug.h" -#include "ih264e_master.h" -#include "ih264e_utils.h" -#include "irc_mem_req_and_acq.h" -#include "irc_rate_control_api.h" #include "ih264e_platform_macros.h" -#include "ime_statistics.h" /*****************************************************************************/ @@ -121,17 +123,17 @@ /** ****************************************************************************** * -* @brief This function generates sps, pps set on request +* @brief This function generates sps, pps set on request * -* @par Description +* @par Description * When the encoder is set in header generation mode, the following function * is called. This generates sps and pps headers and returns the control back * to caller. * -* @param[in] ps_codec +* @param[in] ps_codec * pointer to codec context * -* @return success or failure error code +* @return success or failure error code * ****************************************************************************** */ @@ -275,7 +277,6 @@ IH264E_ERROR_T ih264e_init_entropy_ctxt(process_ctxt_t *ps_proc) * ******************************************************************************* */ - IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc) { /* codec context */ @@ -392,6 +393,9 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc) /* populate slice header */ ih264e_populate_slice_header(ps_proc, ps_slice_hdr, ps_pps, ps_sps); + /* Starting bitstream offset for header in bits */ + bitstream_start_offset = GET_NUM_BITS(ps_bitstrm); + /* generate sei */ u4_insert_per_idr = (NAL_SLICE_IDR == ps_slice_hdr->i1_nal_unit_type); @@ -451,6 +455,11 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc) RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel); ih264e_init_cabac_ctxt(ps_entropy); } + + /* Ending bitstream offset for header in bits */ + bitstream_end_offset = GET_NUM_BITS(ps_bitstrm); + ps_entropy->u4_header_bits[i4_slice_type == PSLICE] += + bitstream_end_offset - bitstream_start_offset; } /* begin entropy coding for the mb set */ @@ -608,12 +617,17 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc) && ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_BLOCKS) { + bitstream_start_offset = GET_NUM_BITS(ps_bitstrm); ih264e_cabac_encode_terminate(ps_cabac_ctxt, 0); + bitstream_end_offset = GET_NUM_BITS(ps_bitstrm); + ps_entropy->u4_header_bits[i4_slice_type == PSLICE] += + bitstream_end_offset - bitstream_start_offset; } } if (ps_entropy->i4_eof) { + bitstream_start_offset = GET_NUM_BITS(ps_bitstrm); if (CAVLC == ps_entropy->u1_entropy_coding_mode_flag) { /* mb skip run */ @@ -635,6 +649,9 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc) { ih264e_cabac_encode_terminate(ps_cabac_ctxt, 1); } + bitstream_end_offset = GET_NUM_BITS(ps_bitstrm); + ps_entropy->u4_header_bits[i4_slice_type == PSLICE] += + bitstream_end_offset - bitstream_start_offset; DEBUG("entropy status %x", ps_entropy->i4_error_code); } @@ -1076,6 +1093,12 @@ WORD32 ih264e_update_proc_ctxt(process_ctxt_t *ps_proc) ih264_list_terminate(ps_codec->pv_entropy_jobq); } + /* update intra cost if valid */ + if (ps_proc->i4_mb_intra_cost != INT_MAX) + { + ps_codec->pi4_mb_intra_cost[(i4_mb_y * i4_wd_mbs) + i4_mb_x] = ps_proc->i4_mb_intra_cost; + } + /* update proc map */ pu1_proc_map[i4_mb_x] = 1; @@ -1110,10 +1133,9 @@ WORD32 ih264e_update_proc_ctxt(process_ctxt_t *ps_proc) ps_proc->apu1_ref_buf_chroma[0] += MB_SIZE; ps_proc->apu1_ref_buf_chroma[1] += MB_SIZE; - - /* Reset cost, distortion params */ ps_proc->i4_mb_cost = INT_MAX; + ps_proc->i4_mb_intra_cost = INT_MAX; ps_proc->i4_mb_distortion = SHRT_MAX; ps_proc->ps_pu += *ps_proc->pu4_mb_pu_cnt; @@ -1258,7 +1280,7 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) ps_proc->pu1_rec_buf_luma = ps_proc->pu1_rec_buf_luma_base + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * MB_SIZE); ps_proc->pu1_rec_buf_chroma = ps_proc->pu1_rec_buf_chroma_base + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * BLK8x8SIZE); - /* Tempral back and forward reference buffer */ + /* Temporal back and forward reference buffer */ ps_proc->apu1_ref_buf_luma[0] = ps_proc->apu1_ref_buf_luma_base[0] + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * MB_SIZE); ps_proc->apu1_ref_buf_chroma[0] = ps_proc->apu1_ref_buf_chroma_base[0] + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * BLK8x8SIZE); ps_proc->apu1_ref_buf_luma[1] = ps_proc->apu1_ref_buf_luma_base[1] + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * MB_SIZE); @@ -1436,7 +1458,14 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) ps_proc->u4_mb_type = I16x16; /* lambda */ - ps_proc->u4_lambda = gu1_qp0[ps_qp_params->u1_mb_qp]; + if (ps_codec->pic_type == PIC_B) + { + ps_proc->u4_lambda = gu1_qp_lambdaB[ps_qp_params->u1_mb_qp]; + } + else + { + ps_proc->u4_lambda = gu1_qp_lambdaIP[ps_qp_params->u1_mb_qp]; + } /* mb distortion */ ps_proc->i4_mb_distortion = SHRT_MAX; @@ -1457,6 +1486,7 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) /* mb cost */ ps_proc->i4_mb_cost = INT_MAX; + ps_proc->i4_mb_intra_cost = INT_MAX; /**********************/ /* init deblk context */ @@ -1586,9 +1616,6 @@ IH264E_ERROR_T ih264e_pad_recon_buffer(process_ctxt_t *ps_proc, return IH264E_SUCCESS; } - - - /** ******************************************************************************* * @@ -1909,7 +1936,7 @@ IH264E_ERROR_T ih264e_dblk_pad_hpel_processing_n_mbs(process_ctxt_t *ps_proc, /** ******************************************************************************* * -* @brief This function performs luma & chroma core coding for a set of mb's. +* @brief This function performs luma & chroma encoding for a set of mb's. * * @par Description: * The mb to be coded is taken and is evaluated over a predefined set of modes @@ -2020,7 +2047,6 @@ WORD32 ih264e_process(process_ctxt_t *ps_proc) u4_valid_modes |= (1 << B16x16); } - /* init entropy */ ps_proc->s_entropy.i4_mb_x = ps_proc->i4_mb_x; ps_proc->s_entropy.i4_mb_y = ps_proc->i4_mb_y; @@ -2070,17 +2096,14 @@ WORD32 ih264e_process(process_ctxt_t *ps_proc) /* get the min sad condition for current mb */ ps_proc->u4_min_sad_reached = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached; ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad; + ps_proc->i4_mb_distortion = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_distortion; + ps_proc->i4_mb_cost = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_cost; + ps_proc->u4_mb_type = ps_proc->ps_nmb_info[u4_mb_index].u4_mb_type; ps_proc->ps_skip_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_skip_mv[0]); ps_proc->ps_ngbr_avbl = &(ps_proc->ps_nmb_info[u4_mb_index].s_ngbr_avbl); ps_proc->ps_pred_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_pred_mv[0]); - ps_proc->i4_mb_distortion = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_distortion; - ps_proc->i4_mb_cost = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_cost; - ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad; - ps_proc->u4_min_sad_reached = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached; - ps_proc->u4_mb_type = ps_proc->ps_nmb_info[u4_mb_index].u4_mb_type; - /* get the best sub pel buffer */ ps_proc->pu1_best_subpel_buf = ps_proc->ps_nmb_info[u4_mb_index].pu1_best_sub_pel_buf; ps_proc->u4_bst_spel_buf_strd = ps_proc->ps_nmb_info[u4_mb_index].u4_bst_spel_buf_strd; @@ -2184,8 +2207,8 @@ WORD32 ih264e_process(process_ctxt_t *ps_proc) } } + } } - } /* is intra */ if (ps_proc->u4_mb_type == I4x4 || ps_proc->u4_mb_type == I16x16 || ps_proc->u4_mb_type == I8x8) @@ -2472,6 +2495,12 @@ WORD32 ih264e_update_rc_post_enc(codec_t *ps_codec, WORD32 ctxt_sel, WORD32 i4_i if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel]) { ps_entropy->ps_bitstrm->u4_strm_buf_offset = 0; + // If an IDR frame was skipped, restore frame num and IDR pic id + if (ps_codec->u4_is_idr == 1) + { + ps_codec->i4_frame_num = ps_codec->i4_restore_frame_num; + ps_codec->i4_idr_pic_id--; + } } else if (i4_stuffing_byte) { @@ -2621,12 +2650,6 @@ WORKER: /* entropy code all mbs enlisted under the current job */ error_status = ih264e_entropy(ps_proc); - if (s_job.i2_mb_y == ps_proc->i4_ht_mbs - 1) - { - error_status |= ih264e_update_rc_post_enc(ps_codec, ctxt_sel, - (ps_codec->i4_poc == 0)); - } - /* Dont execute any further instructions until store synchronization took place */ DATA_SYNC(); diff --git a/encoder/ih264e_process.h b/encoder/ih264e_process.h index 9cfdac8..a5c6556 100644 --- a/encoder/ih264e_process.h +++ b/encoder/ih264e_process.h @@ -30,305 +30,46 @@ * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_PROCESS_H_ -#define IH264E_PROCESS_H_ +#ifndef _IH264E_PROCESS_H_ +#define _IH264E_PROCESS_H_ /*****************************************************************************/ /* Function Declarations */ /*****************************************************************************/ -/** -****************************************************************************** -* -* @brief This function generates sps, pps set on request -* -* @par Description -* When the encoder is set in header generation mode, the following function -* is called. This generates sps and pps headers and returns the control back -* to caller. -* -* @param[in] ps_codec -* pointer to codec context -* -* @return success or failure error code -* -****************************************************************************** -*/ -IH264E_ERROR_T ih264e_generate_sps_pps - ( - codec_t *ps_codec - ); +IH264E_ERROR_T ih264e_generate_sps_pps(codec_t *ps_codec); -/** -******************************************************************************* -* -* @brief initialize entropy context. -* -* @par Description: -* Before invoking the call to perform to entropy coding the entropy context -* associated with the job needs to be initialized. This involves the start -* mb address, end mb address, slice index and the pointer to location at -* which the mb residue info and mb header info are packed. -* -* @param[in] ps_proc -* Pointer to the current process context -* -* @returns error status -* -* @remarks none -* -******************************************************************************* -*/ IH264E_ERROR_T ih264e_init_entropy_ctxt(process_ctxt_t *ps_proc); -/** -******************************************************************************* -* -* @brief entry point for entropy coding -* -* @par Description -* This function calls lower level functions to perform entropy coding for a -* group (n rows) of mb's. After encoding 1 row of mb's, the function takes -* back the control, updates the ctxt and calls lower level functions again. -* This process is repeated till all the rows or group of mb's (which ever is -* minimum) are coded -* -* @param[in] ps_proc -* process context -* -* @returns error status -* -* @remarks -* NOTE : It is assumed that this routine is invoked at the start of a slice, -* so the slice header is generated by default. -* -******************************************************************************* -*/ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc); -/** -******************************************************************************* -* -* @brief Packs header information of a mb in to a buffer -* -* @par Description: -* After the deciding the mode info of a macroblock, the syntax elements -* associated with the mb are packed and stored. The entropy thread unpacks -* this buffer and generates the end bit stream. -* -* @param[in] ps_proc -* Pointer to the current process context -* -* @returns error status -* -* @remarks none -* -******************************************************************************* -*/ -IH264E_ERROR_T ih264e_pack_header_data - ( - process_ctxt_t *ps_proc - ); +IH264E_ERROR_T ih264e_pack_header_data(process_ctxt_t *ps_proc); -/** -******************************************************************************* -* -* @brief update process context after encoding an mb. This involves preserving -* the current mb information for later use, initialize the proc ctxt elements to -* encode next mb. -* -* @par Description: -* This function performs house keeping tasks after encoding an mb. -* After encoding an mb, various elements of the process context needs to be -* updated to encode the next mb. For instance, the source, recon and reference -* pointers, mb indices have to be adjusted to the next mb. The slice index of -* the current mb needs to be updated. If mb qp modulation is enabled, then if -* the qp changes the quant param structure needs to be updated. Also to encoding -* the next mb, the current mb info is used as part of mode prediction or mv -* prediction. Hence the current mb info has to preserved at top/top left/left -* locations. -* -* @param[in] ps_proc -* Pointer to the current process context -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ -WORD32 ih264e_update_proc_ctxt - ( - process_ctxt_t *ps_proc - ); +WORD32 ih264e_update_proc_ctxt(process_ctxt_t *ps_proc); -/** -******************************************************************************* -* -* @brief initialize process context. -* -* @par Description: -* Before dispatching the current job to process thread, the process context -* associated with the job is initialized. Usually every job aims to encode one -* row of mb's. Basing on the row indices provided by the job, the process -* context's buffer ptrs, slice indices and other elements that are necessary -* during core-coding are initialized. -* -* @param[in] ps_proc -* Pointer to the current process context -* -* @returns error status -* -* @remarks none -* -******************************************************************************* -*/ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc); -/** -******************************************************************************* -* -* @brief This function performs luma & chroma padding -* -* @par Description: -* -* @param[in] ps_proc -* Process context corresponding to the job -* -* @param[in] pu1_curr_pic_luma -* Pointer to luma buffer -* -* @param[in] pu1_curr_pic_chroma -* Pointer to chroma buffer -* -* @param[in] i4_mb_x -* mb index x -* -* @param[in] i4_mb_y -* mb index y -* -* @param[in] i4_pad_ht -* number of rows to be padded -* -* @returns error status -* -* @remarks none -* -******************************************************************************* -*/ -IH264E_ERROR_T ih264e_pad_recon_buffer - ( - process_ctxt_t *ps_proc, - UWORD8 *pu1_curr_pic_luma, - UWORD8 *pu1_curr_pic_chroma, - WORD32 i4_mb_x, - WORD32 i4_mb_y, - WORD32 i4_pad_ht - ); +IH264E_ERROR_T ih264e_pad_recon_buffer(process_ctxt_t *ps_proc, + UWORD8 *pu1_curr_pic_luma, + UWORD8 *pu1_curr_pic_chroma, + WORD32 i4_mb_x, + WORD32 i4_mb_y, + WORD32 i4_pad_ht); -/** -******************************************************************************* -* -* @brief This function performs luma half pel planes generation -* -* @par Description: -* -* @param[in] ps_proc -* Process context corresponding to the job -* -* @returns error status -* -* @remarks none -* -******************************************************************************* -*/ -IH264E_ERROR_T ih264e_halfpel_generation - ( - process_ctxt_t *ps_proc, - UWORD8 *pu1_curr_pic_luma, - WORD32 i4_mb_x, - WORD32 i4_mb_y - ); +IH264E_ERROR_T ih264e_halfpel_generation(process_ctxt_t *ps_proc, + UWORD8 *pu1_curr_pic_luma, + WORD32 i4_mb_x, + WORD32 i4_mb_y); -/** -******************************************************************************* -* -* @brief This function performs luma & chroma core coding for a set of mb's. -* -* @par Description: -* The mb to be coded is taken and is evaluated over a predefined set of modes -* (intra (i16, i4, i8)/inter (mv, skip)) for best cost. The mode with least cost -* is selected and using intra/inter prediction filters, prediction is carried out. -* The deviation between src and pred signal constitutes error signal. This error -* signal is transformed (hierarchical transform if necessary) and quantized. The -* quantized residue is packed in to entropy buffer for entropy coding. This is -* repeated for all the mb's enlisted under the job. -* -* @param[in] ps_proc -* Process context corresponding to the job -* -* @returns error status -* -* @remarks none -* -******************************************************************************* -*/ WORD32 ih264e_process(process_ctxt_t *ps_proc); -/** -******************************************************************************* -* -* @brief -* Function to update rc context after encoding -* -* @par Description -* This function updates the rate control context after the frame is encoded. -* Number of bits consumed by the current frame, frame distortion, frame cost, -* number of intra/inter mb's, ... are passed on to rate control context for -* updating the rc model. -* -* @param[in] ps_codec -* Handle to codec context -* -* @param[in] ctxt_sel -* frame context selector -* -* @param[in] pic_cnt -* pic count -* -* @returns i4_stuffing_byte -* number of stuffing bytes (if necessary) -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_update_rc_post_enc(codec_t *ps_codec, WORD32 ctxt_sel, WORD32 pic_cnt); -/** -******************************************************************************* -* -* @brief -* entry point of a spawned encoder thread -* -* @par Description: -* The encoder thread dequeues a proc/entropy job from the encoder queue and -* calls necessary routines. -* -* @param[in] pv_proc -* Process context corresponding to the thread -* -* @returns error status -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_process_thread(void *pv_proc); -#endif /* IH264E_PROCESS_H_ */ +#endif /* _IH264E_PROCESS_H_ */ diff --git a/encoder/ih264e_rate_control.c b/encoder/ih264e_rate_control.c index b81d916..a11558b 100644 --- a/encoder/ih264e_rate_control.c +++ b/encoder/ih264e_rate_control.c @@ -30,16 +30,16 @@ * ittiam * * @par List of Functions: -* - ih264e_rc_init() -* - ih264e_rc_get_picture_details() -* - ih264e_rc_pre_enc() -* - ih264e_update_rc_mb_info() -* - ih264e_rc_get_buffer_status() -* - ih264e_rc_post_enc() -* - ih264e_update_rc_bits_info() +* - ih264e_rc_init +* - ih264e_rc_get_picture_details +* - ih264e_update_rc_framerates +* - ih264e_update_rc_mb_info +* - ih264e_rc_get_buffer_status +* - ih264e_rc_post_enc +* - ih264e_update_rc_bits_info * * @remarks -* None +* none * ******************************************************************************* */ @@ -48,40 +48,51 @@ /* File Includes */ /*****************************************************************************/ -/* User include files */ -#include "irc_datatypes.h" +/* System Include Files */ +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <assert.h> + +/* User Include Files */ +#include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264e.h" -#include "ih264_defs.h" + #include "ih264_macros.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" #include "ih264_common_tables.h" #include "ih264_cabac_tables.h" -#include "ih264e_defs.h" -#include "ih264e_globals.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_mem_req_and_acq.h" #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" #include "irc_rate_control_api.h" -#include "ih264e_time_stamp.h" -#include "ih264e_modify_frm_rate.h" -#include "ih264e_rate_control.h" + +#include "ih264e.h" #include "ih264e_error.h" +#include "ih264e_defs.h" +#include "ih264e_globals.h" +#include "ih264e_rate_control.h" #include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" #include "ih264e_utils.h" -#include "irc_trace_support.h" +#include "ih264e_time_stamp.h" +#include "ih264e_modify_frm_rate.h" /*****************************************************************************/ @@ -91,30 +102,6 @@ /** ******************************************************************************* * -* @brief This function does nothing -* -* @par Description -* This function does nothing -* -* @param[in] variadic function - -* @returns none -* -* @remarks This function is used by the rc library for debugging purposes. -* However this function was not part of rc library. So this is defined here -* to resolve link issues. -* -******************************************************************************* -*/ -int trace_printf(const WORD8 *format, ...) -{ - UNUSED(format); - return(0); -}; - -/** -******************************************************************************* -* * @brief * This function initializes rate control context and variables * @@ -291,12 +278,13 @@ picture_type_e ih264e_rc_get_picture_details(void *pv_rc_api, /** ******************************************************************************* * -* @brief Function to get rate control output before encoding +* @brief Function to catch frame skips before encoding due to source framerate +* pulldown * * @par Description -* This function is called before queing the current frame. It decides if we should -* skip the current iput buffer due to frame rate mismatch. It also updates RC about -* the acehivble frame rate +* This function is called before queuing the current frame. It decides if we +* should skip the current input buffer due to frame rate mismatch. It also +* updates RC about the framerate pulldown * * @param[in] ps_rate_control_api * Handle to rate control api @@ -310,18 +298,6 @@ picture_type_e ih264e_rc_get_picture_details(void *pv_rc_api, * @param[in] ps_frame_time * Handle to frame time context * -* @param[in] i4_delta_time_stamp -* Time stamp difference between frames -* -* @param[in] i4_total_mb_in_frame -* Total Macro Blocks in frame -* -* @param[in/out] pe_vop_coding_type -* Picture coding type(I/P/B) -* -* @param[in/out] pu1_frame_qp -* QP for current frame -* * @returns * Skip or queue the current frame * @@ -417,9 +393,19 @@ void ih264e_update_rc_mb_info(frame_info_t *ps_frame_info, void *pv_proc) ps_frame_info->num_mbs[mb_type]++; /* cost */ - if (ps_proc->u4_is_intra) + if (ps_proc->i4_mb_intra_cost != INT_MAX) + { + ps_frame_info->intra_mb_cost_sum += ps_proc->i4_mb_intra_cost; + } + else { - ps_frame_info->intra_mb_cost_sum += ps_proc->i4_mb_cost; + /* codec context */ + codec_t *ps_codec = ps_proc->ps_codec; + + /* temp var */ + WORD32 i4_mb_id = ps_proc->i4_mb_x + ps_proc->i4_mb_y * ps_proc->i4_wd_mbs; + + ps_frame_info->intra_mb_cost_sum += ps_codec->pi4_mb_intra_cost[i4_mb_id]; } } @@ -495,7 +481,7 @@ void ih264e_rc_get_buffer_status(void *pv_rc_api, * @par Description * This function is used to update the rate control module after the current * frame encoding is done with details such as bits consumed, SAD for I/P/B, -* intra cost ,mb type and other +* intra cost, mb type and other * * @param[in] ps_rate_control_api * Handle to rate control api context @@ -521,7 +507,7 @@ void ih264e_rc_get_buffer_status(void *pv_rc_api, * @param[in] i4_is_first_frame * Is first frame * -* @param[in] pi4_is_post_encode_skip +* @param[out] pi4_is_post_encode_skip * Post encoding skip flag * * @param[in] u1_frame_qp @@ -533,7 +519,9 @@ void ih264e_rc_get_buffer_status(void *pv_rc_api, * @param[in] pi4_avg_activity * Average activity * -* @returns +* @returns In case of underflow, number of stuffing bytes to be added and in +* case of overflow, flag signalling the encoder to avoid this frame from +* sending * * @remarks * @@ -581,22 +569,19 @@ WORD32 ih264e_rc_post_enc(void * ps_rate_control_api, i4_intra_frm_cost = irc_fi_get_total_intra_mb_cost(ps_frame_info); i4_avg_mb_activity = irc_fi_get_avg_activity(ps_frame_info); i4_total_hdr_bits = irc_fi_get_total_header_bits(ps_frame_info); - i4_total_texturebits = irc_fi_get_total_mb_texture_bits(ps_frame_info,MB_TYPE_INTRA); - i4_total_texturebits += irc_fi_get_total_mb_texture_bits(ps_frame_info,MB_TYPE_INTER); + ai4_mb_type_tex_bits[MB_TYPE_INTRA] = irc_fi_get_total_mb_texture_bits(ps_frame_info,MB_TYPE_INTRA); + ai4_mb_type_tex_bits[MB_TYPE_INTER] = irc_fi_get_total_mb_texture_bits(ps_frame_info,MB_TYPE_INTER); + i4_total_texturebits = ai4_mb_type_tex_bits[MB_TYPE_INTRA] + ai4_mb_type_tex_bits[MB_TYPE_INTER]; i4_total_frame_bits = i4_total_hdr_bits + i4_total_texturebits ; *pi4_avg_activity = i4_avg_mb_activity; - - /* Texture bits are not accumulated. Hence subtracting hdr bits from total bits */ - ai4_mb_type_tex_bits[MB_TYPE_INTRA] = 0; - ai4_mb_type_tex_bits[MB_TYPE_INTER] = i4_total_frame_bits - i4_total_hdr_bits; - /* Set post encode skip to zero */ pi4_is_post_encode_skip[0]= 0; /* For NLDRC, get the buffer status for stuffing or skipping */ - if (irc_get_rc_type(ps_rate_control_api) == CBR_NLDRC) + /* Default NLDRC to CBR with no frame drops so the '0 &&'. */ + if (0 && irc_get_rc_type(ps_rate_control_api) == CBR_NLDRC) { WORD32 i4_get_num_bit_to_prevent_vbv_overflow; UWORD8 u1_enc_buf_overflow,u1_enc_buf_underflow; @@ -695,10 +680,12 @@ WORD32 ih264e_rc_post_enc(void * ps_rate_control_api, /** ******************************************************************************* * -* @brief Function to update bits consumed info to rate control context +* @brief Function to update total header and texture bits consumed information +* to rate control context * * @par Description -* Function to update bits consume info to rate control context +* Function to update total header and texture bits consumed information +* to rate control context * * @param[in] ps_frame_info * Frame info context @@ -706,8 +693,7 @@ WORD32 ih264e_rc_post_enc(void * ps_rate_control_api, * @param[in] ps_entropy * Entropy context * -* @returns -* total bits consumed by the frame +* @returns none * * @remarks * diff --git a/encoder/ih264e_rate_control.h b/encoder/ih264e_rate_control.h index cca9ad3..7c3b3b1 100644 --- a/encoder/ih264e_rate_control.h +++ b/encoder/ih264e_rate_control.h @@ -24,93 +24,24 @@ * ih264e_rate_control.h * * @brief -* This file contains function declarations of api functions for h264 rate -* control +* This file contains declarations of api functions for h264 rate control * * @author * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_RATE_CONTROL_H_ -#define IH264E_RATE_CONTROL_H_ +#ifndef _IH264E_RATE_CONTROL_H_ +#define _IH264E_RATE_CONTROL_H_ /*****************************************************************************/ /* Function Declarations */ /*****************************************************************************/ -/** -******************************************************************************* -* -* @brief -* This function initializes rate control context and variables -* -* @par Description -* This function initializes rate control type, source and target frame rate, -* average and peak bitrate, intra-inter frame interval and initial -* quantization parameter -* -* @param[in] pv_rc_api -* Handle to rate control api -* -* @param[in] pv_frame_time -* Handle to frame time context -* -* @param[in] pv_time_stamp -* Handle to time stamp context -* -* @param[in] pv_pd_frm_rate -* Handle to pull down frame time context -* -* @param[in] u4_max_frm_rate -* Maximum frame rate -* -* @param[in] u4_src_frm_rate -* Source frame rate -* -* @param[in] u4_tgt_frm_rate -* Target frame rate -* -* @param[in] e_rate_control_type -* Rate control type -* -* @param[in] u4_avg_bit_rate -* Average bit rate -* -* @param[in] u4_peak_bit_rate -* Peak bit rate -* -* @param[in] u4_max_delay -* Maximum delay between frames -* -* @param[in] u4_intra_frame_interval -* Intra frame interval -* -* @param[in] i4_inter_frm_int -* Inter frame interval -* -* @param[in] pu1_init_qp -* Initial qp -* -* @param[in] i4_max_inter_frm_int -* Maximum inter frame interval -* -* @param[in] pu1_min_max_qp -* Array of min/max qp -* -* @param[in] u1_profile_level -* Encoder profile level -* -* @returns none -* -* @remarks -* -******************************************************************************* -*/ void ih264e_rc_init(void *pv_rc_api, void *pv_frame_time, void *pv_time_stamp, @@ -129,120 +60,17 @@ void ih264e_rc_init(void *pv_rc_api, UWORD8 *pu1_min_max_qp, UWORD8 u1_profile_level); -/** -******************************************************************************* -* -* @brief Function to get picture details -* -* @par Description -* This function returns the Picture type(I/P/B) -* -* @param[in] pv_rc_api -* Handle to Rate control api -* -* @returns -* Picture type -* -* @remarks none -* -******************************************************************************* -*/ picture_type_e ih264e_rc_get_picture_details(void *pv_rc_api, WORD32 *pi4_pic_id, WORD32 *pi4_pic_disp_order_no); - -/** -******************************************************************************* -* -* @brief Function to set frame rate inside RC. -* -* @par Description -* This function is called before encoding the current frame and gets the qp -* for the current frame from rate control module -* -* @param[in] ps_rate_control_api -* Handle to rate control api -* -* @param[in] ps_pd_frm_rate -* Handle to pull down frm rate context -* -* @param[in] ps_time_stamp -* Handle to time stamp context -* -* @param[in] ps_frame_time -* Handle to frame time context -* -* @returns -* Skip or encode the current frame -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_update_rc_framerates(void *ps_rate_control_api, - void *ps_pd_frm_rate, - void *ps_time_stamp, - void *ps_frame_time - ); + void *ps_pd_frm_rate, + void *ps_time_stamp, + void *ps_frame_time); -/** -******************************************************************************* -* -* @brief Function to update mb info for rate control context -* -* @par Description -* After encoding a mb, information such as mb type, qp used, mb distortion -* resulted in encoding the block and so on needs to be preserved for modelling -* RC. This is preserved via this function call. -* -* @param[in] ps_frame_info -* Handle Frame info context -* -* @param[in] ps_proc -* Process context -* -* @returns -* -* @remarks -* -******************************************************************************* -*/ void ih264e_update_rc_mb_info(frame_info_t *ps_frame_info, void *pv_proc); -/** -******************************************************************************* -* -* @brief Function to get rate control buffer status -* -* @par Description -* This function is used to get buffer status(underflow/overflow) by rate -* control module -* -* @param[in] pv_rc_api -* Handle to rate control api context -* -* @param[in] i4_total_frame_bits -* Total frame bits -* -* @param[in] u1_pic_type -* Picture type -* -* @param[in] pi4_num_bits_to_prevent_vbv_underflow -* Number of bits to prevent underflow -* -* @param[out] pu1_is_enc_buf_overflow -* Buffer overflow indication flag -* -* @param[out] pu1_is_enc_buf_underflow -* Buffer underflow indication flag -* -* @returns -* -* @remarks -* -******************************************************************************* -*/ void ih264e_rc_get_buffer_status(void *pv_rc_api, WORD32 i4_total_frame_bits, picture_type_e e_pic_type, @@ -250,58 +78,6 @@ void ih264e_rc_get_buffer_status(void *pv_rc_api, UWORD8 *pu1_is_enc_buf_overflow, UWORD8 *pu1_is_enc_buf_underflow); -/** -******************************************************************************* -* -* @brief Function to update rate control module after encoding -* -* @par Description -* This function is used to update the rate control module after the current -* frame encoding is done with details such as bits consumed, SAD for I/P/B, -* intra cost ,mb type and other -* -* @param[in] ps_rate_control_api -* Handle to rate control api context -* -* @param[in] ps_frame_info -* Handle to frame info context -* -* @param[in] ps_pd_frm_rate -* Handle to pull down frame rate context -* -* @param[in] ps_time_stamp -* Handle to time stamp context -* -* @param[in] ps_frame_time -* Handle to frame time context -* -* @param[in] i4_total_mb_in_frame -* Total mb in frame -* -* @param[in] pe_vop_coding_type -* Picture coding type -* -* @param[in] i4_is_first_frame -* Is first frame -* -* @param[in] pi4_is_post_encode_skip -* Post encoding skip flag -* -* @param[in] u1_frame_qp -* Frame qp -* -* @param[in] pi4_num_intra_in_prev_frame -* Number of intra mbs in previous frame -* -* @param[in] pi4_avg_activity -* Average activity -* -* @returns -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_rc_post_enc(void *ps_rate_control_api, frame_info_t *ps_frame_info, void *ps_pd_frm_rate, @@ -315,28 +91,7 @@ WORD32 ih264e_rc_post_enc(void *ps_rate_control_api, WORD32 *pi4_num_intra_in_prev_frame, WORD32 *pi4_avg_activity); -/** -******************************************************************************* -* -* @brief Function to update bits consumed info to rate control context -* -* @par Description -* Function to update bits consume info to rate control context -* -* @param[in] ps_frame_info -* Frame info context -* -* @param[in] ps_entropy -* Entropy context -* -* @returns -* total bits consumed by the frame -* -* @remarks -* -******************************************************************************* -*/ void ih264e_update_rc_bits_info(frame_info_t *ps_frame_info, void *pv_entropy); -#endif /* IH264E_RATE_CONTROL_H */ +#endif /* _IH264E_RATE_CONTROL_H_ */ diff --git a/encoder/ih264e_rc_mem_interface.c b/encoder/ih264e_rc_mem_interface.c index a74513a..85699f6 100644 --- a/encoder/ih264e_rc_mem_interface.c +++ b/encoder/ih264e_rc_mem_interface.c @@ -30,14 +30,12 @@ * ittiam * * List of Functions -* - fill_memtab() -* - use_or_fill_base() -* - ih264e_map_rc_mem_recs_to_itt_api() -* - ih264e_map_itt_mem_rec_to_rc_mem_rec() -* - ih264e_get_rate_control_mem_tab() +* - ih264e_map_rc_mem_recs_to_itt_api +* - ih264e_map_itt_mem_rec_to_rc_mem_rec +* - ih264e_get_rate_control_mem_tab * * @remarks -* None +* none * ******************************************************************************* */ @@ -47,60 +45,37 @@ /* File Includes */ /*****************************************************************************/ -/* System include files */ +/* System Include Files */ #include <stdio.h> -#include <string.h> +#include <stddef.h> #include <stdlib.h> +#include <string.h> #include <assert.h> -#include <stdarg.h> -#include <math.h> /* User Include Files */ #include "ih264e_config.h" #include "ih264_typedefs.h" -#include "ih264_size_defs.h" -#include "iv2.h" -#include "ive2.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" -#include "ih264e.h" -#include "ithread.h" -#include "ih264_defs.h" + #include "ih264_debug.h" -#include "ih264_macros.h" -#include "ih264_platform_macros.h" -#include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" +#include "ih264_size_defs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" -#include "ih264_common_tables.h" -#include "ih264_list.h" #include "ih264_cabac_tables.h" -#include "ih264e_error.h" -#include "ih264e_defs.h" -#include "ih264e_bitstream.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + +#include "irc_mem_req_and_acq.h" #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" -#include "ih264e_rate_control.h" -#include "ih264e_cabac_structs.h" -#include "ih264e_structs.h" -#include "ih264e_master.h" -#include "ih264_buf_mgr.h" -#include "ih264_dpb_mgr.h" -#include "ih264e_utils.h" -#include "ih264e_platform_macros.h" -#include "ih264_cavlc_tables.h" -#include "ih264e_statistics.h" -#include "ih264e_trace.h" -#include "ih264e_fmt_conv.h" -#include "ih264e_cavlc.h" -#include "ih264e_rc_mem_interface.h" -#include "ih264e_time_stamp.h" +#include "irc_rate_control_api.h" #include "irc_common.h" #include "irc_rd_model.h" #include "irc_est_sad.h" @@ -111,9 +86,17 @@ #include "irc_mb_model_based.h" #include "irc_cbr_buffer_control.h" #include "irc_vbr_str_prms.h" -#include "irc_rate_control_api.h" #include "irc_rate_control_api_structs.h" + +#include "ih264e.h" +#include "ih264e_error.h" +#include "ih264e_defs.h" +#include "ih264e_time_stamp.h" #include "ih264e_modify_frm_rate.h" +#include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" +#include "ih264e_cabac_structs.h" +#include "ih264e_structs.h" /*****************************************************************************/ @@ -123,103 +106,6 @@ /** ****************************************************************************** * -* @brief This function fills memory record attributes -* -* @par Description -* This function fills memory record attributes -* -* @param[in] ps_mem_tab -* pointer to mem records -* -* @param[in] u4_size -* size of the record -* -* @param[in] i4_alignment -* memory alignment size -* -* @param[in] e_usage -* usage -* -* @param[in] e_mem_region -* mem region -* -* @return void -* -****************************************************************************** -*/ -void fill_memtab(itt_memtab_t *ps_mem_tab, - WORD32 u4_size, - WORD32 i4_alignment, - ITT_MEM_USAGE_TYPE_E e_usage, - ITT_MEM_REGION_E e_mem_region) -{ - /* Make the size next multiple of alignment */ - WORD32 i4_aligned_size = (((u4_size) + (i4_alignment-1)) & (~(i4_alignment-1))); - - /* Fill the memtab */ - ps_mem_tab->u4_size = i4_aligned_size; - ps_mem_tab->i4_alignment = i4_alignment; - ps_mem_tab->e_usage = e_usage; - ps_mem_tab->e_mem_region = e_mem_region; -} - -/** -****************************************************************************** -* -* @brief This function fills memory record attributes -* -* @par Description -* This function fills memory record attributes -* -* @param[in] ps_mem_tab -* pointer to mem records -* -* @param[in] ptr_to_be_filled -* handle to the memory record storage space -* -* @param[in] e_func_type -* enum that dictates fill memory records or use memory records -* -* @return void -* -****************************************************************************** -*/ -WORD32 use_or_fill_base(itt_memtab_t *ps_mem_tab, - void **ptr_to_be_filled, - ITT_FUNC_TYPE_E e_func_type) -{ - /* Fill base for freeing the allocated memory */ - if (e_func_type == FILL_BASE) - { - if (ptr_to_be_filled[0] != 0) - { - ps_mem_tab->pv_base = ptr_to_be_filled[0]; - return (0); - } - else - { - return (-1); - } - } - /* obtain the allocated memory from base pointer */ - if (e_func_type == USE_BASE) - { - if (ps_mem_tab->pv_base != 0) - { - ptr_to_be_filled[0] = ps_mem_tab->pv_base; - return (0); - } - else - { - return (-1); - } - } - return (0); -} - -/** -****************************************************************************** -* * @brief This function maps rc mem records structure to encoder lib mem records * structure * @@ -308,7 +194,7 @@ void ih264e_map_itt_mem_rec_to_rc_mem_rec(iv_mem_rec_t *ps_mem, /** ****************************************************************************** * -* @brief Get memtabs for rate control +* @brief Get/Init memtabs for rate control * * @par Description * This routine is used to Get/init memtabs for rate control diff --git a/encoder/ih264e_rc_mem_interface.h b/encoder/ih264e_rc_mem_interface.h index a2946a7..8b05c4c 100644 --- a/encoder/ih264e_rc_mem_interface.h +++ b/encoder/ih264e_rc_mem_interface.h @@ -24,156 +24,24 @@ * ih264e_rc_mem_interface.h * * @brief -* This file contains function declaration and structures for rate control -* memtabs +* Get memory requirements of rate control library * * @author * ittiam * -* @remarks -* The rate control library is a global library across various codecs. It -* anticipates certain structures definitions. Those definitions are to be -* imported from global workspace. Instead of that, the structures needed for -* rc library are copied in to this file and exported to rc library. If the -* structures / enums / ... in the global workspace change, this file also needs -* to be modified accordingly. -* ****************************************************************************** */ -#ifndef IH264E_RC_MEM_INTERFACE_H_ -#define IH264E_RC_MEM_INTERFACE_H_ - - -/*****************************************************************************/ -/* Function Macros */ -/*****************************************************************************/ - -#define FILL_MEMTAB(m_pv_mem_rec, m_j, m_mem_size, m_align, m_type) \ -{ \ - m_pv_mem_rec[m_j].u4_size = sizeof(iv_mem_rec_t); \ - m_pv_mem_rec[m_j].u4_mem_size = m_mem_size; \ - m_pv_mem_rec[m_j].u4_mem_alignment = m_align; \ - m_pv_mem_rec[m_j].e_mem_type = m_type; \ -} - -/*****************************************************************************/ -/* Enums */ -/*****************************************************************************/ -typedef enum -{ - ALIGN_BYTE = 1, - ALIGN_WORD16 = 2, - ALIGN_WORD32 = 4, - ALIGN_WORD64 = 8, - ALIGN_128_BYTE = 128 -}ITT_MEM_ALIGNMENT_TYPE_E; - -typedef enum -{ - SCRATCH = 0, - PERSISTENT = 1, - WRITEONCE = 2 -}ITT_MEM_USAGE_TYPE_E; - -typedef enum -{ - L1D = 0, - SL2 = 1, - DDR = 3 -}ITT_MEM_REGION_E; - -typedef enum -{ - GET_NUM_MEMTAB = 0, - FILL_MEMTAB = 1, - USE_BASE = 2, - FILL_BASE =3 -}ITT_FUNC_TYPE_E; +#ifndef _IH264E_RC_MEM_INTERFACE_H_ +#define _IH264E_RC_MEM_INTERFACE_H_ /*****************************************************************************/ -/* Structures */ +/* Function Declarations */ /*****************************************************************************/ - -/*NOTE : This should be an exact replica of IALG_MemRec, any change in IALG_MemRec - must be replicated here*/ -typedef struct -{ - /* Size in bytes */ - UWORD32 u4_size; - - /* Alignment in bytes */ - WORD32 i4_alignment; - - /* decides which memory region to be placed */ - ITT_MEM_REGION_E e_mem_region; - - /* memory is scratch or persistent */ - ITT_MEM_USAGE_TYPE_E e_usage; - - /* Base pointer for allocated memory */ - void *pv_base; -} itt_memtab_t; - - -/*****************************************************************************/ -/* Extern Function Declarations */ -/*****************************************************************************/ - -/** -****************************************************************************** -* -* @brief This function fills memory record attributes -* -* @par Description -* This function fills memory record attributes -* -* @param[in] ps_mem_tab -* pointer to mem records -* -* @param[in] u4_size -* size of the record -* -* @param[in] i4_alignment -* memory alignment size -* -* @param[in] e_usage -* usage -* -* @param[in] e_mem_region -* mem region -* -* @return void -* -****************************************************************************** -*/ -void fill_memtab(itt_memtab_t *ps_mem_tab, WORD32 u4_size, WORD32 i4_alignment, - ITT_MEM_USAGE_TYPE_E e_usage, ITT_MEM_REGION_E e_mem_region); - -/** -****************************************************************************** -* -* @brief This function fills memory record attributes -* -* @par Description -* This function fills memory record attributes -* -* @param[in] ps_mem_tab -* pointer to mem records -* -* @param[in] ptr_to_be_filled -* handle to the memory record storage space -* -* @param[in] e_func_type -* enum that dictates fill memory records or use memory records -* -* @return void -* -****************************************************************************** -*/ -WORD32 use_or_fill_base(itt_memtab_t *ps_mem_tab, void **ptr_to_be_filled, - ITT_FUNC_TYPE_E e_func_type); +WORD32 ih264e_get_rate_control_mem_tab(void *pv_rate_control, + iv_mem_rec_t *ps_mem, + ITT_FUNC_TYPE_E e_func_type); -#endif // IH264E_RC_MEM_INTERFACE_H_ +#endif /* _IH264E_RC_MEM_INTERFACE_H_ */ diff --git a/encoder/ih264e_statistics.h b/encoder/ih264e_statistics.h index 0ab33ca..d917d71 100644 --- a/encoder/ih264e_statistics.h +++ b/encoder/ih264e_statistics.h @@ -24,24 +24,24 @@ * ih264e_statistics.h * * @brief -* Contains macros for generating stats about h264 encoder +* Contains macros for collecting stats during encoding process * * @author * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_STATISTICS_H_ -#define IH264E_STATISTICS_H_ +#ifndef _IH264E_STATISTICS_H_ +#define _IH264E_STATISTICS_H_ #if CAVLC_LEVEL_STATS /*****************************************************************************/ -/* Extern global declarations */ +/* Global Tables */ /*****************************************************************************/ /** @@ -65,7 +65,7 @@ extern UWORD32 gu4_cavlc_level_bin_else_where; extern UWORD32 gu4_cavlc_level_lut_hit_rate; /*****************************************************************************/ -/* Extern function declarations */ +/* Function declarations */ /*****************************************************************************/ /** @@ -104,7 +104,7 @@ void print_cavlc_level_stats(void); #if GATING_STATS /*****************************************************************************/ -/* Extern global declarations */ +/* global declarations */ /*****************************************************************************/ /** @@ -118,7 +118,7 @@ void print_cavlc_level_stats(void); extern UWORD32 gu4_mb_gated_cnt; /*****************************************************************************/ -/* Extern function declarations */ +/* function declarations */ /*****************************************************************************/ /** @@ -138,4 +138,4 @@ void print_gating_stats(void); #endif -#endif /* IH264E_STATISTICS_H_ */ +#endif /* _IH264E_STATISTICS_H_ */ diff --git a/encoder/ih264e_structs.h b/encoder/ih264e_structs.h index 4c3f63f..11234f9 100644 --- a/encoder/ih264e_structs.h +++ b/encoder/ih264e_structs.h @@ -30,25 +30,23 @@ * Harish * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_STRUCTS_H_ -#define IH264E_STRUCTS_H_ +#ifndef _IH264E_STRUCTS_H_ +#define _IH264E_STRUCTS_H_ /*****************************************************************************/ /* Structure definitions */ /*****************************************************************************/ -/* Early declaration of structs */ typedef struct _codec_t codec_t; typedef struct _proc_t process_ctxt_t; - /*****************************************************************************/ -/* Extern Function type definitions */ +/* Function type definitions */ /*****************************************************************************/ /** @@ -1705,6 +1703,7 @@ struct _proc_t * mb cost */ WORD32 i4_mb_cost; + WORD32 i4_mb_intra_cost; /********************************************************************/ /* i4_ngbr_avbl_mb_16 - ngbr avbl of curr mb */ @@ -2254,6 +2253,11 @@ struct _codec_t WORD32 i4_frame_num; /** + * frame num backup (used in post enc skip case) + */ + WORD32 i4_restore_frame_num; + + /** * slice_type */ WORD32 i4_slice_type; @@ -2581,6 +2585,12 @@ struct _codec_t UWORD16 *pu2_intr_rfrsh_map; /* + * Intra MB Cost Map + * Stores the intra cost of all mb of a frame + */ + WORD32 *pi4_mb_intra_cost; + + /* * Indicates if the current frame is used as a reference frame */ UWORD32 u4_is_curr_frm_ref; @@ -2862,4 +2872,4 @@ struct _codec_t }; -#endif /* IH264E_STRUCTS_H_ */ +#endif /* _IH264E_STRUCTS_H_ */ diff --git a/encoder/ih264e_time_stamp.c b/encoder/ih264e_time_stamp.c index 85b75a3..ce66c1e 100644 --- a/encoder/ih264e_time_stamp.c +++ b/encoder/ih264e_time_stamp.c @@ -30,26 +30,26 @@ * ittiam * * @par List of Functions: -* - gcd() -* - ih264e_get_range() -* - ih264e_frame_time_get_init_free_memtab() -* - ih264e_init_frame_time() -* - ih264e_should_src_be_skipped() -* - ih264e_time_stamp_get_init_free_memtab() -* - ih264e_init_time_stamp() -* - ih264e_update_time_stamp() -* - ih264e_frame_time_get_src_frame_rate() -* - ih264e_frame_time_get_tgt_frame_rate() -* - ih264e_frame_time_get_src_ticks() -* - ih264e_frame_time_get_tgt_ticks() -* - ih264e_frame_time_get_src_time() -* - ih264e_frame_time_get_tgt_time() -* - ih264e_frame_time_update_src_frame_rate() -* - ih264e_frame_time_update_tgt_frame_rate() -* - ih264_time_stamp_update_frame_rate() +* - gcd +* - ih264e_get_range +* - ih264e_frame_time_get_init_free_memtab +* - ih264e_init_frame_time +* - ih264e_should_src_be_skipped +* - ih264e_time_stamp_get_init_free_memtab +* - ih264e_init_time_stamp +* - ih264e_update_time_stamp +* - ih264e_frame_time_get_src_frame_rate +* - ih264e_frame_time_get_tgt_frame_rate +* - ih264e_frame_time_get_src_ticks +* - ih264e_frame_time_get_tgt_ticks +* - ih264e_frame_time_get_src_time +* - ih264e_frame_time_get_tgt_time +* - ih264e_frame_time_update_src_frame_rate +* - ih264e_frame_time_update_tgt_frame_rate +* - ih264_time_stamp_update_frame_rate * * @remarks -* None +* none * ******************************************************************************* */ @@ -58,34 +58,38 @@ /* File Includes */ /*****************************************************************************/ -/* user include files */ -#include "irc_datatypes.h" +/* User Include Files */ +#include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" + #include "ih264_defs.h" -#include "ih264e_defs.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" -#include "irc_cntrl_param.h" -#include "irc_frame_info_collector.h" -#include "ih264e_rate_control.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" #include "ih264_cabac_tables.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + +#include "irc_mem_req_and_acq.h" +#include "irc_cntrl_param.h" +#include "irc_frame_info_collector.h" +#include "irc_common.h" +#include "irc_rate_control_api.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" +#include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_rc_mem_interface.h" #include "ih264e_time_stamp.h" -#include "irc_common.h" -#include "irc_rate_control_api.h" /*****************************************************************************/ @@ -680,7 +684,7 @@ WORD32 ih264e_frame_time_get_tgt_time(frame_time_t *frame_time) * source frame rate * * @returns -* None +* none * * @remarks * @@ -713,7 +717,7 @@ void ih264e_frame_time_update_src_frame_rate(frame_time_t *ps_frame_time, * target frame rate * * @returns -* None +* none * * @remarks * @@ -746,7 +750,7 @@ void ih264e_frame_time_update_tgt_frame_rate(frame_time_t *ps_frame_time, * source frame rate * * @returns -* None +* none * * @remarks * diff --git a/encoder/ih264e_time_stamp.h b/encoder/ih264e_time_stamp.h index 1ee559d..d3af887 100644 --- a/encoder/ih264e_time_stamp.h +++ b/encoder/ih264e_time_stamp.h @@ -31,13 +31,13 @@ * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_TIME_STAMP_H_ -#define IH264E_TIME_STAMP_H_ +#ifndef _IH264E_TIME_STAMP_H_ +#define _IH264E_TIME_STAMP_H_ /*****************************************************************************/ /* Structures */ @@ -68,6 +68,7 @@ typedef struct frame_time_t /* Number of frames not to be skipped while maintaining tgt_frm_rate due to delta_time_stamp */ UWORD32 u4_num_frms_dont_skip; + }frame_time_t; typedef struct frame_time_t *frame_time_handle; @@ -114,385 +115,57 @@ typedef struct time_stamp_t For mpeg4 standard, we just have 16bits and we can't accommodate more than 60000 as frame rate. So we scale it and work with it */ WORD32 is_max_frame_rate_scaled; + } time_stamp_t; typedef struct time_stamp_t *time_stamp_handle; /*****************************************************************************/ -/* Extern function declarations */ +/* Function declarations */ /*****************************************************************************/ -/** -******************************************************************************* -* -* @brief -* Function to init frame time context -* -* @par Description -* Frame time structure stores the time of the source and the target frames to -* be encoded. Based on the time we decide whether or not to encode the source -* frame -* -* @param[in] ps_frame_time -* Pointer Frame time context -* -* @param[in] u4_src_frm_rate -* Source frame rate -* -* @param[in] u4_tgt_frm_rate -* Target frame rate -* -* @returns -* none -* -* @remarks -* -******************************************************************************* -*/ void ih264e_init_frame_time(frame_time_t *ps_frame_time, UWORD32 u4_src_frm_rate, UWORD32 u4_tgt_frm_rate); -/** -******************************************************************************* -* -* @brief -* Function to check if frame can be skipped -* -* @par Description -* Based on the source and target frame time and the delta time stamp -* we decide whether to code the source or not. -* This is based on the assumption -* that the source frame rate is greater that target frame rate. -* Updates the time_stamp structure -* -* @param[in] ps_frame_time -* Handle to frame time context -* -* @param[in] u4_delta_time_stamp -* Time stamp difference between frames -* -* @param[out] pu4_frm_not_skipped_for_dts -* Flag to indicate if frame is already skipped by application -* -* @returns -* Flag to skip frame -* -* @remarks -* -******************************************************************************* -*/ UWORD8 ih264e_should_src_be_skipped(frame_time_t *ps_frame_time, UWORD32 u4_delta_time_stamp, UWORD32 *pu4_frm_not_skipped_for_dts); -/** -******************************************************************************* -* -* @brief -* Function to initialize time stamp context -* -* @par Description -* Time stamp structure stores the time stamp data that -* needs to be sent in to the header of MPEG4. Based on the -* max target frame rate the vop_time increment resolution is set -* so as to support all the frame rates below max frame rate. -* A support till the third decimal point is assumed. -* -* @param[in] ps_time_stamp -* Pointer to time stamp structure -* -* @param[in] u4_max_frm_rate -* Maximum frame rate -* -* @param[in] u4_src_frm_rate -* Source frame rate -* -* @returns -* none -* -* @remarks -* -******************************************************************************* -*/ void ih264e_init_time_stamp(time_stamp_handle time_stamp, UWORD32 max_frm_rate, UWORD32 src_frm_rate); -/** -******************************************************************************* -* -* @brief Function to update time stamp context -* -* @par Description -* Vop time is incremented by increment value. When vop time goes -* more than the vop time resolution set the modulo time base to -* 1 and reduce the vop time by vop time resolution so that the -* excess value is present in vop time and get accumulated over time -* so that the corresponding frame rate is achieved at a average of -* 1000 seconds -* -* @param[in] ps_time_stamp -* Pointer to time stamp structure -* -* @returns -* none -* -* @remarks -* -******************************************************************************* -*/ void ih264e_update_time_stamp(time_stamp_handle time_stamp); -/** -******************************************************************************* -* -* @brief -* Function to init frame time memtabs -* -* @par Description -* Function to init frame time memtabs -* -* @param[in] pps_frame_time -* Pointer to frame time contexts -* -* @param[in] ps_memtab -* Pointer to memtab -* -* @param[in] e_func_type -* Function type (get memtabs/init memtabs) -* -* @returns -* none -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_frame_time_get_init_free_memtab(frame_time_handle *pps_frame_time, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type); -/** -******************************************************************************* -* -* @brief -* Function to initialize time stamp memtabs -* -* @par Description -* Function to initialize time stamp memtabs -* -* @param[in] pps_time_stamp -* Pointer to time stamp context -* -* @param[in] ps_memtab -* Pointer to memtab -* -* @param[in] e_func_type -* Funcion type (Get memtab/ init memtab) -* -* @returns -* number of memtabs used -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_time_stamp_get_init_free_memtab(time_stamp_handle *pps_time_stamp, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type); -/**************************************************************************** - Run-Time Modifying functions -****************************************************************************/ -/** -******************************************************************************* -* -* @brief Function to get source frame rate -* -* @par Description -* Function to get source frame rate -* -* @param[in] ps_frame_time -* Pointer to frame time context -* -* @returns -* source frame rate -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_frame_time_get_src_frame_rate(frame_time_t *ps_frame_time); -/** -******************************************************************************* -* -* @brief Function to get target frame rate -* -* @par Description -* Function to get target frame rate -* -* @param[in] ps_frame_time -* Pointer to frame time context -* -* @returns -* target frame rate -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_frame_time_get_tgt_frame_rate(frame_time_t *ps_frame_time); -/** -******************************************************************************* -* -* @brief Function to get source time increment -* -* @par Description -* Function to get source time increment -* -* @param[in] ps_frame_time -* Pointer to frame time context -* -* @returns -* source time increment -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_frame_time_get_src_ticks(frame_time_t *ps_frame_time); -/** -******************************************************************************* -* -* @brief Function to get target time increment -* -* @par Description -* Function to get target time increment -* -* @param[in] ps_frame_time -* Pointer to frame time context -* -* @returns -* target time increment -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_frame_time_get_tgt_ticks(frame_time_t *ps_frame_time); -/** -******************************************************************************* -* -* @brief Function to get src frame time -* -* @par Description -* Function to get src frame time -* -* @param[in] ps_frame_time -* Pointer to frame time context -* -* @returns -* src frame time -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_frame_time_get_src_time(frame_time_t *frame_time); -/** -******************************************************************************* -* -* @brief Function to get tgt frame time -* -* @par Description -* Function to get tgt frame time -* -* @param[in] ps_frame_time -* Pointer to frame time context -* -* @returns -* tgt frame time -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_frame_time_get_tgt_time(frame_time_t *frame_time); -/** -******************************************************************************* -* -* @brief Function to update source frame time with a new source frame rate -* -* @par Description -* Function to update source frame time with a new source frame rate -* -* @param[in] ps_frame_time -* Pointer to frame time context -* -* @param[in] src_frm_rate -* source frame rate -* -* @returns -* None -* -* @remarks -* -******************************************************************************* -*/ -void ih264e_frame_time_update_src_frame_rate(frame_time_t *ps_frame_time, WORD32 src_frm_rate); +void ih264e_frame_time_update_src_frame_rate(frame_time_t *ps_frame_time, + WORD32 src_frm_rate); -/** -******************************************************************************* -* -* @brief Function to update target frame time with a new source frame rate -* -* @par Description -* Function to update target frame time with a new source frame rate -* -* @param[in] ps_frame_time -* Pointer to frame time context -* -* @param[in] tgt_frm_rate -* target frame rate -* -* @returns -* None -* -* @remarks -* -******************************************************************************* -*/ -void ih264e_frame_time_update_tgt_frame_rate(frame_time_t *ps_frame_time, WORD32 tgt_frm_rate); +void ih264e_frame_time_update_tgt_frame_rate(frame_time_t *ps_frame_time, + WORD32 tgt_frm_rate); -/** -******************************************************************************* -* -* @brief Function to update target frame time with a new source frame rate -* -* @par Description -* When the frame rate changes the time increment is modified by appropriate ticks -* -* @param[in] ps_time_stamp -* Pointer to time stamp structure -* -* @param[in] src_frm_rate -* source frame rate -* -* @returns -* None -* -* @remarks -* -******************************************************************************* -*/ -void ih264_time_stamp_update_frame_rate(time_stamp_t *ps_time_stamp, UWORD32 src_frm_rate); +void ih264_time_stamp_update_frame_rate(time_stamp_t *ps_time_stamp, + UWORD32 src_frm_rate); -#endif /*IH264E_TIME_STAMP_H_*/ +#endif /*_IH264E_TIME_STAMP_H_ */ diff --git a/encoder/ih264e_trace.h b/encoder/ih264e_trace.h index 8134524..d371cc6 100644 --- a/encoder/ih264e_trace.h +++ b/encoder/ih264e_trace.h @@ -24,20 +24,20 @@ * ih264e_trace.h * * @brief -* This file contains extern declarations of routines that could be helpful -* for debugging purposes. +* This file contains declarations of routines that could be helpful for +* debugging purposes. * * @author * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_TRACE_H_ -#define IH264E_TRACE_H_ +#ifndef _IH264E_TRACE_H_ +#define _IH264E_TRACE_H_ #if ENABLE_TRACE /*****************************************************************************/ @@ -58,7 +58,7 @@ typedef struct }enc_trace_t; /*****************************************************************************/ -/* Extern variable declarations */ +/* Global variable declarations */ /*****************************************************************************/ extern enc_trace_t g_enc_trace; @@ -83,13 +83,13 @@ extern enc_trace_t g_enc_trace; ****************************************************************************** */ -#define ENTROPY_TRACE(syntax_string, value) \ - { \ - if(g_enc_trace.fp) \ - { \ - fprintf( g_enc_trace.fp, "%-40s : %d\n", syntax_string, value ); \ - fflush ( g_enc_trace.fp); \ - } \ +#define ENTROPY_TRACE(syntax_string, value) \ + { \ + if(g_enc_trace.fp) \ + { \ + fprintf( g_enc_trace.fp, "%-40s : %d\n", syntax_string, value ); \ + fflush ( g_enc_trace.fp); \ + } \ } @@ -100,7 +100,7 @@ extern enc_trace_t g_enc_trace; */ #define AEV_TRACE(string, value, range) \ - if(range && g_enc_trace.fp) \ + if(range && g_enc_trace.fp) \ { \ fprintf( g_enc_trace.fp, "%-40s:%8d R:%d\n", string, value, range); \ fflush ( g_enc_trace.fp); \ @@ -117,45 +117,11 @@ extern enc_trace_t g_enc_trace; /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ +WORD32 ih264e_trace_init(const char *pu1_file_name); -/** -****************************************************************************** -* -* @brief Dummy trace init when trace is disabled in encoder -* -* @par Description -* This routine needs to be called at start of trace -* -* @param[in] pu1_file_name -* Name of file where trace outputs need to be stores (handle) -* -* @return success or failure error code -* -****************************************************************************** -*/ -extern WORD32 ih264e_trace_init - ( - const char *pu1_file_name - ); - -/** -****************************************************************************** -* -* @brief Dummy trace de-init function when trace is disabled -* -* @par Description -* This routine needs to be called at end of trace -* -* @return success or failure error code -* -****************************************************************************** -*/ -extern WORD32 ih264e_trace_deinit - ( - void - ); +WORD32 ih264e_trace_deinit(void); -#endif // IH264E_TRACE_H_ +#endif /* _IH264E_TRACE_H_ */ diff --git a/encoder/ih264e_utils.c b/encoder/ih264e_utils.c index cb5eb25..bf59781 100644 --- a/encoder/ih264e_utils.c +++ b/encoder/ih264e_utils.c @@ -30,20 +30,21 @@ * ittiam * * @par List of Functions: -* - ih264e_get_min_level() -* - ih264e_get_lvl_idx() -* - ih264e_get_dpb_size() -* - ih264e_get_total_pic_buf_size() -* - ih264e_get_pic_mv_bank_size() -* - ih264e_pic_buf_mgr_add_bufs() -* - ih264e_mv_buf_mgr_add_bufs() -* - ih264e_init_quant_params() -* - ih264e_init_air_map() -* - ih264e_codec_init() -* - ih264e_pic_init() +* - ih264e_input_queue_update +* - ih264e_get_min_level +* - ih264e_get_lvl_idx +* - ih264e_get_dpb_size +* - ih264e_get_total_pic_buf_size +* - ih264e_get_pic_mv_bank_size +* - ih264e_pic_buf_mgr_add_bufs +* - ih264e_mv_buf_mgr_add_bufs +* - ih264e_init_quant_params +* - ih264e_init_air_map +* - ih264e_codec_init +* - ih264e_pic_init * * @remarks -* None +* none * ******************************************************************************* */ @@ -52,139 +53,147 @@ /* File Includes */ /*****************************************************************************/ -/* system include files */ +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <string.h> #include <assert.h> -/* user include files */ +/* User Include Files */ +#include "ih264e_config.h" #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264e.h" #include "ithread.h" -#include "ih264_defs.h" -#include "ih264_size_defs.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" -#include "psnr.h" + +#include "ih264_debug.h" +#include "ih264_macros.h" #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" +#include "ih264_size_defs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" -#include "ih264_cabac_tables.h" -#include "ih264_macros.h" #include "ih264_common_tables.h" -#include "ih264_debug.h" #include "ih264_trans_data.h" -#include "ih264e_defs.h" -#include "ih264e_globals.h" +#include "ih264_cavlc_tables.h" +#include "ih264_cabac_tables.h" #include "ih264_buf_mgr.h" +#include "ih264_list.h" #include "ih264_dpb_mgr.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" +#include "ime.h" +#include "ime_statistics.h" + +#include "irc_mem_req_and_acq.h" #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" +#include "irc_rate_control_api.h" + +#include "psnr.h" + +#include "ih264e.h" +#include "ih264e_error.h" +#include "ih264e_version.h" +#include "ih264e_defs.h" +#include "ih264e_globals.h" +#include "ih264e_time_stamp.h" +#include "ih264e_modify_frm_rate.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_cabac.h" -#include "ih264e_utils.h" -#include "ih264e_config.h" -#include "ih264e_statistics.h" -#include "ih264e_trace.h" -#include "ih264_list.h" -#include "ih264e_encode_header.h" #include "ih264e_me.h" -#include "ime.h" +#include "ih264e_utils.h" #include "ih264e_core_coding.h" -#include "ih264e_rc_mem_interface.h" -#include "ih264e_time_stamp.h" -#include "ih264e_debug.h" -#include "ih264e_process.h" +#include "ih264e_encode_header.h" +#include "ih264e_cavlc.h" +#include "ih264e_cabac.h" #include "ih264e_master.h" -#include "irc_rate_control_api.h" -#include "ime_statistics.h" +#include "ih264e_process.h" +#include "ih264e_fmt_conv.h" +#include "ih264e_statistics.h" +#include "ih264e_trace.h" + /*****************************************************************************/ /* Function Definitions */ /*****************************************************************************/ /** - ******************************************************************************* - * - * @brief - * Queues the current buffer, gets back a another buffer for encoding with corrent - * picture type - * - * @par Description: - * This function performs 3 distinct but related functions. - * 1) Maintains an input queue [Note the the term queue donot imply a - * first-in first-out logic here] that queues input and dequeues them so - * that input frames can be encoded at any predetermined encoding order - * 2) Uses RC library to decide which frame must be encoded in current pass - * and which picture type it must be encoded to. - * 3) Uses RC library to decide the QP at which current frame has to be - * encoded - * 4) Determines if the current picture must be encoded or not based on - * PRE-ENC skip - * - * Input queue is used for storing input buffers till they are used for - * encoding. This queue is maintained at ps_codec->as_inp_list. Whenever a - * valid input comes, it is added to the end of queue. This same input is - * added to RC queue using the identifier as ps_codec->i4_pic_cnt. Hence any - * pic from RC can be located in the input queue easily. - * - * The dequeue operation does not start till we have ps_codec->s_cfg.u4_max_num_bframes - * frames in the queue. THis is done in order to ensure that once output starts - * we will have a constant stream of output with no gaps. - * - * THe output frame order is governed by RC library. When ever we dequeue a - * buffer from RC library, it ensures that we will get them in encoding order - * With the output of RC library, we can use the picture id to dequeue the - * corresponding buffer from input queue and encode it. - * - * Condition at the end of stream. - * ------------------------------- - * At the last valid buffer from the app, we will get ps_ive_ip->u4_is_last - * to be set. This will the given to lib when appropriate input buffer is - * given to encoding. - * - * Since we have to output is not in sync with input, we will have frames to - * encode even after we recive the last vaild input buffer. Hence we have to - * make sure that we donot queue any new buffers once we get the flag [It may - * mess up GOP ?]. This is acheived by setting ps_codec->i4_last_inp_buff_received - * to act as a permenent marker for last frame recived [This may not be needed, - * because in our current app, all buffers after the last are marked as last. - * But can we rely on that?] . Hence after this flgag is set no new buffers are - * queued. - * - * @param[in] ps_codec - * Pointer to codec descriptor - * - * @param[in] ps_ive_ip - * Current input buffer to the encoder - * - * @param[out] ps_inp - * Buffer to be encoded in the current pass - * - * @returns - * Flag indicating if we have a pre-enc skip or not - * - * @remarks - * TODO (bpic) - * The check for null ans is last is redudent. - * Need to see if we can remove it - * - ******************************************************************************* - */ +******************************************************************************* +* +* @brief +* Queues the current buffer, gets back a another buffer for encoding with +* current picture type +* +* @par Description: +* This function performs 3 distinct but related functions. +* 1) Maintains an input queue [Note the the term queue do not imply a first-in +* first-out logic here] that queues input and dequeues them so that input +* frames can be encoded at any predetermined encoding order +* 2) Uses RC library to decide which frame must be encoded in current pass +* and which picture type it must be encoded to. +* 3) Uses RC library to decide the QP at which current frame has to be encoded +* 4) Determines if the current picture must be encoded or not based on PRE-ENC +* skip +* +* Input queue is used for storing input buffers till they are used for +* encoding. This queue is maintained at ps_codec->as_inp_list. Whenever a +* valid input comes, it is added to the end of queue. This same input is +* added to RC queue using the identifier as ps_codec->i4_pic_cnt. Hence any +* pic from RC can be located in the input queue easily. +* +* The dequeue operation does not start till we have ps_codec->s_cfg.u4_max_num_bframes +* frames in the queue. This is done in order to ensure that once output +* starts we will have a constant stream of output with no gaps. +* +* The output frame order is governed by RC library. When ever we dequeue a +* buffer from RC library, it ensures that we will get them in encoding order +* With the output of RC library, we can use the picture id to dequeue the +* corresponding buffer from input queue and encode it. +* +* Condition at the end of stream: +* ------------------------------- +* At the last valid buffer from the app, we will get ps_ive_ip->u4_is_last +* to be set. This will the given to lib when appropriate input buffer is +* given to encoding. +* +* Since we have to output is not in sync with input, we will have frames to +* encode even after we receive the last valid input buffer. Hence we have to +* make sure that we do not queue any new buffers once we get the flag [It may +* mess up GOP ?]. This is achieved by setting ps_codec->i4_last_inp_buff_received +* to act as a permanent marker for last frame received [This may not be needed, +* because in our current app, all buffers after the last are marked as last. +* But can we rely on that?] . Hence after this flag is set no new buffers are +* queued. +* +* @param[in] ps_codec +* Pointer to codec descriptor +* +* @param[in] ps_ive_ip +* Current input buffer to the encoder +* +* @param[out] ps_inp +* Buffer to be encoded in the current pass +* +* @returns +* Flag indicating if we have a pre-enc skip or not +* +* @remarks +* TODO (bpic) : The check for null and is last is redundant. Need to see if we +* can remove it +* +******************************************************************************* +*/ WORD32 ih264e_input_queue_update(codec_t *ps_codec, ive_video_encode_ip_t *ps_ive_ip, inp_buf_t *ps_enc_buff) @@ -208,6 +217,7 @@ WORD32 ih264e_input_queue_update(codec_t *ps_codec, { ps_enc_buff->s_raw_buf.apv_bufs[0] = NULL; ps_enc_buff->u4_is_last = ps_ive_ip->u4_is_last; + ps_codec->i4_pic_cnt -= 1; return 0; } @@ -228,12 +238,13 @@ WORD32 ih264e_input_queue_update(codec_t *ps_codec, if (skip_src) { ps_enc_buff->u4_is_last = ps_ive_ip->u4_is_last; + ps_codec->i4_pic_cnt -= 1; return 1; } } /*************************************************************************** - *Queue the input to the queue + * Queue the input to the queue **************************************************************************/ ps_inp_buf = &(ps_codec->as_inp_list[ps_codec->i4_pic_cnt % MAX_NUM_INP_FRAMES]); @@ -288,8 +299,7 @@ WORD32 ih264e_input_queue_update(codec_t *ps_codec, /* Delay */ - if (ps_codec->i4_encode_api_call_cnt - < (WORD32)(ps_codec->s_cfg.u4_num_bframes)) + if (ps_codec->i4_pic_cnt < (WORD32)(ps_codec->s_cfg.u4_num_bframes)) { ps_enc_buff->s_raw_buf.apv_bufs[0] = NULL; ps_enc_buff->u4_is_last = 0; @@ -344,7 +354,6 @@ WORD32 ih264e_input_queue_update(codec_t *ps_codec, /*************************************************************************** * Now retrieve the correct picture from the queue **************************************************************************/ - /* Mark the skip flag */ i4_skip = 0; ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS; @@ -486,6 +495,7 @@ WORD32 ih264e_get_min_level(WORD32 wd, WORD32 ht) WORD32 lvl_idx = MAX_LEVEL, i; WORD32 pic_size = wd * ht; WORD32 max = MAX(wd, ht); + for (i = 0; i < MAX_LEVEL; i++) { if ((pic_size <= gai4_ih264_max_luma_pic_size[i]) && @@ -495,7 +505,6 @@ WORD32 ih264e_get_min_level(WORD32 wd, WORD32 ht) break; } } - return gai4_ih264_levels[lvl_idx]; } @@ -663,7 +672,6 @@ WORD32 ih264e_get_dpb_size(WORD32 level, WORD32 pic_size) * * @remarks * -* ******************************************************************************* */ WORD32 ih264e_get_total_pic_buf_size(WORD32 pic_size, @@ -1092,8 +1100,8 @@ void ih264e_init_quant_params(process_ctxt_t *ps_proc, int qp) * Initialize AIR mb frame Map * * @par Description: -* Initialize AIR mb frame map -* MB frame map indicates which frame an Mb should be coded as intra according to AIR +* Initialize AIR mb frame map. MB frame map indicates which MB in a frame +* should be coded as intra according to AIR * * @param[in] ps_codec * Pointer to codec context @@ -1102,7 +1110,6 @@ void ih264e_init_quant_params(process_ctxt_t *ps_proc, int qp) * * @remarks * -* ******************************************************************************* */ IH264E_ERROR_T ih264e_init_air_map(codec_t *ps_codec) @@ -1152,125 +1159,148 @@ IH264E_ERROR_T ih264e_init_air_map(codec_t *ps_codec) /** ******************************************************************************* * -* @brief -* Codec level initializations +* @brief Speed preset side effects * * @par Description: -* Initializes the codec with parameters that needs to be set before encoding -* first frame +* Force apply the configuration options basing on the configured speed preset * * @param[in] ps_codec * Pointer to codec context * -* @param[in] ps_inp_buf -* Pointer to input buffer context -* -* @returns error_status +* @returns none * * @remarks * -* ******************************************************************************* */ -IH264E_ERROR_T ih264e_codec_init(codec_t *ps_codec) +void ih264e_speed_preset_side_effects(codec_t *ps_codec) { - /******************************************************************** - * INITIALIZE CODEC CONTEXT * - ********************************************************************/ - /* encoder presets */ - if (ps_codec->s_cfg.u4_enc_speed_preset != IVE_CONFIG) - { - if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST) - {/* high quality */ - /* enable diamond search */ - ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH; - ps_codec->s_cfg.u4_enable_fast_sad = 0; + cfg_params_t *ps_cfg = &ps_codec->s_cfg; - /* disable intra 4x4 */ - ps_codec->s_cfg.u4_enable_intra_4x4 = 1; - ps_codec->luma_energy_compaction[1] = - ih264e_code_luma_intra_macroblock_4x4_rdopt_on; + if (ps_cfg->u4_enc_speed_preset == IVE_SLOWEST) + {/* high quality */ + /* enable diamond search */ + ps_cfg->u4_me_speed_preset = DMND_SRCH; + ps_cfg->u4_enable_fast_sad = 0; - /* sub pel off */ - ps_codec->s_cfg.u4_enable_hpel = 1; + /* disable intra 4x4 */ + ps_cfg->u4_enable_intra_4x4 = 1; + ps_codec->luma_energy_compaction[1] = + ih264e_code_luma_intra_macroblock_4x4_rdopt_on; - /* deblocking off */ - ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; + /* sub pel off */ + ps_cfg->u4_enable_hpel = 1; - /* disabled intra inter gating in Inter slices */ - ps_codec->u4_inter_gate = 0; - } - else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_NORMAL) - {/* normal */ - /* enable diamond search */ - ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH; - ps_codec->s_cfg.u4_enable_fast_sad = 0; + /* deblocking off */ + ps_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; - /* disable intra 4x4 */ - ps_codec->s_cfg.u4_enable_intra_4x4 = 1; + /* disabled intra inter gating in Inter slices */ + ps_codec->u4_inter_gate = 0; + } + else if (ps_cfg->u4_enc_speed_preset == IVE_NORMAL) + {/* normal */ + /* enable diamond search */ + ps_cfg->u4_me_speed_preset = DMND_SRCH; + ps_cfg->u4_enable_fast_sad = 0; - /* sub pel off */ - ps_codec->s_cfg.u4_enable_hpel = 1; + /* disable intra 4x4 */ + ps_cfg->u4_enable_intra_4x4 = 1; - /* deblocking off */ - ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; + /* sub pel off */ + ps_cfg->u4_enable_hpel = 1; - /* disabled intra inter gating in Inter slices */ - ps_codec->u4_inter_gate = 0; - } - else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FAST) - {/* normal */ - /* enable diamond search */ - ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH; - ps_codec->s_cfg.u4_enable_fast_sad = 0; + /* deblocking off */ + ps_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; - /* disable intra 4x4 */ - ps_codec->s_cfg.u4_enable_intra_4x4 = 0; + /* disabled intra inter gating in Inter slices */ + ps_codec->u4_inter_gate = 0; + } + else if (ps_cfg->u4_enc_speed_preset == IVE_FAST) + {/* fast */ + /* enable diamond search */ + ps_cfg->u4_me_speed_preset = DMND_SRCH; + ps_cfg->u4_enable_fast_sad = 0; - /* sub pel off */ - ps_codec->s_cfg.u4_enable_hpel = 1; + /* disable intra 4x4 */ + ps_cfg->u4_enable_intra_4x4 = 0; - /* deblocking off */ - ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; + /* sub pel off */ + ps_cfg->u4_enable_hpel = 1; - /* disabled intra inter gating in Inter slices */ - ps_codec->u4_inter_gate = 1; - } - else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_HIGH_SPEED) - {/* fast */ - /* enable diamond search */ - ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH; - ps_codec->s_cfg.u4_enable_fast_sad = 0; + /* deblocking off */ + ps_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; - /* disable intra 4x4 */ - ps_codec->s_cfg.u4_enable_intra_4x4 = 0; + /* disabled intra inter gating in Inter slices */ + ps_codec->u4_inter_gate = 1; + } + else if (ps_cfg->u4_enc_speed_preset == IVE_HIGH_SPEED) + {/* high speed */ + /* enable diamond search */ + ps_cfg->u4_me_speed_preset = DMND_SRCH; + ps_cfg->u4_enable_fast_sad = 0; - /* sub pel off */ - ps_codec->s_cfg.u4_enable_hpel = 0; + /* disable intra 4x4 */ + ps_cfg->u4_enable_intra_4x4 = 0; - /* deblocking off */ - ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4; + /* sub pel off */ + ps_cfg->u4_enable_hpel = 0; - /* disabled intra inter gating in Inter slices */ - ps_codec->u4_inter_gate = 0; - } - else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST) - {/* fastest */ - /* enable diamond search */ - ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH; + /* deblocking off */ + ps_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4; - /* disable intra 4x4 */ - ps_codec->s_cfg.u4_enable_intra_4x4 = 0; + /* disabled intra inter gating in Inter slices */ + ps_codec->u4_inter_gate = 0; + } + else if (ps_cfg->u4_enc_speed_preset == IVE_FASTEST) + {/* fastest */ + /* enable diamond search */ + ps_cfg->u4_me_speed_preset = DMND_SRCH; - /* sub pel off */ - ps_codec->s_cfg.u4_enable_hpel = 0; + /* disable intra 4x4 */ + ps_cfg->u4_enable_intra_4x4 = 0; - /* deblocking off */ - ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4; + /* sub pel off */ + ps_cfg->u4_enable_hpel = 0; - /* disabled intra inter gating in Inter slices */ - ps_codec->u4_inter_gate = 1; - } + /* deblocking off */ + ps_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4; + + /* disabled intra inter gating in Inter slices */ + ps_codec->u4_inter_gate = 1; + } +} + +/** +******************************************************************************* +* +* @brief +* Codec level initializations +* +* @par Description: +* Initializes the codec with parameters that needs to be set before encoding +* first frame +* +* @param[in] ps_codec +* Pointer to codec context +* +* @param[in] ps_inp_buf +* Pointer to input buffer context +* +* @returns error_status +* +* @remarks +* +******************************************************************************* +*/ +IH264E_ERROR_T ih264e_codec_init(codec_t *ps_codec) +{ + /******************************************************************** + * INITIALIZE CODEC CONTEXT * + ********************************************************************/ + /* encoder presets */ + if (ps_codec->s_cfg.u4_enc_speed_preset != IVE_CONFIG) + { + ih264e_speed_preset_side_effects(ps_codec); } /***************************************************************** @@ -1283,6 +1313,12 @@ IH264E_ERROR_T ih264e_codec_init(codec_t *ps_codec) ps_codec->i4_air_pic_cnt = -1; } + /*****************************************************************/ + /* Initialize Intra Cost Map */ + /*****************************************************************/ + memset(ps_codec->pi4_mb_intra_cost, 0, ps_codec->s_cfg.i4_wd_mbs * + ps_codec->s_cfg.i4_ht_mbs * sizeof(*ps_codec->pi4_mb_intra_cost)); + /****************************************************/ /* INITIALIZE RATE CONTROL */ /****************************************************/ @@ -1362,7 +1398,6 @@ IH264E_ERROR_T ih264e_codec_init(codec_t *ps_codec) DEBUG_HISTOGRAM_INIT(); - /* Init dependecy vars */ ps_codec->i4_last_inp_buff_received = 0; @@ -1397,7 +1432,6 @@ IH264E_ERROR_T ih264e_codec_init(codec_t *ps_codec) * * @remarks * -* ******************************************************************************* */ IH264E_ERROR_T ih264e_pic_init(codec_t *ps_codec, inp_buf_t *ps_inp_buf) @@ -1489,6 +1523,7 @@ IH264E_ERROR_T ih264e_pic_init(codec_t *ps_codec, inp_buf_t *ps_inp_buf) /* set idr flag */ ps_codec->u4_is_idr = 1; + ps_codec->i4_restore_frame_num = ps_codec->i4_frame_num; /* reset frame num */ ps_codec->i4_frame_num = 0; @@ -1589,9 +1624,8 @@ IH264E_ERROR_T ih264e_pic_init(codec_t *ps_codec, inp_buf_t *ps_inp_buf) * note that i4_pic_cnt == -1 is used to filter uninit ref pics. * Now since we only have max two ref pics, we will always find max 2 * ref pics. - * - * 2) 3) Self explanatory + * 2), 3) Self explanatory ***************************************************************************/ { /* Search for buffs with maximum pic cnt */ @@ -2274,3 +2308,4 @@ void ih264e_compute_quality_stats(process_ctxt_t *ps_proc) ps_codec->s_global_quality_stats.total_frames; } } + diff --git a/encoder/ih264e_utils.h b/encoder/ih264e_utils.h index 27e37e8..4c24c8d 100644 --- a/encoder/ih264e_utils.h +++ b/encoder/ih264e_utils.h @@ -29,332 +29,48 @@ * @author * Harish * -* @par List of Functions: -* -ih264e_input_queue_update() -* -ih264e_get_min_level() -* -ih264e_get_lvl_idx() -* -ih264e_get_dpb_size() -* -ih264e_get_total_pic_buf_size() -* -ih264e_get_pic_mv_bank_size() -* -ih264e_pic_buf_mgr_add_bufs() -* -ih264e_mv_buf_mgr_add_bufs() -* -ih264e_init_quant_params() -* -ih264e_init_air_map() -* -ih264e_codec_init() -* -ih264e_pic_init() -* * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_UTILS_H_ -#define IH264E_UTILS_H_ +#ifndef _IH264E_UTILS_H_ +#define _IH264E_UTILS_H_ + +/*****************************************************************************/ +/* Function Declarations */ +/*****************************************************************************/ -/** - ******************************************************************************* - * - * @brief - * Queues the current buffer, gets back a another buffer for encoding with corrent - * picture type - * - * @par Description: - * - * @param[in] ps_codec - * Pointer to codec descriptor - * - * @param[in] ps_ive_ip - * Current input buffer to the encoder - * - * @param[out] ps_inp - * Buffer to be encoded in the current pass - * - * @returns - * Flag indicating if we have a pre-enc skip or not - * - * @remarks - * - ******************************************************************************* - */ WORD32 ih264e_input_queue_update(codec_t *ps_codec, ive_video_encode_ip_t *ps_ive_ip, inp_buf_t *ps_enc_buff); -/** -******************************************************************************* -* -* @brief -* Used to get minimum level index for a given picture size -* -* @par Description: -* Gets the minimum level index and then gets corresponding level. -* Also used to ignore invalid levels like 2.3, 3.3 etc -* -* @param[in] wd -* Width -* -* @param[in] ht -* Height -* -* @returns Level index for a given level -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_get_min_level(WORD32 wd, WORD32 ht); -/** -******************************************************************************* -* -* @brief -* Used to get level index for a given level -* -* @par Description: -* Converts from level_idc (which is multiplied by 30) to an index that can be -* used as a lookup. Also used to ignore invalid levels like 2.2 , 3.2 etc -* -* @param[in] level -* Level of the stream -* -* @returns Level index for a given level -* -* @remarks -* -******************************************************************************* -*/ WORD32 ih264e_get_lvl_idx(WORD32 level); -/** -******************************************************************************* -* -* @brief returns maximum number of pictures allowed in dpb for a given level -* -* @par Description: -* For given width, height and level, number of pictures allowed in decoder -* picture buffer is computed as per Annex A.3.1 -* -* @param[in] level -* level of the bit-stream -* -* @param[in] pic_size -* width * height -* -* @returns Number of buffers in DPB -* -* @remarks -* From annexure A.3.1 of H264 specification, -* max_dec_frame_buffering <= MaxDpbSize, where MaxDpbSize is equal to -* Min( 1024 * MaxDPB / ( PicWidthInMbs * FrameHeightInMbs * 384 ), 16 ) and -* MaxDPB is given in Table A-1 in units of 1024 bytes. However the MaxDPB size -* presented in the look up table gas_ih264_lvl_tbl is in units of 512 -* bytes. Hence the expression is modified accordingly. -* -******************************************************************************* -*/ WORD32 ih264e_get_dpb_size(WORD32 level, WORD32 pic_size); -/** -******************************************************************************* -* -* @brief -* Used to get reference picture buffer size for a given level and -* and padding used -* -* @par Description: -* Used to get reference picture buffer size for a given level and padding used -* Each picture is padded on all four sides -* -* @param[in] pic_size -* Number of luma samples (Width * Height) -* -* @param[in] level -* Level -* -* @param[in] horz_pad -* Total padding used in horizontal direction -* -* @param[in] vert_pad -* Total padding used in vertical direction -* -* @returns Total picture buffer size -* -* @remarks -* -* -******************************************************************************* -*/ WORD32 ih264e_get_total_pic_buf_size(WORD32 pic_size, WORD32 level, WORD32 horz_pad, WORD32 vert_pad, WORD32 num_ref_frames, WORD32 num_reorder_frames); -/** -******************************************************************************* -* -* @brief Returns MV bank buffer size for a given number of luma samples -* -* @par Description: -* For given number of luma samples one MV bank size is computed. -* Each MV bank includes pu_map and enc_pu_t for all the min PUs(4x4) in a picture -* -* @param[in] num_luma_samples -* Max number of luma pixels in the frame -* -* @returns Total MV Bank size -* -* @remarks -* -* -******************************************************************************* -*/ WORD32 ih264e_get_pic_mv_bank_size(WORD32 num_luma_samples); -/** -******************************************************************************* -* -* @brief -* Function to initialize ps_pic_buf structs add pic buffers to -* buffer manager in case of non-shared mode -* -* @par Description: -* Function to initialize ps_pic_buf structs add pic buffers to -* buffer manager in case of non-shared mode -* To be called once per stream or for every reset -* -* @param[in] ps_codec -* Pointer to codec context -* -* @returns error status -* -* @remarks -* -* -******************************************************************************* -*/ IH264E_ERROR_T ih264e_pic_buf_mgr_add_bufs(codec_t *ps_codec); -/** -******************************************************************************* -* -* @brief Function to add buffers to MV Bank buffer manager -* -* @par Description: -* Function to add buffers to MV Bank buffer manager. To be called once per -* stream or for every reset -* -* @param[in] ps_codec -* Pointer to codec context -* -* @returns error status -* -* @remarks -* -******************************************************************************* -*/ IH264E_ERROR_T ih264e_mv_buf_mgr_add_bufs(codec_t *ps_codec); -/** -******************************************************************************* -* -* @brief Function to initialize quant params structure -* -* @par Description: -* The forward quantization modules depends on qp/6, qp mod 6, forward scale -* matrix, forward threshold matrix, weight list. The inverse quantization -* modules depends on qp/6, qp mod 6, inverse scale matrix, weight list. -* These params are initialized in this function. -* -* @param[in] ps_proc -* pointer to process context -* -* @param[in] qp -* quantization parameter -* -* @returns none -* -* @remarks -* -******************************************************************************* -*/ void ih264e_init_quant_params(process_ctxt_t *ps_proc, int qp); -/** -******************************************************************************* -* -* @brief -* Initialize AIR mb frame Map -* -* @par Description: -* Initialize AIR mb frame map -* MB frame map indicates which frame an Mb should be coded as intra according to AIR -* -* @param[in] ps_codec -* Pointer to codec context -* -* @returns error_status -* -* @remarks -* -* -******************************************************************************* -*/ IH264E_ERROR_T ih264e_init_air_map(codec_t *ps_codec); -/** -******************************************************************************* -* -* @brief -* Codec level initializations -* -* @par Description: -* Initializes the codec with parameters that needs to be set before encoding -* first frame -* -* @param[in] ps_codec -* Pointer to codec context -* -* @param[in] ps_inp_buf -* Pointer to input buffer context -* -* @returns error_status -* -* @remarks -* -* -******************************************************************************* -*/ +void ih264e_speed_preset_side_effects(codec_t *ps_codec); + IH264E_ERROR_T ih264e_codec_init(codec_t *ps_codec); -/** -******************************************************************************* -* -* @brief -* Picture level initializations -* -* @par Description: -* Before beginning to encode the frame, the current function initializes all -* the ctxts (proc, entropy, me, ...) basing on the input configured params. -* It locates space for storing recon in the encoder picture buffer set, fetches -* reference frame from encoder picture buffer set. Calls RC pre-enc to get -* qp and pic type for the current frame. Queues proc jobs so that -* the other threads can begin encoding. In brief, this function sets up the -* tone for the entire encoder. -* -* @param[in] ps_codec -* Pointer to codec context -* -* @param[in] ps_inp_buf -* Pointer to input buffer context -* -* @returns error_status -* -* @remarks -* -* -******************************************************************************* -*/ IH264E_ERROR_T ih264e_pic_init(codec_t *ps_codec, inp_buf_t *ps_inp_buf); -#endif /* IH264E_UTILS_H_ */ +#endif /* _IH264E_UTILS_H_ */ diff --git a/encoder/ih264e_version.c b/encoder/ih264e_version.c index a8b0db0..b4889f5 100644 --- a/encoder/ih264e_version.c +++ b/encoder/ih264e_version.c @@ -24,16 +24,16 @@ * ih264e_version.c * * @brief -* Contains version info for H264 encoder +* Contains version info of h264 encoder * * @author * ittiam * * @par List of Functions: -* - ih264e_get_version() +* - ih264e_get_version * * @remarks -* None +* none * ******************************************************************************* */ @@ -41,20 +41,16 @@ /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ -/* system include files */ + +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <string.h> -/* user include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "iv2.h" -#include "ive2.h" -#include "ih264e.h" -#include "ih264_defs.h" -#include "ih264_debug.h" -#include "ih264_structs.h" #include "ih264e_version.h" @@ -73,7 +69,7 @@ /** * Version string. First two digits signify major version and last two minor */ -#define CODEC_RELEASE_VER "01.00" +#define CODEC_RELEASE_VER "01.02" /** * Vendor name */ diff --git a/encoder/ih264e_version.h b/encoder/ih264e_version.h index 303a1e2..18176e4 100644 --- a/encoder/ih264e_version.h +++ b/encoder/ih264e_version.h @@ -30,35 +30,19 @@ * ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264E_VERSION_H_ -#define IH264E_VERSION_H_ +#ifndef _IH264E_VERSION_H_ +#define _IH264E_VERSION_H_ + + +/*****************************************************************************/ +/* Function Declarations */ +/*****************************************************************************/ -/** -******************************************************************************* -* -* @brief -* Fills the version info in the given char pointer -* -* @par Description: -* Fills the version info in the given char pointer -* -* @param[in] pc_version -* Pointer to hold version info -* -* @param[in] u4_version_bufsize -* Size of the buffer passed -* -* @returns error status -* -* @remarks none -* -******************************************************************************* -*/ IV_STATUS_T ih264e_get_version(CHAR *pc_version, UWORD32 u4_version_bufsize); -#endif /* IH264E_VERSION_H_ */ +#endif /* _IH264E_VERSION_H_ */ diff --git a/encoder/ime.c b/encoder/ime.c index cfd6e81..06a743f 100644 --- a/encoder/ime.c +++ b/encoder/ime.c @@ -20,16 +20,21 @@ /** ******************************************************************************* * @file - * ih264e_me.c + * ime.c * * @brief - * + * This file contains functions needed for computing motion vectors of a + * 16x16 block * * @author * Ittiam * * @par List of Functions: - * - + * - ime_diamond_search_16x16 + * - ime_evaluate_init_srchposn_16x16 + * - ime_full_pel_motion_estimation_16x16 + * - ime_sub_pel_motion_estimation_16x16 + * - ime_compute_skip_cost * * @remarks * None @@ -69,17 +74,11 @@ * point of the diamond grid, the function marks the candidate Mb partition as * mv. * -* @param[in] ps_mb_part -* pointer to current mb partition ctxt with respect to ME -* * @param[in] ps_me_ctxt * pointer to me context * -* @param[in] u4_lambda_motion -* lambda motion -* -* @param[in] u4_enable_fast_sad -* enable/disable fast sad computation +* @param[in] i4_reflist +* ref list * * @returns mv pair & corresponding distortion and cost * @@ -150,7 +149,7 @@ void ime_diamond_search_16x16(me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist) i2_mv_u_x = i2_mvx; i2_mv_u_y = i2_mvy; - while (u4_num_layers--) + while (u4_num_layers) { /* FIXME : is this the write way to check for out of bounds ? */ if ( (i2_mvx - 1 < i4_srch_range_w) || @@ -175,14 +174,14 @@ void ime_diamond_search_16x16(me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist) DEBUG_SAD_HISTOGRAM_ADD(i4_sad[3], 2); /* compute cost */ - i4_cost[0] = i4_sad[0] + u4_lambda_motion * ( pu1_mv_bits[ ((i2_mvx - 1) << 2) - ps_mb_part->s_mv_pred.i2_mvx] - + pu1_mv_bits[(i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy] ); - i4_cost[1] = i4_sad[1] + u4_lambda_motion * ( pu1_mv_bits[ ((i2_mvx + 1) << 2) - ps_mb_part->s_mv_pred.i2_mvx] - + pu1_mv_bits[(i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy] ); - i4_cost[2] = i4_sad[2] + u4_lambda_motion * ( pu1_mv_bits[ (i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] - + pu1_mv_bits[((i2_mvy - 1) << 2) - ps_mb_part->s_mv_pred.i2_mvy] ); - i4_cost[3] = i4_sad[3] + u4_lambda_motion * ( pu1_mv_bits[ (i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] - + pu1_mv_bits[((i2_mvy + 1) << 2) - ps_mb_part->s_mv_pred.i2_mvy] ); + i4_cost[0] = i4_sad[0] + (WORD32)(u4_lambda_motion * ( pu1_mv_bits[ ((i2_mvx - 1) << 2) - ps_mb_part->s_mv_pred.i2_mvx] + + pu1_mv_bits[(i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy] )); + i4_cost[1] = i4_sad[1] + (WORD32)(u4_lambda_motion * ( pu1_mv_bits[ ((i2_mvx + 1) << 2) - ps_mb_part->s_mv_pred.i2_mvx] + + pu1_mv_bits[(i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy] )); + i4_cost[2] = i4_sad[2] + (WORD32)(u4_lambda_motion * ( pu1_mv_bits[ (i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] + + pu1_mv_bits[((i2_mvy - 1) << 2) - ps_mb_part->s_mv_pred.i2_mvy] )); + i4_cost[3] = i4_sad[3] + (WORD32)(u4_lambda_motion * ( pu1_mv_bits[ (i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] + + pu1_mv_bits[((i2_mvy + 1) << 2) - ps_mb_part->s_mv_pred.i2_mvy] )); if (i4_cost_least > i4_cost[0]) @@ -231,8 +230,7 @@ void ime_diamond_search_16x16(me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist) i2_mvx = i2_mv_u_x; i2_mvy = i2_mv_u_y; } - - + u4_num_layers--; } if (i4_cost_least < ps_mb_part->i4_mb_cost) @@ -256,14 +254,11 @@ void ime_diamond_search_16x16(me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist) * This function determines the position in the search window at which the motion * estimation should begin in order to minimise the number of search iterations. * -* @param[in] ps_mb_part -* pointer to current mb partition ctxt with respect to ME -* -* @param[in] u4_lambda_motion -* lambda motion +* @param[in] ps_me_ctxt +* pointer to me context * -* @param[in] u4_fast_flag -* enable/disable fast sad computation +* @param[in] i4_reflist +* ref list * * @returns mv pair & corresponding distortion and cost * @@ -339,9 +334,10 @@ void ime_evaluate_init_srchposn_16x16 ps_me_ctxt->pf_ime_compute_sad_16x16[u4_enable_fast_sad](pu1_curr_mb, pu1_ref, i4_src_strd, i4_ref_strd, i4_mb_cost_least, &i4_mb_distortion); DEBUG_SAD_HISTOGRAM_ADD(i4_mb_distortion, 3); + /* compute cost */ - i4_mb_cost = i4_mb_distortion + u4_lambda_motion * ( pu1_mv_bits[ (ps_mv_list[i].i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] - + pu1_mv_bits[(ps_mv_list[i].i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy] ); + i4_mb_cost = i4_mb_distortion + (WORD32)(u4_lambda_motion * ( pu1_mv_bits[ (ps_mv_list[i].i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] + + pu1_mv_bits[(ps_mv_list[i].i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy] )); if (i4_mb_cost < i4_mb_cost_least) { @@ -371,17 +367,15 @@ void ime_evaluate_init_srchposn_16x16 * range * * @par Description: -* This function begins by computing the mv predict vector for the current mb. -* This is used for cost computations. Further basing on the algo. chosen, it -* looks through a set of candidate vectors that best represent the mb a least -* cost and returns this information. -* -* @param[in] ps_proc -* pointer to current proc ctxt +* For a given algorithm (diamond, Hex, nStep, ...) chosen, it searches for the +* best matching full pixel predictor within the search range * * @param[in] ps_me_ctxt * pointer to me context * +* @param[in] i4_reflist +* ref list +* * @returns mv pair & corresponding distortion and cost * * @remarks none @@ -437,16 +431,15 @@ void ime_full_pel_motion_estimation_16x16 * @par Description: * This function begins by searching across all sub pixel sample points * around the full pel motion vector. The vector with least cost is chosen as -* the mv for the current mb. If the skip mode is not evaluated while analysing -* the initial search candidates then analyse it here and update the mv. -* -* @param[in] ps_proc -* pointer to current proc ctxt +* the mv for the current mb. * * @param[in] ps_me_ctxt * pointer to me context * -* @returns none +* @param[in] i4_reflist +* ref list +* +* @returns mv pair & corresponding distortion and cost * * @remarks none * @@ -564,8 +557,8 @@ void ime_sub_pel_motion_estimation_16x16 i4_mb_distortion = ai4_sad[i]; /* compute cost */ - i4_mb_cost = i4_mb_distortion + u4_lambda_motion * ( pu1_mv_bits[ mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] - + pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy] ); + i4_mb_cost = i4_mb_distortion + (WORD32)(u4_lambda_motion * ( pu1_mv_bits[ mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] + + pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy] )); if (i4_mb_cost < i4_mb_cost_least) { @@ -598,8 +591,8 @@ void ime_sub_pel_motion_estimation_16x16 i4_mb_distortion = ai4_sad[2 + i]; /* compute cost */ - i4_mb_cost = i4_mb_distortion + u4_lambda_motion * ( pu1_mv_bits[ mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] - + pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy] ); + i4_mb_cost = i4_mb_distortion + (WORD32)(u4_lambda_motion * ( pu1_mv_bits[ mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] + + pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy] )); if (i4_mb_cost < i4_mb_cost_least) { @@ -635,8 +628,8 @@ void ime_sub_pel_motion_estimation_16x16 i4_mb_distortion = ai4_sad[4 + i + 2 * j]; /* compute cost */ - i4_mb_cost = i4_mb_distortion + u4_lambda_motion * ( pu1_mv_bits[ mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] - + pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy] ); + i4_mb_cost = i4_mb_distortion + (WORD32)(u4_lambda_motion * ( pu1_mv_bits[ mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] + + pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy] )); if (i4_mb_cost < i4_mb_cost_least) { @@ -686,7 +679,7 @@ void ime_sub_pel_motion_estimation_16x16 * @remarks * NOTE: while computing the skip cost, do not enable early exit from compute * sad function because, a negative bias gets added later -* Note tha the last ME candidate in me ctxt is taken as skip motion vector +* Note that the last ME candidate in me ctxt is taken as skip motion vector * ******************************************************************************* */ diff --git a/encoder/ime.h b/encoder/ime.h index f035e9e..9876724 100644 --- a/encoder/ime.h +++ b/encoder/ime.h @@ -23,7 +23,7 @@ * ime.h * * @brief - * Contains declarations of global variables for H264 encoder + * Contains declarations of me functions * * @author * Ittiam @@ -33,8 +33,8 @@ ******************************************************************************* */ -#ifndef IME_H_ -#define IME_H_ +#ifndef _IME_H_ +#define _IME_H_ /*****************************************************************************/ /* Constant Macros */ @@ -51,148 +51,17 @@ /* Extern Function Declarations */ /*****************************************************************************/ - -/** -******************************************************************************* -* -* @brief Diamond Search -* -* @par Description: -* This function computes the sad at vertices of several layers of diamond grid -* at a time. The number of layers of diamond grid that would be evaluated is -* configurable.The function computes the sad at vertices of a diamond grid. If -* the sad at the center of the diamond grid is lesser than the sad at any other -* point of the diamond grid, the function marks the candidate Mb partition as -* mv. -* -* @param[in] ps_mb_part -* pointer to current mb partition ctxt with respect to ME -* -* @param[in] ps_me_ctxt -* pointer to me context -* -* @param[in] u4_lambda -* lambda motion -* -* @param[in] u4_fast_flag -* enable/disable fast sad computation -* -* @returns mv pair & corresponding distortion and cost -* -* @remarks This module cannot be part of the final product due to its lack of -* computational feasibility. This is only for quality eval purposes. -* -******************************************************************************* - */ extern void ime_diamond_search_16x16(me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist); - -/** -******************************************************************************* -* -* @brief This function computes the best motion vector among the tentative mv -* candidates chosen. -* -* @par Description: -* This function determines the position in the search window at which the motion -* estimation should begin in order to minimise the number of search iterations. -* -* @param[in] ps_mb_part -* pointer to current mb partition ctxt with respect to ME -* -* @param[in] u4_lambda_motion -* lambda motion -* -* @param[in] u4_fast_flag -* enable/disable fast sad computation -* -* @returns mv pair & corresponding distortion and cost -* -* @remarks none -* -******************************************************************************* -*/ extern void ime_evaluate_init_srchposn_16x16(me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist); -/** -******************************************************************************* -* -* @brief Searches for the best matching full pixel predictor within the search -* range -* -* @par Description: -* This function begins by computing the mv predict vector for the current mb. -* This is used for cost computations. Further basing on the algo. chosen, it -* looks through a set of candidate vectors that best represent the mb a least -* cost and returns this information. -* -* @param[in] ps_proc -* pointer to current proc ctxt -* -* @param[in] ps_me_ctxt -* pointer to me context -* -* @returns mv pair & corresponding distortion and cost -* -* @remarks none -* -******************************************************************************* -*/ extern void ime_full_pel_motion_estimation_16x16(me_ctxt_t *ps_me_ctxt, WORD32 i4_ref_list); -/** -******************************************************************************* -* -* @brief Searches for the best matching sub pixel predictor within the search -* range -* -* @par Description: -* This function begins by searching across all sub pixel sample points -* around the full pel motion vector. The vector with least cost is chosen as -* the mv for the current mb. If the skip mode is not evaluated while analysing -* the initial search candidates then analyse it here and update the mv. -* -* @param[in] ps_proc -* pointer to current proc ctxt -* -* @param[in] ps_me_ctxt -* pointer to me context -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ extern void ime_sub_pel_motion_estimation_16x16(me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist); -/** -******************************************************************************* -* -* @brief This function computes cost of skip macroblocks -* -* @par Description: -* -* @param[in] ps_me_ctxt -* pointer to me ctxt -* -* @param[in] ps_skip_mv -* pointer to skip mv -* - @param[in] is_slice_type_b -* Whether slice type is BSLICE or not - -* @returns none -* -* @remarks -* NOTE: while computing the skip cost, do not enable early exit from compute -* sad function because, a negative bias gets added later -* -******************************************************************************* -*/ extern void ime_compute_skip_cost(me_ctxt_t *ps_me_ctxt, ime_mv_t *ps_skip_mv, mb_part_ctxt *ps_smb_part_info, @@ -201,4 +70,4 @@ extern void ime_compute_skip_cost(me_ctxt_t *ps_me_ctxt, WORD32 is_slice_type_b); -#endif /* IME_H_ */ +#endif /* _IME_H_ */ diff --git a/encoder/ime_defs.h b/encoder/ime_defs.h index f82018d..2ade8b4 100644 --- a/encoder/ime_defs.h +++ b/encoder/ime_defs.h @@ -20,11 +20,10 @@ /** ******************************************************************************* * @file -* ihevc_typedefs.h +* ime_defs.h * * @brief -* Type definitions used in the code -* +* Constant definitions used in the code * * @remarks * None @@ -34,13 +33,14 @@ #ifndef _IME_DEFS_H_ #define _IME_DEFS_H_ - -/* Macros to Label candidates */ -#define SKIP_CAND 0 -#define ZERO_CAND 1 -#define LEFT_CAND 2 -#define TOP_CAND 3 -#define TOPR_CAND 4 +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ +#define SKIP_CAND 0 +#define ZERO_CAND 1 +#define LEFT_CAND 2 +#define TOP_CAND 3 +#define TOPR_CAND 4 #define NONE 0 #define LEFT 1 diff --git a/encoder/ime_distortion_metrics.c b/encoder/ime_distortion_metrics.c index f8c44df..467182c 100644 --- a/encoder/ime_distortion_metrics.c +++ b/encoder/ime_distortion_metrics.c @@ -20,7 +20,7 @@ /** ****************************************************************************** -* @file ih264e_distortion_metrics.c +* @file ime_distortion_metrics.c * * @brief * This file contains definitions of routines that compute distortion @@ -44,7 +44,6 @@ * - ime_compute_satqd_8x16_chroma() * - ime_compute_satqd_16x16_lumaintra() * -* * @remarks * None * @@ -541,7 +540,6 @@ void ime_compute_sad_16x16_fast(UWORD8 *pu1_src, WORD32 i4_max_sad, WORD32 *pi4_mb_distortion) { - WORD32 i4_sad = 0; UWORD32 u4_src_offset = 2 * src_strd - 16; UWORD32 u4_est_offset = 2 * est_strd - 16; @@ -607,7 +605,6 @@ void ime_compute_sad_16x16_fast(UWORD8 *pu1_src, * ****************************************************************************** */ - void ime_compute_sad_8x8(UWORD8 *pu1_src, UWORD8 *pu1_est, WORD32 src_strd, @@ -673,15 +670,12 @@ void ime_compute_sad_8x8(UWORD8 *pu1_src, * ****************************************************************************** */ -void ime_compute_sad_4x4 - ( - UWORD8 *pu1_src, - UWORD8 *pu1_est, - WORD32 src_strd, - WORD32 est_strd, - WORD32 i4_max_sad, - WORD32 *pi4_mb_distortion - ) +void ime_compute_sad_4x4(UWORD8 *pu1_src, + UWORD8 *pu1_est, + WORD32 src_strd, + WORD32 est_strd, + WORD32 i4_max_sad, + WORD32 *pi4_mb_distortion) { WORD32 i4_sad = 0; @@ -703,13 +697,11 @@ void ime_compute_sad_4x4 *pi4_mb_distortion = i4_sad; } - /** ****************************************************************************** * * @brief computes distortion (SAD) between 2 16x8 blocks * -* * @par Description * This functions computes SAD between 2 16x8 blocks. There is a provision * for early exit if the up-to computed SAD exceeds maximum allowed SAD. To @@ -737,15 +729,12 @@ void ime_compute_sad_4x4 * ****************************************************************************** */ -void ime_compute_sad_16x8 - ( - UWORD8 *pu1_src, - UWORD8 *pu1_est, - WORD32 src_strd, - WORD32 est_strd, - WORD32 i4_max_sad, - WORD32 *pi4_mb_distortion - ) +void ime_compute_sad_16x8(UWORD8 *pu1_src, + UWORD8 *pu1_est, + WORD32 src_strd, + WORD32 est_strd, + WORD32 i4_max_sad, + WORD32 *pi4_mb_distortion) { WORD32 i4_sad = 0; UWORD32 u4_src_offset = src_strd - 16; @@ -870,133 +859,125 @@ void ime_compute_sad_16x16_ea8(UWORD8 *pu1_src, return; } - /** ******************************************************************************* * -* @brief This function computes SAD between two 16x16 blocks -* It also computes if the block will be zero after H264 transform and quant for -* Intra 16x16 blocks +* @brief This function computes SAD between two 16x16 blocks. It also computes +* if the block will be zero after H264 transform and quant * * @param[in] pu1_src * UWORD8 pointer to the source * -* @param[out] pu1_dst -* UWORD8 pointer to the destination +* @param[out] pu1_est +* UWORD8 pointer to the estimated block * -* @param[in] src_strd -* integer source stride +* @param[in] i4_src_strd +* source stride * -* @param[in] dst_strd -* integer destination stride +* @param[in] i4_est_strd +* est buffer stride * * @param[in] pu2_thrsh -* Threshold for each element of transofrmed quantized block +* Threshold for each element of transformed quantized block * * @param[out] pi4_mb_distortion -* integer evaluated sad +* evaluated sad * * @param[out] pu4_is_zero -* Poitner to store if the block is zero after transform and quantization +* Pointer to store if the block is zero after transform and quantization * * @remarks * ****************************************************************************** */ void ime_compute_satqd_16x16_lumainter(UWORD8 *pu1_src, - UWORD8 *pu1_est, - WORD32 src_strd, - WORD32 est_strd, - UWORD16 *pu2_thrsh, - WORD32 *pi4_mb_distortion, - UWORD32 *pu4_is_non_zero) + UWORD8 *pu1_est, + WORD32 i4_src_strd, + WORD32 i4_est_strd, + UWORD16 *pu2_thrsh, + WORD32 *pi4_mb_distortion, + UWORD32 *pu4_is_non_zero) { - UWORD32 i,j; - WORD16 s1,s2,s3,s4,sad_1,sad_2,ls1,ls2,ls3,ls4,ls5,ls6,ls7,ls8; - UWORD8 *pu1_src_lp,*pu1_est_lp; + WORD32 i, j; + WORD16 s1, s2, s3, s4; + WORD16 sad_1, sad_2; + WORD16 ls1, ls2, ls3, ls4, ls5, ls6, ls7, ls8; + UWORD8 *pu1_src_lp, *pu1_est_lp; UWORD32 sad = 0; (*pi4_mb_distortion) = 0; - for(i=0;i<4;i++) + + for (i = 0; i < 4; i++) { - for(j=0;j<4;j++) + for (j = 0; j < 4; j++) { - pu1_src_lp = pu1_src + 4*j; - pu1_est_lp = pu1_est + 4*j; + pu1_src_lp = pu1_src + 4 * j; + pu1_est_lp = pu1_est + 4 * j; - s1 = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); - s4 = ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1])+ ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); + s1 = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); + s4 = ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1]) + ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); - pu1_src_lp += src_strd; - pu1_est_lp += est_strd; + pu1_src_lp += i4_src_strd; + pu1_est_lp += i4_est_strd; - s2 = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); - s3 = ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1])+ ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); + s2 = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); + s3 = ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1]) + ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); - pu1_src_lp += src_strd; - pu1_est_lp += est_strd; + pu1_src_lp += i4_src_strd; + pu1_est_lp += i4_est_strd; - s2 += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); - s3 += ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1])+ ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); + s2 += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); + s3 += ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1]) + ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); - pu1_src_lp += src_strd; - pu1_est_lp += est_strd; + pu1_src_lp += i4_src_strd; + pu1_est_lp += i4_est_strd; - s1 += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); - s4 += ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1])+ ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); + s1 += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); + s4 += ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1]) + ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); - sad_1 = s1+s2+s3+s4; + sad_1 = s1 + s2 + s3 + s4; - if(sad == 0) + if (sad == 0) { - sad_2 = sad_1<<1; - - ls1 = sad_2 -(s2 + s3); - ls2 = sad_2 -(s1 + s4); - ls3 = sad_2 -(s3 + s4); - ls4 = sad_2 -(s3 - (s1<<1)); - ls5 = sad_2 -(s4 - (s2<<1)); - ls6 = sad_2 -(s1 + s2); - ls7 = sad_2 -(s2 - (s4<<1)); - ls8 = sad_2 -(s1 - (s3<<1)); - - if( - pu2_thrsh[8] <= sad_1 || - pu2_thrsh[0] <= ls2 || - pu2_thrsh[1] <= ls1 || - pu2_thrsh[2] <= ls8 || - pu2_thrsh[3] <= ls5 || - - pu2_thrsh[4] <= ls6 || - pu2_thrsh[5] <= ls3 || - pu2_thrsh[6] <= ls7 || - pu2_thrsh[7] <= ls4 - - )sad = 1; + sad_2 = sad_1 << 1; + + ls1 = sad_2 - (s2 + s3); + ls2 = sad_2 - (s1 + s4); + ls3 = sad_2 - (s3 + s4); + ls4 = sad_2 - (s3 - (s1 << 1)); + ls5 = sad_2 - (s4 - (s2 << 1)); + ls6 = sad_2 - (s1 + s2); + ls7 = sad_2 - (s2 - (s4 << 1)); + ls8 = sad_2 - (s1 - (s3 << 1)); + + if (pu2_thrsh[8] <= sad_1 || + pu2_thrsh[0] <= ls2 || pu2_thrsh[1] <= ls1 || + pu2_thrsh[2] <= ls8 || pu2_thrsh[3] <= ls5 || + pu2_thrsh[4] <= ls6 || pu2_thrsh[5] <= ls3 || + pu2_thrsh[6] <= ls7 || pu2_thrsh[7] <= ls4) { + sad = 1; + } } (*pi4_mb_distortion) += sad_1; } - pu1_src += (src_strd *4); - pu1_est += (est_strd *4); + pu1_src += (i4_src_strd * 4); + pu1_est += (i4_est_strd * 4); } *pu4_is_non_zero = sad; } - /** ****************************************************************************** * -* @brief computes distortion (SAD and SAQTD) between 2 16x8 (interleaved) chroma blocks -* +* @brief computes distortion (SAD and SAQTD) between 2 16x8 (interleaved) chroma +* blocks * -* @par Description -* This functions computes SAD between2 16x8 chroma blocks(interleaved) -* It also checks if the SATDD(Sum of absolute transformed wuqntized differnce beteern the blocks -* If SAQTD is zero, it gives back zero -* Other wise sad is retrned -* There is no provison for early exit -* -* The transform done here is the transform for chroma blocks in H264 +* @par Description +* This functions computes SAD between2 16x8 chroma blocks(interleaved). It +* also checks if the SATQD, Sum of absolute transformed quantized difference +* between the blocks. If SAQTD is zero, it gives back zero Other wise sad is +* returned. There is no provison for early exit. The transform done here is +* the transform for chroma blocks in H264 * * @param[in] pu1_src * UWORD8 pointer to the source @@ -1017,90 +998,73 @@ void ime_compute_satqd_16x16_lumainter(UWORD8 *pu1_src, * integer evaluated sad * * @remarks -* Fucntion code is nit updated. -* Will require debugging and minor modifications * ****************************************************************************** */ void ime_compute_satqd_8x16_chroma(UWORD8 *pu1_src, - UWORD8 *pu1_est, - WORD32 src_strd, - WORD32 est_strd, - WORD32 max_sad, - UWORD16 *thrsh) + UWORD8 *pu1_est, + WORD32 src_strd, + WORD32 est_strd, + WORD32 max_sad, + UWORD16 *thrsh) { - WORD32 i,j,plane; - WORD16 s1,s2,s3,s4,sad_1,sad_2,ls1,ls2,ls3,ls4,ls5,ls6,ls7,ls8; - UWORD8 *pu1_src_lp,*pu1_est_lp,*pu1_src_plane,*pu1_est_plane; - WORD32 sad =0; - UNUSED(max_sad); + WORD32 i, j, plane; + WORD16 s1, s2, s3, s4; + WORD16 sad_1, sad_2; + WORD16 ls1, ls2, ls3, ls4, ls5, ls6, ls7, ls8; + UWORD8 *pu1_src_lp, *pu1_est_lp, *pu1_src_plane, *pu1_est_plane; + WORD32 sad = 0; + UNUSED(max_sad); pu1_src_plane = pu1_src; pu1_est_plane = pu1_est; - for(plane =0;plane<2;plane++) + for (plane = 0; plane < 2; plane++) { - for(i=0;i<4;i++) + for (i = 0; i < 4; i++) { - for(j=0;j<4;j++) + for (j = 0; j < 4; j++) { - pu1_src_lp = pu1_src + 8*j; - pu1_est_lp = pu1_est + 8*j; + pu1_src_lp = pu1_src + 8 * j; + pu1_est_lp = pu1_est + 8 * j; - s1 = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[6] - (WORD16)pu1_est_lp[6]); - s4 = ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2])+ ABS((WORD16)pu1_src_lp[4] - (WORD16)pu1_est_lp[4]); + s1 = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[6] - (WORD16)pu1_est_lp[6]); + s4 = ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]) + ABS((WORD16)pu1_src_lp[4] - (WORD16)pu1_est_lp[4]); pu1_src_lp += src_strd; pu1_est_lp += est_strd; - s2 = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[6] - (WORD16)pu1_est_lp[6]); - s3 = ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2])+ ABS((WORD16)pu1_src_lp[4] - (WORD16)pu1_est_lp[4]); + s2 = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[6] - (WORD16)pu1_est_lp[6]); + s3 = ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]) + ABS((WORD16)pu1_src_lp[4] - (WORD16)pu1_est_lp[4]); pu1_src_lp += src_strd; pu1_est_lp += est_strd; - s2 += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[6] - (WORD16)pu1_est_lp[6]); - s3 += ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2])+ ABS((WORD16)pu1_src_lp[4] - (WORD16)pu1_est_lp[4]); + s2 += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[6] - (WORD16)pu1_est_lp[6]); + s3 += ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]) + ABS((WORD16)pu1_src_lp[4] - (WORD16)pu1_est_lp[4]); pu1_src_lp += src_strd; pu1_est_lp += est_strd; - s1 += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[6] - (WORD16)pu1_est_lp[6]); - s4 += ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2])+ ABS((WORD16)pu1_src_lp[4] - (WORD16)pu1_est_lp[4]); - - sad_1 = s1+s2+s3+s4; - sad_2 = sad_1<<1; - - ls1 = sad_2 -(s2 + s3); - ls2 = sad_2 -(s1 + s4); - ls3 = sad_2 -(s3 + s4); - ls4 = sad_2 -(s3 - (s1<<1)); - ls5 = sad_2 -(s4 - (s2<<1)); - ls6 = sad_2 -(s1 + s2); - ls7 = sad_2 -(s2 - (s4<<1)); - ls8 = sad_2 -(s1 - (s3<<1)); - - if( - //thrsh[0] > sad_1 && Chroma Dc is checked later - thrsh[1] > ls1 && - thrsh[2] > sad_1 && - thrsh[3] > ls2 && - - thrsh[4] > ls3 && - thrsh[5] > ls4 && - thrsh[6] > ls3 && - thrsh[7] > ls5 && - - thrsh[8] > sad_1 && - thrsh[9] > ls1 && - thrsh[10]> sad_1 && - thrsh[11]> ls2 && - - thrsh[12]> ls6 && - thrsh[13]> ls7 && - thrsh[14]> ls6 && - thrsh[15]> ls8 - ) + s1 += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[6] - (WORD16)pu1_est_lp[6]); + s4 += ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]) + ABS((WORD16)pu1_src_lp[4] - (WORD16)pu1_est_lp[4]); + + sad_1 = s1 + s2 + s3 + s4; + sad_2 = sad_1 << 1; + + ls1 = sad_2 - (s2 + s3); + ls2 = sad_2 - (s1 + s4); + ls3 = sad_2 - (s3 + s4); + ls4 = sad_2 - (s3 - (s1 << 1)); + ls5 = sad_2 - (s4 - (s2 << 1)); + ls6 = sad_2 - (s1 + s2); + ls7 = sad_2 - (s2 - (s4 << 1)); + ls8 = sad_2 - (s1 - (s3 << 1)); + + if (thrsh[1] > ls1 && thrsh[2] > sad_1 && thrsh[3] > ls2 && + thrsh[4] > ls3 && thrsh[5] > ls4 && thrsh[6] > ls3 && thrsh[7] > ls5 && + thrsh[8] > sad_1 && thrsh[9] > ls1 && thrsh[10] > sad_1 && thrsh[11] > ls2 && + thrsh[12] > ls6 && thrsh[13] > ls7 && thrsh[14] > ls6 && thrsh[15] > ls8) { /*set current sad to be zero*/ } @@ -1112,29 +1076,28 @@ void ime_compute_satqd_8x16_chroma(UWORD8 *pu1_src, pu1_src += (src_strd *4); pu1_est += (est_strd *4); } - if(sad < (thrsh[0]<<1))sad = 0; - else return ; + if (sad < (thrsh[0] << 1)) + sad = 0; + else + return; - pu1_src = pu1_src_plane+1; - pu1_est = pu1_est_plane+1; + pu1_src = pu1_src_plane + 1; + pu1_est = pu1_est_plane + 1; } return ; } - /** ****************************************************************************** * * @brief computes distortion (SAD and SAQTD) between 2 16x16 blocks * * @par Description -* This functions computes SAD between 2 16x16 blocks. -* It also checks if the SATDD(Sum of absolute transformed wuqntized differnce beteern the blocks -* If SAQTD is zero, it gives back zero -* Other wise sad is retrned -* There is no provison for early exit -* -* The transform done here is the transform for inter 16x16 blocks in H264 +* This functions computes SAD between2 16x8 chroma blocks(interleaved). It +* also checks if the SATQD, Sum of absolute transformed quantized difference +* between the blocks. If SAQTD is zero, it gives back zero Other wise sad is +* returned. There is no provison for early exit. The transform done here is the +* transform for intra 16x16 blocks in H264 * * @param[in] pu1_src * UWORD8 pointer to the source @@ -1159,80 +1122,76 @@ void ime_compute_satqd_8x16_chroma(UWORD8 *pu1_src, ****************************************************************************** */ void ime_compute_satqd_16x16_lumaintra(UWORD8 *pu1_src, - UWORD8 *pu1_est, - WORD32 src_strd, - WORD32 est_strd, - WORD32 max_sad, - UWORD16 *thrsh, - WORD32 *pi4_mb_distortion, - UWORD8 *sig_nz_sad) + UWORD8 *pu1_est, + WORD32 src_strd, + WORD32 est_strd, + WORD32 max_sad, + UWORD16 *thrsh, + WORD32 *pi4_mb_distortion, + UWORD8 *sig_nz_sad) { - UWORD32 i,j; - WORD16 s1[4],s2[4],s3[4],s4[4],sad[4]; - UWORD8 *pu1_src_lp,*pu1_est_lp; + UWORD32 i, j; + WORD16 s1[4], s2[4], s3[4], s4[4], sad[4]; + UWORD8 *pu1_src_lp, *pu1_est_lp; UWORD8 *sig_sad_dc; UWORD32 nz_sad_sig = 0; - UNUSED(max_sad); - *pi4_mb_distortion =0; + UNUSED(max_sad); + *pi4_mb_distortion = 0; sig_sad_dc = sig_nz_sad; sig_nz_sad++; - for(i=0;i<4;i++) + for (i = 0; i < 4; i++) { - for(j=0;j<4;j++) + for (j = 0; j < 4; j++) { - pu1_src_lp = pu1_src + 4*j; - pu1_est_lp = pu1_est + 4*j; + pu1_src_lp = pu1_src + 4 * j; + pu1_est_lp = pu1_est + 4 * j; - s1[j] = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); - s4[j] = ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1])+ ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); + s1[j] = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); + s4[j] = ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1]) + ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); pu1_src_lp += src_strd; pu1_est_lp += est_strd; - s2[j] = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); - s3[j] = ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1])+ ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); + s2[j] = ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); + s3[j] = ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1]) + ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); pu1_src_lp += src_strd; pu1_est_lp += est_strd; - s2[j] += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); - s3[j] += ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1])+ ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); + s2[j] += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); + s3[j] += ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1]) + ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); pu1_src_lp += src_strd; pu1_est_lp += est_strd; - s1[j] += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0])+ ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); - s4[j] += ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1])+ ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); + s1[j] += ABS((WORD16)pu1_src_lp[0] - (WORD16)pu1_est_lp[0]) + ABS((WORD16)pu1_src_lp[3] - (WORD16)pu1_est_lp[3]); + s4[j] += ABS((WORD16)pu1_src_lp[1] - (WORD16)pu1_est_lp[1]) + ABS((WORD16)pu1_src_lp[2] - (WORD16)pu1_est_lp[2]); - sad[j] = ((s1[j]+s2[j]+s3[j]+s4[j])<<1); + sad[j] = ((s1[j] + s2[j] + s3[j] + s4[j]) << 1); } - for(j=0;j<4;j++) + for (j = 0; j < 4; j++) { - if( - //thrsh[0] > (sad[j] >> 1) &&Dc goes in the other part - thrsh[1] > (sad[j] -(s2[j] + s3[j])) && - thrsh[2] > (sad[j]>>1) && - thrsh[3] > (sad[j] -(s1[j] + s4[j])) && - - thrsh[4] > (sad[j] -(s3[j] + s4[j])) && - thrsh[5] > (sad[j] -(s3[j] - (s1[j]<<1))) && - thrsh[6] > (sad[j] -(s3[j] + s4[j])) && - thrsh[7] > (sad[j] -(s4[j] - (s2[j]<<1))) && - - thrsh[8] > (sad[j]>>1) && - thrsh[9] > (sad[j] -(s2[j] + s3[j])) && - thrsh[10]> (sad[j]>>1) && - thrsh[11]> (sad[j] -(s1[j] + s4[j])) && - - thrsh[12]> (sad[j] -(s1[j] + s2[j])) && - thrsh[13]> (sad[j] -(s2[j] - (s4[j]<<1))) && - thrsh[14]> (sad[j] -(s1[j] + s2[j])) && - thrsh[15]> (sad[j] -(s1[j] - (s3[j]<<1))) - ) + if (thrsh[1] > (sad[j] - (s2[j] + s3[j])) && thrsh[2] > (sad[j] >> 1) + && thrsh[3] > (sad[j] - (s1[j] + s4[j])) && + + thrsh[4] > (sad[j] - (s3[j] + s4[j])) + && thrsh[5] > (sad[j] - (s3[j] - (s1[j] << 1))) + && thrsh[6] > (sad[j] - (s3[j] + s4[j])) + && thrsh[7] > (sad[j] - (s4[j] - (s2[j] << 1))) && + + thrsh[8] > (sad[j] >> 1) + && thrsh[9] > (sad[j] - (s2[j] + s3[j])) + && thrsh[10] > (sad[j] >> 1) + && thrsh[11] > (sad[j] - (s1[j] + s4[j])) && + + thrsh[12] > (sad[j] - (s1[j] + s2[j])) + && thrsh[13] > (sad[j] - (s2[j] - (s4[j] << 1))) + && thrsh[14] > (sad[j] - (s1[j] + s2[j])) + && thrsh[15] > (sad[j] - (s1[j] - (s3[j] << 1)))) { //sad[j] = 0; /*set current sad to be zero*/ sig_nz_sad[j] = 0;/*Signal that the sad is zero*/ @@ -1243,21 +1202,25 @@ void ime_compute_satqd_16x16_lumaintra(UWORD8 *pu1_src, nz_sad_sig = 1; } - (*pi4_mb_distortion) += (sad[j]>>1); - //if((*pi4_mb_distortion) >= max_sad)return; /*return or some thing*/ + (*pi4_mb_distortion) += (sad[j] >> 1); + //if ((*pi4_mb_distortion) >= max_sad)return; /*return or some thing*/ } sig_nz_sad += 4; - pu1_src += (src_strd *4); - pu1_est += (est_strd *4); + pu1_src += (src_strd * 4); + pu1_est += (est_strd * 4); } - if((*pi4_mb_distortion) < thrsh[0]<<2) + if ((*pi4_mb_distortion) < thrsh[0] << 2) { *sig_sad_dc = 0; - if(nz_sad_sig == 0)(*pi4_mb_distortion) = 0; + if (nz_sad_sig == 0) + (*pi4_mb_distortion) = 0; + } + else + { + *sig_sad_dc = 1; } - else *sig_sad_dc = 1; } diff --git a/encoder/ime_distortion_metrics.h b/encoder/ime_distortion_metrics.h index 5056ba0..d8675dc 100644 --- a/encoder/ime_distortion_metrics.h +++ b/encoder/ime_distortion_metrics.h @@ -20,7 +20,8 @@ /** ****************************************************************************** -* @file ih264e_distortion_metrics.h +* @file +* ime_distortion_metrics.h * * @brief * This file contains declarations of routines that compute distortion @@ -35,8 +36,8 @@ ******************************************************************************* */ -#ifndef IME_DISTORTION_METRICS_H_ -#define IME_DISTORTION_METRICS_H_ +#ifndef _IME_DISTORTION_METRICS_H_ +#define _IME_DISTORTION_METRICS_H_ /*****************************************************************************/ @@ -88,33 +89,34 @@ typedef void ime_compute_sad_stat(UWORD8 *pu1_src, UWORD32 *pu4_is_zero); typedef void ime_compute_satqd_16x16_lumainter_ft(UWORD8 *pu1_src, - UWORD8 *pu1_est, - WORD32 src_strd, - WORD32 est_strd, - UWORD16 *pu2_thrsh, - WORD32 *pi4_mb_distortion, - UWORD32 *pu4_is_zero); + UWORD8 *pu1_est, + WORD32 src_strd, + WORD32 est_strd, + UWORD16 *pu2_thrsh, + WORD32 *pi4_mb_distortion, + UWORD32 *pu4_is_zero); typedef void ime_compute_satqd_8x16_chroma_ft(UWORD8 *pu1_src, - UWORD8 *pu1_est, - WORD32 src_strd, - WORD32 est_strd, - WORD32 i4_max_sad, - UWORD16 *thrsh); + UWORD8 *pu1_est, + WORD32 src_strd, + WORD32 est_strd, + WORD32 i4_max_sad, + UWORD16 *thrsh); typedef void ime_compute_satqd_16x16_lumaintra_ft(UWORD8 *pu1_src, - UWORD8 *pu1_est, - WORD32 src_strd, - WORD32 est_strd, - WORD32 i4_max_sad, - UWORD16 *thrsh, - WORD32 *pi4_mb_distortion, - UWORD8 *sig_nz_sad); + UWORD8 *pu1_est, + WORD32 src_strd, + WORD32 est_strd, + WORD32 i4_max_sad, + UWORD16 *thrsh, + WORD32 *pi4_mb_distortion, + UWORD8 *sig_nz_sad); /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ +/* C declarations */ ime_compute_sad_ft ime_compute_sad_16x16; ime_compute_sad_ft ime_compute_sad_16x16_fast; ime_compute_sad_ft ime_compute_sad_16x8; @@ -130,8 +132,7 @@ ime_compute_satqd_16x16_lumainter_ft ime_compute_satqd_16x16_lumainter; ime_compute_satqd_8x16_chroma_ft ime_compute_satqd_8x16_chroma; ime_compute_satqd_16x16_lumaintra_ft ime_compute_satqd_16x16_lumaintra; - -/*SSE4.2 Declarations*/ +/* SSE4.2 Declarations */ ime_compute_sad_ft ime_compute_sad_16x16_sse42; ime_compute_sad_ft ime_compute_sad_16x16_fast_sse42; ime_compute_sad_ft ime_compute_sad_16x8_sse42; @@ -140,7 +141,7 @@ ime_sub_pel_compute_sad_16x16_ft ime_sub_pel_compute_sad_16x16_sse42; ime_compute_sad4_diamond ime_calculate_sad4_prog_sse42; ime_compute_satqd_16x16_lumainter_ft ime_compute_satqd_16x16_lumainter_sse42; -/* assembly */ +/* A9 Declarations */ ime_compute_sad_ft ime_compute_sad_16x16_a9q; ime_compute_sad_ft ime_compute_sad_16x16_fast_a9q; ime_compute_sad_ft ime_compute_sad_16x8_a9q; @@ -152,8 +153,7 @@ ime_sub_pel_compute_sad_16x16_ft ime_sub_pel_compute_sad_16x16_a9q; ime_compute_sad_stat ime_compute_16x16_sad_stat_a9; ime_compute_satqd_16x16_lumainter_ft ime_compute_satqd_16x16_lumainter_a9q; - -/* assembly - AV8 declarations */ +/* AV8 declarations */ ime_compute_sad_ft ime_compute_sad_16x16_av8; ime_compute_sad_ft ime_compute_sad_16x16_fast_av8; ime_compute_sad_ft ime_compute_sad_16x8_av8; @@ -165,6 +165,6 @@ ime_sub_pel_compute_sad_16x16_ft ime_sub_pel_compute_sad_16x16_av8; ime_compute_sad_stat ime_compute_16x16_sad_stat_av8; ime_compute_satqd_16x16_lumainter_ft ime_compute_satqd_16x16_lumainter_av8; -#endif /* IME_DISTORTION_METRICS_H_ */ +#endif /* _IME_DISTORTION_METRICS_H_ */ diff --git a/encoder/ime_macros.h b/encoder/ime_macros.h index a7b8c65..d00df37 100644 --- a/encoder/ime_macros.h +++ b/encoder/ime_macros.h @@ -20,11 +20,10 @@ /** ******************************************************************************* * @file -* ihevc_typedefs.h +* ime_macros.h * * @brief -* Type definitions used in the code -* +* definitions used in the code * * @remarks * None @@ -34,7 +33,7 @@ #ifndef _IME_MACROS_H_ #define _IME_MACROS_H_ -#define ABS(x) ((x) < 0 ? (-(x)) : (x)) +#define ABS(x) ((x) < 0 ? (-(x)) : (x)) #define MAX(a,b) ((a > b)?(a):(b)) #define MIN(a,b) ((a < b)?(a):(b)) diff --git a/encoder/ime_statistics.h b/encoder/ime_statistics.h index eeacaf2..45b5327 100644 --- a/encoder/ime_statistics.h +++ b/encoder/ime_statistics.h @@ -20,11 +20,10 @@ /** ******************************************************************************* * @file -* ihevc_typedefs.h +* ime_statistics.h * * @brief -* Type definitions used in the code -* +* This file presents some useful statistics associated with me * * @remarks * None @@ -33,10 +32,10 @@ */ #ifndef _IME_STATISTICS_H_ #define _IME_STATISTICS_H_ + #define DEBUG_HISTOGRAM_ENABLE 0 #define SAD_EXIT_STATS 0 - #if SAD_EXIT_STATS /** diff --git a/encoder/ime_structs.h b/encoder/ime_structs.h index 9baacb3..6cde09e 100644 --- a/encoder/ime_structs.h +++ b/encoder/ime_structs.h @@ -18,24 +18,21 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ /** - ******************************************************************************* - * @file - * ih264e_me.h - * - * @brief - * - * - * @author - * Ittiam - * - * @par List of Functions: - * - - * - * @remarks - * None - * - ******************************************************************************* - */ +******************************************************************************* +* @file +* ime_structs.h +* +* @brief +* Structure definitions used in the code +* +* @author +* Ittiam +* +* @remarks +* None +* +******************************************************************************* +*/ #ifndef _IME_STRUCTS_H_ #define _IME_STRUCTS_H_ @@ -97,7 +94,7 @@ typedef struct */ UWORD32 u4_exit; - /* + /** * Buffer corresponding to best half pel cost */ UWORD8 *pu1_best_hpel_buf; @@ -220,12 +217,12 @@ typedef struct /* * Minimum distortion to search for - * */ + */ WORD32 i4_min_sad; - /* + /** * Signal that minimum sad has been reached in ME - * */ + */ UWORD32 u4_min_sad_reached; /** @@ -243,14 +240,24 @@ typedef struct */ UWORD32 u4_me_speed_preset; + /** + * Is left mb intra + */ UWORD32 u4_left_is_intra; + /** + * Is left mb skip + */ UWORD32 u4_left_is_skip; - /* skip_type can be PREDL0, PREDL1 or BIPRED */ + /** + * skip_type can be PREDL0, PREDL1 or BIPRED + */ WORD32 i4_skip_type; - /* Biasing given for skip prediction */ + /** + * Biasing given for skip prediction + */ WORD32 i4_skip_bias[2]; /** @@ -258,7 +265,8 @@ typedef struct * We need 1(L0)+1(L1)+1(bi) */ mb_part_ctxt as_mb_part[MAX_NUM_REFLIST + 1]; - /* + + /** * Threshold to compare the sad with */ UWORD16 *pu2_sad_thrsh; @@ -273,7 +281,7 @@ typedef struct ime_compute_sad2_diamond *pf_ime_compute_sad2_diamond; ime_sub_pel_compute_sad_16x16_ft *pf_ime_sub_pel_compute_sad_16x16; - /* + /** * Function poitners for SATQD */ ime_compute_sad_stat *pf_ime_compute_sad_stat_luma_16x16; @@ -283,14 +291,14 @@ typedef struct */ UWORD8 u1_mb_qp; - /* + /** * Buffers for holding subpel and bipred temp buffers */ UWORD8 *apu1_subpel_buffs[SUBPEL_BUFF_CNT]; WORD32 u4_subpel_buf_strd; - /* + /** * Buffers to store the best halfpel plane* */ UWORD8 *pu1_hpel_buf; @@ -298,5 +306,5 @@ typedef struct } me_ctxt_t; -#endif // _IME_STRUCTS_H_ +#endif /* _IME_STRUCTS_H_ */ diff --git a/encoder/ime_typedefs.h b/encoder/ime_typedefs.h index d36632d..a0033db 100644 --- a/encoder/ime_typedefs.h +++ b/encoder/ime_typedefs.h @@ -20,17 +20,20 @@ /** ******************************************************************************* * @file -* ihevc_typedefs.h +* ime_typedefs.h * * @brief -* Type definitions used in the code +* Type definitions used in the software * +* @author +* Ittiam * * @remarks * None * ******************************************************************************* */ + #ifndef _IME_TYPEDEFS_H_ #define _IME_TYPEDEFS_H_ @@ -47,4 +50,4 @@ typedef long WORD64; typedef char CHAR; -#endif /*_IME_TYPEDEFS_H_*/ +#endif /* _IME_TYPEDEFS_H_ */ diff --git a/encoder/irc_bit_allocation.c b/encoder/irc_bit_allocation.c index 6f52970..3ea8a13 100644 --- a/encoder/irc_bit_allocation.c +++ b/encoder/irc_bit_allocation.c @@ -172,14 +172,11 @@ static void check_update_rbip(rem_bit_in_prd_t *ps_rbip, static void irc_ba_update_rbip(rem_bit_in_prd_t *ps_rbip, pic_handling_handle ps_pic_handling, - WORD32 i4_num_of_bits) + number_t vq_num_bits) { - number_t vq_num_bits; - check_update_rbip(ps_rbip, ps_pic_handling); /* rem_bits_in_period += num_of_bits */ - SET_VAR_Q(vq_num_bits, i4_num_of_bits, 0); add32_var_q(vq_num_bits, ps_rbip->vq_rem_bits_in_period, &ps_rbip->vq_rem_bits_in_period); } @@ -359,7 +356,7 @@ WORD32 irc_ba_get_cur_frm_est_texture_bits(bit_allocation_t *ps_bit_allocation, number_t vq_max_consumable_bits; number_t vq_rem_frms_in_period[MAX_PIC_TYPE], vq_est_texture_bits_for_frm; number_t vq_prev_hdr_bits[MAX_PIC_TYPE]; - + number_t vq_num_bits; WORD32 complexity_est = 0; /* Get the rem_frms_in_gop & the frms_in_gop from the pic_type state struct */ @@ -376,7 +373,8 @@ WORD32 irc_ba_get_cur_frm_est_texture_bits(bit_allocation_t *ps_bit_allocation, /* Remove the header bits from the remaining bits to find how many bits you can transfer.*/ - irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, 0); + SET_VAR_Q(vq_num_bits, 0, 0); + irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, vq_num_bits); for(i = 0; i < MAX_PIC_TYPE; i++) { SET_VAR_Q(vq_rem_frms_in_period[i], i4_rem_frms_in_period[i], 0); @@ -559,7 +557,11 @@ WORD32 irc_ba_get_rem_bits_in_period(bit_allocation_t *ps_bit_allocation, pic_handling_handle ps_pic_handling) { WORD32 i4_rem_bits_in_gop = 0; - irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, 0); + + number_t vq_num_bits; + SET_VAR_Q(vq_num_bits, 0, 0); + + irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, vq_num_bits); number_t_to_word32(ps_bit_allocation->s_rbip.vq_rem_bits_in_period, &i4_rem_bits_in_gop); return (i4_rem_bits_in_gop); @@ -581,8 +583,10 @@ void irc_ba_update_cur_frm_consumed_bits(bit_allocation_t *ps_bit_allocation, WORD32 i4_error_bits = irc_get_error_bits(ps_bit_allocation->ps_error_bits); /* Update the remaining bits in period */ - irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, - (-i4_total_frame_bits + i4_error_bits)); + number_t vq_num_bits; + SET_VAR_Q(vq_num_bits, (-i4_total_frame_bits + i4_error_bits), 0); + + irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, vq_num_bits); /* * Update the header bits so that it can be used as an estimate to the next @@ -619,8 +623,15 @@ void irc_ba_update_cur_frm_consumed_bits(bit_allocation_t *ps_bit_allocation, if(i4_last_frm_in_gop) { - WORD32 i4_num_bits_in_a_gop = get_number_of_frms_in_a_gop( - ps_pic_handling) * ps_bit_allocation->i4_bits_per_frm; + WORD32 i4_tot_frms_in_gop = get_number_of_frms_in_a_gop( + ps_pic_handling); + number_t vq_total_frms_in_gop, vq_bits_per_frm, vq_num_bits_in_gop; + + SET_VAR_Q(vq_total_frms_in_gop, i4_tot_frms_in_gop, 0); + SET_VAR_Q(vq_bits_per_frm, ps_bit_allocation->i4_bits_per_frm, 0); + + mult32_var_q(vq_bits_per_frm, vq_total_frms_in_gop, + &vq_num_bits_in_gop); /* * If the number of gops in period has been increased due to scene * change, slowly bring in down across the gops @@ -638,7 +649,7 @@ void irc_ba_update_cur_frm_consumed_bits(bit_allocation_t *ps_bit_allocation, * the next period else increase it */ irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, - i4_num_bits_in_a_gop); + vq_num_bits_in_gop); } /* Update the lower modules */ irc_update_error_bits(ps_bit_allocation->ps_error_bits); @@ -722,10 +733,16 @@ void irc_ba_change_rem_bits_in_prd_at_force_I_frame(bit_allocation_t *ps_bit_all pic_handling_handle ps_pic_handling) { WORD32 i4_frms_in_period; + number_t vq_frms_in_period, vq_bits_per_frm, vq_num_bits_in_period; + i4_frms_in_period = irc_pic_type_get_frms_in_gop_force_I_frm( ps_pic_handling); - irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, - ps_bit_allocation->i4_bits_per_frm * i4_frms_in_period); + SET_VAR_Q(vq_frms_in_period, i4_frms_in_period, 0); + SET_VAR_Q(vq_bits_per_frm, ps_bit_allocation->i4_bits_per_frm, 0); + + mult32_var_q(vq_bits_per_frm, vq_frms_in_period, &vq_num_bits_in_period); + + irc_ba_update_rbip(&ps_bit_allocation->s_rbip, ps_pic_handling, vq_num_bits_in_period); } void irc_ba_check_and_update_bit_allocation(bit_allocation_t *ps_bit_allocation, diff --git a/encoder/irc_cbr_buffer_control.c b/encoder/irc_cbr_buffer_control.c index 9febbc8..5280e9c 100644 --- a/encoder/irc_cbr_buffer_control.c +++ b/encoder/irc_cbr_buffer_control.c @@ -370,8 +370,7 @@ void irc_update_cbr_buffer(cbr_buffer_t *ps_cbr_buffer, /*SS - Fix for lack of stuffing*/ if(ps_cbr_buffer->i4_ebf > ps_cbr_buffer->i4_buffer_size) { - trace_printf( - (const WORD8*)"Error: Should not be coming here with stuffing\n"); + TRACE_PRINTF((const WORD8*)"Error: Should not be coming here with stuffing\n"); ps_cbr_buffer->i4_ebf = ps_cbr_buffer->i4_buffer_size; } } diff --git a/encoder/irc_datatypes.h b/encoder/irc_datatypes.h index 8e4685a..1fc8b10 100644 --- a/encoder/irc_datatypes.h +++ b/encoder/irc_datatypes.h @@ -17,25 +17,9 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ -/** -******************************************************************************* -* @file -* ih264_typedefs.h -* -* @brief -* Type definitions used in the code -* -* @author -* Ittiam -* -* @remarks -* None -* -******************************************************************************* -*/ -#ifndef _IH264_TYPEDEFS_H_ -#define _IH264_TYPEDEFS_H_ +#ifndef _RC_DATATYPES_H_ +#define _RC_DATATYPES_H_ /*****************************************************************************/ @@ -61,4 +45,4 @@ typedef int WORD32; typedef char CHAR; typedef double DOUBLE; -#endif /* _IH264_TYPEDEFS_H_ */ +#endif // _RC_DATATYPES_H_ diff --git a/encoder/irc_mem_req_and_acq.h b/encoder/irc_mem_req_and_acq.h index a2946a7..37f30fc 100644 --- a/encoder/irc_mem_req_and_acq.h +++ b/encoder/irc_mem_req_and_acq.h @@ -21,28 +21,23 @@ /** ****************************************************************************** * @file -* ih264e_rc_mem_interface.h +* irc_mem_req_and_acq.h * * @brief -* This file contains function declaration and structures for rate control +* This file contains interface definitions for allocating rate control * memtabs * * @author * ittiam * * @remarks -* The rate control library is a global library across various codecs. It -* anticipates certain structures definitions. Those definitions are to be -* imported from global workspace. Instead of that, the structures needed for -* rc library are copied in to this file and exported to rc library. If the -* structures / enums / ... in the global workspace change, this file also needs -* to be modified accordingly. +* none * -****************************************************************************** +******************************************************************************* */ -#ifndef IH264E_RC_MEM_INTERFACE_H_ -#define IH264E_RC_MEM_INTERFACE_H_ +#ifndef _RC_MEM_REQ_AND_ACQ_H_ +#define _RC_MEM_REQ_AND_ACQ_H_ /*****************************************************************************/ /* Function Macros */ @@ -90,13 +85,10 @@ typedef enum FILL_BASE =3 }ITT_FUNC_TYPE_E; - /*****************************************************************************/ /* Structures */ /*****************************************************************************/ -/*NOTE : This should be an exact replica of IALG_MemRec, any change in IALG_MemRec - must be replicated here*/ typedef struct { /* Size in bytes */ @@ -115,65 +107,20 @@ typedef struct void *pv_base; } itt_memtab_t; - /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ -/** -****************************************************************************** -* -* @brief This function fills memory record attributes -* -* @par Description -* This function fills memory record attributes -* -* @param[in] ps_mem_tab -* pointer to mem records -* -* @param[in] u4_size -* size of the record -* -* @param[in] i4_alignment -* memory alignment size -* -* @param[in] e_usage -* usage -* -* @param[in] e_mem_region -* mem region -* -* @return void -* -****************************************************************************** -*/ -void fill_memtab(itt_memtab_t *ps_mem_tab, WORD32 u4_size, WORD32 i4_alignment, - ITT_MEM_USAGE_TYPE_E e_usage, ITT_MEM_REGION_E e_mem_region); +void fill_memtab(itt_memtab_t *ps_mem_tab, + WORD32 u4_size, + WORD32 i4_alignment, + ITT_MEM_USAGE_TYPE_E e_usage, + ITT_MEM_REGION_E e_mem_region); -/** -****************************************************************************** -* -* @brief This function fills memory record attributes -* -* @par Description -* This function fills memory record attributes -* -* @param[in] ps_mem_tab -* pointer to mem records -* -* @param[in] ptr_to_be_filled -* handle to the memory record storage space -* -* @param[in] e_func_type -* enum that dictates fill memory records or use memory records -* -* @return void -* -****************************************************************************** -*/ -WORD32 use_or_fill_base(itt_memtab_t *ps_mem_tab, void **ptr_to_be_filled, +WORD32 use_or_fill_base(itt_memtab_t *ps_mem_tab, + void **ptr_to_be_filled, ITT_FUNC_TYPE_E e_func_type); -#endif // IH264E_RC_MEM_INTERFACE_H_ +#endif // _RC_MEM_REQ_AND_ACQ_H_ diff --git a/encoder/irc_rate_control_api.c b/encoder/irc_rate_control_api.c index 4a64645..ef88117 100644 --- a/encoder/irc_rate_control_api.c +++ b/encoder/irc_rate_control_api.c @@ -54,6 +54,73 @@ #define GET_LO_DEV_QP(Qprev) (( ((WORD32) Qprev)*LO_DEV_FCTR + (1<<(DEV_Q-1)))>>DEV_Q) #define CLIP_QP(Qc, hi_d, lo_d) (((Qc) < (lo_d))?((lo_d)):(((Qc) > (hi_d))?(hi_d):(Qc))) +/***************************************************************************** + Function Name : fill_memtab + Description : fill memtab + Inputs : + ps_mem_tab - Memtab pointer + u4_size - Size of the memtab + i4_alignment - alignment of the memtab + e_usage - usage + e_mem_region - region + *****************************************************************************/ +void fill_memtab(itt_memtab_t *ps_mem_tab, + WORD32 u4_size, + WORD32 i4_alignment, + ITT_MEM_USAGE_TYPE_E e_usage, + ITT_MEM_REGION_E e_mem_region) +{ + /* Make the size next multiple of alignment */ + WORD32 i4_aligned_size = (((u4_size) + (i4_alignment-1)) & (~(i4_alignment-1))); + + /* Fill the memtab */ + ps_mem_tab->u4_size = i4_aligned_size; + ps_mem_tab->i4_alignment = i4_alignment; + ps_mem_tab->e_usage = e_usage; + ps_mem_tab->e_mem_region = e_mem_region; +} + +/***************************************************************************** + Function Name : use_or_fill_base + Description : Get or Set base pointer for the memtab + Inputs : + ps_mem_tab - Memtab pointer + ptr_to_be_filled - Pointer to base pointer + e_func_type - Get/Set flag + *****************************************************************************/ +WORD32 use_or_fill_base(itt_memtab_t *ps_mem_tab, + void **ptr_to_be_filled, + ITT_FUNC_TYPE_E e_func_type) +{ + /* Fill base for freeing the allocated memory */ + if (e_func_type == FILL_BASE) + { + if (ptr_to_be_filled[0] != 0) + { + ps_mem_tab->pv_base = ptr_to_be_filled[0]; + return (0); + } + else + { + return (-1); + } + } + /* obtain the allocated memory from base pointer */ + if (e_func_type == USE_BASE) + { + if (ps_mem_tab->pv_base != 0) + { + ptr_to_be_filled[0] = ps_mem_tab->pv_base; + return (0); + } + else + { + return (-1); + } + } + return (0); +} + /*****************************************************************************/ /* Restricts the quantization parameter variation within delta */ /*****************************************************************************/ @@ -163,11 +230,13 @@ void irc_initialise_rate_control(rate_control_api_t *ps_rate_control_api, UWORD32 u4_tgt_ticks) { WORD32 i; - UWORD32 u4_frms_in_delay_prd = (u4_frame_rate * u4_max_delay) / 1000000; + UWORD32 u4_frms_in_delay_prd; + + X_PROD_Y_DIV_Z(u4_frame_rate, u4_max_delay, 1000000, u4_frms_in_delay_prd); ps_rate_control_api->e_rc_type = e_rate_control_type; ps_rate_control_api->u1_is_mb_level_rc_on = u1_is_mb_level_rc_on; - trace_printf((const WORD8*)"RC type = %d\n", e_rate_control_type); + TRACE_PRINTF((const WORD8*)"RC type = %d\n", e_rate_control_type); /* Set the avg_bitrate_changed flag for each pic_type to 0 */ for(i = 0; i < MAX_PIC_TYPE; i++) @@ -202,7 +271,7 @@ void irc_initialise_rate_control(rate_control_api_t *ps_rate_control_api, VBR_STORAGE_DVD_COMP */ if(pu4_peak_bit_rate[0] != pu4_peak_bit_rate[1]) { - trace_printf((const WORD8*)"For VBR_STORAGE and VBR_STORAGE_DVD_COMP the peak bit rates should be same\n"); + TRACE_PRINTF((const WORD8*)"For VBR_STORAGE and VBR_STORAGE_DVD_COMP the peak bit rates should be same\n"); } irc_init_vbr_vbv(ps_rate_control_api->ps_vbr_storage_vbv, (WORD32)pu4_peak_bit_rate[0], @@ -307,8 +376,8 @@ void irc_initialise_rate_control(rate_control_api_t *ps_rate_control_api, /* Initialize the mb level rate control module */ irc_init_mb_level_rc(ps_rate_control_api->ps_mb_rate_control); - ps_rate_control_api->i4_prev_frm_est_bits = u4_avg_bit_rate * 1000 - / u4_frame_rate; + X_PROD_Y_DIV_Z(u4_avg_bit_rate, 1000, u4_frame_rate, + ps_rate_control_api->i4_prev_frm_est_bits); ps_rate_control_api->prev_ref_pic_type = I_PIC; } @@ -363,7 +432,7 @@ UWORD8 irc_get_frame_level_qp(rate_control_api_t *ps_rate_control_api, && (ps_rate_control_api->e_rc_type != CONST_QP) && (ps_rate_control_api->e_rc_type != VBR_STREAMING)) { - trace_printf((const WORD8*)(const WORD8*)" Only VBR,NLDRC and CONST QP supported for now \n"); + TRACE_PRINTF((const WORD8*)(const WORD8*)" Only VBR,NLDRC and CONST QP supported for now \n"); return (0); } @@ -427,7 +496,7 @@ UWORD8 irc_get_frame_level_qp(rate_control_api_t *ps_rate_control_api, /* Total estimated bits */ i4_cur_est_bits = i4_cur_est_header_bits + i4_cur_est_texture_bits; - trace_printf((const WORD8*)"ft %d, etb = %d, eb %d, ", e_pic_type, + TRACE_PRINTF((const WORD8*)"ft %d, etb = %d, eb %d, ", e_pic_type, i4_cur_est_texture_bits, i4_cur_est_bits); /* Threshold the estimated bits based on the buffer fullness*/ @@ -496,7 +565,7 @@ UWORD8 irc_get_frame_level_qp(rate_control_api_t *ps_rate_control_api, - i4_cur_est_header_bits; } - trace_printf((const WORD8*)"emtb = %d, ", i4_cur_est_texture_bits); + TRACE_PRINTF((const WORD8*)"emtb = %d, ", i4_cur_est_texture_bits); /* * If the estimated texture bits go to values less than zero @@ -516,7 +585,7 @@ UWORD8 irc_get_frame_level_qp(rate_control_api_t *ps_rate_control_api, { i4_cur_est_texture_bits = (i4_ud_max_bits - i4_cur_est_header_bits); - trace_printf((const WORD8*)"udcb = %d, ", + TRACE_PRINTF((const WORD8*)"udcb = %d, ", i4_ud_max_bits - i4_cur_est_header_bits); } @@ -549,7 +618,7 @@ UWORD8 irc_get_frame_level_qp(rate_control_api_t *ps_rate_control_api, << 1) + 1]; } - trace_printf((const WORD8*)"ehb %d, etb %d, fqp %d, es %d, eb %d, ", + TRACE_PRINTF((const WORD8*)"ehb %d, etb %d, fqp %d, es %d, eb %d, ", i4_cur_est_header_bits, i4_cur_est_texture_bits, u1_frame_qp, u4_estimated_sad, i4_cur_est_bits); @@ -662,7 +731,7 @@ UWORD8 irc_get_frame_level_qp(rate_control_api_t *ps_rate_control_api, u1_frame_qp = ps_rate_control_api->au1_init_qp[e_pic_type]; } - trace_printf((const WORD8*)"fqp %d\n", u1_frame_qp); + TRACE_PRINTF((const WORD8*)"fqp %d\n", u1_frame_qp); return (u1_frame_qp); } @@ -688,7 +757,7 @@ vbv_buf_status_e irc_get_buffer_status(rate_control_api_t *ps_rate_control_api, i4_total_frame_bits, pi4_num_bits_to_prevent_vbv_underflow); - trace_printf((const WORD8*)"e_buf_status = %d\n", e_buf_status); + TRACE_PRINTF((const WORD8*)"e_buf_status = %d\n", e_buf_status); } else if(ps_rate_control_api->e_rc_type == VBR_STORAGE) { @@ -756,6 +825,7 @@ void irc_update_frame_level_info(rate_control_api_t *ps_rate_control_api, { u1_is_scd = 0; } + /* For frames that contain plane areas that differ from reference frames, encoder * might generate more INTRA MBs because of lower SAD compared with INTER MBs. * Such cases should not be treated as scene change. @@ -765,8 +835,7 @@ void irc_update_frame_level_info(rate_control_api_t *ps_rate_control_api, { u1_is_scd = 0; } - - trace_printf((const WORD8*)"i4_total_frame_bits %d\n", i4_total_frame_bits); + TRACE_PRINTF((const WORD8*)"i4_total_frame_bits %d\n", i4_total_frame_bits); if(!i4_is_it_a_skip && !i4_is_pic_handling_done) { @@ -996,7 +1065,7 @@ void irc_update_frame_level_info(rate_control_api_t *ps_rate_control_api, */ ps_rate_control_api->au1_prev_frm_qp[I_PIC] = (UWORD8)i4_avg_qp; - trace_printf((const WORD8*)"SCD DETECTED\n"); + TRACE_PRINTF((const WORD8*)"SCD DETECTED\n"); } else { @@ -1066,7 +1135,7 @@ void irc_update_frame_level_info(rate_control_api_t *ps_rate_control_api, ps_rate_control_api->prev_ref_pic_type = e_pic_type; } - trace_printf((const WORD8*)"ft %d,hb %d,tb %d,qp %d,fs %d\n", e_pic_type, + TRACE_PRINTF((const WORD8*)"ft %d,hb %d,tb %d,qp %d,fs %d\n", e_pic_type, i4_model_updation_hdr_bits, i4_tot_texture_bits, i4_avg_qp, u4_frame_sad); diff --git a/encoder/irc_rate_control_api_structs.h b/encoder/irc_rate_control_api_structs.h index 3248c74..562ccf3 100644 --- a/encoder/irc_rate_control_api_structs.h +++ b/encoder/irc_rate_control_api_structs.h @@ -16,7 +16,7 @@ * ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore - */ +*/ #ifndef _RATE_CONTROL_API_STRUCTS_H_ #define _RATE_CONTROL_API_STRUCTS_H_ diff --git a/encoder/irc_rd_model.c b/encoder/irc_rd_model.c index 62c7811..1df42c7 100644 --- a/encoder/irc_rd_model.c +++ b/encoder/irc_rd_model.c @@ -126,11 +126,9 @@ static UWORD8 find_model_coeffs(UWORD32 *pi4_res_bits, float x0, y0; float model_coeff_a = 0.0, model_coeff_b = 0.0, model_coeff_c = 0.0; -#if !(ENABLE_QUAD_RC_MODEL||ENABLE_LIN_MODEL_WITH_INTERCEPT) UNUSED(pu1_num_skips); UNUSED(pmc_model_coeff); UNUSED(pmc_model_coeff_lin); -#endif for(i = 0; i < u1_num_frms; i++) { diff --git a/encoder/irc_trace_support.h b/encoder/irc_trace_support.h index c35bd4f..1845c90 100644 --- a/encoder/irc_trace_support.h +++ b/encoder/irc_trace_support.h @@ -18,44 +18,17 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ -/** -******************************************************************************* -* @file -* ih264e_trace_support.h -* -* @brief -* This file contains extern declarations of routines that could be helpful -* for debugging purposes. -* -* @author -* Harish -* -* @remarks -* None -* -******************************************************************************* -*/ - -#ifndef TRACE_SUPPORT_H_ -#define TRACE_SUPPORT_H_ - -/*****************************************************************************/ -/* Structures */ -/*****************************************************************************/ - -typedef struct -{ - WORD8 * pu1_buf; - WORD32 i4_offset; - WORD32 i4_max_size; -}trace_support_t; - -/*****************************************************************************/ -/* Extern function declarations */ -/*****************************************************************************/ - -void init_trace_support(WORD8 *pu1_buf, WORD32 i4_size); - -int trace_printf(const WORD8 *format, ...); - -#endif // TRACE_SUPPORT_H_ +#ifndef _RC_TRACE_SUPPORT_H_ +#define _RC_TRACE_SUPPORT_H_ + +#if DEBUG_RC +#define TRACE_PRINTF(...) \ +{ \ + printf("\n[RC DBG] %s/%d:: ", __FUNCTION__, __LINE__); \ + printf(__VA_ARGS__); \ +} +#else +#define TRACE_PRINTF(...) {} +#endif + +#endif // _RC_TRACE_SUPPORT_H_ diff --git a/encoder/irc_vbr_str_prms.c b/encoder/irc_vbr_str_prms.c index 29055c2..4d5bfe0 100644 --- a/encoder/irc_vbr_str_prms.c +++ b/encoder/irc_vbr_str_prms.c @@ -17,6 +17,7 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /*****************************************************************************/ /* Includes */ /*****************************************************************************/ diff --git a/encoder/iv2.h b/encoder/iv2.h index 538bb1e..ed17e81 100644 --- a/encoder/iv2.h +++ b/encoder/iv2.h @@ -23,17 +23,15 @@ * iv2.h * * @brief -* This file contains all the necessary structure and enumeration -* definitions needed for the Application Program Interface(API) of the -* Ittiam Video codecs This is version 2 of Ittiam Video API +* This file contains all the necessary structure and enumeration definitions +* needed for the Application Program Interface(API) of the Ittiam Video codecs. +* This is version 2 of Ittiam Video API * * @author -* Ittiam -* -* @par List of Functions: +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ @@ -77,7 +75,6 @@ typedef enum { }IV_MEM_TYPE_T; /* The color formats used in video/image codecs */ - typedef enum { IV_CHROMA_NA = 0x7FFFFFFF, IV_YUV_420P = 0x0, @@ -267,6 +264,7 @@ typedef struct UWORD32 u4_bufsize; }iv_bits_buf_t; + /*****************************************************************************/ /* Get Number of Memory Records */ /*****************************************************************************/ diff --git a/encoder/ive2.h b/encoder/ive2.h index 2ba0ec8..a67ef90 100644 --- a/encoder/ive2.h +++ b/encoder/ive2.h @@ -23,17 +23,15 @@ * ive2.h * * @brief -* This file contains all the necessary structure and enumeration -* definitions needed for the Application Program Interface(API) of the -* Ittiam Video Encoders This is version 2 +* This file contains all the necessary structure and enumeration definitions +* needed for the Application Program Interface(API) of the Ittiam Video +* Encoders. This is version 2 * * @author -* Ittiam -* -* @par List of Functions: +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ diff --git a/encoder/svc/irc_svc_rate_control_api.c b/encoder/svc/irc_svc_rate_control_api.c index a2e9453..024713b 100644 --- a/encoder/svc/irc_svc_rate_control_api.c +++ b/encoder/svc/irc_svc_rate_control_api.c @@ -71,7 +71,7 @@ UWORD8 irc_get_frame_level_init_qp(rate_control_handle *ps_rate_control_api, rc_ if((e_rc_type != VBR_STORAGE) && (e_rc_type != VBR_STORAGE_DVD_COMP) && (e_rc_type != CBR_NLDRC) && (e_rc_type != CONST_QP) && (e_rc_type != VBR_STREAMING)) { - trace_printf( + TRACE_PRINTF( (const WORD8 *) (const WORD8 *) " Only VBR,NLDRC and CONST QP supported for now \n"); return (0); } diff --git a/encoder/svc/isvce_api.c b/encoder/svc/isvce_api.c index 8900995..2004dba 100644 --- a/encoder/svc/isvce_api.c +++ b/encoder/svc/isvce_api.c @@ -114,6 +114,7 @@ #include "ime_structs.h" /* Dependencies of 'ih264e_utils.h' */ #include "ih264e_defs.h" +#include "irc_mem_req_and_acq.h" #include "ih264e_rc_mem_interface.h" #include "ih264e_structs.h" #include "ih264e_utils.h" @@ -433,13 +434,6 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, void *pv_api_ip, return (IV_FAIL); } - if(ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420P) - { - ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; - ps_op->s_ive_op.u4_error_code |= IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED; - return (IV_FAIL); - } - if(ps_ip->s_ive_ip.e_recon_color_fmt != IV_YUV_420P) { ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; @@ -2261,7 +2255,7 @@ static WORD32 isvce_init(isvce_codec_t *ps_codec) /* reset status flags */ for(i = 0; i < MAX_CTXT_SETS; i++) { - ps_codec->au4_entropy_thread_active[i] = 0; + ps_codec->ae_entropy_thread_exit_state[i] = INACTIVE; ps_codec->ai4_pic_cnt[i] = -1; ps_codec->s_rate_control.pre_encode_skip[i] = 0; diff --git a/encoder/svc/isvce_defs.h b/encoder/svc/isvce_defs.h index c277abd..a661ffa 100644 --- a/encoder/svc/isvce_defs.h +++ b/encoder/svc/isvce_defs.h @@ -342,4 +342,13 @@ typedef enum ISVCE_MEMREC_TYPES_T */ } ISVCE_MEMREC_TYPES_T; +typedef enum ISVCE_ENTROPY_THREAD_STATES_T +{ + INACTIVE, + + IN_PROCESS, + + ERRONEOUS_EXIT +} ISVCE_ENTROPY_THREAD_STATES_T; + #endif diff --git a/encoder/svc/isvce_encode.c b/encoder/svc/isvce_encode.c index d3f6198..8c6aa11 100644 --- a/encoder/svc/isvce_encode.c +++ b/encoder/svc/isvce_encode.c @@ -243,14 +243,17 @@ WORD32 isvce_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) /* initialize codec ctxt with default params for the first encode api call */ if(ps_codec->i4_encode_api_call_cnt == 0) { - isvce_codec_init(ps_codec); + error_status = isvce_codec_init(ps_codec); + + SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR, + ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL); } error_status = isvce_svc_frame_params_validate(ps_codec->s_rate_control.apps_rate_control_api, ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers); - SET_ERROR_ON_RETURN(error_status, IVE_UNSUPPORTEDPARAM, - ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL); + SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR, ps_video_encode_op->s_ive_op.u4_error_code, + IV_FAIL); /* parse configuration params */ for(i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++) diff --git a/encoder/svc/isvce_encode_header.h b/encoder/svc/isvce_encode_header.h index c443ed0..d7c9f8c 100644 --- a/encoder/svc/isvce_encode_header.h +++ b/encoder/svc/isvce_encode_header.h @@ -103,12 +103,12 @@ * in case of errors ****************************************************************************** */ -#define RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel) \ - if(ps_entropy->i4_error_code != IH264E_SUCCESS) \ - { \ - DATA_SYNC(); \ - ps_codec->au4_entropy_thread_active[ctxt_sel] = 0; \ - return ps_entropy->i4_error_code; \ +#define RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel) \ + if(ps_entropy->i4_error_code != IH264E_SUCCESS) \ + { \ + DATA_SYNC(); \ + ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = ERRONEOUS_EXIT; \ + return ps_entropy->i4_error_code; \ } /*****************************************************************************/ diff --git a/encoder/svc/isvce_process.c b/encoder/svc/isvce_process.c index 113dc38..cf679d9 100644 --- a/encoder/svc/isvce_process.c +++ b/encoder/svc/isvce_process.c @@ -1122,7 +1122,7 @@ IH264E_ERROR_T isvce_entropy(isvce_process_ctxt_t *ps_proc) DATA_SYNC(); /* allow threads to dequeue entropy jobs */ - ps_codec->au4_entropy_thread_active[ctxt_sel] = 0; + ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = INACTIVE; return ps_entropy->i4_error_code; } @@ -2684,6 +2684,7 @@ WORD32 isvce_process_thread(void *pv_proc) IH264_ERROR_T ret = IH264_SUCCESS; + WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS; WORD32 error_status = IH264_SUCCESS; WORD32 is_blocking = 0; @@ -2693,24 +2694,23 @@ WORD32 isvce_process_thread(void *pv_proc) { /* dequeue a job from the entropy queue */ { + bool b_is_entropy_state_invalid = false; WORD32 retval = ithread_mutex_lock(ps_codec->pv_entropy_mutex); - - /* codec context selector */ - WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS; - - volatile UWORD32 *pu4_buf = &ps_codec->au4_entropy_thread_active[ctxt_sel]; + volatile ISVCE_ENTROPY_THREAD_STATES_T *pe_entropy_thread_state = + &ps_codec->ae_entropy_thread_exit_state[ctxt_sel]; /* have the lock */ if(retval == 0) { - if(*pu4_buf == 0) + if(*pe_entropy_thread_state == INACTIVE) { /* no entropy threads are active, try dequeuing a job from the entropy * queue */ ret = ih264_list_dequeue(ps_proc->pv_entropy_jobq, &s_job, is_blocking); + if(IH264_SUCCESS == ret) { - *pu4_buf = 1; + *pe_entropy_thread_state = IN_PROCESS; ithread_mutex_unlock(ps_codec->pv_entropy_mutex); goto WORKER; } @@ -2720,8 +2720,20 @@ WORD32 isvce_process_thread(void *pv_proc) break; } } + else if(*pe_entropy_thread_state == ERRONEOUS_EXIT) + { + b_is_entropy_state_invalid = true; + } + ithread_mutex_unlock(ps_codec->pv_entropy_mutex); } + + if(b_is_entropy_state_invalid) + { + ps_proc->i4_error_code = IH264_FAIL; + + return IH264_FAIL; + } } /* dequeue a job from the process queue */ @@ -2729,7 +2741,9 @@ WORD32 isvce_process_thread(void *pv_proc) if(IH264_SUCCESS != ret) { if(ps_proc->i4_id) + { break; + } else { is_blocking = 1; @@ -2753,6 +2767,7 @@ WORD32 isvce_process_thread(void *pv_proc) if(error_status != IH264_SUCCESS) { + ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = ERRONEOUS_EXIT; ps_proc->i4_error_code = error_status; return ret; } @@ -2771,6 +2786,7 @@ WORD32 isvce_process_thread(void *pv_proc) if(error_status != IH264_SUCCESS) { + ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = ERRONEOUS_EXIT; ps_proc->i4_error_code = error_status; return ret; } diff --git a/encoder/svc/isvce_rate_control.c b/encoder/svc/isvce_rate_control.c index 1562f08..e4a85bb 100644 --- a/encoder/svc/isvce_rate_control.c +++ b/encoder/svc/isvce_rate_control.c @@ -49,7 +49,6 @@ /*****************************************************************************/ #include "ih264_typedefs.h" -#include "irc_datatypes.h" #include "iv2.h" #include "ive2.h" #include "isvce.h" @@ -160,11 +159,9 @@ void isvce_rc_init(void *pv_rc_api, void *pv_frame_time, void *pv_time_stamp, vo UWORD8 *pu1_init_qp, WORD32 i4_max_inter_frm_int, UWORD8 *pu1_min_max_qp, UWORD8 u1_profile_level) { - // UWORD8 u1_is_mb_level_rc_on = 0; UWORD32 au4_peak_bit_rate[2] = {0, 0}; UWORD32 u4_min_bit_rate = 0; WORD32 i4_is_gop_closed = 1; - // WORD32 i4_use_est_intra_sad = 1; UWORD32 u4_src_ticks = 0; UWORD32 u4_tgt_ticks = 0; UWORD8 u1_level_idx = ih264e_get_lvl_idx(u1_profile_level); diff --git a/encoder/svc/isvce_rc_mem_interface.c b/encoder/svc/isvce_rc_mem_interface.c index 7431854..28bea36 100644 --- a/encoder/svc/isvce_rc_mem_interface.c +++ b/encoder/svc/isvce_rc_mem_interface.c @@ -83,6 +83,7 @@ #include "ih264e_error.h" #include "isvce_defs.h" #include "ih264e_bitstream.h" +#include "irc_mem_req_and_acq.h" #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" #include "isvce_rate_control.h" diff --git a/encoder/svc/isvce_rc_mem_interface.h b/encoder/svc/isvce_rc_mem_interface.h index ff7a475..a2cf2fc 100644 --- a/encoder/svc/isvce_rc_mem_interface.h +++ b/encoder/svc/isvce_rc_mem_interface.h @@ -43,7 +43,7 @@ #ifndef _ISVCE_RC_MEM_INTERFACE_H_ #define _ISVCE_RC_MEM_INTERFACE_H_ -#include "ih264e_rc_mem_interface.h" +#include "irc_mem_req_and_acq.h" /** *************************************************************************** diff --git a/encoder/svc/isvce_structs.h b/encoder/svc/isvce_structs.h index 25200f4..9d8f6c5 100644 --- a/encoder/svc/isvce_structs.h +++ b/encoder/svc/isvce_structs.h @@ -2184,7 +2184,7 @@ typedef struct isvce_codec_t /** * Flag to determine if the entropy thread is active */ - volatile UWORD32 au4_entropy_thread_active[MAX_CTXT_SETS]; + volatile ISVCE_ENTROPY_THREAD_STATES_T ae_entropy_thread_exit_state[MAX_CTXT_SETS]; /** * Mutex used to keep the entropy calls thread-safe diff --git a/encoder/svc/isvce_utils.c b/encoder/svc/isvce_utils.c index 5f4220d..485a52e 100644 --- a/encoder/svc/isvce_utils.c +++ b/encoder/svc/isvce_utils.c @@ -101,6 +101,7 @@ #include "ih264e_defs.h" #include "ih264e_structs.h" /* Dependencies of 'ih264e_utils.h' */ +#include "irc_mem_req_and_acq.h" #include "ih264e_rc_mem_interface.h" #include "ih264e_time_stamp.h" #include "ih264e_utils.h" @@ -518,6 +519,36 @@ WORD32 isvce_svc_inp_params_validate(isvce_init_ip_t *ps_ip, isvce_cfg_params_t ******************************************************************************* * * @brief +* Validates SVC RC params +* +* @param[in] ps_cfg +* Cfg parameters +* +* @returns error code in conformance with 'IH264E_ERROR_T' +* +******************************************************************************* +*/ +WORD32 isvce_svc_rc_params_validate(isvce_cfg_params_t *ps_cfg) +{ + WORD32 i; + + /* RC requires total bits in a second to fit int32_t */ + for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++) + { + if((((((UWORD64) ps_cfg->au4_target_bitrate[i]) * 1000llu) / ps_cfg->u4_tgt_frame_rate) * + ps_cfg->u4_idr_frm_interval) > ((UWORD64) INT32_MAX)) + { + return IH264E_BITRATE_NOT_SUPPORTED; + } + } + + return IH264E_SUCCESS; +} + +/** +******************************************************************************* +* +* @brief * Validates SVC frame-level input params * * @param[in] ps_cfg @@ -3544,6 +3575,15 @@ IH264E_ERROR_T isvce_codec_init(isvce_codec_t *ps_codec) ps_codec->i4_air_pic_cnt = -1; } + { + WORD32 i4_err_code = isvce_svc_rc_params_validate(&ps_codec->s_cfg); + + if(IH264E_SUCCESS != i4_err_code) + { + return i4_err_code; + } + } + /****************************************************/ /* INITIALIZE RATE CONTROL */ /****************************************************/ diff --git a/encoder/svc/isvce_utils.h b/encoder/svc/isvce_utils.h index ad14446..497809e 100644 --- a/encoder/svc/isvce_utils.h +++ b/encoder/svc/isvce_utils.h @@ -180,6 +180,8 @@ extern WORD32 isvce_svc_au_props_validate(svc_inp_params_t *ps_svc_inp_params, U extern WORD32 isvce_svc_inp_params_validate(isvce_init_ip_t *ps_ip, isvce_cfg_params_t *ps_cfg); +extern WORD32 isvce_svc_rc_params_validate(isvce_cfg_params_t *ps_cfg); + extern WORD32 isvce_svc_frame_params_validate( rate_control_api_t *aps_rate_control_api[MAX_NUM_SPATIAL_LAYERS], UWORD8 u1_num_spatial_layers); diff --git a/encoder/x86/ih264e_function_selector.c b/encoder/x86/ih264e_function_selector.c index b0acb19..54dc22f 100644 --- a/encoder/x86/ih264e_function_selector.c +++ b/encoder/x86/ih264e_function_selector.c @@ -27,17 +27,18 @@ * Contains functions to initialize function pointers used in h264 * * @author -* Ittiam +* ittiam * * @par List of Functions: +* - ih264e_init_function_ptr +* - ih264e_default_arch * * @remarks -* None +* none * ******************************************************************************* */ - /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ @@ -52,38 +53,46 @@ #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264_defs.h" -#include "ih264_size_defs.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" + +#include "ih264_macros.h" #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" +#include "ih264_size_defs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" #include "ih264_cabac_tables.h" -#include "ih264_macros.h" #include "ih264_platform_macros.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" #include "ih264e_cabac.h" #include "ih264e_platform_macros.h" + +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ + /** ******************************************************************************* * -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context +* @brief Initialize the intra/inter/transform/deblk/entropy function pointers * * @par Description: the current routine initializes the function pointers of * codec context basing on the architecture in use @@ -100,6 +109,7 @@ void ih264e_init_function_ptr(void *pv_codec) { codec_t *ps_codec = (codec_t *)pv_codec; + ih264e_init_function_ptr_generic(ps_codec); switch(ps_codec->s_cfg.e_arch) { @@ -139,4 +149,3 @@ IV_ARCH_T ih264e_default_arch(void) return ARCH_X86_SSE42; } - diff --git a/encoder/x86/ih264e_function_selector_sse42.c b/encoder/x86/ih264e_function_selector_sse42.c index 6888e5d..30fbc5d 100644 --- a/encoder/x86/ih264e_function_selector_sse42.c +++ b/encoder/x86/ih264e_function_selector_sse42.c @@ -26,13 +26,13 @@ * Contains functions to initialize function pointers of codec context * * @author -* Ittiam +* ittiam * * @par List of Functions: * - ih264e_init_function_ptr_sse42 * * @remarks -* None +* none * ******************************************************************************* */ @@ -42,53 +42,59 @@ /* File Includes */ /*****************************************************************************/ - -/* System Include files */ +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <string.h> -/* User Include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264_defs.h" -#include "ih264_size_defs.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" + #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_cavlc_tables.h" #include "ih264_cabac_tables.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_cabac.h" -#include "ih264e_platform_macros.h" +#include "ih264e_half_pel.h" +#include "ih264e_intra_modes_eval.h" #include "ih264e_core_coding.h" -#include "ih264_cavlc_tables.h" #include "ih264e_cavlc.h" -#include "ih264e_intra_modes_eval.h" +#include "ih264e_cabac.h" #include "ih264e_fmt_conv.h" -#include "ih264e_half_pel.h" +#include "ih264e_platform_macros.h" + + +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ /** ******************************************************************************* * -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context +* @brief Initialize the intra/inter/transform/deblk/entropy function pointers * * @par Description: the current routine initializes the function pointers of * codec context basing on the architecture in use @@ -105,19 +111,17 @@ void ih264e_init_function_ptr_sse42(codec_t *ps_codec) { WORD32 i; - process_ctxt_t *ps_proc = NULL; - me_ctxt_t *ps_me_ctxt = NULL; /* Init luma forward transform fn ptr */ ps_codec->pf_resi_trans_quant_4x4 = ih264_resi_trans_quant_4x4_sse42; - ps_codec->pf_resi_trans_quant_chroma_4x4 = ih264_resi_trans_quant_chroma_4x4_sse42; - ps_codec->pf_hadamard_quant_4x4 = ih264_hadamard_quant_4x4_sse42; - ps_codec->pf_hadamard_quant_2x2_uv = ih264_hadamard_quant_2x2_uv_sse42; + ps_codec->pf_resi_trans_quant_chroma_4x4 = ih264_resi_trans_quant_chroma_4x4_sse42; + ps_codec->pf_hadamard_quant_4x4 = ih264_hadamard_quant_4x4_sse42; + ps_codec->pf_hadamard_quant_2x2_uv = ih264_hadamard_quant_2x2_uv_sse42; /* Init inverse transform fn ptr */ ps_codec->pf_iquant_itrans_recon_4x4 = ih264_iquant_itrans_recon_4x4_sse42; - ps_codec->pf_iquant_itrans_recon_chroma_4x4 = ih264_iquant_itrans_recon_chroma_4x4_sse42; - ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_sse42; + ps_codec->pf_iquant_itrans_recon_chroma_4x4 = ih264_iquant_itrans_recon_chroma_4x4_sse42; + ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_sse42; /* sad me level functions */ ps_codec->apf_compute_sad_16x16[0] = ime_compute_sad_16x16_sse42; @@ -127,14 +131,14 @@ void ih264e_init_function_ptr_sse42(codec_t *ps_codec) /* sad me level functions */ for(i = 0; i < (MAX_PROCESS_CTXT); i++) { - ps_proc = &ps_codec->as_process[i]; + process_ctxt_t *ps_proc = &ps_codec->as_process[i]; + me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt; - ps_me_ctxt = &ps_proc->s_me_ctxt; ps_me_ctxt->pf_ime_compute_sad_16x16[0] = ime_compute_sad_16x16_sse42; ps_me_ctxt->pf_ime_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_sse42; ps_me_ctxt->pf_ime_compute_sad_16x8 = ime_compute_sad_16x8_sse42; ps_me_ctxt->pf_ime_compute_sad4_diamond = ime_calculate_sad4_prog_sse42; ps_me_ctxt->pf_ime_sub_pel_compute_sad_16x16 = ime_sub_pel_compute_sad_16x16_sse42; - ps_me_ctxt->pf_ime_compute_sad_stat_luma_16x16 = ime_compute_satqd_16x16_lumainter_sse42; + ps_me_ctxt->pf_ime_compute_sad_stat_luma_16x16 = ime_compute_satqd_16x16_lumainter_sse42; } } diff --git a/encoder/x86/ih264e_function_selector_ssse3.c b/encoder/x86/ih264e_function_selector_ssse3.c index 4419112..33937c5 100644 --- a/encoder/x86/ih264e_function_selector_ssse3.c +++ b/encoder/x86/ih264e_function_selector_ssse3.c @@ -26,69 +26,74 @@ * Contains functions to initialize function pointers of codec context * * @author -* Ittiam +* ittiam * * @par List of Functions: * - ih264e_init_function_ptr_ssse3 * * @remarks -* None +* none * ******************************************************************************* */ - /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ - -/* System Include files */ +/* System Include Files */ #include <stdio.h> #include <stddef.h> #include <stdlib.h> #include <string.h> -/* User Include files */ +/* User Include Files */ #include "ih264_typedefs.h" #include "iv2.h" #include "ive2.h" -#include "ih264_defs.h" -#include "ih264_size_defs.h" -#include "ih264e_defs.h" -#include "ih264e_error.h" -#include "ih264e_bitstream.h" -#include "ime_distortion_metrics.h" -#include "ime_defs.h" -#include "ime_structs.h" + #include "ih264_error.h" +#include "ih264_defs.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" #include "ih264_structs.h" #include "ih264_trans_quant_itrans_iquant.h" #include "ih264_inter_pred_filters.h" -#include "ih264_mem_fns.h" -#include "ih264_padding.h" #include "ih264_intra_pred_filters.h" #include "ih264_deblk_edge_filters.h" +#include "ih264_cavlc_tables.h" #include "ih264_cabac_tables.h" + +#include "ime_defs.h" +#include "ime_distortion_metrics.h" +#include "ime_structs.h" + #include "irc_cntrl_param.h" #include "irc_frame_info_collector.h" + +#include "ih264e_error.h" +#include "ih264e_defs.h" #include "ih264e_rate_control.h" +#include "ih264e_bitstream.h" #include "ih264e_cabac_structs.h" #include "ih264e_structs.h" -#include "ih264e_platform_macros.h" -#include "ih264e_cabac.h" +#include "ih264e_half_pel.h" +#include "ih264e_intra_modes_eval.h" #include "ih264e_core_coding.h" -#include "ih264_cavlc_tables.h" #include "ih264e_cavlc.h" -#include "ih264e_intra_modes_eval.h" +#include "ih264e_cabac.h" #include "ih264e_fmt_conv.h" -#include "ih264e_half_pel.h" +#include "ih264e_platform_macros.h" + + +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ /** ******************************************************************************* * -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context +* @brief Initialize the intra/inter/transform/deblk/entropy function pointers * * @par Description: the current routine initializes the function pointers of * codec context basing on the architecture in use @@ -104,64 +109,63 @@ */ void ih264e_init_function_ptr_ssse3(codec_t *ps_codec) { + /* Init function pointers for intra pred leaf level functions luma + * Intra 16x16 */ + ps_codec->apf_intra_pred_16_l[0] = ih264_intra_pred_luma_16x16_mode_vert_ssse3; + ps_codec->apf_intra_pred_16_l[1] = ih264_intra_pred_luma_16x16_mode_horz_ssse3; + ps_codec->apf_intra_pred_16_l[2] = ih264_intra_pred_luma_16x16_mode_dc_ssse3; + ps_codec->apf_intra_pred_16_l[3] = ih264_intra_pred_luma_16x16_mode_plane_ssse3; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 4x4 */ + ps_codec->apf_intra_pred_4_l[0] = ih264_intra_pred_luma_4x4_mode_vert_ssse3; + ps_codec->apf_intra_pred_4_l[1] = ih264_intra_pred_luma_4x4_mode_horz_ssse3; + ps_codec->apf_intra_pred_4_l[2] = ih264_intra_pred_luma_4x4_mode_dc_ssse3; + ps_codec->apf_intra_pred_4_l[3] = ih264_intra_pred_luma_4x4_mode_diag_dl_ssse3; + ps_codec->apf_intra_pred_4_l[4] = ih264_intra_pred_luma_4x4_mode_diag_dr_ssse3; + ps_codec->apf_intra_pred_4_l[5] = ih264_intra_pred_luma_4x4_mode_vert_r_ssse3; + ps_codec->apf_intra_pred_4_l[6] = ih264_intra_pred_luma_4x4_mode_horz_d_ssse3; + ps_codec->apf_intra_pred_4_l[7] = ih264_intra_pred_luma_4x4_mode_vert_l_ssse3; + ps_codec->apf_intra_pred_4_l[8] = ih264_intra_pred_luma_4x4_mode_horz_u_ssse3; /* Init function pointers for intra pred leaf level functions luma - * Intra 16x16 */ - ps_codec->apf_intra_pred_16_l[0] = ih264_intra_pred_luma_16x16_mode_vert_ssse3; - ps_codec->apf_intra_pred_16_l[1] = ih264_intra_pred_luma_16x16_mode_horz_ssse3; - ps_codec->apf_intra_pred_16_l[2] = ih264_intra_pred_luma_16x16_mode_dc_ssse3; - ps_codec->apf_intra_pred_16_l[3] = ih264_intra_pred_luma_16x16_mode_plane_ssse3; - - /* Init function pointers for intra pred leaf level functions luma - * Intra 4x4 */ - ps_codec->apf_intra_pred_4_l[0] = ih264_intra_pred_luma_4x4_mode_vert_ssse3; - ps_codec->apf_intra_pred_4_l[1] = ih264_intra_pred_luma_4x4_mode_horz_ssse3; - ps_codec->apf_intra_pred_4_l[2] = ih264_intra_pred_luma_4x4_mode_dc_ssse3; - ps_codec->apf_intra_pred_4_l[3] = ih264_intra_pred_luma_4x4_mode_diag_dl_ssse3; - ps_codec->apf_intra_pred_4_l[4] = ih264_intra_pred_luma_4x4_mode_diag_dr_ssse3; - ps_codec->apf_intra_pred_4_l[5] = ih264_intra_pred_luma_4x4_mode_vert_r_ssse3; - ps_codec->apf_intra_pred_4_l[6] = ih264_intra_pred_luma_4x4_mode_horz_d_ssse3; - ps_codec->apf_intra_pred_4_l[7] = ih264_intra_pred_luma_4x4_mode_vert_l_ssse3; - ps_codec->apf_intra_pred_4_l[8] = ih264_intra_pred_luma_4x4_mode_horz_u_ssse3; - - /* Init function pointers for intra pred leaf level functions luma - * Intra 8x8 */ - ps_codec->apf_intra_pred_8_l[0] = ih264_intra_pred_luma_8x8_mode_vert_ssse3; - ps_codec->apf_intra_pred_8_l[2] = ih264_intra_pred_luma_8x8_mode_dc_ssse3; - ps_codec->apf_intra_pred_8_l[3] = ih264_intra_pred_luma_8x8_mode_diag_dl_ssse3; - ps_codec->apf_intra_pred_8_l[4] = ih264_intra_pred_luma_8x8_mode_diag_dr_ssse3; - ps_codec->apf_intra_pred_8_l[5] = ih264_intra_pred_luma_8x8_mode_vert_r_ssse3; - ps_codec->apf_intra_pred_8_l[6] = ih264_intra_pred_luma_8x8_mode_horz_d_ssse3; - ps_codec->apf_intra_pred_8_l[7] = ih264_intra_pred_luma_8x8_mode_vert_l_ssse3; - ps_codec->apf_intra_pred_8_l[8] = ih264_intra_pred_luma_8x8_mode_horz_u_ssse3; - - /* Init function pointers for intra pred leaf level functions chroma - * Intra 8x8 */ - ps_codec->apf_intra_pred_c[1] = ih264_intra_pred_chroma_8x8_mode_horz_ssse3; - ps_codec->apf_intra_pred_c[2] = ih264_intra_pred_chroma_8x8_mode_vert_ssse3; - ps_codec->apf_intra_pred_c[3] = ih264_intra_pred_chroma_8x8_mode_plane_ssse3; + * Intra 8x8 */ + ps_codec->apf_intra_pred_8_l[0] = ih264_intra_pred_luma_8x8_mode_vert_ssse3; + ps_codec->apf_intra_pred_8_l[2] = ih264_intra_pred_luma_8x8_mode_dc_ssse3; + ps_codec->apf_intra_pred_8_l[3] = ih264_intra_pred_luma_8x8_mode_diag_dl_ssse3; + ps_codec->apf_intra_pred_8_l[4] = ih264_intra_pred_luma_8x8_mode_diag_dr_ssse3; + ps_codec->apf_intra_pred_8_l[5] = ih264_intra_pred_luma_8x8_mode_vert_r_ssse3; + ps_codec->apf_intra_pred_8_l[6] = ih264_intra_pred_luma_8x8_mode_horz_d_ssse3; + ps_codec->apf_intra_pred_8_l[7] = ih264_intra_pred_luma_8x8_mode_vert_l_ssse3; + ps_codec->apf_intra_pred_8_l[8] = ih264_intra_pred_luma_8x8_mode_horz_u_ssse3; + + /* Init function pointers for intra pred leaf level functions chroma + * Intra 8x8 */ + ps_codec->apf_intra_pred_c[1] = ih264_intra_pred_chroma_8x8_mode_horz_ssse3; + ps_codec->apf_intra_pred_c[2] = ih264_intra_pred_chroma_8x8_mode_vert_ssse3; + ps_codec->apf_intra_pred_c[3] = ih264_intra_pred_chroma_8x8_mode_plane_ssse3; /* Init inverse transform fn ptr */ ps_codec->pf_iquant_itrans_recon_8x8 = ih264_iquant_itrans_recon_8x8_ssse3; - ps_codec->pf_iquant_itrans_recon_4x4_dc = ih264_iquant_itrans_recon_4x4_dc_ssse3; + ps_codec->pf_iquant_itrans_recon_4x4_dc = ih264_iquant_itrans_recon_4x4_dc_ssse3; ps_codec->pf_iquant_itrans_recon_chroma_4x4_dc = ih264_iquant_itrans_recon_chroma_4x4_dc_ssse3; /* Init fn ptr luma deblocking */ ps_codec->pf_deblk_luma_vert_bs4 = ih264_deblk_luma_vert_bs4_ssse3; - ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4_ssse3; - ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4_ssse3; - ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4_ssse3; + ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4_ssse3; + ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4_ssse3; + ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4_ssse3; /* Init fn ptr chroma deblocking */ - ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4_ssse3; - ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4_ssse3; - ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4_ssse3; - ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4_ssse3; - - /* Padding Functions */ - ps_codec->pf_pad_left_luma = ih264_pad_left_luma_ssse3; - ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma_ssse3; - ps_codec->pf_pad_right_luma = ih264_pad_right_luma_ssse3; - ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma_ssse3; + ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4_ssse3; + ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4_ssse3; + ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4_ssse3; + ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4_ssse3; + + /* Padding Functions */ + ps_codec->pf_pad_left_luma = ih264_pad_left_luma_ssse3; + ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma_ssse3; + ps_codec->pf_pad_right_luma = ih264_pad_right_luma_ssse3; + ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma_ssse3; /* Inter pred leaf level functions */ ps_codec->pf_inter_pred_luma_copy = ih264_inter_pred_luma_copy_ssse3; diff --git a/encoder/x86/ih264e_half_pel_ssse3.c b/encoder/x86/ih264e_half_pel_ssse3.c index 8da73b7..415f9a5 100644 --- a/encoder/x86/ih264e_half_pel_ssse3.c +++ b/encoder/x86/ih264e_half_pel_ssse3.c @@ -27,14 +27,14 @@ * and cascaded 2D filter used in motion estimation in H264 encoder. * * @author - * Ittiam + * ittiam * * @par List of Functions: * ih264e_sixtapfilter_horz_ssse3 * ih264e_sixtap_filter_2dvh_vert_ssse3 * * @remarks - * None + * none * ******************************************************************************* */ @@ -55,7 +55,6 @@ #include "ih264_defs.h" #include "ih264e_half_pel.h" #include "ih264_macros.h" -#include "ih264e_debug.h" #include "ih264_inter_pred_filters.h" #include "ih264_mem_fns.h" #include "ih264_padding.h" @@ -90,10 +89,10 @@ * integer destination stride * * @returns -* None +* none * * @remarks -* None +* none * ******************************************************************************* */ @@ -236,10 +235,10 @@ void ih264e_sixtapfilter_horz_ssse3(UWORD8 *pu1_src, * integer destination stride of pi16_pred1 * * @returns -* None +* none * * @remarks -* None +* none * ******************************************************************************* */ diff --git a/encoder/x86/ih264e_intra_modes_eval_ssse3.c b/encoder/x86/ih264e_intra_modes_eval_ssse3.c index ea8a6c8..7eb7dae 100644 --- a/encoder/x86/ih264e_intra_modes_eval_ssse3.c +++ b/encoder/x86/ih264e_intra_modes_eval_ssse3.c @@ -23,11 +23,11 @@ * ih264e_intra_modes_eval_ssse3.c * * @brief -* This file contains definitions of routines that perform rate distortion +* This file contains definitions of routines that perform rate distortion * analysis on a macroblock if they are to be coded as intra. * * @author -* Ittiam +* ittiam * * @par List of Functions: * ih264e_evaluate_intra16x16_modes_ssse3 @@ -35,7 +35,7 @@ * ih264e_evaluate_intra_chroma_modes_ssse3 * * @remarks -* None +* none * ******************************************************************************* */ @@ -128,7 +128,7 @@ * says what all modes are valid * * @return -* None +* none * ****************************************************************************** */ diff --git a/encoder/x86/ih264e_platform_macros.h b/encoder/x86/ih264e_platform_macros.h index b4dfadd..2c1513f 100644 --- a/encoder/x86/ih264e_platform_macros.h +++ b/encoder/x86/ih264e_platform_macros.h @@ -17,138 +17,35 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ -/** - ******************************************************************************* - * @file - * ih264e_platform_macros.h - * - * @brief - * Contains platform specific routines used for codec context intialization - * - * @author - * ittiam - * - * @remarks - * none - * - ******************************************************************************* - */ - - -#ifndef IH264E_PLATFORM_MACROS_H_ -#define IH264E_PLATFORM_MACROS_H_ - -/*****************************************************************************/ -/* Extern Function Declarations */ -/*****************************************************************************/ /** ******************************************************************************* +* @file +* ih264e_platform_macros.h * -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context -* -* @par Description: the current routine initializes the function pointers of -* codec context basing on the architecture in use -* -* @param[in] ps_codec -* Codec context pointer +* @brief +* Contains platform specific routines used for codec context intialization * -* @returns none +* @author +* ittiam * -* @remarks none +* @remarks +* none * ******************************************************************************* */ + +#ifndef _IH264E_PLATFORM_MACROS_H_ +#define _IH264E_PLATFORM_MACROS_H_ + +/*****************************************************************************/ +/* Function Declarations */ +/*****************************************************************************/ + void ih264e_init_function_ptr_generic(codec_t *ps_codec); -/** -******************************************************************************* -* -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context -* -* @par Description: the current routine initializes the function pointers of -* codec context basing on the architecture in use -* -* @param[in] ps_codec -* Codec context pointer -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ void ih264e_init_function_ptr_ssse3(codec_t *ps_codec); void ih264e_init_function_ptr_sse42(codec_t *ps_codec); - -/** -******************************************************************************* -* -* @brief Initialize the intra/inter/transform/deblk function pointers of -* codec context -* -* @par Description: the current routine initializes the function pointers of -* codec context basing on the architecture in use -* -* @param[in] ps_codec -* Codec context pointer -* -* @returns none -* -* @remarks none -* -******************************************************************************* -*/ void ih264e_init_function_ptr(void *pv_codec); - -/** -******************************************************************************* -* -* @brief Determine the architecture of the encoder executing environment -* -* @par Description: This routine returns the architecture of the enviro- -* ment in which the current encoder is being tested -* -* @param[in] void -* -* @returns IV_ARCH_T -* architecture -* -* @remarks none -* -******************************************************************************* -*/ IV_ARCH_T ih264e_default_arch(void); -/** -******************************************************************************* -* -* @brief Data Memory Barrier, Data Synchronization Barrier -* -* -* @par Description: These functions do nothing on x86 side. But on arm platforms, -* -* Data Memory Barrier acts as a memory barrier. It ensures that all explicit -* memory accesses that appear in program order before the DMB instruction are -* observed before any explicit memory accesses that appear in program order -* after the DMB instruction. It does not affect the ordering of any other -* instructions executing on the processor -* -* Data Synchronization Barrier acts as a special kind of memory barrier. No -* instruction in program order after this instruction executes until this instruction -* completes. This instruction completes when: -* 1. All explicit memory accesses before this instruction complete. -* 2. All Cache, Branch predictor and TLB maintenance operations before -* this instruction complete. -* -* @param[in] void -* -* @returns void -* -* @remarks none -* -******************************************************************************* -*/ - -#endif /* IH264E_PLATFORM_MACROS_H_ */ +#endif /* _IH264E_PLATFORM_MACROS_H_ */ diff --git a/encoder/x86/ime_platform_macros.h b/encoder/x86/ime_platform_macros.h index 18e2e8f..fc3b1a3 100644 --- a/encoder/x86/ime_platform_macros.h +++ b/encoder/x86/ime_platform_macros.h @@ -34,7 +34,6 @@ ******************************************************************************* */ - #ifndef _IME_PLATFORM_MACROS_H_ #define _IME_PLATFORM_MACROS_H_ @@ -49,4 +48,4 @@ ABS(src[3]-est[3]) -#endif /* _IH264_PLATFORM_MACROS_H_ */ +#endif /* _IME_PLATFORM_MACROS_H_ */ diff --git a/test/Android.bp b/examples/Android.bp index 7a9ac03..36a45ec 100644 --- a/test/Android.bp +++ b/examples/Android.bp @@ -41,7 +41,7 @@ cc_defaults { "-Wno-unused-variable", ], local_include_dirs: [ - "encoder", + "avcenc", ], static_libs: ["libavcenc"], } @@ -50,9 +50,9 @@ cc_test { name: "avcdec", defaults: ["avcdec_defaults"], local_include_dirs: [ - "decoder", + "avcdec", ], - srcs: ["decoder/main.c"], + srcs: ["avcdec/main.c"], static_libs: ["libavcdec"], } @@ -73,11 +73,11 @@ cc_test { defaults: ["avcenc_defaults"], srcs: [ - "encoder/main.c", - "encoder/psnr.c", - "encoder/input.c", - "encoder/output.c", - "encoder/recon.c", + "avcenc/main.c", + "avcenc/psnr.c", + "avcenc/input.c", + "avcenc/output.c", + "avcenc/recon.c", ], } diff --git a/examples/avcdec/avcdec.cmake b/examples/avcdec/avcdec.cmake new file mode 100644 index 0000000..4a62262 --- /dev/null +++ b/examples/avcdec/avcdec.cmake @@ -0,0 +1,2 @@ +libavc_add_executable(avcdec libavcdec SOURCES ${AVC_ROOT}/examples/avcdec/main.c) +target_compile_definitions(avcdec PRIVATE PROFILE_ENABLE MD5_DISABLE) diff --git a/test/decoder/dec.cfg b/examples/avcdec/dec.cfg index f452ea1..f452ea1 100644 --- a/test/decoder/dec.cfg +++ b/examples/avcdec/dec.cfg diff --git a/test/decoder/main.c b/examples/avcdec/main.c index e90bdac..e90bdac 100644 --- a/test/decoder/main.c +++ b/examples/avcdec/main.c diff --git a/test/encoder/app.h b/examples/avcenc/app.h index 4abbe54..9935e52 100644 --- a/test/encoder/app.h +++ b/examples/avcenc/app.h @@ -17,23 +17,24 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ -/*****************************************************************************/ -/* */ -/* File Name : app.h */ -/* */ -/* Description : This file contains all the necessary structure and */ -/* enumeration definitions needed for the Application */ -/* */ -/* List of Functions : */ -/* */ -/* Issues / Problems : None */ -/* */ -/* Revision History : */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 26 08 2010 Ittiam Draft */ -/* */ -/*****************************************************************************/ + +/** +******************************************************************************* +* @file +* app.h +* +* @brief +* This file contains all the necessary structure and enumeration definitions +* needed for the Application +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ #ifndef _APP_H_ #define _APP_H_ @@ -45,6 +46,7 @@ #else #include <sys/time.h> #endif + /*****************************************************************************/ /* Function Macros */ /*****************************************************************************/ @@ -56,7 +58,6 @@ /*****************************************************************************/ /* Constant Macros */ /*****************************************************************************/ - #define DEFAULT_NUM_INPUT_BUFS 32 #define DEFAULT_MAX_INPUT_BUFS 32 @@ -66,24 +67,12 @@ #define DEFAULT_NUM_RECON_BUFS 32 #define DEFAULT_MAX_RECON_BUFS DEFAULT_NUM_RECON_BUFS - -#define LEN_STATUS_BUFFER (10 * 1024) -#define MAX_VBV_BUFF_SIZE (120 * 16384) -#define MAX_NUM_IO_BUFS 3 - #define DEFAULT_MAX_REF_FRM 2 #define DEFAULT_MAX_REORDER_FRM 0 -#define DEFAULT_QP_MIN 4 -#define DEFAULT_QP_MAX 51 -#define DEFAULT_MAX_BITRATE 240000000 -#define DEFAULT_NUM_BFRAMES 0 #define DEFAULT_MAX_SRCH_RANGE_X 256 #define DEFAULT_MAX_SRCH_RANGE_Y 256 -#define DEFAULT_MAX_FRAMERATE 120000 -#define DEFAULT_NUM_CORES 1 -#define DEFAULT_NUM_CORES_PRE_ENC 0 -#define DEFAULT_FPS 30 -#define DEFAULT_ENC_SPEED 100 +#define DEFAULT_QP_MIN 4 +#define DEFAULT_QP_MAX 49 #define DEFAULT_MEM_REC_CNT 0 #define DEFAULT_RECON_ENABLE 0 @@ -92,7 +81,9 @@ #define DEFAULT_NUM_FRMS 0xFFFFFFFF #define DEFAULT_INP_COLOR_FMT IV_YUV_420SP_UV #define DEFAULT_RECON_COLOR_FMT IV_YUV_420P +#define DEFAULT_NUM_CORES 1 #define DEFAULT_LOOPBACK 0 +#define DEFAULT_MAX_FRAMERATE 120000 /* in ticks (1000 ticks = 1s) */ #define DEFAULT_SRC_FRAME_RATE 30 #define DEFAULT_TGT_FRAME_RATE 30 #define DEFAULT_MAX_WD 1920 @@ -106,24 +97,25 @@ #define DEFAULT_ENABLE_FAST_SAD 0 #define DEFAULT_ENABLE_ALT_REF 0 #define DEFAULT_RC 1 +#define DEFAULT_MAX_BITRATE 240000000 #define DEFAULT_BITRATE 6000000 #define DEFAULT_I_QP 25 #define DEFAULT_I_QP_MAX DEFAULT_QP_MAX -#define DEFAULT_I_QP_MIN 0 +#define DEFAULT_I_QP_MIN DEFAULT_QP_MIN #define DEFAULT_P_QP 28 #define DEFAULT_P_QP_MAX DEFAULT_QP_MAX -#define DEFAULT_P_QP_MIN 0 +#define DEFAULT_P_QP_MIN DEFAULT_QP_MIN #define DEFAULT_B_QP 28 #define DEFAULT_B_QP_MAX DEFAULT_QP_MAX -#define DEFAULT_B_QP_MIN 0 +#define DEFAULT_B_QP_MIN DEFAULT_QP_MIN #define DEFAULT_AIR 0 #define DEFAULT_AIR_REFRESH_PERIOD 30 #define DEFAULT_SRCH_RNG_X 64 -#define DEFAULT_SRCH_RNG_Y 48 +#define DEFAULT_SRCH_RNG_Y 64 #define DEFAULT_I_INTERVAL 30 -#define DEFAULT_IDR_INTERVAL 1000 +#define DEFAULT_IDR_INTERVAL 1200 #define DEFAULT_CONSTRAINED_INTRAPRED 0 -#define DEFAULT_B_FRAMES 0 +#define DEFAULT_NUM_BFRAMES 0 #define DEFAULT_DISABLE_DEBLK_LEVEL 0 #define DEFAULT_HPEL 1 #define DEFAULT_QPEL 1 @@ -132,7 +124,17 @@ #define DEFAULT_SLICE_MODE 0 #define DEFAULT_SLICE_PARAM 256 #define DEFAULT_ENTROPY_CODING_MODE 0 - +#define NUM_SEI_MDCV_PRIMARIES 3 +#define NUM_SEI_CCV_PRIMARIES 3 +#define SII_MAX_SUB_LAYERS 8 +#define SII_SUB_LAYER_IDX 0 +#define SHUTTER_INTERVAL_INFO_PRESENT_FLAG 1 +#define SII_TIME_SCALE 24000000 +#define FIXED_SHUTTER_INTERVAL_WITHIN_CVS_FLAG 0 +#define SII_NUM_UNITS_IN_SHUTTER_INTERVAL 480000 +#define SII_MAX_SUB_LAYERS_MINUS1 (SII_MAX_SUB_LAYERS - 1) +#define SUB_LAYER_NUM_UNITS_IN_SHUTTER_INTERVAL_HFR 480000 +#define SUB_LAYER_NUM_UNITS_IN_SHUTTER_INTERVAL_SFR 240000 #define DEFAULT_MAX_DISPLAY_MASTERING_LUMINANCE 50000 #define DEFAULT_MIN_DISPLAY_MASTERING_LUMINANCE 1 @@ -184,6 +186,12 @@ /*****************************************************************************/ /* Structure definitions */ /*****************************************************************************/ + +/** +************************************************************************** +* @brief input buffer context +************************************************************************** +*/ typedef struct { UWORD8 *pu1_buf; @@ -191,10 +199,15 @@ typedef struct UWORD32 u4_timestamp_low; UWORD32 u4_timestamp_high; UWORD32 u4_is_free; - void *pv_mb_info; - void *pv_pic_info; -}input_buf_t; - + void *pv_mb_info; + void *pv_pic_info; +} input_buf_t; + +/** +************************************************************************** +* @brief output buffer context +************************************************************************** +*/ typedef struct { UWORD8 *pu1_buf; @@ -202,8 +215,13 @@ typedef struct UWORD32 u4_timestamp_low; UWORD32 u4_timestamp_high; UWORD32 u4_is_free; -}output_buf_t; +} output_buf_t; +/** +************************************************************************** +* @brief recon buffer context +************************************************************************** +*/ typedef struct { UWORD8 *pu1_buf; @@ -211,8 +229,13 @@ typedef struct UWORD32 u4_timestamp_low; UWORD32 u4_timestamp_high; UWORD32 u4_is_free; -}recon_buf_t; +} recon_buf_t; +/** +************************************************************************** +* @brief app context +************************************************************************** +*/ typedef struct { iv_obj_t *ps_enc; @@ -233,12 +256,13 @@ typedef struct IV_ARCH_T e_arch; IV_SOC_T e_soc; - WORD32 header_generated; + WORD32 header_generated; void *pv_codec_obj; UWORD32 u4_num_cores; UWORD32 u4_pre_enc_me; UWORD32 u4_pre_enc_ipe; + CHAR ac_ip_fname[STRLENGTH]; CHAR ac_op_fname[STRLENGTH]; CHAR ac_recon_fname[STRLENGTH]; @@ -246,7 +270,6 @@ typedef struct CHAR ac_mb_info_fname[STRLENGTH]; CHAR ac_pic_info_fname[STRLENGTH]; - FILE *fp_ip; FILE *fp_op; FILE *fp_recon; @@ -254,8 +277,6 @@ typedef struct FILE *fp_psnr_ip; FILE *fp_mb_info; FILE *fp_pic_info; - FILE *fp_dump_op; - UWORD32 u4_loopback; UWORD32 u4_max_frame_rate; @@ -266,13 +287,11 @@ typedef struct UWORD32 u4_max_level; UWORD32 u4_strd; - UWORD32 u4_wd; UWORD32 u4_ht; UWORD32 u4_psnr_enable; - UWORD32 u4_enc_speed; UWORD32 u4_me_speed; UWORD32 u4_enable_fast_sad; @@ -280,9 +299,9 @@ typedef struct UWORD32 u4_rc; UWORD32 u4_max_bitrate; UWORD32 u4_bitrate; - UWORD32 u4_i_qp,u4_i_qp_max,u4_i_qp_min; - UWORD32 u4_p_qp,u4_p_qp_max,u4_p_qp_min; - UWORD32 u4_b_qp,u4_b_qp_max,u4_b_qp_min; + UWORD32 u4_i_qp, u4_i_qp_max, u4_i_qp_min; + UWORD32 u4_p_qp, u4_p_qp_max, u4_p_qp_min; + UWORD32 u4_b_qp, u4_b_qp_max, u4_b_qp_min; UWORD32 u4_air; UWORD32 u4_air_refresh_period; UWORD32 u4_srch_rng_x; @@ -290,14 +309,12 @@ typedef struct UWORD32 u4_i_interval; UWORD32 u4_idr_interval; UWORD32 u4_constrained_intra_pred; - UWORD32 u4_b_frames; UWORD32 u4_num_bframes; UWORD32 u4_disable_deblk_level; UWORD32 u4_hpel; UWORD32 u4_qpel; UWORD32 u4_enable_intra_4x4; IV_PROFILE_T e_profile; - UWORD32 u4_slice_mode; UWORD32 u4_slice_param; UWORD32 u4_entropy_coding_mode; @@ -311,17 +328,17 @@ typedef struct output_buf_t as_output_buf[DEFAULT_MAX_OUTPUT_BUFS]; recon_buf_t as_recon_buf[DEFAULT_MAX_RECON_BUFS]; - DOUBLE adbl_psnr[3]; + DOUBLE adbl_psnr[3]; UWORD32 u4_psnr_cnt; - UWORD8 *pu1_psnr_buf; - UWORD8 u4_psnr_buf_size; + UWORD8 *pu1_psnr_buf; + UWORD8 u4_psnr_buf_size; UWORD32 u4_vbv_buffer_delay; UWORD32 u4_vbv_buf_size; - TIMER enc_start_time; - TIMER enc_last_time; - WORD32 avg_time; + TIMER enc_start_time; + TIMER enc_last_time; + WORD32 avg_time; UWORD32 u4_sei_mdcv_params_present_flag; UWORD32 au4_display_primaries_x[NUM_SEI_MDCV_PRIMARIES]; @@ -369,6 +386,7 @@ typedef struct } app_ctxt_t; + /*****************************************************************************/ /* Function Declarations */ /*****************************************************************************/ @@ -391,10 +409,17 @@ void free_input(app_ctxt_t *ps_app_ctxt); void free_recon(app_ctxt_t *ps_app_ctxt); void free_output(app_ctxt_t *ps_app_ctxt); -void init_raw_buf_descr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_raw_buf, UWORD8 *pu1_buf, IV_COLOR_FORMAT_T e_color_fmt); +void init_raw_buf_descr(app_ctxt_t *ps_app_ctxt, + iv_raw_buf_t *ps_raw_buf, + UWORD8 *pu1_buf, + IV_COLOR_FORMAT_T e_color_fmt); #ifndef MD5_DISABLE -void calc_md5_cksum(UWORD8 *pu1_inbuf,UWORD32 u4_stride,UWORD32 u4_width,UWORD32 u4_height,UWORD8 *pu1_cksum_p ); +void calc_md5_cksum(UWORD8 *pu1_inbuf, + UWORD32 u4_stride, + UWORD32 u4_width, + UWORD32 u4_height, + UWORD8 *pu1_cksum_p); #else #define calc_md5_cksum(a, b, c, d, e) #endif diff --git a/examples/avcenc/avcenc.cmake b/examples/avcenc/avcenc.cmake new file mode 100644 index 0000000..d2089ed --- /dev/null +++ b/examples/avcenc/avcenc.cmake @@ -0,0 +1,11 @@ +list( + APPEND + AVCENC_SRCS + "${AVC_ROOT}/examples/avcenc/input.c" + "${AVC_ROOT}/examples/avcenc/main.c" + "${AVC_ROOT}/examples/avcenc/output.c" + "${AVC_ROOT}/examples/avcenc/psnr.c" + "${AVC_ROOT}/examples/avcenc/recon.c") + +libavc_add_executable(avcenc libavcenc SOURCES ${AVCENC_SRCS}) +target_compile_definitions(avcenc PRIVATE PROFILE_ENABLE MD5_DISABLE) diff --git a/test/encoder/enc.cfg b/examples/avcenc/enc.cfg index ba62199..ba62199 100644 --- a/test/encoder/enc.cfg +++ b/examples/avcenc/enc.cfg diff --git a/test/encoder/input.c b/examples/avcenc/input.c index 77b1090..80a637d 100644 --- a/test/encoder/input.c +++ b/examples/avcenc/input.c @@ -18,6 +18,23 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ +/** +******************************************************************************* +* @file +* input.c +* +* @brief +* Contains functions necessary for managing input buffers +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ + /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ @@ -30,7 +47,6 @@ /* User include files */ #include "ih264_typedefs.h" -#include "ih264_defs.h" #include "iv2.h" #include "ive2.h" #include "ih264e.h" @@ -50,6 +66,11 @@ /* Function Definitions */ /*****************************************************************************/ +/** +************************************************************************** +* @brief read pic level metadata from a file +************************************************************************** +*/ IV_STATUS_T read_pic_info(app_ctxt_t *ps_app_ctxt, void *pv_pic_info) { IV_STATUS_T ret = IV_SUCCESS; @@ -77,6 +98,11 @@ IV_STATUS_T read_pic_info(app_ctxt_t *ps_app_ctxt, void *pv_pic_info) return ret; } +/** +************************************************************************** +* @brief read mb level metadata from a file +************************************************************************** +*/ IV_STATUS_T read_mb_info(app_ctxt_t *ps_app_ctxt, void *pv_mb_info) { IV_STATUS_T ret = IV_SUCCESS; @@ -84,7 +110,7 @@ IV_STATUS_T read_mb_info(app_ctxt_t *ps_app_ctxt, void *pv_mb_info) WORD32 size; WORD32 bytes; - num_mbs = ALIGN16(ps_app_ctxt->u4_wd) * ALIGN16(ps_app_ctxt->u4_ht); + num_mbs = ALIGN16(ps_app_ctxt->u4_wd) * ALIGN16(ps_app_ctxt->u4_ht); num_mbs /= 256; switch(ps_app_ctxt->u4_mb_info_type) @@ -117,52 +143,55 @@ IV_STATUS_T read_mb_info(app_ctxt_t *ps_app_ctxt, void *pv_mb_info) return ret; } +/** +************************************************************************** +* @brief read input from a file +************************************************************************** +*/ IV_STATUS_T read_input(FILE *fp, iv_raw_buf_t *ps_raw_buf) { - WORD32 bytes; - WORD32 wd, ht, strd; - UWORD8 *pu1_buf; WORD32 i; - WORD32 comp; - WORD32 num_comp; - if (IV_YUV_422ILE == ps_raw_buf->e_color_fmt) + if(IV_YUV_422ILE == ps_raw_buf->e_color_fmt) { - wd = ps_raw_buf->au4_wd[0]; - ht = ps_raw_buf->au4_ht[0]; - strd = ps_raw_buf->au4_strd[0]; - pu1_buf = ps_raw_buf->apv_bufs[0]; + WORD32 wd = ps_raw_buf->au4_wd[0]; + WORD32 ht = ps_raw_buf->au4_ht[0]; + WORD32 strd = ps_raw_buf->au4_strd[0]; + UWORD8 *pu1_buf = ps_raw_buf->apv_bufs[0]; for(i = 0; i < ht; i++) { - bytes = fread(pu1_buf, sizeof(UWORD8), wd, fp); - if(bytes != wd ) + WORD32 bytes = fread(pu1_buf, sizeof(UWORD8), wd, fp); + + if(bytes != wd) { - return(IV_FAIL); + return (IV_FAIL); } pu1_buf += strd; } } else { - num_comp = 2; + WORD32 num_comp = 2; + WORD32 comp_idx; if(IV_YUV_420P == ps_raw_buf->e_color_fmt) num_comp = 3; - for(comp = 0; comp < num_comp; comp++) + for(comp_idx = 0; comp_idx < num_comp; comp_idx++) { - wd = ps_raw_buf->au4_wd[comp]; - ht = ps_raw_buf->au4_ht[comp]; - strd = ps_raw_buf->au4_strd[comp]; - pu1_buf = ps_raw_buf->apv_bufs[comp]; + WORD32 wd = ps_raw_buf->au4_wd[comp_idx]; + WORD32 ht = ps_raw_buf->au4_ht[comp_idx]; + WORD32 strd = ps_raw_buf->au4_strd[comp_idx]; + UWORD8 *pu1_buf = ps_raw_buf->apv_bufs[comp_idx]; for(i = 0; i < ht; i++) { - bytes = fread(pu1_buf, sizeof(UWORD8), wd, fp); + WORD32 bytes = fread(pu1_buf, sizeof(UWORD8), wd, fp); + if(bytes != wd) { - return(IV_FAIL); + return (IV_FAIL); } pu1_buf += strd; } @@ -171,53 +200,55 @@ IV_STATUS_T read_input(FILE *fp, iv_raw_buf_t *ps_raw_buf) return IV_SUCCESS; } - +/** +************************************************************************** +* @brief write input to a file +************************************************************************** +*/ IV_STATUS_T dump_input(FILE *fp, iv_raw_buf_t *ps_raw_buf) { - WORD32 bytes; - WORD32 wd, ht, strd; - UWORD8 *pu1_buf; WORD32 i; - WORD32 comp; - WORD32 num_comp; - if (IV_YUV_422ILE == ps_raw_buf->e_color_fmt) + if(IV_YUV_422ILE == ps_raw_buf->e_color_fmt) { - wd = ps_raw_buf->au4_wd[0]; - ht = ps_raw_buf->au4_ht[0]; - strd = ps_raw_buf->au4_strd[0]; - pu1_buf = ps_raw_buf->apv_bufs[0]; + WORD32 wd = ps_raw_buf->au4_wd[0]; + WORD32 ht = ps_raw_buf->au4_ht[0]; + WORD32 strd = ps_raw_buf->au4_strd[0]; + UWORD8 *pu1_buf = ps_raw_buf->apv_bufs[0]; for(i = 0; i < ht; i++) { - bytes = fwrite(pu1_buf, sizeof(UWORD8), wd, fp); - if(bytes != wd ) + WORD32 bytes = fwrite(pu1_buf, sizeof(UWORD8), wd, fp); + + if(bytes != wd) { - return(IV_FAIL); + return (IV_FAIL); } pu1_buf += strd; } } else { - num_comp = 2; + WORD32 num_comp = 2; + WORD32 comp_idx; if(IV_YUV_420P == ps_raw_buf->e_color_fmt) num_comp = 3; - for(comp = 0; comp < num_comp; comp++) + for(comp_idx = 0; comp_idx < num_comp; comp_idx++) { - wd = ps_raw_buf->au4_wd[comp]; - ht = ps_raw_buf->au4_ht[comp]; - strd = ps_raw_buf->au4_strd[comp]; - pu1_buf = ps_raw_buf->apv_bufs[comp]; + WORD32 wd = ps_raw_buf->au4_wd[comp_idx]; + WORD32 ht = ps_raw_buf->au4_ht[comp_idx]; + WORD32 strd = ps_raw_buf->au4_strd[comp_idx]; + UWORD8 *pu1_buf = ps_raw_buf->apv_bufs[comp_idx]; for(i = 0; i < ht; i++) { - bytes = fwrite(pu1_buf, sizeof(UWORD8), wd, fp); + WORD32 bytes = fwrite(pu1_buf, sizeof(UWORD8), wd, fp); + if(bytes != wd) { - return(IV_FAIL); + return (IV_FAIL); } pu1_buf += strd; } @@ -226,77 +257,83 @@ IV_STATUS_T dump_input(FILE *fp, iv_raw_buf_t *ps_raw_buf) return IV_SUCCESS; } +/** +************************************************************************** +* @brief allocate input buffers +************************************************************************** +*/ void allocate_input(app_ctxt_t *ps_app_ctxt) { - WORD32 num_bufs; - WORD32 pic_size; - WORD32 luma_size; - WORD32 chroma_size; + WORD32 luma_size = ps_app_ctxt->u4_wd * ps_app_ctxt->u4_ht; + WORD32 chroma_size = luma_size >> 1; + WORD32 pic_size = luma_size + chroma_size * 2; WORD32 num_mbs; WORD32 i; - UWORD8 *pu1_buf[3]; - ih264e_ctl_getbufinfo_op_t *ps_get_buf_info_op = &ps_app_ctxt->s_get_buf_info_op; - num_bufs = MAX(DEFAULT_NUM_INPUT_BUFS, ps_get_buf_info_op->s_ive_op.u4_min_inp_bufs); + num_bufs = MAX(DEFAULT_NUM_INPUT_BUFS, + ps_get_buf_info_op->s_ive_op.u4_min_inp_bufs); num_bufs = MIN(DEFAULT_MAX_INPUT_BUFS, num_bufs); - /* Size of buffer */ - luma_size = ps_app_ctxt->u4_wd * ps_app_ctxt->u4_ht; - chroma_size = luma_size >> 1; - pic_size = luma_size + chroma_size; - - num_mbs = ALIGN16(ps_app_ctxt->u4_max_wd) * ALIGN16(ps_app_ctxt->u4_max_ht); + num_mbs = ALIGN16(ps_app_ctxt->u4_max_wd) * ALIGN16(ps_app_ctxt->u4_max_ht); num_mbs /= 256; /* Memset the input buffer array to set is_free to 0 */ - memset(ps_app_ctxt->as_input_buf, 0, sizeof(input_buf_t) * DEFAULT_MAX_INPUT_BUFS); + memset(ps_app_ctxt->as_input_buf, 0, + sizeof(input_buf_t) * DEFAULT_MAX_INPUT_BUFS); for(i = 0; i < num_bufs; i++) { - pu1_buf[0] = (UWORD8 *)ih264a_aligned_malloc(16, pic_size); - if(NULL == pu1_buf[0]) + UWORD8 *pu1_buf = (UWORD8 *)ih264a_aligned_malloc(16, pic_size); + if(NULL == pu1_buf) { CHAR ac_error[STRLENGTH]; sprintf(ac_error, "Allocation failed for input buffer of size %d\n", pic_size); codec_exit(ac_error); } - ps_app_ctxt->as_input_buf[i].pu1_buf = pu1_buf[0]; + ps_app_ctxt->as_input_buf[i].pu1_buf = pu1_buf; - pu1_buf[0] = (UWORD8 *)ih264a_aligned_malloc(16, num_mbs * sizeof(ih264e_mb_info_t)); - if(NULL == pu1_buf[0]) + pu1_buf = (UWORD8 *)ih264a_aligned_malloc( + 16, num_mbs * sizeof(ih264e_mb_info_t)); + if(NULL == pu1_buf) { CHAR ac_error[STRLENGTH]; - sprintf(ac_error, "Allocation failed for mb info buffer of size %d\n", + sprintf(ac_error, + "Allocation failed for mb info buffer of size %d\n", (WORD32)(num_mbs * sizeof(ih264e_mb_info_t))); codec_exit(ac_error); } - ps_app_ctxt->as_input_buf[i].pv_mb_info = pu1_buf[0]; - pu1_buf[0] = (UWORD8 *)ih264a_aligned_malloc(16, sizeof(ih264e_pic_info2_t)); - if(NULL == pu1_buf[0]) + ps_app_ctxt->as_input_buf[i].pv_mb_info = pu1_buf; + pu1_buf = (UWORD8 *)ih264a_aligned_malloc(16, + sizeof(ih264e_pic_info2_t)); + if(NULL == pu1_buf) { CHAR ac_error[STRLENGTH]; - sprintf(ac_error, "Allocation failed for pic info buffer of size %d\n", - (WORD32) sizeof(ih264e_pic_info2_t)); + sprintf(ac_error, + "Allocation failed for pic info buffer of size %d\n", + (WORD32)sizeof(ih264e_pic_info2_t)); codec_exit(ac_error); } - ps_app_ctxt->as_input_buf[i].pv_pic_info = pu1_buf[0]; + ps_app_ctxt->as_input_buf[i].pv_pic_info = pu1_buf; ps_app_ctxt->as_input_buf[i].u4_buf_size = pic_size; ps_app_ctxt->as_input_buf[i].u4_is_free = 1; } - return; } - +/** +************************************************************************** +* @brief free input buffers +************************************************************************** +*/ void free_input(app_ctxt_t *ps_app_ctxt) { - WORD32 num_bufs; WORD32 i; - num_bufs = MAX(DEFAULT_NUM_INPUT_BUFS, ps_app_ctxt->s_get_buf_info_op.s_ive_op.u4_min_inp_bufs); + num_bufs = MAX(DEFAULT_NUM_INPUT_BUFS, + ps_app_ctxt->s_get_buf_info_op.s_ive_op.u4_min_inp_bufs); num_bufs = MIN(DEFAULT_MAX_INPUT_BUFS, num_bufs); for(i = 0; i < num_bufs; i++) @@ -305,6 +342,5 @@ void free_input(app_ctxt_t *ps_app_ctxt) ih264a_aligned_free(ps_app_ctxt->as_input_buf[i].pv_mb_info); ih264a_aligned_free(ps_app_ctxt->as_input_buf[i].pv_pic_info); } - return; } diff --git a/test/encoder/main.c b/examples/avcenc/main.c index 25a063c..79629b7 100644 --- a/test/encoder/main.c +++ b/examples/avcenc/main.c @@ -18,6 +18,23 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ +/** +******************************************************************************* +* @file +* main.c +* +* @brief +* sample test application +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ + /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ @@ -35,22 +52,15 @@ #else #include <sys/time.h> #endif + /* User include files */ #include "ih264_typedefs.h" -#include "ih264_defs.h" #include "iv2.h" #include "ive2.h" #include "ih264e.h" #include "app.h" #include "psnr.h" -/* Function declarations */ -#ifndef MD5_DISABLE -void calc_md5_cksum(UWORD8 *pu1_inbuf,UWORD32 u4_stride,UWORD32 u4_width,UWORD32 u4_height,UWORD8 *pu1_cksum_p ); -#else -#define calc_md5_cksum(a, b, c, d, e) -#endif - /*****************************************************************************/ /* Enums */ /*****************************************************************************/ @@ -126,126 +136,129 @@ typedef enum PIC_INFO_TYPE, } ARGUMENT_T; +/*****************************************************************************/ +/* Structure definitions */ +/*****************************************************************************/ + +/** +************************************************************************** +* @brief argument mapping construct +************************************************************************** +*/ typedef struct { - CHAR argument_shortname[8]; - CHAR argument_name[128]; - ARGUMENT_T argument; - CHAR description[512]; + CHAR argument_shortname[8]; + CHAR argument_name[128]; + ARGUMENT_T argument; + CHAR description[512]; } argument_t; -static const argument_t argument_mapping[] = - { - { "--", "--help", HELP, "Print this help\n" }, - { "-i", "--input", INPUT_FILE, "Input file\n" }, - { "-o", "--output", OUTPUT_FILE, "Output file\n" }, - { "--", "--recon_enable", RECON_ENABLE, "Recon enable flag\n" }, - { "-r", "--recon", RECON_FILE, "Recon file \n" }, - { "--", "--input_chroma_format", INPUT_CHROMA_FORMAT, - "Input Chroma format Supported values YUV_420P, YUV_420SP_UV, YUV_420SP_VU\n" }, - { "--", "--recon_chroma_format", RECON_CHROMA_FORMAT, - "Recon Chroma format Supported values YUV_420P, YUV_420SP_UV, YUV_420SP_VU\n" }, - { "-w", "--width", WD, "Width of input file\n" }, - { "-h", "--height", HT, "Height file\n" }, - { "--", "--start_frame", START_FRM, "Starting frame number\n" }, - { "-f", "--num_frames", NUM_FRMS, "Number of frames to be encoded\n" }, - { "--", "--rc", RC, "Rate control mode 0: Constant Qp, 1: Storage, 2: CBR non low delay, 3: CBR low delay \n" }, - { "--", "--max_framerate", MAX_FRAMERATE, "Maximum frame rate \n" }, - { "--", "--tgt_framerate", TGT_FRAMERATE, "Target frame rate \n" }, - { "--", "--src_framerate", SRC_FRAMERATE, "Source frame rate \n" }, - { "--", "--i_interval", I_INTERVAL, "Intra frame interval \n" }, - { "--", "--idr_interval", IDR_INTERVAL, "IDR frame interval \n" }, - { "--", "--constrained_intrapred", CONSTRAINED_INTRA_PRED, "Constrained IntraPrediction Flag \n" }, - { "--", "--bframes", NUM_B_FRMS, "Maximum number of consecutive B frames \n" }, - { "--", "--speed", ENC_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n" }, - { "--", "--me_speed", ME_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n" }, - { "--", "--fast_sad", FAST_SAD, " Flag for faster sad execution\n" }, - { "--", "--alt_ref", ALT_REF , "Flag to enable alternate refernce frames"}, - { "--", "--hpel", HPEL, "Flag to enable/disable Quarter pel estimation \n" }, - { "--", "--qpel", QPEL, "Flag to enable/disable Quarter pel estimation \n" }, - { "--", "--disable_deblock_level", DISABLE_DEBLOCK_LEVEL, - "Disable deblock level - 0 : Enables deblock completely, 1: enables for I and 8th frame , 2: Enables for I only, 3 : disables completely\n" }, - { "--", "--search_range_x", SRCH_RNG_X, "Search range for X \n" }, - { "--", "--search_range_y", SRCH_RNG_Y, "Search range for Y \n" }, - { "--", "--psnr", PSNR, "Enable PSNR computation (Disable while benchmarking performance) \n" }, - { "--", "--pre_enc_me", PRE_ENC_ME, "Flag to enable/disable Pre Enc Motion Estimation\n" }, - { "--", "--pre_enc_ipe", PRE_ENC_IPE, "Flag to enable/disable Pre Enc Intra prediction Estimation\n" }, - { "-n", "--num_cores", NUMCORES, "Number of cores to be used\n" }, - { "--", "--adaptive_intra_refresh", AIR ,"Adaptive Intra Refresh enable/disable\n"}, - { "--", "--air_refresh_period", AIR_REFRESH_PERIOD,"adaptive intra refresh period\n"}, - { "--", "--slice", SLICE_MODE, "Slice mode- 0 :No slice, 1: Bytes per slice, 2: MB/CTB per slice \n" }, - { "--", "--slice_param", SLICE_PARAM, "Slice param value based on slice mode. Slice mode of 1 implies number of bytes per slice, 2 implies number of MBs/CTBs, for 0 value is neglected \n" }, - { "--", "--max_wd", MAX_WD, "Maximum width (Default: 1920) \n" }, - { "--", "--max_ht", MAX_HT, "Maximum height (Default: 1088)\n" }, - { "--", "--max_level", MAX_LEVEL, "Maximum Level (Default: 50)\n" }, - { "--", "--arch", ARCH, "Set Architecture. Supported values ARM_NONEON, ARM_A9Q, ARM_A7, ARM_A5, ARM_NEONINTR, X86_GENERIC, X86_SSSE3, X86_SSE4 \n" }, - { "--", "--soc", SOC, "Set SOC. Supported values GENERIC, HISI_37X \n" }, - { "--", "--chksum", CHKSUM_FILE, "Save Check sum file for recon data\n" }, - { "--", "--chksum_enable", CHKSUM_ENABLE, "Recon MD5 Checksum file\n"}, - { "-c", "--config", CONFIG, "config file (Default: enc.cfg)\n" }, - { "--", "--loopback", LOOPBACK, "Enable encoding in a loop\n" }, - { "--", "--profile", PROFILE, "Profile mode: Supported values BASE, MAIN, HIGH\n" }, - { "--", "--max_bitrate", MAX_BITRATE, "Max bitrate\n"}, - { "--", "--bitrate", BITRATE, "Target bitrate\n"}, - { "--", "--qp_i", I_QP, "QP for I frames\n"}, - { "--", "--qp_p", P_QP, "QP for P frames\n"}, - { "--", "--qp_b", B_QP, "QP for B frames\n"}, - { "--", "--qp_i_max", I_QP_MAX, "Max QP for I frames\n"}, - { "--", "--qp_p_max", P_QP_MAX, "Max QP for P frames\n"}, - { "--", "--qp_b_max", B_QP_MAX, "Max QP for B frames\n"}, - { "--", "--qp_i_min", I_QP_MIN, "Min QP for I frames\n"}, - { "--", "--qp_p_min", P_QP_MIN, "Min QP for P frames\n"}, - { "--", "--qp_b_min", B_QP_MIN, "Min QP for B frames\n"}, - { "--", "--entropy", ENTROPY, "Entropy coding mode(0: CAVLC or 1: CABAC)\n"}, - { "--", "--vbv_delay", VBV_DELAY, "VBV buffer delay\n"}, - { "--", "--vbv_size", VBV_SIZE, "VBV buffer size\n"}, - { "-i4", "--intra_4x4_enable", INTRA_4x4_ENABLE, "Intra 4x4 enable \n" }, - { "--", "--mb_info_file", MB_INFO_FILE, "MB info file\n"}, - { "--", "--mb_info_type", MB_INFO_TYPE, "MB info type\n"}, - { "--", "--pic_info_file", PIC_INFO_FILE, "Pic info file\n"}, - { "--", "--pic_info_type", PIC_INFO_TYPE, "Pic info type\n"}, - }; - - - /*****************************************************************************/ -/* Function Declarations */ +/* Global definitions */ /*****************************************************************************/ +/** +************************************************************************** +* @brief list of supported arguments +************************************************************************** +*/ +static const argument_t argument_mapping[] = +{ + { "--", "--help", HELP, "Print this help\n" }, + { "-i", "--input", INPUT_FILE, "Input file\n" }, + { "-o", "--output", OUTPUT_FILE, "Output file\n" }, + { "--", "--recon_enable", RECON_ENABLE, "Recon enable flag\n" }, + { "-r", "--recon", RECON_FILE, "Recon file \n" }, + { "--", "--input_chroma_format", INPUT_CHROMA_FORMAT, + "Input Chroma format Supported values YUV_420P, YUV_420SP_UV, YUV_420SP_VU\n" }, + { "--", "--recon_chroma_format", RECON_CHROMA_FORMAT, + "Recon Chroma format Supported values YUV_420P, YUV_420SP_UV, YUV_420SP_VU\n" }, + { "-w", "--width", WD, "Width of input file\n" }, + { "-h", "--height", HT, "Height of input file\n" }, + { "--", "--start_frame", START_FRM, "Starting frame number\n" }, + { "-f", "--num_frames", NUM_FRMS, "Number of frames to be encoded\n" }, + { "--", "--rc", RC, "Rate control mode 0: Constant Qp, 1: Storage, 2: CBR non low delay \n" }, + { "--", "--max_framerate", MAX_FRAMERATE, "Maximum frame rate \n" }, + { "--", "--tgt_framerate", TGT_FRAMERATE, "Target frame rate \n" }, + { "--", "--src_framerate", SRC_FRAMERATE, "Source frame rate \n" }, + { "--", "--i_interval", I_INTERVAL, "Intra frame interval \n" }, + { "--", "--idr_interval", IDR_INTERVAL, "IDR frame interval \n" }, + { "--", "--constrained_intrapred", CONSTRAINED_INTRA_PRED, "Constrained IntraPrediction Flag \n" }, + { "--", "--bframes", NUM_B_FRMS, "Maximum number of consecutive B frames \n" }, + { "--", "--speed", ENC_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n" }, + { "--", "--me_speed", ME_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n" }, + { "--", "--fast_sad", FAST_SAD, "Flag for faster sad execution\n" }, + { "--", "--alt_ref", ALT_REF , "Flag to enable alternate reference frames\n"}, + { "--", "--hpel", HPEL, "Flag to enable/disable Quarter pel estimation \n" }, + { "--", "--qpel", QPEL, "Flag to enable/disable Quarter pel estimation \n" }, + { "--", "--disable_deblock_level", DISABLE_DEBLOCK_LEVEL, + "Disable deblock level - 0 : Enables deblock completely, " + "1: enables for I and 8th frame , 2: Enables for I only, " + "3 : disables completely\n" }, + { "--", "--search_range_x", SRCH_RNG_X, "Search range for X \n" }, + { "--", "--search_range_y", SRCH_RNG_Y, "Search range for Y \n" }, + { "--", "--psnr", PSNR, "Enable PSNR computation (Disable while benchmarking performance) \n" }, + { "--", "--pre_enc_me", PRE_ENC_ME, "Flag to enable/disable Pre Enc Motion Estimation\n" }, + { "--", "--pre_enc_ipe", PRE_ENC_IPE, "Flag to enable/disable Pre Enc Intra prediction Estimation\n" }, + { "-n", "--num_cores", NUMCORES, "Number of cores to be used\n" }, + { "--", "--adaptive_intra_refresh", AIR, "Adaptive Intra Refresh enable/disable\n"}, + { "--", "--air_refresh_period", AIR_REFRESH_PERIOD,"adaptive intra refresh period\n"}, + { "--", "--slice", SLICE_MODE, "Slice mode - 0 :No slice, 1: Bytes per slice, 2: MB/CTB per slice\n" }, + { "--", "--slice_param", SLICE_PARAM, "Slice param value based on slice mode. Slice mode of 1 implies number of bytes per slice, 2 implies number of MBs/CTBs, for 0 value is neglected \n" }, + { "--", "--max_wd", MAX_WD, "Maximum width (Default: 1920) \n" }, + { "--", "--max_ht", MAX_HT, "Maximum height (Default: 1088)\n" }, + { "--", "--max_level", MAX_LEVEL, "Maximum Level (Default: 50)\n" }, + { "--", "--arch", ARCH, "Set Architecture. Supported values ARM_NONEON, ARM_A9Q, ARM_A7, ARM_A5, ARM_NEONINTR, X86_GENERIC, X86_SSSE3, X86_SSE4 \n" }, + { "--", "--soc", SOC, "Set SOC. Supported values GENERIC\n" }, + { "--", "--chksum", CHKSUM_FILE, "Save Check sum file for recon data\n" }, + { "--", "--chksum_enable", CHKSUM_ENABLE, "Recon MD5 Checksum file\n"}, + { "-c", "--config", CONFIG, "config file (Default: enc.cfg)\n" }, + { "--", "--loopback", LOOPBACK, "Enable encoding in a loop\n" }, + { "--", "--profile", PROFILE, "Profile mode: Supported values BASE, MAIN, HIGH\n" }, + { "--", "--max_bitrate", MAX_BITRATE, "Max bitrate\n"}, + { "--", "--bitrate", BITRATE, "Target bitrate\n"}, + { "--", "--qp_i", I_QP, "QP for I frames\n"}, + { "--", "--qp_p", P_QP, "QP for P frames\n"}, + { "--", "--qp_b", B_QP, "QP for B frames\n"}, + { "--", "--qp_i_max",I_QP_MAX, "Max QP for I frames\n"}, + { "--", "--qp_p_max", P_QP_MAX, "Max QP for P frames\n"}, + { "--", "--qp_b_max", B_QP_MAX, "Max QP for B frames\n"}, + { "--", "--qp_i_min", I_QP_MIN, "Min QP for I frames\n"}, + { "--", "--qp_p_min", P_QP_MIN, "Min QP for P frames\n"}, + { "--", "--qp_b_min", B_QP_MIN, "Min QP for B frames\n"}, + { "--", "--entropy", ENTROPY, "Entropy coding mode(0: CAVLC or 1: CABAC)\n"}, + { "--", "--vbv_delay", VBV_DELAY, "VBV buffer delay\n"}, + { "--", "--vbv_size", VBV_SIZE, "VBV buffer size\n"}, + { "--", "--intra_4x4_enable", INTRA_4x4_ENABLE, "Intra 4x4 enable \n" }, + { "--", "--mb_info_file", MB_INFO_FILE, "MB info file\n"}, + { "--", "--mb_info_type", MB_INFO_TYPE, "MB info type\n"}, + { "--", "--pic_info_file", PIC_INFO_FILE, "Pic info file\n"}, + { "--", "--pic_info_type", PIC_INFO_TYPE, "Pic info type\n"}, +}; /*****************************************************************************/ /* Function Definitions */ /*****************************************************************************/ - +/** +******************************************************************************* +* +* @brief Returns malloc data. Ideally should return aligned memory +* +* @param[in] alignment +* Alignment +* +* @param[in] size +* size +* +* @returns pointer to allocated memory +* +* @remarks none +* +******************************************************************************* +*/ #if(defined X86) && (defined X86_MINGW) -/*****************************************************************************/ -/* Function to print library calls */ -/*****************************************************************************/ -/*****************************************************************************/ -/* */ -/* Function Name : memalign */ -/* */ -/* Description : Returns malloc data. Ideally should return aligned memory*/ -/* support alignment will be added later */ -/* */ -/* Inputs : alignment */ -/* size */ -/* Globals : */ -/* Processing : */ -/* */ -/* Outputs : */ -/* Returns : */ -/* */ -/* Issues : */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 09 2012 100189 Initial Version */ -/* */ -/*****************************************************************************/ void * ih264a_aligned_malloc(WORD32 alignment, WORD32 size) { @@ -291,53 +304,43 @@ void ih264a_aligned_free(void *pv_buf) #endif -/*****************************************************************************/ -/* */ -/* Function Name : codec_exit */ -/* */ -/* Description : handles unrecoverable errors */ -/* Inputs : Error message */ -/* Globals : None */ -/* Processing : Prints error message to console and exits. */ -/* Outputs : Error message to the console */ -/* Returns : None */ -/* */ -/* Issues : */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 07 06 2006 Sankar Creation */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief handles unrecoverable errors. Prints error message to console and exits. +* +* @param[in] pc_err_message +* error message +* +* @returns none +* +******************************************************************************* +*/ void codec_exit(CHAR *pc_err_message) { printf("%s\n", pc_err_message); exit(-1); } -/*****************************************************************************/ -/* */ -/* Function Name : codec_exit */ -/* */ -/* Description : handles unrecoverable errors */ -/* Inputs : Error message */ -/* Globals : None */ -/* Processing : Prints error message to console and exits. */ -/* Outputs : Error mesage to the console */ -/* Returns : None */ -/* */ -/* Issues : */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 07 06 2006 Sankar Creation */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief Maps input string to color format +* +* @param[in] value +* string +* +* @returns color format ID +* +* @remarks If the input string is not recognized, display a message and choose +* YUV420P as color format +* +******************************************************************************* +*/ IV_COLOR_FORMAT_T get_chroma_fmt(CHAR *value) { - IV_COLOR_FORMAT_T e_chroma_format; + IV_COLOR_FORMAT_T e_chroma_format = IV_YUV_420P; + if((strcmp(value, "YUV_420P")) == 0) e_chroma_format = IV_YUV_420P; else if((strcmp(value, "YUV_422ILE")) == 0) @@ -351,35 +354,30 @@ IV_COLOR_FORMAT_T get_chroma_fmt(CHAR *value) else if((strcmp(value, "YUV_420SP_VU")) == 0) e_chroma_format = IV_YUV_420SP_VU; else - { printf("\nInvalid colour format setting it to IV_YUV_420P\n"); - e_chroma_format = IV_YUV_420P; - } + return e_chroma_format; } -/*****************************************************************************/ -/* */ -/* Function Name : codec_exit */ -/* */ -/* Description : handles unrecoverable errors */ -/* Inputs : Error message */ -/* Globals : None */ -/* Processing : Prints error message to console and exits. */ -/* Outputs : Error mesage to the console */ -/* Returns : None */ -/* */ -/* Issues : */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 07 06 2006 Sankar Creation */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief Maps input string to a speed preset +* +* @param[in] value +* string +* +* @returns speed preset ID +* +* @remarks If the input string is not recognized, display a message and choose +* IVE_FASTEST as speed preset +* +******************************************************************************* +*/ IVE_SPEED_CONFIG get_speed_preset(CHAR *value) { - IVE_SPEED_CONFIG e_enc_speed_preset; + IVE_SPEED_CONFIG e_enc_speed_preset = IVE_FASTEST; + if((strcmp(value, "CONFIG")) == 0) e_enc_speed_preset = IVE_CONFIG; else if((strcmp(value, "SLOWEST")) == 0) @@ -393,40 +391,21 @@ IVE_SPEED_CONFIG get_speed_preset(CHAR *value) else if((strcmp(value, "FASTEST")) == 0) e_enc_speed_preset = IVE_FASTEST; else - { printf("\nInvalid speed preset, setting it to IVE_FASTEST\n"); - e_enc_speed_preset = IVE_FASTEST; - } + return e_enc_speed_preset; } -/*****************************************************************************/ -/* */ -/* Function Name : print_usage */ -/* */ -/* Description : Prints argument format */ -/* */ -/* */ -/* Inputs : */ -/* Globals : */ -/* Processing : Prints argument format */ -/* */ -/* Outputs : */ -/* Returns : */ -/* */ -/* Issues : */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 09 2012 100189 Initial Version */ -/* */ -/*****************************************************************************/ - +/** +******************************************************************************* +* @brief prints application usage +******************************************************************************* +*/ void print_usage(void) { WORD32 i = 0; WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t); + printf("\nUsage:\n"); while(i < num_entries) { @@ -436,364 +415,353 @@ void print_usage(void) } } -/*****************************************************************************/ -/* */ -/* Function Name : get_argument */ -/* */ -/* Description : Gets argument for a given string */ -/* */ -/* */ -/* Inputs : name */ -/* Globals : */ -/* Processing : Searches the given string in the array and returns */ -/* appropriate argument ID */ -/* */ -/* Outputs : Argument ID */ -/* Returns : Argument ID */ -/* */ -/* Issues : */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 09 2012 100189 Initial Version */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief Maps input string to a argument +* +* @param[in] value +* string +* +* @returns argument ID +* +* @remarks If the input string is not recognized, returns INVALID +* +******************************************************************************* +*/ ARGUMENT_T get_argument(CHAR *name) { - WORD32 i = 0; + WORD32 i; WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t); - while(i < num_entries) + + for(i = 0;i < num_entries;i++) { - if((0 == strcmp(argument_mapping[i].argument_name, name)) || - ((0 == strcmp(argument_mapping[i].argument_shortname, name)) && - (0 != strcmp(argument_mapping[i].argument_shortname, "--")))) + if((0 == strcmp(argument_mapping[i].argument_name, name)) || + ((0 == strcmp(argument_mapping[i].argument_shortname, name)) && + (0 != strcmp(argument_mapping[i].argument_shortname, "--")))) { return argument_mapping[i].argument; } - i++; } return INVALID; } -/*****************************************************************************/ -/* */ -/* Function Name : get_argument */ -/* */ -/* Description : Gets argument for a given string */ -/* */ -/* */ -/* Inputs : name */ -/* Globals : */ -/* Processing : Searches the given string in the array and returns */ -/* appropriate argument ID */ -/* */ -/* Outputs : Argument ID */ -/* Returns : Argument ID */ -/* */ -/* Issues : */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 09 2012 100189 Initial Version */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief Parse input argument +* +* @param[in] ps_app_ctxt +* pointer to application context +* +* @param[in] argument +* argument string +* +* @param[in] value +* value corresponding to the argument +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void parse_argument(app_ctxt_t *ps_app_ctxt, CHAR *argument, CHAR *value) { - ARGUMENT_T arg; + ARGUMENT_T arg = get_argument(argument); - arg = get_argument(argument); switch(arg) { - case HELP: - print_usage(); - exit(-1); - break; - case SLICE_MODE: - sscanf(value, "%d", &ps_app_ctxt->u4_slice_mode); - break; - case SLICE_PARAM: - sscanf(value, "%d", &ps_app_ctxt->u4_slice_param); - break; - case INPUT_FILE: - sscanf(value, "%s", ps_app_ctxt->ac_ip_fname); - break; - - case OUTPUT_FILE: - sscanf(value, "%s", ps_app_ctxt->ac_op_fname); - break; - - case RECON_FILE: - sscanf(value, "%s", ps_app_ctxt->ac_recon_fname); - break; - - case RECON_ENABLE: - sscanf(value, "%d", &ps_app_ctxt->u4_recon_enable); - break; - - case CHKSUM_FILE: - sscanf(value, "%s", ps_app_ctxt->ac_chksum_fname); - break; - - case CHKSUM_ENABLE: - sscanf(value, "%d", &ps_app_ctxt->u4_chksum_enable); - break; - - case MB_INFO_FILE: - sscanf(value, "%s", ps_app_ctxt->ac_mb_info_fname); - break; - - case MB_INFO_TYPE: - sscanf(value, "%d", &ps_app_ctxt->u4_mb_info_type); - break; - - case PIC_INFO_FILE: - sscanf(value, "%s", ps_app_ctxt->ac_pic_info_fname); - break; - - case PIC_INFO_TYPE: - sscanf(value, "%d", &ps_app_ctxt->u4_pic_info_type); - break; - - case INPUT_CHROMA_FORMAT: - ps_app_ctxt->e_inp_color_fmt = get_chroma_fmt(value); - break; - - case RECON_CHROMA_FORMAT: - ps_app_ctxt->e_recon_color_fmt = get_chroma_fmt(value); - break; - - case MAX_WD: - sscanf(value, "%d", &ps_app_ctxt->u4_max_wd); - break; - - case MAX_HT: - sscanf(value, "%d", &ps_app_ctxt->u4_max_ht); - break; - - case WD: - sscanf(value, "%d", &ps_app_ctxt->u4_wd); - break; - - case HT: - sscanf(value, "%d", &ps_app_ctxt->u4_ht); - break; - - case MAX_LEVEL: - sscanf(value, "%d", &ps_app_ctxt->u4_max_level); - break; - - case ENC_SPEED: - ps_app_ctxt->u4_enc_speed = get_speed_preset(value); - break; - - case ME_SPEED: - sscanf(value, "%d", &ps_app_ctxt->u4_me_speed); - break; - - case START_FRM: - sscanf(value, "%d", &ps_app_ctxt->u4_start_frm); - break; - - case NUM_FRMS: - sscanf(value, "%d", &ps_app_ctxt->u4_max_num_frms); - break; - - case MAX_FRAMERATE: - sscanf(value, "%d", &ps_app_ctxt->u4_max_frame_rate); - if(ps_app_ctxt->u4_max_frame_rate <= 0) - ps_app_ctxt->u4_max_frame_rate = DEFAULT_MAX_FRAMERATE; - break; - - case SRC_FRAMERATE: - sscanf(value, "%d", &ps_app_ctxt->u4_src_frame_rate); - if(ps_app_ctxt->u4_src_frame_rate <= 0) - ps_app_ctxt->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE; - break; - - case TGT_FRAMERATE: - sscanf(value, "%d", &ps_app_ctxt->u4_tgt_frame_rate); - if(ps_app_ctxt->u4_tgt_frame_rate <= 0) - ps_app_ctxt->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE; - break; - - case RC: - sscanf(value, "%d", &ps_app_ctxt->u4_rc); - break; - - case MAX_BITRATE: - sscanf(value, "%d", &ps_app_ctxt->u4_max_bitrate); - break; - - case BITRATE: - sscanf(value, "%d", &ps_app_ctxt->u4_bitrate); - break; - - case I_QP: - sscanf(value, "%d", &ps_app_ctxt->u4_i_qp); - break; - - case I_QP_MAX: - sscanf(value, "%d", &ps_app_ctxt->u4_i_qp_max); - break; - - case I_QP_MIN: - sscanf(value, "%d", &ps_app_ctxt->u4_i_qp_min); - break; - - case P_QP: - sscanf(value, "%d", &ps_app_ctxt->u4_p_qp); - break; - - case P_QP_MAX: - sscanf(value, "%d", &ps_app_ctxt->u4_p_qp_max); - break; - - case P_QP_MIN: - sscanf(value, "%d", &ps_app_ctxt->u4_p_qp_min); - break; - - case B_QP: - sscanf(value, "%d", &ps_app_ctxt->u4_b_qp); - break; - - case B_QP_MAX: - sscanf(value, "%d", &ps_app_ctxt->u4_b_qp_max); - break; - - case B_QP_MIN: - sscanf(value, "%d", &ps_app_ctxt->u4_b_qp_min); - break; - - case ENTROPY: - sscanf(value, "%d", &ps_app_ctxt->u4_entropy_coding_mode); - break; - - case AIR: - sscanf(value, "%d", &ps_app_ctxt->u4_air); - break; - - case ARCH: - if((strcmp(value, "ARM_NONEON")) == 0) - ps_app_ctxt->e_arch = ARCH_ARM_NONEON; - else if((strcmp(value, "ARM_A9Q")) == 0) - ps_app_ctxt->e_arch = ARCH_ARM_A9Q; - else if((strcmp(value, "ARM_A7")) == 0) - ps_app_ctxt->e_arch = ARCH_ARM_A7; - else if((strcmp(value, "ARM_A5")) == 0) - ps_app_ctxt->e_arch = ARCH_ARM_A5; - else if((strcmp(value, "ARM_NEONINTR")) == 0) - ps_app_ctxt->e_arch = ARCH_ARM_NEONINTR; - else if((strcmp(value, "X86_GENERIC")) == 0) - ps_app_ctxt->e_arch = ARCH_X86_GENERIC; - else if((strcmp(value, "X86_SSSE3")) == 0) - ps_app_ctxt->e_arch = ARCH_X86_SSSE3; - else if((strcmp(value, "X86_SSE42")) == 0) - ps_app_ctxt->e_arch = ARCH_X86_SSE42; - else if((strcmp(value, "ARM_A53")) == 0) - ps_app_ctxt->e_arch = ARCH_ARM_A53; - else if((strcmp(value, "ARM_A57")) == 0) - ps_app_ctxt->e_arch = ARCH_ARM_A57; - else if((strcmp(value, "ARM_V8_NEON")) == 0) - ps_app_ctxt->e_arch = ARCH_ARM_V8_NEON; - else - { - printf("\nInvalid Arch. Setting it to ARM_A9Q\n"); - ps_app_ctxt->e_arch = ARCH_ARM_A9Q; - } - - break; - case SOC: - if((strcmp(value, "GENERIC")) == 0) - ps_app_ctxt->e_soc = SOC_GENERIC; - else if((strcmp(value, "HISI_37X")) == 0) - ps_app_ctxt->e_soc = SOC_HISI_37X; - else - { - ps_app_ctxt->e_soc = SOC_GENERIC; - } - break; - - case NUMCORES: - sscanf(value, "%d", &ps_app_ctxt->u4_num_cores); - break; - - case LOOPBACK: - sscanf(value, "%d", &ps_app_ctxt->u4_loopback); - break; - - case PRE_ENC_ME: - sscanf(value, "%d", &ps_app_ctxt->u4_pre_enc_me); - break; - - case PRE_ENC_IPE: - sscanf(value, "%d", &ps_app_ctxt->u4_pre_enc_ipe); - break; - - case HPEL: - sscanf(value, "%d", &ps_app_ctxt->u4_hpel); - break; - - case QPEL: - sscanf(value, "%d", &ps_app_ctxt->u4_qpel); - break; - - case SRCH_RNG_X: - sscanf(value, "%d", &ps_app_ctxt->u4_srch_rng_x); - break; - - case SRCH_RNG_Y: - sscanf(value, "%d", &ps_app_ctxt->u4_srch_rng_y); - break; - - case I_INTERVAL: - sscanf(value, "%d", &ps_app_ctxt->u4_i_interval); - break; - - case IDR_INTERVAL: - sscanf(value, "%d", &ps_app_ctxt->u4_idr_interval); - break; - - case CONSTRAINED_INTRA_PRED: - sscanf(value, "%d", &ps_app_ctxt->u4_constrained_intra_pred); - break; - - case NUM_B_FRMS: - sscanf(value, "%d", &ps_app_ctxt->u4_num_bframes); - break; - - case DISABLE_DEBLOCK_LEVEL: - sscanf(value, "%d", &ps_app_ctxt->u4_disable_deblk_level); - break; - - case VBV_DELAY: - sscanf(value, "%d", &ps_app_ctxt->u4_vbv_buffer_delay); - break; - - case VBV_SIZE: - sscanf(value, "%d", &ps_app_ctxt->u4_vbv_buf_size); - break; - - case FAST_SAD: - sscanf(value, "%d", &ps_app_ctxt->u4_enable_fast_sad); - break; - - case ALT_REF: - sscanf(value, "%d", &ps_app_ctxt->u4_enable_alt_ref); - break; - - case AIR_REFRESH_PERIOD: - sscanf(value, "%d", &ps_app_ctxt->u4_air_refresh_period); - break; - - case PROFILE: + case HELP: + print_usage(); + exit(-1); + break; + + case SLICE_MODE: + sscanf(value, "%d", &ps_app_ctxt->u4_slice_mode); + break; + + case SLICE_PARAM: + sscanf(value, "%d", &ps_app_ctxt->u4_slice_param); + break; + + case INPUT_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_ip_fname); + break; + + case OUTPUT_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_op_fname); + break; + + case RECON_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_recon_fname); + break; + + case RECON_ENABLE: + sscanf(value, "%d", &ps_app_ctxt->u4_recon_enable); + break; + + case CHKSUM_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_chksum_fname); + break; + + case CHKSUM_ENABLE: + sscanf(value, "%d", &ps_app_ctxt->u4_chksum_enable); + break; + + case MB_INFO_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_mb_info_fname); + break; + + case MB_INFO_TYPE: + sscanf(value, "%d", &ps_app_ctxt->u4_mb_info_type); + break; + + case PIC_INFO_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_pic_info_fname); + break; + + case PIC_INFO_TYPE: + sscanf(value, "%d", &ps_app_ctxt->u4_pic_info_type); + break; + + case INPUT_CHROMA_FORMAT: + ps_app_ctxt->e_inp_color_fmt = get_chroma_fmt(value); + break; + + case RECON_CHROMA_FORMAT: + ps_app_ctxt->e_recon_color_fmt = get_chroma_fmt(value); + break; + + case MAX_WD: + sscanf(value, "%d", &ps_app_ctxt->u4_max_wd); + break; + + case MAX_HT: + sscanf(value, "%d", &ps_app_ctxt->u4_max_ht); + break; + + case WD: + sscanf(value, "%d", &ps_app_ctxt->u4_wd); + break; + + case HT: + sscanf(value, "%d", &ps_app_ctxt->u4_ht); + break; + + case MAX_LEVEL: + sscanf(value, "%d", &ps_app_ctxt->u4_max_level); + break; + + case ENC_SPEED: + ps_app_ctxt->u4_enc_speed = get_speed_preset(value); + break; + + case ME_SPEED: + sscanf(value, "%d", &ps_app_ctxt->u4_me_speed); + break; + + case START_FRM: + sscanf(value, "%d", &ps_app_ctxt->u4_start_frm); + break; + + case NUM_FRMS: + sscanf(value, "%d", &ps_app_ctxt->u4_max_num_frms); + break; + + case MAX_FRAMERATE: + sscanf(value, "%d", &ps_app_ctxt->u4_max_frame_rate); + if(ps_app_ctxt->u4_max_frame_rate <= 0) + ps_app_ctxt->u4_max_frame_rate = DEFAULT_MAX_FRAMERATE; + break; + + case SRC_FRAMERATE: + sscanf(value, "%d", &ps_app_ctxt->u4_src_frame_rate); + if(ps_app_ctxt->u4_src_frame_rate <= 0) + ps_app_ctxt->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE; + break; + + case TGT_FRAMERATE: + sscanf(value, "%d", &ps_app_ctxt->u4_tgt_frame_rate); + if(ps_app_ctxt->u4_tgt_frame_rate <= 0) + ps_app_ctxt->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE; + break; + + case RC: + sscanf(value, "%d", &ps_app_ctxt->u4_rc); + break; + + case MAX_BITRATE: + sscanf(value, "%d", &ps_app_ctxt->u4_max_bitrate); + break; + + case BITRATE: + sscanf(value, "%d", &ps_app_ctxt->u4_bitrate); + break; + + case I_QP: + sscanf(value, "%d", &ps_app_ctxt->u4_i_qp); + break; + + case I_QP_MAX: + sscanf(value, "%d", &ps_app_ctxt->u4_i_qp_max); + break; + + case I_QP_MIN: + sscanf(value, "%d", &ps_app_ctxt->u4_i_qp_min); + break; + + case P_QP: + sscanf(value, "%d", &ps_app_ctxt->u4_p_qp); + break; + + case P_QP_MAX: + sscanf(value, "%d", &ps_app_ctxt->u4_p_qp_max); + break; + + case P_QP_MIN: + sscanf(value, "%d", &ps_app_ctxt->u4_p_qp_min); + break; + + case B_QP: + sscanf(value, "%d", &ps_app_ctxt->u4_b_qp); + break; + + case B_QP_MAX: + sscanf(value, "%d", &ps_app_ctxt->u4_b_qp_max); + break; + + case B_QP_MIN: + sscanf(value, "%d", &ps_app_ctxt->u4_b_qp_min); + break; + + case ENTROPY: + sscanf(value, "%d", &ps_app_ctxt->u4_entropy_coding_mode); + break; + + case AIR: + sscanf(value, "%d", &ps_app_ctxt->u4_air); + break; + + case ARCH: + if((strcmp(value, "ARM_NONEON")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_NONEON; + else if((strcmp(value, "ARM_A9Q")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_A9Q; + else if((strcmp(value, "ARM_A7")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_A7; + else if((strcmp(value, "ARM_A5")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_A5; + else if((strcmp(value, "ARM_NEONINTR")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_NEONINTR; + else if((strcmp(value, "X86_GENERIC")) == 0) + ps_app_ctxt->e_arch = ARCH_X86_GENERIC; + else if((strcmp(value, "X86_SSSE3")) == 0) + ps_app_ctxt->e_arch = ARCH_X86_SSSE3; + else if((strcmp(value, "X86_SSE42")) == 0) + ps_app_ctxt->e_arch = ARCH_X86_SSE42; + else if((strcmp(value, "ARM_A53")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_A53; + else if((strcmp(value, "ARM_A57")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_A57; + else if((strcmp(value, "ARM_V8_NEON")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_V8_NEON; + else + { + printf("\nInvalid Arch. Setting it to ARM_A9Q\n"); + ps_app_ctxt->e_arch = ARCH_ARM_A9Q; + } + break; + + case SOC: + if((strcmp(value, "GENERIC")) == 0) + ps_app_ctxt->e_soc = SOC_GENERIC; + else + { + printf("\nInvalid SOC. Setting it to SOC_GENERIC\n"); + ps_app_ctxt->e_soc = SOC_GENERIC; + } + break; + + case NUMCORES: + sscanf(value, "%d", &ps_app_ctxt->u4_num_cores); + break; + + case LOOPBACK: + sscanf(value, "%d", &ps_app_ctxt->u4_loopback); + break; + + case PRE_ENC_ME: + sscanf(value, "%d", &ps_app_ctxt->u4_pre_enc_me); + break; + + case PRE_ENC_IPE: + sscanf(value, "%d", &ps_app_ctxt->u4_pre_enc_ipe); + break; + + case HPEL: + sscanf(value, "%d", &ps_app_ctxt->u4_hpel); + break; + + case QPEL: + sscanf(value, "%d", &ps_app_ctxt->u4_qpel); + break; + + case SRCH_RNG_X: + sscanf(value, "%d", &ps_app_ctxt->u4_srch_rng_x); + break; + + case SRCH_RNG_Y: + sscanf(value, "%d", &ps_app_ctxt->u4_srch_rng_y); + break; + + case I_INTERVAL: + sscanf(value, "%d", &ps_app_ctxt->u4_i_interval); + break; + + case IDR_INTERVAL: + sscanf(value, "%d", &ps_app_ctxt->u4_idr_interval); + break; + + case CONSTRAINED_INTRA_PRED: + sscanf(value, "%d", &ps_app_ctxt->u4_constrained_intra_pred); + break; + + case NUM_B_FRMS: + sscanf(value, "%d", &ps_app_ctxt->u4_num_bframes); + break; + + case DISABLE_DEBLOCK_LEVEL: + sscanf(value, "%d", &ps_app_ctxt->u4_disable_deblk_level); + break; + + case VBV_DELAY: + sscanf(value, "%d", &ps_app_ctxt->u4_vbv_buffer_delay); + break; + + case VBV_SIZE: + sscanf(value, "%d", &ps_app_ctxt->u4_vbv_buf_size); + break; + + case FAST_SAD: + sscanf(value, "%d", &ps_app_ctxt->u4_enable_fast_sad); + break; + + case ALT_REF: + sscanf(value, "%d", &ps_app_ctxt->u4_enable_alt_ref); + break; + + case AIR_REFRESH_PERIOD: + sscanf(value, "%d", &ps_app_ctxt->u4_air_refresh_period); + break; + + case PROFILE: if((strcmp(value, "BASE")) == 0) ps_app_ctxt->e_profile = IV_PROFILE_BASE; else if((strcmp(value, "MAIN")) == 0) - ps_app_ctxt->e_profile = IV_PROFILE_MAIN; + ps_app_ctxt->e_profile = IV_PROFILE_MAIN; else if((strcmp(value, "HIGH")) == 0) - ps_app_ctxt->e_profile = IV_PROFILE_HIGH; + ps_app_ctxt->e_profile = IV_PROFILE_HIGH; else { printf("\nInvalid profile. Setting it to BASE\n"); @@ -801,74 +769,92 @@ void parse_argument(app_ctxt_t *ps_app_ctxt, CHAR *argument, CHAR *value) } break; - case PSNR: - sscanf(value, "%d", &ps_app_ctxt->u4_psnr_enable); - break; - - case INTRA_4x4_ENABLE: - sscanf(value, "%d", &ps_app_ctxt->u4_enable_intra_4x4); - break; + case PSNR: + sscanf(value, "%d", &ps_app_ctxt->u4_psnr_enable); + break; + case INTRA_4x4_ENABLE: + sscanf(value, "%d", &ps_app_ctxt->u4_enable_intra_4x4); + break; - case INVALID: + case INVALID: default: printf("Ignoring argument : %s\n", argument); break; } } -/*****************************************************************************/ -/* */ -/* Function Name : read_cfg_file */ -/* */ -/* Description : Reads arguments from a configuration file */ -/* */ -/* */ -/* Inputs : ps_app_ctxt : Application context */ -/* fp_cfg_file : Configuration file handle */ -/* Globals : */ -/* Processing : Parses the arguments and fills in the application context*/ -/* */ -/* Outputs : Arguments parsed */ -/* Returns : None */ -/* */ -/* Issues : */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 07 09 2012 100189 Initial Version */ -/* */ -/*****************************************************************************/ +/** +******************************************************************************* +* +* @brief Parse config file +* +* @param[in] ps_app_ctxt +* pointer to application context +* +* @param[in] fp_cfg +* config file pointer +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void read_cfg_file(app_ctxt_t *ps_app_ctxt, FILE *fp_cfg) { - CHAR line[STRLENGTH]; - CHAR description[STRLENGTH]; - CHAR value[STRLENGTH]; - CHAR argument[STRLENGTH]; - - while(0 == (feof(fp_cfg))) + while(1) { - int ret; - line[0] = '\0'; - if(NULL == fgets(line, sizeof(line), fp_cfg)) - break; - argument[0] = '\0'; - /* Reading Input File Name */ - ret = sscanf(line, "%s %s %s", argument, value, description); - if(ret < 2) + CHAR line[STRLENGTH] = {'\0'}; + CHAR argument[STRLENGTH] = {'\0'}; + CHAR value[STRLENGTH]; + CHAR description[STRLENGTH]; + + if(NULL == fgets(line, STRLENGTH, fp_cfg)) return; + + /* split string on whitespace */ + sscanf(line, "%s %s %s", argument, value, description); + if(argument[0] == '\0') continue; parse_argument(ps_app_ctxt, argument, value); } } +/** +******************************************************************************* +* +* @brief handles unrecoverable errors. Prints error message to console and exits. +* +* @param[in] pc_err_message +* error message +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void invalid_argument_exit(CHAR *pc_err_message) { print_usage(); codec_exit(pc_err_message); } +/** +******************************************************************************* +* +* @brief validate configured params +* +* @param[in] ps_app_ctxt +* pointer to application context +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void validate_params(app_ctxt_t *ps_app_ctxt) { CHAR ac_error[STRLENGTH]; @@ -899,118 +885,125 @@ void validate_params(app_ctxt_t *ps_app_ctxt) sprintf(ac_error, "Invalid height: %d", ps_app_ctxt->u4_ht); invalid_argument_exit(ac_error); } - if(0 == (WORD32)ps_app_ctxt->u4_max_num_frms) { sprintf(ac_error, "Invalid number of frames to be encoded: %d", ps_app_ctxt->u4_max_num_frms); invalid_argument_exit(ac_error); } - if ((0 != (WORD32)ps_app_ctxt->u4_entropy_coding_mode) - && (1 != (WORD32)ps_app_ctxt->u4_entropy_coding_mode)) - { - sprintf(ac_error, "Invalid entropy codeing mode: %d", - ps_app_ctxt->u4_entropy_coding_mode); - invalid_argument_exit(ac_error); - } - return; } +/** +******************************************************************************* +* +* @brief initialize default params +* +* @param[in] ps_app_ctxt +* pointer to application context +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ void init_default_params(app_ctxt_t *ps_app_ctxt) { - - ps_app_ctxt->ps_enc = NULL; - ps_app_ctxt->ps_mem_rec = NULL; - ps_app_ctxt->u4_num_mem_rec = DEFAULT_MEM_REC_CNT; - ps_app_ctxt->u4_recon_enable = DEFAULT_RECON_ENABLE; - ps_app_ctxt->u4_chksum_enable = DEFAULT_CHKSUM_ENABLE; - ps_app_ctxt->u4_mb_info_type = 0; - ps_app_ctxt->u4_pic_info_type = 0; - ps_app_ctxt->u4_mb_info_size = 0; - ps_app_ctxt->u4_pic_info_size = 0; - ps_app_ctxt->u4_start_frm = DEFAULT_START_FRM; - ps_app_ctxt->u4_max_num_frms = DEFAULT_NUM_FRMS; - ps_app_ctxt->avg_time = 0; - ps_app_ctxt->u4_total_bytes = 0; - ps_app_ctxt->u4_pics_cnt = 0; - ps_app_ctxt->e_inp_color_fmt = DEFAULT_INP_COLOR_FMT; - ps_app_ctxt->e_recon_color_fmt = DEFAULT_RECON_COLOR_FMT; - ps_app_ctxt->e_arch = ARCH_ARM_A9Q; - ps_app_ctxt->e_soc = SOC_GENERIC; - ps_app_ctxt->header_generated = 0; - ps_app_ctxt->pv_codec_obj = NULL; - ps_app_ctxt->u4_num_cores = DEFAULT_NUM_CORES; - ps_app_ctxt->u4_pre_enc_me = 0; - ps_app_ctxt->u4_pre_enc_ipe = 0; - ps_app_ctxt->ac_ip_fname[0] = '\0'; - ps_app_ctxt->ac_op_fname[0] = '\0'; - ps_app_ctxt->ac_recon_fname[0] = '\0'; - ps_app_ctxt->ac_chksum_fname[0] = '\0'; - ps_app_ctxt->ac_mb_info_fname[0] = '\0'; - ps_app_ctxt->fp_ip = NULL; - ps_app_ctxt->fp_op = NULL; - ps_app_ctxt->fp_recon = NULL; - ps_app_ctxt->fp_chksum = NULL; - ps_app_ctxt->fp_psnr_ip = NULL; - ps_app_ctxt->fp_mb_info = NULL; - ps_app_ctxt->fp_pic_info = NULL; - ps_app_ctxt->u4_loopback = DEFAULT_LOOPBACK; - ps_app_ctxt->u4_max_frame_rate = DEFAULT_MAX_FRAMERATE; - ps_app_ctxt->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE; - ps_app_ctxt->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE; - ps_app_ctxt->u4_max_wd = DEFAULT_MAX_WD; - ps_app_ctxt->u4_max_ht = DEFAULT_MAX_HT; - ps_app_ctxt->u4_max_level = DEFAULT_MAX_LEVEL; - ps_app_ctxt->u4_strd = DEFAULT_STRIDE; - ps_app_ctxt->u4_wd = DEFAULT_WD; - ps_app_ctxt->u4_ht = DEFAULT_HT; - ps_app_ctxt->u4_psnr_enable = DEFAULT_PSNR_ENABLE; - ps_app_ctxt->u4_enc_speed = IVE_FASTEST; - ps_app_ctxt->u4_me_speed = DEFAULT_ME_SPEED; - ps_app_ctxt->u4_enable_fast_sad = DEFAULT_ENABLE_FAST_SAD; - ps_app_ctxt->u4_enable_alt_ref = DEFAULT_ENABLE_ALT_REF; - ps_app_ctxt->u4_rc = DEFAULT_RC; - ps_app_ctxt->u4_max_bitrate = DEFAULT_MAX_BITRATE; - ps_app_ctxt->u4_num_bframes = DEFAULT_NUM_BFRAMES; - ps_app_ctxt->u4_bitrate = DEFAULT_BITRATE; - ps_app_ctxt->u4_i_qp = DEFAULT_I_QP; - ps_app_ctxt->u4_p_qp = DEFAULT_P_QP; - ps_app_ctxt->u4_b_qp = DEFAULT_B_QP; - ps_app_ctxt->u4_i_qp_min = DEFAULT_QP_MIN; - ps_app_ctxt->u4_i_qp_max = DEFAULT_QP_MAX; - ps_app_ctxt->u4_p_qp_min = DEFAULT_QP_MIN; - ps_app_ctxt->u4_p_qp_max = DEFAULT_QP_MAX; - ps_app_ctxt->u4_b_qp_min = DEFAULT_QP_MIN; - ps_app_ctxt->u4_b_qp_max = DEFAULT_QP_MAX; - ps_app_ctxt->u4_air = DEFAULT_AIR; - ps_app_ctxt->u4_air_refresh_period = DEFAULT_AIR_REFRESH_PERIOD; - ps_app_ctxt->u4_srch_rng_x = DEFAULT_SRCH_RNG_X; - ps_app_ctxt->u4_srch_rng_y = DEFAULT_SRCH_RNG_Y; - ps_app_ctxt->u4_i_interval = DEFAULT_I_INTERVAL; - ps_app_ctxt->u4_idr_interval = DEFAULT_IDR_INTERVAL; - ps_app_ctxt->u4_constrained_intra_pred = DEFAULT_CONSTRAINED_INTRAPRED; - ps_app_ctxt->u4_disable_deblk_level = DEFAULT_DISABLE_DEBLK_LEVEL; - ps_app_ctxt->u4_hpel = DEFAULT_HPEL; - ps_app_ctxt->u4_qpel = DEFAULT_QPEL; - ps_app_ctxt->u4_enable_intra_4x4 = DEFAULT_I4; - ps_app_ctxt->e_profile = DEFAULT_EPROFILE; - ps_app_ctxt->u4_slice_mode = DEFAULT_SLICE_MODE; - ps_app_ctxt->u4_slice_param = DEFAULT_SLICE_PARAM; - ps_app_ctxt->pv_input_thread_handle = NULL; + ps_app_ctxt->ps_enc = NULL; + ps_app_ctxt->ps_mem_rec = NULL; + ps_app_ctxt->u4_num_mem_rec = DEFAULT_MEM_REC_CNT; + ps_app_ctxt->u4_recon_enable = DEFAULT_RECON_ENABLE; + ps_app_ctxt->u4_chksum_enable = DEFAULT_CHKSUM_ENABLE; + ps_app_ctxt->u4_mb_info_type = 0; + ps_app_ctxt->u4_pic_info_type = 0; + ps_app_ctxt->u4_mb_info_size = 0; + ps_app_ctxt->u4_pic_info_size = 0; + ps_app_ctxt->u4_start_frm = DEFAULT_START_FRM; + ps_app_ctxt->u4_max_num_frms = DEFAULT_NUM_FRMS; + ps_app_ctxt->u4_total_bytes = 0; + ps_app_ctxt->u4_pics_cnt = 0; + ps_app_ctxt->e_inp_color_fmt = DEFAULT_INP_COLOR_FMT; + ps_app_ctxt->e_recon_color_fmt = DEFAULT_RECON_COLOR_FMT; + ps_app_ctxt->e_arch = ARCH_ARM_A9Q; + ps_app_ctxt->e_soc = SOC_GENERIC; + ps_app_ctxt->header_generated = 0; + ps_app_ctxt->pv_codec_obj = NULL; + ps_app_ctxt->u4_num_cores = DEFAULT_NUM_CORES; + ps_app_ctxt->u4_pre_enc_me = 0; + ps_app_ctxt->u4_pre_enc_ipe = 0; + ps_app_ctxt->ac_ip_fname[0] = '\0'; + ps_app_ctxt->ac_op_fname[0] = '\0'; + ps_app_ctxt->ac_recon_fname[0] = '\0'; + ps_app_ctxt->ac_chksum_fname[0] = '\0'; + ps_app_ctxt->ac_mb_info_fname[0] = '\0'; + ps_app_ctxt->fp_ip = NULL; + ps_app_ctxt->fp_op = NULL; + ps_app_ctxt->fp_recon = NULL; + ps_app_ctxt->fp_chksum = NULL; + ps_app_ctxt->fp_psnr_ip = NULL; + ps_app_ctxt->fp_mb_info = NULL; + ps_app_ctxt->fp_pic_info = NULL; + ps_app_ctxt->u4_loopback = DEFAULT_LOOPBACK; + ps_app_ctxt->u4_max_frame_rate = DEFAULT_MAX_FRAMERATE; + ps_app_ctxt->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE; + ps_app_ctxt->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE; + ps_app_ctxt->u4_max_wd = DEFAULT_MAX_WD; + ps_app_ctxt->u4_max_ht = DEFAULT_MAX_HT; + ps_app_ctxt->u4_max_level = DEFAULT_MAX_LEVEL; + ps_app_ctxt->u4_strd = DEFAULT_STRIDE; + ps_app_ctxt->u4_wd = DEFAULT_WD; + ps_app_ctxt->u4_ht = DEFAULT_HT; + ps_app_ctxt->u4_psnr_enable = DEFAULT_PSNR_ENABLE; + ps_app_ctxt->u4_enc_speed = IVE_FASTEST; + ps_app_ctxt->u4_me_speed = DEFAULT_ME_SPEED; + ps_app_ctxt->u4_enable_fast_sad = DEFAULT_ENABLE_FAST_SAD; + ps_app_ctxt->u4_enable_alt_ref = DEFAULT_ENABLE_ALT_REF; + ps_app_ctxt->u4_rc = DEFAULT_RC; + ps_app_ctxt->u4_max_bitrate = DEFAULT_MAX_BITRATE; + ps_app_ctxt->u4_bitrate = DEFAULT_BITRATE; + ps_app_ctxt->u4_i_qp = DEFAULT_I_QP; + ps_app_ctxt->u4_i_qp_max = DEFAULT_QP_MAX; + ps_app_ctxt->u4_i_qp_min = DEFAULT_QP_MIN; + ps_app_ctxt->u4_p_qp = DEFAULT_P_QP; + ps_app_ctxt->u4_p_qp_max = DEFAULT_QP_MAX; + ps_app_ctxt->u4_p_qp_min = DEFAULT_QP_MIN; + ps_app_ctxt->u4_b_qp = DEFAULT_B_QP; + ps_app_ctxt->u4_b_qp_max = DEFAULT_QP_MAX; + ps_app_ctxt->u4_b_qp_min = DEFAULT_QP_MIN; + ps_app_ctxt->u4_air = DEFAULT_AIR; + ps_app_ctxt->u4_air_refresh_period = DEFAULT_AIR_REFRESH_PERIOD; + ps_app_ctxt->u4_srch_rng_x = DEFAULT_SRCH_RNG_X; + ps_app_ctxt->u4_srch_rng_y = DEFAULT_SRCH_RNG_Y; + ps_app_ctxt->u4_i_interval = DEFAULT_I_INTERVAL; + ps_app_ctxt->u4_idr_interval = DEFAULT_IDR_INTERVAL; + ps_app_ctxt->u4_constrained_intra_pred = DEFAULT_CONSTRAINED_INTRAPRED; + ps_app_ctxt->u4_num_bframes = DEFAULT_NUM_BFRAMES; + ps_app_ctxt->u4_disable_deblk_level = DEFAULT_DISABLE_DEBLK_LEVEL; + ps_app_ctxt->u4_hpel = DEFAULT_HPEL; + ps_app_ctxt->u4_qpel = DEFAULT_QPEL; + ps_app_ctxt->u4_enable_intra_4x4 = DEFAULT_I4; + ps_app_ctxt->e_profile = DEFAULT_EPROFILE; + ps_app_ctxt->u4_slice_mode = DEFAULT_SLICE_MODE; + ps_app_ctxt->u4_slice_param = DEFAULT_SLICE_PARAM; + ps_app_ctxt->u4_entropy_coding_mode = DEFAULT_ENTROPY_CODING_MODE; + ps_app_ctxt->pv_input_thread_handle = NULL; ps_app_ctxt->pv_output_thread_handle = NULL; - ps_app_ctxt->pv_recon_thread_handle = NULL; - ps_app_ctxt->u4_vbv_buf_size = 0; - ps_app_ctxt->u4_vbv_buffer_delay = 1000; - ps_app_ctxt->adbl_psnr[0] = 0.0; - ps_app_ctxt->adbl_psnr[1] = 0.0; - ps_app_ctxt->adbl_psnr[2] = 0.0; - ps_app_ctxt->u4_psnr_cnt = 0; - ps_app_ctxt->pu1_psnr_buf = NULL; - ps_app_ctxt->u4_psnr_buf_size = 0; - ps_app_ctxt->u4_entropy_coding_mode = DEFAULT_ENTROPY_CODING_MODE; - - return; + ps_app_ctxt->pv_recon_thread_handle = NULL; + ps_app_ctxt->adbl_psnr[0] = 0.0; + ps_app_ctxt->adbl_psnr[1] = 0.0; + ps_app_ctxt->adbl_psnr[2] = 0.0; + ps_app_ctxt->u4_psnr_cnt = 0; + ps_app_ctxt->pu1_psnr_buf = NULL; + ps_app_ctxt->u4_psnr_buf_size = 0; + ps_app_ctxt->u4_vbv_buffer_delay = 1000; + ps_app_ctxt->u4_vbv_buf_size = 0; + ps_app_ctxt->avg_time = 0; } +/** +******************************************************************************* +* @brief configure input dimensions +******************************************************************************* +*/ void set_dimensions(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high) @@ -1019,22 +1012,17 @@ void set_dimensions(app_ctxt_t *ps_app_ctxt, ih264e_ctl_set_dimensions_op_t s_frame_dimensions_op; IV_STATUS_T status; + s_frame_dimensions_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_dimensions_ip_t); s_frame_dimensions_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_frame_dimensions_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS; - - s_frame_dimensions_ip.s_ive_ip.u4_ht = ps_app_ctxt->u4_ht; s_frame_dimensions_ip.s_ive_ip.u4_wd = ps_app_ctxt->u4_wd; - - s_frame_dimensions_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + s_frame_dimensions_ip.s_ive_ip.u4_ht = ps_app_ctxt->u4_ht; s_frame_dimensions_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_frame_dimensions_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_frame_dimensions_ip.s_ive_ip.u4_size = - sizeof(ih264e_ctl_set_dimensions_ip_t); - s_frame_dimensions_op.s_ive_op.u4_size = - sizeof(ih264e_ctl_set_dimensions_op_t); + s_frame_dimensions_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_dimensions_op_t); - status = ih264e_api_function(ps_app_ctxt->ps_enc, - &s_frame_dimensions_ip, + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_frame_dimensions_ip, &s_frame_dimensions_op); if(status != IV_SUCCESS) { @@ -1043,9 +1031,13 @@ void set_dimensions(app_ctxt_t *ps_app_ctxt, s_frame_dimensions_op.s_ive_op.u4_error_code); codec_exit(ac_error); } - return; } +/** +******************************************************************************* +* @brief configure source & target framerates +******************************************************************************* +*/ void set_frame_rate(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high) @@ -1054,32 +1046,32 @@ void set_frame_rate(app_ctxt_t *ps_app_ctxt, ih264e_ctl_set_frame_rate_op_t s_frame_rate_op; IV_STATUS_T status; - s_frame_rate_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; - s_frame_rate_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE; - - s_frame_rate_ip.s_ive_ip.u4_src_frame_rate = - ps_app_ctxt->u4_src_frame_rate; - s_frame_rate_ip.s_ive_ip.u4_tgt_frame_rate = - ps_app_ctxt->u4_tgt_frame_rate; + s_frame_rate_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_frame_rate_ip_t); + s_frame_rate_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_frame_rate_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE; + s_frame_rate_ip.s_ive_ip.u4_src_frame_rate = ps_app_ctxt->u4_src_frame_rate; + s_frame_rate_ip.s_ive_ip.u4_tgt_frame_rate = ps_app_ctxt->u4_tgt_frame_rate; + s_frame_rate_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_frame_rate_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_frame_rate_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_frame_rate_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_frame_rate_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_frame_rate_op_t); - s_frame_rate_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_frame_rate_ip_t); - s_frame_rate_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_frame_rate_op_t); - - status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_frame_rate_ip,&s_frame_rate_op); + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_frame_rate_ip, + &s_frame_rate_op); if(status != IV_SUCCESS) - { - CHAR ac_error[STRLENGTH]; - sprintf(ac_error, "Unable to set frame rate = 0x%x\n", - s_frame_rate_op.s_ive_op.u4_error_code); - codec_exit(ac_error); - } - return; + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set frame rate = 0x%x\n", + s_frame_rate_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } } - +/** +******************************************************************************* +* @brief configure IPE params +******************************************************************************* +*/ void set_ipe_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high) @@ -1088,22 +1080,19 @@ void set_ipe_params(app_ctxt_t *ps_app_ctxt, ih264e_ctl_set_ipe_params_op_t s_ipe_params_op; IV_STATUS_T status; - s_ipe_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; - s_ipe_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS; + s_ipe_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_ipe_params_ip_t); + s_ipe_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_ipe_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS; + s_ipe_params_ip.s_ive_ip.u4_enable_intra_4x4 = ps_app_ctxt->u4_enable_intra_4x4; + s_ipe_params_ip.s_ive_ip.u4_enc_speed_preset = ps_app_ctxt->u4_enc_speed; + s_ipe_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_ipe_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + s_ipe_params_ip.s_ive_ip.u4_constrained_intra_pred = ps_app_ctxt->u4_constrained_intra_pred; - s_ipe_params_ip.s_ive_ip.u4_enable_intra_4x4 = ps_app_ctxt->u4_enable_intra_4x4; - s_ipe_params_ip.s_ive_ip.u4_enc_speed_preset = ps_app_ctxt->u4_enc_speed; + s_ipe_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_ipe_params_op_t); - s_ipe_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_ipe_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; - - s_ipe_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_ipe_params_ip_t); - s_ipe_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_ipe_params_op_t); - - s_ipe_params_ip.s_ive_ip.u4_constrained_intra_pred = - ps_app_ctxt->u4_constrained_intra_pred; - - status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_ipe_params_ip,&s_ipe_params_op); + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_ipe_params_ip, + &s_ipe_params_op); if(status != IV_SUCCESS) { CHAR ac_error[STRLENGTH]; @@ -1111,60 +1100,66 @@ void set_ipe_params(app_ctxt_t *ps_app_ctxt, s_ipe_params_op.s_ive_op.u4_error_code); codec_exit(ac_error); } - return; } +/** +******************************************************************************* +* @brief configure bitrate +******************************************************************************* +*/ void set_bit_rate(app_ctxt_t *ps_app_ctxt, - UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high) + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) { ih264e_ctl_set_bitrate_ip_t s_bitrate_ip; ih264e_ctl_set_bitrate_op_t s_bitrate_op; IV_STATUS_T status; - s_bitrate_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; - s_bitrate_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE; - - s_bitrate_ip.s_ive_ip.u4_target_bitrate = ps_app_ctxt->u4_bitrate; - - s_bitrate_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_bitrate_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_bitrate_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_bitrate_ip_t); + s_bitrate_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_bitrate_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE; + s_bitrate_ip.s_ive_ip.u4_target_bitrate = ps_app_ctxt->u4_bitrate; + s_bitrate_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_bitrate_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_bitrate_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_bitrate_ip_t); - s_bitrate_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_bitrate_op_t); + s_bitrate_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_bitrate_op_t); - status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_bitrate_ip,&s_bitrate_op); + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_bitrate_ip, + &s_bitrate_op); if(status != IV_SUCCESS) - { - CHAR ac_error[STRLENGTH]; - sprintf(ac_error, "Unable to set bit rate = 0x%x\n", - s_bitrate_op.s_ive_op.u4_error_code); - codec_exit(ac_error); - } - return; + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set bit rate = 0x%x\n", + s_bitrate_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } } - +/** +******************************************************************************* +* @brief configure frame type +******************************************************************************* +*/ void set_frame_type(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high, - IV_PICTURE_CODING_TYPE_T e_frame_type) + IV_PICTURE_CODING_TYPE_T e_frame_type) { ih264e_ctl_set_frame_type_ip_t s_frame_type_ip; ih264e_ctl_set_frame_type_op_t s_frame_type_op; IV_STATUS_T status; - s_frame_type_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; - s_frame_type_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE; - - s_frame_type_ip.s_ive_ip.e_frame_type = e_frame_type; - - s_frame_type_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_frame_type_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_frame_type_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_frame_type_ip_t); + s_frame_type_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_frame_type_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE; + s_frame_type_ip.s_ive_ip.e_frame_type = e_frame_type; + s_frame_type_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_frame_type_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_frame_type_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_frame_type_ip_t); - s_frame_type_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_frame_type_op_t); + s_frame_type_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_frame_type_op_t); - status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_frame_type_ip,&s_frame_type_op); + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_frame_type_ip, + &s_frame_type_op); if(status != IV_SUCCESS) { CHAR ac_error[STRLENGTH]; @@ -1172,70 +1167,73 @@ void set_frame_type(app_ctxt_t *ps_app_ctxt, s_frame_type_op.s_ive_op.u4_error_code); codec_exit(ac_error); } - return; } +/** +******************************************************************************* +* @brief configure qp +******************************************************************************* +*/ void set_qp(app_ctxt_t *ps_app_ctxt, - UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high) + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) { ih264e_ctl_set_qp_ip_t s_qp_ip; ih264e_ctl_set_qp_op_t s_qp_op; IV_STATUS_T status; - s_qp_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; - s_qp_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP; - + s_qp_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_qp_ip_t); + s_qp_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_qp_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP; s_qp_ip.s_ive_ip.u4_i_qp = ps_app_ctxt->u4_i_qp; s_qp_ip.s_ive_ip.u4_i_qp_max = ps_app_ctxt->u4_i_qp_max; s_qp_ip.s_ive_ip.u4_i_qp_min = ps_app_ctxt->u4_i_qp_min; - s_qp_ip.s_ive_ip.u4_p_qp = ps_app_ctxt->u4_p_qp; s_qp_ip.s_ive_ip.u4_p_qp_max = ps_app_ctxt->u4_p_qp_max; s_qp_ip.s_ive_ip.u4_p_qp_min = ps_app_ctxt->u4_p_qp_min; - s_qp_ip.s_ive_ip.u4_b_qp = ps_app_ctxt->u4_b_qp; s_qp_ip.s_ive_ip.u4_b_qp_max = ps_app_ctxt->u4_b_qp_max; s_qp_ip.s_ive_ip.u4_b_qp_min = ps_app_ctxt->u4_b_qp_min; + s_qp_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_qp_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_qp_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_qp_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; - - s_qp_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_qp_ip_t); - s_qp_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_qp_op_t); + s_qp_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_qp_op_t); - status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_qp_ip,&s_qp_op); + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_qp_ip, &s_qp_op); if(status != IV_SUCCESS) - { - CHAR ac_error[STRLENGTH]; - sprintf(ac_error, "Unable to set qp 0x%x\n", - s_qp_op.s_ive_op.u4_error_code); - codec_exit(ac_error); - } - return; + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set qp 0x%x\n", + s_qp_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } } +/** +******************************************************************************* +* @brief configure encoder mode +******************************************************************************* +*/ void set_enc_mode(app_ctxt_t *ps_app_ctxt, - UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high, IVE_ENC_MODE_T e_enc_mode) { - IV_STATUS_T status; - ih264e_ctl_set_enc_mode_ip_t s_enc_mode_ip; ih264e_ctl_set_enc_mode_op_t s_enc_mode_op; + IV_STATUS_T status; + s_enc_mode_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_enc_mode_ip_t); s_enc_mode_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_enc_mode_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE; - s_enc_mode_ip.s_ive_ip.e_enc_mode = e_enc_mode; - - s_enc_mode_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; s_enc_mode_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_enc_mode_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_enc_mode_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_enc_mode_ip_t); s_enc_mode_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_enc_mode_op_t); status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_enc_mode_ip, - &s_enc_mode_op); + &s_enc_mode_op); if(status != IV_SUCCESS) { CHAR ac_error[STRLENGTH]; @@ -1243,10 +1241,13 @@ void set_enc_mode(app_ctxt_t *ps_app_ctxt, s_enc_mode_op.s_ive_op.u4_error_code); codec_exit(ac_error); } - return; } - +/** +******************************************************************************* +* @brief configure vbv params +******************************************************************************* +*/ void set_vbv_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high) @@ -1255,20 +1256,17 @@ void set_vbv_params(app_ctxt_t *ps_app_ctxt, ih264e_ctl_set_vbv_params_op_t s_vbv_op; IV_STATUS_T status; - s_vbv_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; - s_vbv_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS; - + s_vbv_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_vbv_params_ip_t); + s_vbv_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_vbv_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS; + s_vbv_ip.s_ive_ip.u4_vbv_buffer_delay = ps_app_ctxt->u4_vbv_buffer_delay; s_vbv_ip.s_ive_ip.u4_vbv_buf_size = ps_app_ctxt->u4_vbv_buf_size; - s_vbv_ip.s_ive_ip.u4_vbv_buffer_delay = - ps_app_ctxt->u4_vbv_buffer_delay; + s_vbv_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_vbv_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_vbv_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_vbv_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_vbv_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_vbv_params_op_t); - s_vbv_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_vbv_params_ip_t); - s_vbv_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_vbv_params_op_t); - - status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_vbv_ip,&s_vbv_op); + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_vbv_ip, &s_vbv_op); if(status != IV_SUCCESS) { CHAR ac_error[STRLENGTH]; @@ -1276,9 +1274,13 @@ void set_vbv_params(app_ctxt_t *ps_app_ctxt, s_vbv_op.s_ive_op.u4_error_code); codec_exit(ac_error); } - return; } +/** +******************************************************************************* +* @brief configure air params +******************************************************************************* +*/ void set_air_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high) @@ -1287,54 +1289,52 @@ void set_air_params(app_ctxt_t *ps_app_ctxt, ih264e_ctl_set_air_params_op_t s_air_op; IV_STATUS_T status; - s_air_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; - s_air_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS; - + s_air_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_air_params_ip_t); + s_air_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_air_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS; s_air_ip.s_ive_ip.e_air_mode = ps_app_ctxt->u4_air; s_air_ip.s_ive_ip.u4_air_refresh_period = ps_app_ctxt->u4_air_refresh_period; + s_air_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_air_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_air_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_air_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_air_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_air_params_op_t); - s_air_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_air_params_ip_t); - s_air_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_air_params_op_t); - - status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_air_ip,&s_air_op); + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_air_ip, &s_air_op); if(status != IV_SUCCESS) - { - CHAR ac_error[STRLENGTH]; - sprintf(ac_error, "Unable to set air params = 0x%x\n", - s_air_op.s_ive_op.u4_error_code); - codec_exit(ac_error); - } - return; + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set air params = 0x%x\n", + s_air_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } } +/** +******************************************************************************* +* @brief configure me params +******************************************************************************* +*/ void set_me_params(app_ctxt_t *ps_app_ctxt, - UWORD32 u4_timestamp_low, - UWORD32 u4_timestamp_high) + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) { - IV_STATUS_T status; - ih264e_ctl_set_me_params_ip_t s_me_params_ip; ih264e_ctl_set_me_params_op_t s_me_params_op; + IV_STATUS_T status; + s_me_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_me_params_ip_t); s_me_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_me_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS; - + s_me_params_ip.s_ive_ip.u4_me_speed_preset = ps_app_ctxt->u4_me_speed; + s_me_params_ip.s_ive_ip.u4_enable_hpel = ps_app_ctxt->u4_hpel; + s_me_params_ip.s_ive_ip.u4_enable_qpel = ps_app_ctxt->u4_qpel; s_me_params_ip.s_ive_ip.u4_enable_fast_sad = ps_app_ctxt->u4_enable_fast_sad; s_me_params_ip.s_ive_ip.u4_enable_alt_ref = ps_app_ctxt->u4_enable_alt_ref; - - s_me_params_ip.s_ive_ip.u4_enable_hpel = ps_app_ctxt->u4_hpel; - s_me_params_ip.s_ive_ip.u4_enable_qpel = ps_app_ctxt->u4_qpel; - s_me_params_ip.s_ive_ip.u4_me_speed_preset = ps_app_ctxt->u4_me_speed; - s_me_params_ip.s_ive_ip.u4_srch_rng_x = ps_app_ctxt->u4_srch_rng_x; - s_me_params_ip.s_ive_ip.u4_srch_rng_y = ps_app_ctxt->u4_srch_rng_y; - - s_me_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + s_me_params_ip.s_ive_ip.u4_srch_rng_x = ps_app_ctxt->u4_srch_rng_x; + s_me_params_ip.s_ive_ip.u4_srch_rng_y = ps_app_ctxt->u4_srch_rng_y; s_me_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_me_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_me_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_me_params_ip_t); s_me_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_me_params_op_t); status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_me_params_ip, @@ -1346,29 +1346,29 @@ void set_me_params(app_ctxt_t *ps_app_ctxt, s_me_params_op.s_ive_op.u4_error_code); codec_exit(ac_error); } - return; } - +/** +******************************************************************************* +* @brief configure gop params +******************************************************************************* +*/ void set_gop_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high) { - IV_STATUS_T status; - ih264e_ctl_set_gop_params_ip_t s_gop_params_ip; ih264e_ctl_set_gop_params_op_t s_gop_params_op; + IV_STATUS_T status; + s_gop_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_gop_params_ip_t); s_gop_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_gop_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS; - s_gop_params_ip.s_ive_ip.u4_i_frm_interval = ps_app_ctxt->u4_i_interval; s_gop_params_ip.s_ive_ip.u4_idr_frm_interval = ps_app_ctxt->u4_idr_interval; - - s_gop_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; s_gop_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_gop_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; - s_gop_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_gop_params_ip_t); s_gop_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_gop_params_op_t); status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_gop_params_ip, @@ -1376,37 +1376,37 @@ void set_gop_params(app_ctxt_t *ps_app_ctxt, if(status != IV_SUCCESS) { CHAR ac_error[STRLENGTH]; - sprintf(ac_error, "Unable to set ME params = 0x%x\n", + sprintf(ac_error, "Unable to set GOP params = 0x%x\n", s_gop_params_op.s_ive_op.u4_error_code); codec_exit(ac_error); } - return; } +/** +******************************************************************************* +* @brief configure profile params +******************************************************************************* +*/ void set_profile_params(app_ctxt_t *ps_app_ctxt, - UWORD32 u4_timestamp_low, - UWORD32 u4_timestamp_high) + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) { - IV_STATUS_T status; - ih264e_ctl_set_profile_params_ip_t s_profile_params_ip; ih264e_ctl_set_profile_params_op_t s_profile_params_op; + IV_STATUS_T status; + s_profile_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_profile_params_ip_t); s_profile_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_profile_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS; - s_profile_params_ip.s_ive_ip.e_profile = ps_app_ctxt->e_profile; - - s_profile_params_ip.s_ive_ip.u4_entropy_coding_mode = ps_app_ctxt->u4_entropy_coding_mode; - s_profile_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; s_profile_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_profile_params_ip.s_ive_ip.u4_entropy_coding_mode = ps_app_ctxt->u4_entropy_coding_mode; - s_profile_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_profile_params_ip_t); s_profile_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_profile_params_op_t); status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_profile_params_ip, - &s_profile_params_op); + &s_profile_params_op); if(status != IV_SUCCESS) { CHAR ac_error[STRLENGTH]; @@ -1414,32 +1414,32 @@ void set_profile_params(app_ctxt_t *ps_app_ctxt, s_profile_params_op.s_ive_op.u4_error_code); codec_exit(ac_error); } - return; } +/** +******************************************************************************* +* @brief configure deblock params +******************************************************************************* +*/ void set_deblock_params(app_ctxt_t *ps_app_ctxt, - UWORD32 u4_timestamp_low, - UWORD32 u4_timestamp_high) + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) { - IV_STATUS_T status; - ih264e_ctl_set_deblock_params_ip_t s_deblock_params_ip; ih264e_ctl_set_deblock_params_op_t s_deblock_params_op; + IV_STATUS_T status; + s_deblock_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_deblock_params_ip_t); s_deblock_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_deblock_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS; - - s_deblock_params_ip.s_ive_ip.u4_disable_deblock_level = - ps_app_ctxt->u4_disable_deblk_level; - + s_deblock_params_ip.s_ive_ip.u4_disable_deblock_level = ps_app_ctxt->u4_disable_deblk_level; s_deblock_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; s_deblock_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; - s_deblock_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_deblock_params_ip_t); s_deblock_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_deblock_params_op_t); status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_deblock_params_ip, - &s_deblock_params_op); + &s_deblock_params_op); if(status != IV_SUCCESS) { CHAR ac_error[STRLENGTH]; @@ -1447,20 +1447,22 @@ void set_deblock_params(app_ctxt_t *ps_app_ctxt, s_deblock_params_op.s_ive_op.u4_error_code); codec_exit(ac_error); } - return; } - +/** +******************************************************************************* +* @brief configure VUI params +******************************************************************************* +*/ void set_vui_params(app_ctxt_t *ps_app_ctxt) { - IV_STATUS_T status; - ih264e_vui_ip_t s_vui_params_ip; ih264e_vui_op_t s_vui_params_op; + IV_STATUS_T status; + s_vui_params_ip.u4_size = sizeof(ih264e_vui_ip_t); s_vui_params_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_vui_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_VUI_PARAMS; - s_vui_params_ip.u1_aspect_ratio_info_present_flag = 0; s_vui_params_ip.u1_aspect_ratio_idc = 0; s_vui_params_ip.u2_sar_width = 0; @@ -1479,7 +1481,7 @@ void set_vui_params(app_ctxt_t *ps_app_ctxt) s_vui_params_ip.u1_chroma_sample_loc_type_bottom_field = 0; s_vui_params_ip.u1_vui_timing_info_present_flag = 0; s_vui_params_ip.u4_vui_num_units_in_tick = 0; - s_vui_params_ip.u4_vui_time_scale = 0; + s_vui_params_ip.u4_vui_time_scale = ps_app_ctxt->u4_tgt_frame_rate * 2000; s_vui_params_ip.u1_fixed_frame_rate_flag = 0; s_vui_params_ip.u1_nal_hrd_parameters_present_flag = 0; s_vui_params_ip.u1_vcl_hrd_parameters_present_flag = 0; @@ -1494,12 +1496,10 @@ void set_vui_params(app_ctxt_t *ps_app_ctxt) s_vui_params_ip.u1_num_reorder_frames = 0; s_vui_params_ip.u1_max_dec_frame_buffering = 0; - - s_vui_params_ip.u4_size = sizeof(ih264e_vui_ip_t); s_vui_params_op.u4_size = sizeof(ih264e_vui_op_t); status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_vui_params_ip, - &s_vui_params_op); + &s_vui_params_op); if(status != IV_SUCCESS) { CHAR ac_error[STRLENGTH]; @@ -1808,10 +1808,14 @@ void set_sei_sii_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, return; } -#define PEAK_WINDOW_SIZE 8 - +/** +******************************************************************************* +* @brief encode input +******************************************************************************* +*/ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) { +#define PEAK_WINDOW_SIZE 8 ih264e_video_encode_ip_t ih264e_video_encode_ip = {0}; ih264e_video_encode_op_t ih264e_video_encode_op = {0}; @@ -1825,10 +1829,10 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) WORD32 i, is_last = 0, buff_size = 0, num_bytes = 0; UWORD32 u4_total_time = 0; UWORD8 *pu1_buf = NULL; - UWORD32 u4_timestamp_low, u4_timestamp_high; + UWORD32 u4_timestamp_low = 0, u4_timestamp_high = 0; void *pv_mb_info = NULL, *pv_pic_info = NULL; - TIMER curtime ; + TIMER curtime; #ifdef WINDOWS_TIMER TIMER frequency; #endif @@ -1837,34 +1841,31 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) WORD32 peak_avg_max = 0, timetaken = 0; iv_raw_buf_t s_inp_buf, s_recon_buf; CHAR ac_error[STRLENGTH]; - WORD32 end_of_frames=0; - WORD32 i4_inp_done =0; - - u4_timestamp_low = 0; - u4_timestamp_high = 0; + WORD32 end_of_frames = 0; + WORD32 i4_inp_done = 0; - /*************************************************************************/ - /* Allocate I/O Buffers */ - /*************************************************************************/ + /* Allocate I/O Buffers */ allocate_input(ps_app_ctxt); allocate_output(ps_app_ctxt); allocate_recon(ps_app_ctxt); - /* init psnr */ + /* init psnr ctxt */ init_psnr(ps_app_ctxt); /* open file pointers */ ps_app_ctxt->fp_ip = fopen(ps_app_ctxt->ac_ip_fname, "rb"); if(NULL == ps_app_ctxt->fp_ip) { - sprintf(ac_error, "Unable to open input file for reading: %s", ps_app_ctxt->ac_ip_fname); + sprintf(ac_error, "Unable to open input file for reading: %s", + ps_app_ctxt->ac_ip_fname); invalid_argument_exit(ac_error); } ps_app_ctxt->fp_op = fopen(ps_app_ctxt->ac_op_fname, "wb"); if(NULL == ps_app_ctxt->fp_op) { - sprintf(ac_error, "Unable to open output file for writing: %s", ps_app_ctxt->ac_op_fname); + sprintf(ac_error, "Unable to open output file for writing: %s", + ps_app_ctxt->ac_op_fname); invalid_argument_exit(ac_error); } @@ -1873,49 +1874,57 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) ps_app_ctxt->fp_recon = fopen(ps_app_ctxt->ac_recon_fname, "wb"); if(NULL == ps_app_ctxt->fp_recon) { - sprintf(ac_error, "Unable to open recon file for writing: %s", ps_app_ctxt->ac_recon_fname); + sprintf(ac_error, "Unable to open recon file for writing: %s", + ps_app_ctxt->ac_recon_fname); invalid_argument_exit(ac_error); } } if(1 == ps_app_ctxt->u4_chksum_enable) { - ps_app_ctxt->fp_chksum = fopen(ps_app_ctxt->ac_chksum_fname, "wb"); + ps_app_ctxt->fp_chksum = fopen(ps_app_ctxt->ac_chksum_fname, "wb"); if(NULL == ps_app_ctxt->fp_chksum) { - sprintf(ac_error, "Unable to open checksum file for writing: %s", ps_app_ctxt->ac_chksum_fname); + sprintf(ac_error, "Unable to open checksum file for writing: %s", + ps_app_ctxt->ac_chksum_fname); invalid_argument_exit(ac_error); } } - /* If PSNR is enabled, open input file again and hold a different file pointer - * This makes it easy to compute PSNR without adding dependency between input and recon threads + /* + * If PSNR is enabled, open input file again and hold a different file pointer + * This makes it easy to compute PSNR without adding dependency between + * input and recon threads */ if(1 == ps_app_ctxt->u4_psnr_enable) { - ps_app_ctxt->fp_psnr_ip = fopen(ps_app_ctxt->ac_ip_fname, "rb"); + ps_app_ctxt->fp_psnr_ip = fopen(ps_app_ctxt->ac_ip_fname, "rb"); if(NULL == ps_app_ctxt->fp_psnr_ip) { - sprintf(ac_error, "Unable to open input file for reading: %s", ps_app_ctxt->ac_ip_fname); + sprintf(ac_error, "Unable to open input file for reading: %s", + ps_app_ctxt->ac_ip_fname); invalid_argument_exit(ac_error); } } if(0 != ps_app_ctxt->u4_mb_info_type) { - ps_app_ctxt->fp_mb_info = fopen(ps_app_ctxt->ac_mb_info_fname, "rb"); + ps_app_ctxt->fp_mb_info = fopen(ps_app_ctxt->ac_mb_info_fname, "rb"); if(NULL == ps_app_ctxt->fp_mb_info) { - sprintf(ac_error, "Unable to open MB info file for reading: %s", ps_app_ctxt->ac_mb_info_fname); + sprintf(ac_error, "Unable to open MB info file for reading: %s", + ps_app_ctxt->ac_mb_info_fname); invalid_argument_exit(ac_error); } } - if (ps_app_ctxt->u4_pic_info_type) + + if(ps_app_ctxt->u4_pic_info_type) { - ps_app_ctxt->fp_pic_info = fopen(ps_app_ctxt->ac_pic_info_fname, "rb"); + ps_app_ctxt->fp_pic_info = fopen(ps_app_ctxt->ac_pic_info_fname, "rb"); if(NULL == ps_app_ctxt->fp_pic_info) { - sprintf(ac_error, "Unable to open Pic info file for reading: %s", ps_app_ctxt->ac_pic_info_fname); + sprintf(ac_error, "Unable to open Pic info file for reading: %s", + ps_app_ctxt->ac_pic_info_fname); invalid_argument_exit(ac_error); } } @@ -2070,10 +2079,7 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) } set_sei_sii_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high); - /******************************************************************************/ - /****************** Input Initialization **************************************/ - /******************************************************************************/ - + /* Input Initialization */ for(i = 0; i < DEFAULT_MAX_INPUT_BUFS; i++) { if(ps_app_ctxt->as_input_buf[i].u4_is_free) @@ -2085,103 +2091,97 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) break; } } - if (i == DEFAULT_MAX_INPUT_BUFS) { printf("\n Unable to find a free input buffer!!"); exit(0); } - memset(&ih264e_video_encode_ip, 0, sizeof(ih264e_video_encode_ip)); - memset(&ih264e_video_encode_op, 0, sizeof(ih264e_video_encode_op)); - ps_video_encode_ip->u4_size = sizeof(ih264e_video_encode_ip_t); - ps_video_encode_op->u4_size = sizeof(ih264e_video_encode_op_t); - ps_video_encode_ip->e_cmd = IVE_CMD_VIDEO_ENCODE; ps_video_encode_ip->pv_bufs = pu1_buf; ps_video_encode_ip->pv_mb_info = pv_mb_info; ps_video_encode_ip->pv_pic_info = pv_pic_info; ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type; + + ps_video_encode_op->u4_size = sizeof(ih264e_video_encode_op_t); + /* * Since the buffers are used for reading, - * And after each row we have a stride we nned to calculate + * And after each row we have a stride we need to calculate * the luma size according to the stride */ ps_inp_raw_buf->e_color_fmt = ps_app_ctxt->e_inp_color_fmt; - - /* Initialize for 420SP */ - if(IV_YUV_420SP_UV == ps_app_ctxt->e_inp_color_fmt|| - IV_YUV_420SP_VU == ps_app_ctxt->e_inp_color_fmt) + if(IV_YUV_420SP_UV == ps_app_ctxt->e_inp_color_fmt + || IV_YUV_420SP_VU == ps_app_ctxt->e_inp_color_fmt) { - /*init luma buffer*/ + /* init luma buffer */ ps_inp_raw_buf->apv_bufs[0] = pu1_buf; - /*Init chroma buffer*/ + /* init chroma buffer */ pu1_buf += ps_app_ctxt->u4_strd * ps_app_ctxt->u4_ht; ps_inp_raw_buf->apv_bufs[1] = pu1_buf; - ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd; - ps_inp_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd; + ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd; + ps_inp_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd; - ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; - ps_inp_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; + ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; + ps_inp_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; - ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd; - ps_inp_raw_buf->au4_strd[1] = ps_app_ctxt->u4_strd; + ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd; + ps_inp_raw_buf->au4_strd[1] = ps_app_ctxt->u4_strd; } else if(IV_YUV_420P == ps_app_ctxt->e_inp_color_fmt) { - /* init buffers */ + /* init luma buffer */ ps_inp_raw_buf->apv_bufs[0] = pu1_buf; pu1_buf += (ps_app_ctxt->u4_wd) * ps_app_ctxt->u4_ht; + + /* init chroma buffer U */ ps_inp_raw_buf->apv_bufs[1] = pu1_buf; pu1_buf += (ps_app_ctxt->u4_wd >> 1) * (ps_app_ctxt->u4_ht >> 1); + + /* init chroma buffer V */ ps_inp_raw_buf->apv_bufs[2] = pu1_buf; - ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd; - ps_inp_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd / 2; - ps_inp_raw_buf->au4_wd[2] = ps_app_ctxt->u4_wd / 2; + ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd; + ps_inp_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd / 2; + ps_inp_raw_buf->au4_wd[2] = ps_app_ctxt->u4_wd / 2; - ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; - ps_inp_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; - ps_inp_raw_buf->au4_ht[2] = ps_app_ctxt->u4_ht / 2; + ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; + ps_inp_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; + ps_inp_raw_buf->au4_ht[2] = ps_app_ctxt->u4_ht / 2; - ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd; - ps_inp_raw_buf->au4_strd[1] = ps_app_ctxt->u4_strd / 2; - ps_inp_raw_buf->au4_strd[2] = ps_app_ctxt->u4_strd / 2; + ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd; + ps_inp_raw_buf->au4_strd[1] = ps_app_ctxt->u4_strd / 2; + ps_inp_raw_buf->au4_strd[2] = ps_app_ctxt->u4_strd / 2; } else if(IV_YUV_422ILE == ps_app_ctxt->e_inp_color_fmt) { - /*init luma buffer*/ + /* init luma buffer */ ps_inp_raw_buf->apv_bufs[0] = pu1_buf; - ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd * 2; + ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd * 2; - ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; + ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; - ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd *2; + ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd * 2; } - /* - * Here we read input and other associated buffers. Regardless of success - * we will proceed from here as we will need extra calls to flush out - * input queue in encoder. Note that this is not necessary. You can just - * send encode calls till with valid output and recon buffers till the - * queue is flushed. - */ + /* Read input and other associated buffers */ while(1) { - IV_STATUS_T mb_info_status = IV_SUCCESS, pic_info_status = IV_SUCCESS; + IV_STATUS_T mb_info_status = IV_SUCCESS; + IV_STATUS_T pic_info_status = IV_SUCCESS; status = read_input(ps_app_ctxt->fp_ip, ps_inp_raw_buf); - if (ps_app_ctxt->u4_mb_info_type != 0) + if(ps_app_ctxt->u4_mb_info_type != 0) { mb_info_status = read_mb_info(ps_app_ctxt, pv_mb_info); } - if (ps_app_ctxt->u4_pic_info_type != 0) + if(ps_app_ctxt->u4_pic_info_type != 0) { pic_info_status = read_pic_info(ps_app_ctxt, pv_pic_info); } @@ -2194,15 +2194,14 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) break; } else + { fseek(ps_app_ctxt->fp_ip, 0, SEEK_SET); + } } break; } - /******************************************************************************/ - /****************** Output Initialization *************************************/ - /******************************************************************************/ - + /* Output Initialization */ for(i = 0; i < DEFAULT_MAX_OUTPUT_BUFS; i++) { if(ps_app_ctxt->as_output_buf[i].u4_is_free) @@ -2213,23 +2212,28 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) break; } } + if (i == DEFAULT_MAX_OUTPUT_BUFS) + { + printf("\n Unable to find a free output buffer!!"); + exit(0); + } ps_video_encode_ip->s_out_buf.pv_buf = pu1_buf; ps_video_encode_ip->s_out_buf.u4_bytes = 0; ps_video_encode_ip->s_out_buf.u4_bufsize = buff_size; - /******************************************************************************/ - /****************** Recon Initialization **************************************/ - /******************************************************************************/ - init_raw_buf_descr(ps_app_ctxt, &s_recon_buf, ps_app_ctxt->as_recon_buf[0].pu1_buf, ps_app_ctxt->e_recon_color_fmt); + /* Recon Initialization */ + init_raw_buf_descr(ps_app_ctxt, &s_recon_buf, + ps_app_ctxt->as_recon_buf[0].pu1_buf, + ps_app_ctxt->e_recon_color_fmt); + ps_video_encode_ip->s_recon_buf = s_recon_buf; if(ps_app_ctxt->u4_psnr_enable) - init_raw_buf_descr(ps_app_ctxt, &s_inp_buf, ps_app_ctxt->pu1_psnr_buf, ps_app_ctxt->e_inp_color_fmt); - - ps_video_encode_ip->s_recon_buf = s_recon_buf; + { + init_raw_buf_descr(ps_app_ctxt, &s_inp_buf, + ps_app_ctxt->pu1_psnr_buf, + ps_app_ctxt->e_inp_color_fmt); + } - /******************************************************************************/ - /************************* Un Initialized *************************************/ - /******************************************************************************/ if(0 == ps_app_ctxt->u4_loopback) { /* If input file is read completely and loopback is not enabled, @@ -2240,9 +2244,8 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) } } - /* If last frame, send input null to get back encoded frames */ - if ( is_last == 1 || ((ps_app_ctxt->u4_max_num_frms) <= u4_timestamp_low) ) + if(is_last == 1 || ((ps_app_ctxt->u4_max_num_frms) <= u4_timestamp_low)) { is_last = 1; ps_inp_raw_buf->apv_bufs[0] = NULL; @@ -2252,18 +2255,20 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) ps_video_encode_ip->u4_is_last = is_last; ps_video_encode_ip->u4_mb_info_type = ps_app_ctxt->u4_mb_info_type; - ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type;; + ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type; + ps_video_encode_op->s_out_buf.pv_buf = NULL; ps_video_encode_ip->u4_timestamp_high = u4_timestamp_high; ps_video_encode_ip->u4_timestamp_low = u4_timestamp_low; - GETTIME(&ps_app_ctxt->enc_last_time); - status = ih264e_api_function(ps_enc, &ih264e_video_encode_ip, &ih264e_video_encode_op); - - if (IV_SUCCESS != status) + /* encoder api call */ + status = ih264e_api_function(ps_enc, &ih264e_video_encode_ip, + &ih264e_video_encode_op); + if(IV_SUCCESS != status) { - printf("Encode Frame failed = 0x%x\n", ih264e_video_encode_op.s_ive_op.u4_error_code); + printf("Encode Frame failed = 0x%x\n", + ih264e_video_encode_op.s_ive_op.u4_error_code); break; } @@ -2277,6 +2282,7 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) #ifdef PROFILE_ENABLE { WORD32 peak_avg, id; + u4_total_time += timetaken; peak_window[peak_window_idx++] = timetaken; if(peak_window_idx == PEAK_WINDOW_SIZE) @@ -2292,17 +2298,13 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) } #endif - /******************************************************************************/ - /****************** Writing Output ********************************************/ - /******************************************************************************/ + /* Write Output */ num_bytes = 0; - if(1 == ps_video_encode_op->output_present) { num_bytes = ps_video_encode_op->s_out_buf.u4_bytes; buff_size = ps_video_encode_op->s_out_buf.u4_bufsize; pu1_buf = (UWORD8*)ps_video_encode_op->s_out_buf.pv_buf; - status = write_output(ps_app_ctxt->fp_op, pu1_buf, num_bytes); if(IV_SUCCESS != status) { @@ -2312,12 +2314,13 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) } /* free input bufer if codec returns a valid input buffer */ - if (ps_video_encode_op->s_inp_buf.apv_bufs[0]) + if(ps_video_encode_op->s_inp_buf.apv_bufs[0]) { /* Reuse of freed input buffer */ for(i = 0; i < DEFAULT_MAX_INPUT_BUFS; i++) { - if(ps_app_ctxt->as_input_buf[i].pu1_buf == ps_video_encode_op->s_inp_buf.apv_bufs[0]) + if(ps_app_ctxt->as_input_buf[i].pu1_buf + == ps_video_encode_op->s_inp_buf.apv_bufs[0]) { ps_app_ctxt->as_input_buf[i].u4_is_free = 1; break; @@ -2326,11 +2329,12 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) } /* free output buffer if codec returns a valid output buffer */ - // if(ps_video_encode_op->s_out_buf.pv_buf) + if(ps_video_encode_op->s_out_buf.pv_buf) { for(i = 0; i < DEFAULT_MAX_OUTPUT_BUFS; i++) { - if(ps_app_ctxt->as_output_buf[i].pu1_buf == ps_video_encode_op->s_out_buf.pv_buf) + if(ps_app_ctxt->as_output_buf[i].pu1_buf + == ps_video_encode_op->s_out_buf.pv_buf) { ps_app_ctxt->as_output_buf[i].u4_is_free = 1; break; @@ -2338,41 +2342,33 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) } } - /********************************************************************** - * Print stats - **********************************************************************/ + /* Print stats */ { - UWORD8 u1_pic_type[][5] = - { "IDR", "I", "P", "B", "NA" }; + UWORD8 u1_pic_type[][5] = { "IDR", "I", "P", "B", "NA" }; WORD32 lookup_idx = 0; - if (ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type - == IV_IDR_FRAME) - { - lookup_idx = 0; - } - else if(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type - == IV_I_FRAME) + switch(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type) { - lookup_idx = 1; - } - else if(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type - == IV_P_FRAME) - { - lookup_idx = 2; - } - else if(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type - == IV_B_FRAME) - { - lookup_idx = 3; - } - else if(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type - == IV_NA_FRAME) - { - lookup_idx = 4; + case IV_IDR_FRAME: + lookup_idx = 0; + break; + case IV_I_FRAME: + lookup_idx = 1; + break; + case IV_P_FRAME: + lookup_idx = 2; + break; + case IV_B_FRAME: + lookup_idx = 3; + break; + case IV_NA_FRAME: + lookup_idx = 4; + break; + default: + break; } - if (ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type + if(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type != IV_NA_FRAME) { ps_app_ctxt->u4_pics_cnt++; @@ -2380,7 +2376,7 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) ps_app_ctxt->u4_total_bytes += num_bytes; } - if (ps_app_ctxt->u4_psnr_enable == 0) + if(ps_app_ctxt->u4_psnr_enable == 0) { printf("[%s] PicNum %4d Bytes Generated %6d TimeTaken(microsec): %6d AvgTime: %6d PeakAvgTimeMax: %6d\n", u1_pic_type[lookup_idx], ps_app_ctxt->u4_pics_cnt, @@ -2500,7 +2496,8 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) } } - /* Pic count is 1 more than actual num frames encoded, because last call is to just get the output */ + /* Pic count is 1 more than actual num frames encoded, because last call is + * to just get the output */ ps_app_ctxt->u4_pics_cnt--; if(ps_app_ctxt->u4_psnr_enable) @@ -2538,29 +2535,12 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) free_recon(ps_app_ctxt); } -/*****************************************************************************/ -/* */ -/* Function Name : main */ -/* */ -/* Description : Application to demonstrate codec API */ -/* */ -/* */ -/* Inputs : argc - Number of arguments */ -/* argv[] - Arguments */ -/* Globals : */ -/* Processing : Shows how to use create, process, control and delete */ -/* */ -/* Outputs : Codec output in a file */ -/* Returns : */ -/* */ -/* Issues : Assumes both PROFILE_ENABLE to be */ -/* defined for multithread decode-display working */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes */ -/* 20 11 2013 100189 Initial Version */ -/*****************************************************************************/ +/** +******************************************************************************* +* @brief Application to demonstrate codec API. Shows how to use create, +* process, control and delete +******************************************************************************* +*/ #ifdef IOS int h264enc_main(char * homedir,char *documentdir, int screen_wd, int screen_ht) #else @@ -2677,7 +2657,6 @@ int main(int argc, char *argv[]) #endif - validate_params(&s_app_ctxt); @@ -2689,42 +2668,44 @@ int main(int argc, char *argv[]) ih264e_num_mem_rec_op_t s_num_mem_rec_op; s_num_mem_rec_ip.s_ive_ip.u4_size = sizeof(ih264e_num_mem_rec_ip_t); - s_num_mem_rec_op.s_ive_op.u4_size = sizeof(ih264e_num_mem_rec_op_t); - s_num_mem_rec_ip.s_ive_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC; - status = ih264e_api_function(0, &s_num_mem_rec_ip, &s_num_mem_rec_op); + s_num_mem_rec_op.s_ive_op.u4_size = sizeof(ih264e_num_mem_rec_op_t); + status = ih264e_api_function(NULL, &s_num_mem_rec_ip, &s_num_mem_rec_op); if(status != IV_SUCCESS) { - sprintf(ac_error, "Get number of memory records failed = 0x%x\n", s_num_mem_rec_op.s_ive_op.u4_error_code); + sprintf(ac_error, "Get number of memory records failed = 0x%x\n", + s_num_mem_rec_op.s_ive_op.u4_error_code); codec_exit(ac_error); } - s_app_ctxt.u4_num_mem_rec = num_mem_recs = s_num_mem_rec_op.s_ive_op.u4_num_mem_rec; + s_app_ctxt.u4_num_mem_rec = s_num_mem_rec_op.s_ive_op.u4_num_mem_rec; + num_mem_recs = s_num_mem_rec_op.s_ive_op.u4_num_mem_rec; } - /* Allocate array to hold memory records */ - s_app_ctxt.ps_mem_rec = (iv_mem_rec_t *) malloc(num_mem_recs * sizeof(iv_mem_rec_t)); + /*************************************************************************/ + /* Allocate and Default initialize MemRecords */ + /*************************************************************************/ + s_app_ctxt.ps_mem_rec = malloc(num_mem_recs * sizeof(iv_mem_rec_t)); if(NULL == s_app_ctxt.ps_mem_rec) { - - sprintf(ac_error, "Unable to allocate memory for hold memory records: Size %d", (WORD32)(num_mem_recs * sizeof(iv_mem_rec_t))); + sprintf(ac_error, + "Unable to allocate memory for hold memory records: Size %d", + (WORD32)(num_mem_recs * sizeof(iv_mem_rec_t))); codec_exit(ac_error); } - + /* Default init memory records */ { - iv_mem_rec_t *ps_mem_rec; - ps_mem_rec = s_app_ctxt.ps_mem_rec; - for(i = 0; i < num_mem_recs; i++) + iv_mem_rec_t *ps_mem_rec = s_app_ctxt.ps_mem_rec; + + for(i = 0; i < num_mem_recs; i++, ps_mem_rec++) { ps_mem_rec->u4_size = sizeof(iv_mem_rec_t); ps_mem_rec->pv_base = NULL; ps_mem_rec->u4_mem_size = 0; ps_mem_rec->u4_mem_alignment = 0; ps_mem_rec->e_mem_type = IV_NA_MEM_TYPE; - - ps_mem_rec++; } } @@ -2736,22 +2717,21 @@ int main(int argc, char *argv[]) ih264e_fill_mem_rec_op_t s_fill_mem_rec_op; s_fill_mem_rec_ip.s_ive_ip.u4_size = sizeof(ih264e_fill_mem_rec_ip_t); - s_fill_mem_rec_op.s_ive_op.u4_size = sizeof(ih264e_fill_mem_rec_op_t); - s_fill_mem_rec_ip.s_ive_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC; s_fill_mem_rec_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec; s_fill_mem_rec_ip.s_ive_ip.u4_num_mem_rec = s_app_ctxt.u4_num_mem_rec; s_fill_mem_rec_ip.s_ive_ip.u4_max_wd = s_app_ctxt.u4_max_wd; s_fill_mem_rec_ip.s_ive_ip.u4_max_ht = s_app_ctxt.u4_max_ht; - s_fill_mem_rec_ip.s_ive_ip.u4_max_level = s_app_ctxt.u4_max_level; - s_fill_mem_rec_ip.s_ive_ip.e_color_format = DEFAULT_INP_COLOR_FMT; s_fill_mem_rec_ip.s_ive_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM; s_fill_mem_rec_ip.s_ive_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM; + s_fill_mem_rec_ip.s_ive_ip.u4_max_level = s_app_ctxt.u4_max_level; + s_fill_mem_rec_ip.s_ive_ip.e_color_format = DEFAULT_INP_COLOR_FMT; s_fill_mem_rec_ip.s_ive_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; s_fill_mem_rec_ip.s_ive_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; - status = ih264e_api_function(0, &s_fill_mem_rec_ip, &s_fill_mem_rec_op); + s_fill_mem_rec_op.s_ive_op.u4_size = sizeof(ih264e_fill_mem_rec_op_t); + status = ih264e_api_function(NULL, &s_fill_mem_rec_ip, &s_fill_mem_rec_op); if(status != IV_SUCCESS) { sprintf(ac_error, "Fill memory records failed = 0x%x\n", @@ -2764,19 +2744,19 @@ int main(int argc, char *argv[]) /* Allocating Memory for Mem Records */ /*************************************************************************/ { - WORD32 total_size; - iv_mem_rec_t *ps_mem_rec; - total_size = 0; + iv_mem_rec_t *ps_mem_rec = s_app_ctxt.ps_mem_rec; + WORD32 total_size = 0; - ps_mem_rec = s_app_ctxt.ps_mem_rec; for(i = 0; i < num_mem_recs; i++) { - ps_mem_rec->pv_base = ih264a_aligned_malloc(ps_mem_rec->u4_mem_alignment, - ps_mem_rec->u4_mem_size); + ps_mem_rec->pv_base = ih264a_aligned_malloc( + ps_mem_rec->u4_mem_alignment, + ps_mem_rec->u4_mem_size); if(ps_mem_rec->pv_base == NULL) { - sprintf(ac_error, "Allocation failure for mem record id %d size %d\n", - i, ps_mem_rec->u4_mem_size); + sprintf(ac_error, + "Allocation failure for mem record id %d size %d\n", i, + ps_mem_rec->u4_mem_size); codec_exit(ac_error); } total_size += ps_mem_rec->u4_mem_size; @@ -2800,8 +2780,6 @@ int main(int argc, char *argv[]) s_app_ctxt.ps_enc = ps_enc; s_init_ip.s_ive_ip.u4_size = sizeof(ih264e_init_ip_t); - s_init_op.s_ive_op.u4_size = sizeof(ih264e_init_op_t); - s_init_ip.s_ive_ip.e_cmd = IV_CMD_INIT; s_init_ip.s_ive_ip.u4_num_mem_rec = s_app_ctxt.u4_num_mem_rec; s_init_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec; @@ -2811,29 +2789,31 @@ int main(int argc, char *argv[]) s_init_ip.s_ive_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM; s_init_ip.s_ive_ip.u4_max_level = s_app_ctxt.u4_max_level; s_init_ip.s_ive_ip.e_inp_color_fmt = s_app_ctxt.e_inp_color_fmt; - if(s_app_ctxt.u4_recon_enable || s_app_ctxt.u4_psnr_enable || s_app_ctxt.u4_chksum_enable) + if(s_app_ctxt.u4_recon_enable || s_app_ctxt.u4_psnr_enable + || s_app_ctxt.u4_chksum_enable) { - s_init_ip.s_ive_ip.u4_enable_recon = 1; + s_init_ip.s_ive_ip.u4_enable_recon = 1; } else { - s_init_ip.s_ive_ip.u4_enable_recon = 0; + s_init_ip.s_ive_ip.u4_enable_recon = 0; } - s_init_ip.s_ive_ip.e_recon_color_fmt = s_app_ctxt.e_recon_color_fmt; - s_init_ip.s_ive_ip.e_rc_mode = s_app_ctxt.u4_rc; - s_init_ip.s_ive_ip.u4_max_framerate = s_app_ctxt.u4_max_frame_rate; - s_init_ip.s_ive_ip.u4_max_bitrate = s_app_ctxt.u4_max_bitrate; - s_init_ip.s_ive_ip.u4_num_bframes = s_app_ctxt.u4_num_bframes; - s_init_ip.s_ive_ip.e_content_type = IV_PROGRESSIVE; - s_init_ip.s_ive_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; - s_init_ip.s_ive_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; - s_init_ip.s_ive_ip.e_slice_mode = s_app_ctxt.u4_slice_mode; - s_init_ip.s_ive_ip.u4_slice_param = s_app_ctxt.u4_slice_param; - s_init_ip.s_ive_ip.e_arch = s_app_ctxt.e_arch; - s_init_ip.s_ive_ip.e_soc = s_app_ctxt.e_soc; + s_init_ip.s_ive_ip.e_recon_color_fmt = s_app_ctxt.e_recon_color_fmt; + s_init_ip.s_ive_ip.e_rc_mode = s_app_ctxt.u4_rc; + s_init_ip.s_ive_ip.u4_max_framerate = s_app_ctxt.u4_max_frame_rate; + s_init_ip.s_ive_ip.u4_max_bitrate = s_app_ctxt.u4_max_bitrate; + s_init_ip.s_ive_ip.u4_num_bframes = s_app_ctxt.u4_num_bframes; + s_init_ip.s_ive_ip.e_content_type = IV_PROGRESSIVE; + s_init_ip.s_ive_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; + s_init_ip.s_ive_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; + s_init_ip.s_ive_ip.e_slice_mode = s_app_ctxt.u4_slice_mode; + s_init_ip.s_ive_ip.u4_slice_param = s_app_ctxt.u4_slice_param; + s_init_ip.s_ive_ip.e_arch = s_app_ctxt.e_arch; + s_init_ip.s_ive_ip.e_soc = s_app_ctxt.e_soc; - status = ih264e_api_function(ps_enc, &s_init_ip, &s_init_op); + s_init_op.s_ive_op.u4_size = sizeof(ih264e_init_op_t); + status = ih264e_api_function(ps_enc, &s_init_ip, &s_init_op); if(status != IV_SUCCESS) { sprintf(ac_error, "Init memory records failed = 0x%x\n", @@ -2848,24 +2828,24 @@ int main(int argc, char *argv[]) { ih264e_ctl_set_num_cores_ip_t s_ctl_set_num_cores_ip; ih264e_ctl_set_num_cores_op_t s_ctl_set_num_cores_op; + + s_ctl_set_num_cores_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_num_cores_ip_t); s_ctl_set_num_cores_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_ctl_set_num_cores_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES; s_ctl_set_num_cores_ip.s_ive_ip.u4_num_cores = s_app_ctxt.u4_num_cores; s_ctl_set_num_cores_ip.s_ive_ip.u4_timestamp_high = 0; s_ctl_set_num_cores_ip.s_ive_ip.u4_timestamp_low = 0; - s_ctl_set_num_cores_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_num_cores_ip_t); s_ctl_set_num_cores_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_num_cores_op_t); - status = ih264e_api_function(ps_enc, (void *) &s_ctl_set_num_cores_ip, - (void *) &s_ctl_set_num_cores_op); + status = ih264e_api_function(ps_enc, (void *)&s_ctl_set_num_cores_ip, + (void *)&s_ctl_set_num_cores_op); if(status != IV_SUCCESS) { sprintf(ac_error, "Unable to set processor params = 0x%x\n", s_ctl_set_num_cores_op.s_ive_op.u4_error_code); codec_exit(ac_error); } - } /*************************************************************************/ @@ -2875,15 +2855,18 @@ int main(int argc, char *argv[]) ih264e_ctl_getversioninfo_ip_t s_ctl_set_getversioninfo_ip; ih264e_ctl_getversioninfo_op_t s_ctl_set_getversioninfo_op; CHAR ac_version_string[STRLENGTH]; + + s_ctl_set_getversioninfo_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_getversioninfo_ip_t); s_ctl_set_getversioninfo_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_ctl_set_getversioninfo_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETVERSION; s_ctl_set_getversioninfo_ip.s_ive_ip.pu1_version = (UWORD8 *)ac_version_string; s_ctl_set_getversioninfo_ip.s_ive_ip.u4_version_bufsize = sizeof(ac_version_string); - s_ctl_set_getversioninfo_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_getversioninfo_ip_t); + s_ctl_set_getversioninfo_op.s_ive_op.u4_size = sizeof(ih264e_ctl_getversioninfo_op_t); - status = ih264e_api_function(ps_enc, (void *) &s_ctl_set_getversioninfo_ip, - (void *) &s_ctl_set_getversioninfo_op); + status = ih264e_api_function(ps_enc, + (void *)&s_ctl_set_getversioninfo_ip, + (void *)&s_ctl_set_getversioninfo_op); if(status != IV_SUCCESS) { sprintf(ac_error, "Unable to get codec version = 0x%x\n", @@ -2901,17 +2884,17 @@ int main(int argc, char *argv[]) ih264e_ctl_getbufinfo_op_t s_get_buf_info_op; s_get_buf_info_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_getbufinfo_ip_t); - s_get_buf_info_op.s_ive_op.u4_size = sizeof(ih264e_ctl_getbufinfo_op_t); - s_get_buf_info_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_get_buf_info_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETBUFINFO; s_get_buf_info_ip.s_ive_ip.u4_max_ht = s_app_ctxt.u4_max_ht; s_get_buf_info_ip.s_ive_ip.u4_max_wd = s_app_ctxt.u4_max_wd; s_get_buf_info_ip.s_ive_ip.e_inp_color_fmt = s_app_ctxt.e_inp_color_fmt; - status = ih264e_api_function(ps_enc, &s_get_buf_info_ip, &s_get_buf_info_op); + s_get_buf_info_op.s_ive_op.u4_size = sizeof(ih264e_ctl_getbufinfo_op_t); - if (status != IV_SUCCESS) + status = ih264e_api_function(ps_enc, &s_get_buf_info_ip, + &s_get_buf_info_op); + if(status != IV_SUCCESS) { sprintf(ac_error, "Unable to get I/O buffer requirements = 0x%x\n", s_get_buf_info_op.s_ive_op.u4_error_code); @@ -2920,70 +2903,69 @@ int main(int argc, char *argv[]) s_app_ctxt.s_get_buf_info_op = s_get_buf_info_op; } - /*****************************************************************************/ - /* Add the following initializations based on the parameters in context */ - /*****************************************************************************/ + /**************************************************************************/ + /* Add the following initializations based on the parameters in context */ + /**************************************************************************/ - - /*****************************************************************************/ - /* Video control Set Frame dimensions */ - /*****************************************************************************/ + /**************************************************************************/ + /* Video control Set Frame dimensions */ + /**************************************************************************/ s_app_ctxt.u4_strd = s_app_ctxt.u4_wd; set_dimensions(&s_app_ctxt, 0, 0); - /*****************************************************************************/ - /* Video control Set Frame rates */ - /*****************************************************************************/ + /**************************************************************************/ + /* Video control Set Frame rates */ + /**************************************************************************/ set_frame_rate(&s_app_ctxt, 0, 0); - /*****************************************************************************/ - /* Video control Set IPE Params */ - /*****************************************************************************/ + /**************************************************************************/ + /* Video control Set IPE Params */ + /**************************************************************************/ set_ipe_params(&s_app_ctxt, 0, 0); - /*****************************************************************************/ - /* Video control Set Bitrate */ - /*****************************************************************************/ + /**************************************************************************/ + /* Video control Set Bitrate */ + /**************************************************************************/ set_bit_rate(&s_app_ctxt, 0, 0); - /*****************************************************************************/ - /* Video control Set QP */ - /*****************************************************************************/ - set_qp(&s_app_ctxt,0,0); - - /*****************************************************************************/ - /* Video control Set AIR params */ - /*****************************************************************************/ - set_air_params(&s_app_ctxt,0,0); - - /*****************************************************************************/ - /* Video control Set VBV params */ - /*****************************************************************************/ - set_vbv_params(&s_app_ctxt,0,0); - - /*****************************************************************************/ - /* Video control Set Motion estimation params */ - /*****************************************************************************/ - set_me_params(&s_app_ctxt,0,0); - - /*****************************************************************************/ - /* Video control Set GOP params */ - /*****************************************************************************/ + /**************************************************************************/ + /* Video control Set QP */ + /**************************************************************************/ + set_qp(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set AIR params */ + /**************************************************************************/ + set_air_params(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set VBV params */ + /**************************************************************************/ + set_vbv_params(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set Motion estimation params */ + /**************************************************************************/ + set_me_params(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set GOP params */ + /**************************************************************************/ set_gop_params(&s_app_ctxt, 0, 0); - /*****************************************************************************/ - /* Video control Set Deblock params */ - /*****************************************************************************/ + /**************************************************************************/ + /* Video control Set Deblock params */ + /**************************************************************************/ set_deblock_params(&s_app_ctxt, 0, 0); - /*****************************************************************************/ - /* Video control Set Profile params */ - /*****************************************************************************/ + /**************************************************************************/ + /* Video control Set Profile params */ + /**************************************************************************/ set_profile_params(&s_app_ctxt, 0, 0); - /*****************************************************************************/ - /* Video usability information */ - /*****************************************************************************/ + /**************************************************************************/ + /* Video usability information */ + /**************************************************************************/ set_vui_params(&s_app_ctxt); #ifdef IOS @@ -3008,11 +2990,13 @@ int main(int argc, char *argv[]) #endif /*************************************************************************/ - /* begin encoding */ + /* Encoding */ /*************************************************************************/ - synchronous_encode(ps_enc, &s_app_ctxt); + /*************************************************************************/ + /* Print summary */ + /*************************************************************************/ { DOUBLE bytes_per_frame; DOUBLE bytes_per_second; @@ -3049,18 +3033,15 @@ int main(int argc, char *argv[]) { ih264e_retrieve_mem_rec_ip_t s_retrieve_mem_ip; ih264e_retrieve_mem_rec_op_t s_retrieve_mem_op; - iv_mem_rec_t *ps_mem_rec; - s_retrieve_mem_ip.s_ive_ip.u4_size = - sizeof(ih264e_retrieve_mem_rec_ip_t); - s_retrieve_mem_op.s_ive_op.u4_size = - sizeof(ih264e_retrieve_mem_rec_op_t); + iv_mem_rec_t *ps_mem_rec = s_app_ctxt.ps_mem_rec; + s_retrieve_mem_ip.s_ive_ip.u4_size = sizeof(ih264e_retrieve_mem_rec_ip_t); s_retrieve_mem_ip.s_ive_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC; s_retrieve_mem_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec; - status = ih264e_api_function(ps_enc, &s_retrieve_mem_ip, - &s_retrieve_mem_op); + s_retrieve_mem_op.s_ive_op.u4_size = sizeof(ih264e_retrieve_mem_rec_op_t); + status = ih264e_api_function(ps_enc, &s_retrieve_mem_ip, &s_retrieve_mem_op); if(status != IV_SUCCESS) { sprintf(ac_error, "Unable to retrieve memory records = 0x%x\n", @@ -3069,15 +3050,12 @@ int main(int argc, char *argv[]) } /* Free memory records */ - ps_mem_rec = s_app_ctxt.ps_mem_rec; for(i = 0; i < num_mem_recs; i++) { ih264a_aligned_free(ps_mem_rec->pv_base); ps_mem_rec++; } - free(s_app_ctxt.ps_mem_rec); - } return 0; diff --git a/test/encoder/output.c b/examples/avcenc/output.c index 8d16400..0702afd 100644 --- a/test/encoder/output.c +++ b/examples/avcenc/output.c @@ -18,20 +18,35 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ +/** +******************************************************************************* +* @file +* output.c +* +* @brief +* Contains functions necessary for managing output buffers +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ + /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ /* System include files */ - #include <stdlib.h> #include <stdio.h> #include <assert.h> #include <string.h> -/* User include files */ +/* User include files */ #include "ih264_typedefs.h" -#include "ih264_defs.h" #include "iv2.h" #include "ive2.h" #include "ih264e.h" @@ -41,12 +56,22 @@ /* Constant Macros */ /*****************************************************************************/ #define PEAK_WINDOW_SIZE 8 + + /*****************************************************************************/ /* Macros */ /*****************************************************************************/ + + /*****************************************************************************/ -/* Function Declarations */ +/* Function Definitions */ /*****************************************************************************/ + +/** +************************************************************************** +* @brief Write bitstream buffers to a file +************************************************************************** +*/ IV_STATUS_T write_output(FILE *fp, UWORD8 *pu1_buf, WORD32 num_bytes) { WORD32 bytes; @@ -59,19 +84,27 @@ IV_STATUS_T write_output(FILE *fp, UWORD8 *pu1_buf, WORD32 num_bytes) return IV_SUCCESS; } +/** +************************************************************************** +* @brief allocate bitstream buffers +************************************************************************** +*/ void allocate_output(app_ctxt_t *ps_app_ctxt) { - WORD32 num_bufs; WORD32 i; UWORD8 *pu1_buf; WORD32 buf_size; - num_bufs = MAX(DEFAULT_NUM_OUTPUT_BUFS, ps_app_ctxt->s_get_buf_info_op.s_ive_op.u4_min_out_bufs); + + num_bufs = MAX(DEFAULT_NUM_OUTPUT_BUFS, + ps_app_ctxt->s_get_buf_info_op.s_ive_op.u4_min_out_bufs); num_bufs = MIN(DEFAULT_MAX_OUTPUT_BUFS, num_bufs); buf_size = ps_app_ctxt->s_get_buf_info_op.s_ive_op.au4_min_out_buf_size[0]; + /* Memset the output buffer array to set is_free to 0 */ - memset(ps_app_ctxt->as_output_buf, 0, sizeof(output_buf_t) * DEFAULT_MAX_OUTPUT_BUFS); + memset(ps_app_ctxt->as_output_buf, 0, + sizeof(output_buf_t) * DEFAULT_MAX_OUTPUT_BUFS); for(i = 0; i < num_bufs; i++) { @@ -79,31 +112,33 @@ void allocate_output(app_ctxt_t *ps_app_ctxt) if(NULL == pu1_buf) { CHAR ac_error[STRLENGTH]; - sprintf(ac_error, "Allocation failed for output buffer of size %d\n", + sprintf(ac_error, + "Allocation failed for output buffer of size %d\n", buf_size); codec_exit(ac_error); } ps_app_ctxt->as_output_buf[i].pu1_buf = pu1_buf; ps_app_ctxt->as_output_buf[i].u4_buf_size = buf_size; ps_app_ctxt->as_output_buf[i].u4_is_free = 1; - } - return; } +/** +************************************************************************** +* @brief free bitstream buffers +************************************************************************** +*/ void free_output(app_ctxt_t *ps_app_ctxt) { - WORD32 num_bufs; WORD32 i; - num_bufs = MAX(DEFAULT_NUM_OUTPUT_BUFS, ps_app_ctxt->s_get_buf_info_op.s_ive_op.u4_min_out_bufs); + num_bufs = MAX(DEFAULT_NUM_OUTPUT_BUFS, + ps_app_ctxt->s_get_buf_info_op.s_ive_op.u4_min_out_bufs); num_bufs = MIN(DEFAULT_MAX_OUTPUT_BUFS, num_bufs); for(i = 0; i < num_bufs; i++) { - ih264a_aligned_free(ps_app_ctxt->as_output_buf[i].pu1_buf); } - return; } diff --git a/examples/avcenc/psnr.c b/examples/avcenc/psnr.c new file mode 100644 index 0000000..9762374 --- /dev/null +++ b/examples/avcenc/psnr.c @@ -0,0 +1,220 @@ +/****************************************************************************** + * + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore +*/ + +/** +******************************************************************************* +* @file +* psnr.c +* +* @brief +* Contains functions necessary for computing psnr +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ +/* System include files */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +/* User include files */ +#include "ih264_typedefs.h" +#include "iv2.h" +#include "ive2.h" +#include "ih264e.h" +#include "app.h" +#include "psnr.h" + + +/*****************************************************************************/ +/* Function Definition */ +/*****************************************************************************/ + +/** +************************************************************************** +* @brief Initialize PSNR for the Y, U, V component +************************************************************************** +*/ +void init_psnr(app_ctxt_t *ps_app_ctxt) +{ + ps_app_ctxt->adbl_psnr[0] = 0; + ps_app_ctxt->adbl_psnr[1] = 0; + ps_app_ctxt->adbl_psnr[2] = 0; + ps_app_ctxt->u4_psnr_cnt = 0; +} + +/** +************************************************************************** +* @brief Computes PSNR for the Y, U, V component +************************************************************************** +*/ +void compute_psnr(app_ctxt_t *ps_app_ctxt, + iv_raw_buf_t *ps_buf1, + iv_raw_buf_t *ps_buf2) +{ + WORD32 i, j; + WORD32 comp; + DOUBLE df_psnr[3]; + WORD32 wd, ht, strd1, strd2; + UWORD8 *pu1_buf1, *pu1_buf2; + WORD32 incr1, incr2; + + printf("\nPicNum %4d\t ", ps_app_ctxt->u4_psnr_cnt); + + for(comp = 0; comp < 3; comp++) + { + df_psnr[comp] = 0; + pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[comp]; + pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[comp]; + wd = ps_buf1->au4_wd[comp]; + ht = ps_buf1->au4_ht[comp]; + strd1 = ps_buf1->au4_strd[comp] - ps_buf1->au4_wd[comp]; + strd2 = ps_buf2->au4_strd[comp] - ps_buf2->au4_wd[comp]; + incr1 = 1; + incr2 = 1; + + if((IV_YUV_420SP_UV == ps_buf1->e_color_fmt) + || (IV_YUV_420SP_VU == ps_buf1->e_color_fmt)) + { + switch(comp) + { + case 0: + pu1_buf1 = ps_buf1->apv_bufs[0]; + break; + case 1: + if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt) + pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[1]; + else + pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[1] + 1; + incr1 = 2; + wd = ps_buf1->au4_wd[0] >> 1; + ht = ps_buf1->au4_ht[0] >> 1; + break; + case 2: + if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt) + pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[1] + 1; + else + pu1_buf1 = ps_buf1->apv_bufs[1]; + incr1 = 2; + wd = ps_buf1->au4_wd[0] >> 1; + ht = ps_buf1->au4_ht[0] >> 1; + strd1 = ps_buf1->au4_strd[1] - ps_buf1->au4_wd[1]; + break; + } + } + if((IV_YUV_420SP_UV == ps_buf2->e_color_fmt) + || (IV_YUV_420SP_VU == ps_buf2->e_color_fmt)) + { + switch(comp) + { + case 0: + pu1_buf2 = ps_buf2->apv_bufs[0]; + break; + case 1: + if(IV_YUV_420SP_UV == ps_buf2->e_color_fmt) + pu1_buf2 = ps_buf2->apv_bufs[1]; + else + pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[1] + 1; + incr2 = 2; + wd = ps_buf1->au4_wd[0] >> 1; + ht = ps_buf1->au4_ht[0] >> 1; + + break; + case 2: + if(IV_YUV_420SP_UV == ps_buf2->e_color_fmt) + pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[1] + 1; + else + pu1_buf2 = ps_buf2->apv_bufs[1]; + incr2 = 2; + wd = ps_buf1->au4_wd[0] >> 1; + ht = ps_buf1->au4_ht[0] >> 1; + strd2 = ps_buf2->au4_strd[1] - ps_buf2->au4_wd[1]; + + break; + } + } + + for(i = 0; i < ht; i++) + { + for(j = 0; j < wd; j++) + { + WORD32 diff; + diff = (*pu1_buf1 - *pu1_buf2); + pu1_buf1 += incr1; + pu1_buf2 += incr2; + df_psnr[comp] += diff * diff; + } + pu1_buf1 += strd1; + pu1_buf2 += strd2; + } + df_psnr[comp] /= (wd * ht); + if(df_psnr[comp]) + df_psnr[comp] = 20 * log10(255 / sqrt(df_psnr[comp])); + else + df_psnr[comp] = 100; + + ps_app_ctxt->adbl_psnr[comp] += df_psnr[comp]; + switch(comp) + { + case 0: + printf("Y :"); + break; + case 1: + printf("U :"); + break; + case 2: + printf("V :"); + break; + default: + break; + } + printf("%2.2f\t", df_psnr[comp]); + } + + ps_app_ctxt->u4_psnr_cnt++; +} + +/** +************************************************************************** +* @brief Prints PSNR for the Y, U, V component +************************************************************************** +*/ +void print_average_psnr(app_ctxt_t *ps_app_ctxt) +{ + printf("\n"); + + printf("Avg PSNR Y : %-2.2f\n", + (ps_app_ctxt->adbl_psnr[0] / ps_app_ctxt->u4_psnr_cnt)); + printf("Avg PSNR U : %-2.2f\n", + (ps_app_ctxt->adbl_psnr[1] / ps_app_ctxt->u4_psnr_cnt)); + printf("Avg PSNR V : %-2.2f\n", + (ps_app_ctxt->adbl_psnr[2] / ps_app_ctxt->u4_psnr_cnt)); +} + diff --git a/common/ih264_resi_trans.h b/examples/avcenc/psnr.h index ee0add3..f91e0bb 100644 --- a/common/ih264_resi_trans.h +++ b/examples/avcenc/psnr.h @@ -17,54 +17,38 @@ ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ + /** ******************************************************************************* * @file -* ih264_resi_trans.h +* psnr.h * * @brief -* Functions declarations for residue and forward transform -* -* @par List of Functions: -* - ih264_resi_trans_ft -* - ih264_resi_trans_4x4 -* - ih264_resi_trans_4x4 -* - ih264_resi_trans_4x4_a9 -* - ih264_resi_trans_4x4_a9 +* Contains declarations of functions for psnr computation * * @author -* Ittiam +* ittiam * * @remarks -* None +* none * ******************************************************************************* */ -#ifndef IH264_RESI_TRANS_H_ -#define IH264_RESI_TRANS_H_ +#ifndef _PSNR_H_ +#define _PSNR_H_ /*****************************************************************************/ -/* Extern Function Declarations */ +/* Function Declarations */ /*****************************************************************************/ +void init_psnr(app_ctxt_t *ps_app_ctxt); -typedef void ih264_resi_trans_ft(UWORD8 *pu1_src, - UWORD8 *pu1_pred, - WORD32 *pi4_out, - WORD32 src_strd, - WORD32 pred_strd, - WORD32 out_strd); - -/*C functions*/ - -ih264_resi_trans_ft ih264_resi_trans_4x4; - -ih264_resi_trans_ft ih264_resi_trans_8x8; +void compute_psnr(app_ctxt_t *ps_app_ctxt, + iv_raw_buf_t *ps_buf1, + iv_raw_buf_t *ps_buf2); -/*A9 functions*/ +void print_average_psnr(app_ctxt_t *ps_app_ctxt); -ih264_resi_trans_ft ih264_resi_trans_4x4_a9; +#endif /* _PSNR_H_ */ -ih264_resi_trans_ft ih264_resi_trans_8x8_a9; -#endif /* IH264_RESI_TRANS_H_ */ diff --git a/test/encoder/recon.c b/examples/avcenc/recon.c index 89cfe40..20bab6c 100644 --- a/test/encoder/recon.c +++ b/examples/avcenc/recon.c @@ -18,20 +18,35 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ +/** +******************************************************************************* +* @file +* recon.c +* +* @brief +* Contains functions necessary for managing recon buffers +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ + /*****************************************************************************/ /* File Includes */ /*****************************************************************************/ /* System include files */ - #include <stdlib.h> #include <stdio.h> #include <assert.h> #include <string.h> -/* User include files */ +/* User include files */ #include "ih264_typedefs.h" -#include "ih264_defs.h" #include "iv2.h" #include "ive2.h" #include "ih264e.h" @@ -48,62 +63,61 @@ /*****************************************************************************/ -/* Function Declarations */ +/* Function Definitions */ /*****************************************************************************/ +/** +************************************************************************** +* @brief Write recon buffers to a file +************************************************************************** +*/ IV_STATUS_T write_recon(FILE *fp, iv_raw_buf_t *ps_raw_buf) { - WORD32 bytes; - WORD32 wd, ht; - UWORD8 *pu1_buf; - WORD32 i; - WORD32 comp; - WORD32 num_comp; + WORD32 num_comp = 2; + WORD32 comp_idx; - num_comp = 2; if(IV_YUV_420P == ps_raw_buf->e_color_fmt) num_comp = 3; - for(comp = 0; comp < num_comp; comp++) + for(comp_idx = 0; comp_idx < num_comp; comp_idx++) { - wd = ps_raw_buf->au4_wd[comp]; - ht = ps_raw_buf->au4_ht[comp]; - pu1_buf = ps_raw_buf->apv_bufs[comp]; + WORD32 wd = ps_raw_buf->au4_wd[comp_idx]; + WORD32 ht = ps_raw_buf->au4_ht[comp_idx]; + UWORD8 *pu1_buf = ps_raw_buf->apv_bufs[comp_idx]; + WORD32 i; + for(i = 0; i < ht; i++) { - bytes = fwrite(pu1_buf, sizeof(UWORD8), wd, fp); + WORD32 bytes = fwrite(pu1_buf, sizeof(UWORD8), wd, fp); if(bytes != wd) { - return(IV_FAIL); + return (IV_FAIL); } pu1_buf += wd; } } - fflush(fp); return IV_SUCCESS; } + +/** +************************************************************************** +* @brief Allocate space for recon buffers +************************************************************************** +*/ void allocate_recon(app_ctxt_t *ps_app_ctxt) { - - WORD32 num_bufs; - WORD32 pic_size; - WORD32 luma_size; - WORD32 chroma_size; + WORD32 num_bufs = DEFAULT_NUM_RECON_BUFS; + /* Size of buffer for YUV420 */ + WORD32 luma_size = ps_app_ctxt->u4_max_wd * ps_app_ctxt->u4_max_ht; + WORD32 chroma_size = (luma_size) / 4; + WORD32 pic_size = luma_size + chroma_size * 2; WORD32 i; - UWORD8 *pu1_buf; - - num_bufs = DEFAULT_NUM_RECON_BUFS; - - /* Size of buffer for YUV420/420SP */ - luma_size = ps_app_ctxt->u4_max_wd * ps_app_ctxt->u4_max_ht; - chroma_size = (luma_size) / 4; - pic_size = luma_size + chroma_size * 2; - for(i = 0; i < num_bufs; i++) { - pu1_buf = (UWORD8 *)ih264a_aligned_malloc(16, pic_size); + UWORD8 *pu1_buf = (UWORD8 *)ih264a_aligned_malloc(16, pic_size); + if(NULL == pu1_buf) { CHAR ac_error[STRLENGTH]; @@ -115,10 +129,10 @@ void allocate_recon(app_ctxt_t *ps_app_ctxt) ps_app_ctxt->as_recon_buf[i].u4_buf_size = pic_size; ps_app_ctxt->as_recon_buf[i].u4_is_free = 1; } - if(ps_app_ctxt->u4_psnr_enable) { - pu1_buf = (UWORD8 *)ih264a_aligned_malloc(16, pic_size); + UWORD8 *pu1_buf = (UWORD8 *)ih264a_aligned_malloc(16, pic_size); + if(NULL == pu1_buf) { CHAR ac_error[STRLENGTH]; @@ -129,81 +143,80 @@ void allocate_recon(app_ctxt_t *ps_app_ctxt) ps_app_ctxt->pu1_psnr_buf = pu1_buf; ps_app_ctxt->u4_psnr_buf_size = pic_size; } - return; } +/** +************************************************************************** +* @brief free recon buffers +************************************************************************** +*/ void free_recon(app_ctxt_t *ps_app_ctxt) { - - WORD32 num_bufs; + WORD32 num_bufs = DEFAULT_NUM_RECON_BUFS; WORD32 i; - num_bufs = DEFAULT_NUM_RECON_BUFS; - for(i = 0; i < num_bufs; i++) { ih264a_aligned_free(ps_app_ctxt->as_recon_buf[i].pu1_buf); } - if(ps_app_ctxt->u4_psnr_enable) { ih264a_aligned_free(ps_app_ctxt->pu1_psnr_buf); - } - return; } - - -void init_raw_buf_descr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_raw_buf, UWORD8 *pu1_buf, IV_COLOR_FORMAT_T e_color_fmt) +/** +************************************************************************** +* @brief initialize raw buffer descriptor +* All the pointers and dimensions are initialized here to support change in +* resolution from the application +************************************************************************** +*/ +void init_raw_buf_descr(app_ctxt_t *ps_app_ctxt, + iv_raw_buf_t *ps_raw_buf, + UWORD8 *pu1_buf, + IV_COLOR_FORMAT_T e_color_fmt) { - WORD32 luma_size; - WORD32 chroma_size; + WORD32 luma_size = ps_app_ctxt->u4_max_wd * ps_app_ctxt->u4_max_ht; + WORD32 chroma_size = (luma_size) / 4; - /* All the pointers and dimensions are initialized here - * to support change in resolution from the application */ - luma_size = ps_app_ctxt->u4_max_wd * ps_app_ctxt->u4_max_ht; - chroma_size = (luma_size) / 4; + ps_raw_buf->u4_size = sizeof(iv_raw_buf_t); + ps_raw_buf->e_color_fmt = e_color_fmt; ps_raw_buf->apv_bufs[0] = pu1_buf; pu1_buf += luma_size; - ps_raw_buf->apv_bufs[1] = pu1_buf; pu1_buf += chroma_size; - ps_raw_buf->apv_bufs[2] = NULL; if(IV_YUV_420P == e_color_fmt) { ps_raw_buf->apv_bufs[2] = pu1_buf; } - ps_raw_buf->e_color_fmt = e_color_fmt; - ps_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd; - ps_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; - ps_raw_buf->au4_strd[0] = ps_app_ctxt->u4_wd; - + ps_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd; + ps_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; + ps_raw_buf->au4_strd[0] = ps_app_ctxt->u4_wd; /* Initialize for 420SP */ { - ps_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd; - ps_raw_buf->au4_wd[2] = 0; + ps_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd; + ps_raw_buf->au4_wd[2] = 0; - ps_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; - ps_raw_buf->au4_ht[2] = 0; + ps_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; + ps_raw_buf->au4_ht[2] = 0; - ps_raw_buf->au4_strd[1] = ps_app_ctxt->u4_wd; - ps_raw_buf->au4_strd[2] = 0; + ps_raw_buf->au4_strd[1] = ps_app_ctxt->u4_wd; + ps_raw_buf->au4_strd[2] = 0; } - if(IV_YUV_420P == e_color_fmt) { - ps_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd / 2; - ps_raw_buf->au4_wd[2] = ps_app_ctxt->u4_wd / 2; + ps_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd / 2; + ps_raw_buf->au4_wd[2] = ps_app_ctxt->u4_wd / 2; - ps_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; - ps_raw_buf->au4_ht[2] = ps_app_ctxt->u4_ht / 2; + ps_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; + ps_raw_buf->au4_ht[2] = ps_app_ctxt->u4_ht / 2; - ps_raw_buf->au4_strd[1] = ps_app_ctxt->u4_wd / 2; - ps_raw_buf->au4_strd[2] = ps_app_ctxt->u4_wd / 2; + ps_raw_buf->au4_strd[1] = ps_app_ctxt->u4_wd / 2; + ps_raw_buf->au4_strd[2] = ps_app_ctxt->u4_wd / 2; } /* If stride is not initialized, then use width as stride */ if(0 == ps_raw_buf->au4_strd[0]) @@ -212,9 +225,5 @@ void init_raw_buf_descr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_raw_buf, UWORD ps_raw_buf->au4_strd[1] = ps_raw_buf->au4_wd[1]; ps_raw_buf->au4_strd[2] = ps_raw_buf->au4_wd[2]; } - - ps_raw_buf->u4_size = sizeof(iv_raw_buf_t); - return; } - diff --git a/test/mvcdec/dec.cfg b/examples/mvcdec/dec.cfg index f452ea1..f452ea1 100644 --- a/test/mvcdec/dec.cfg +++ b/examples/mvcdec/dec.cfg diff --git a/test/mvcdec/main.c b/examples/mvcdec/main.c index e5b700f..e5b700f 100644 --- a/test/mvcdec/main.c +++ b/examples/mvcdec/main.c diff --git a/test/mvcdec/mvcdec.cmake b/examples/mvcdec/mvcdec.cmake index 8f3e6c2..721f180 100644 --- a/test/mvcdec/mvcdec.cmake +++ b/examples/mvcdec/mvcdec.cmake @@ -1,4 +1,4 @@ -list(APPEND MVC_DEC_APP_SRCS "${AVC_ROOT}/test/mvcdec/main.c") +list(APPEND MVC_DEC_APP_SRCS "${AVC_ROOT}/examples/mvcdec/main.c") libavc_add_executable(mvcdec libmvcdec SOURCES ${MVC_DEC_APP_SRCS}) target_compile_definitions(mvcdec PRIVATE PROFILE_ENABLE MD5_DISABLE) diff --git a/test/svcdec/dec.cfg b/examples/svcdec/dec.cfg index 5d31a8f..5d31a8f 100644 --- a/test/svcdec/dec.cfg +++ b/examples/svcdec/dec.cfg diff --git a/test/svcdec/main.c b/examples/svcdec/main.c index 412062c..412062c 100644 --- a/test/svcdec/main.c +++ b/examples/svcdec/main.c diff --git a/test/svcdec/svcdec.cmake b/examples/svcdec/svcdec.cmake index 53e1457..d84f507 100644 --- a/test/svcdec/svcdec.cmake +++ b/examples/svcdec/svcdec.cmake @@ -1,4 +1,4 @@ -list(APPEND SVC_DEC_APP_SRCS "${AVC_ROOT}/test/svcdec/main.c") +list(APPEND SVC_DEC_APP_SRCS "${AVC_ROOT}/examples/svcdec/main.c") libavc_add_executable(svcdec libsvcdec SOURCES ${SVC_DEC_APP_SRCS}) target_compile_definitions(svcdec PRIVATE PROFILE_ENABLE MD5_DISABLE) diff --git a/test/svcenc/app.h b/examples/svcenc/app.h index 682557c..682557c 100644 --- a/test/svcenc/app.h +++ b/examples/svcenc/app.h diff --git a/test/svcenc/enc.cfg b/examples/svcenc/enc.cfg index ba62199..ba62199 100644 --- a/test/svcenc/enc.cfg +++ b/examples/svcenc/enc.cfg diff --git a/test/svcenc/input.c b/examples/svcenc/input.c index 47ed17a..47ed17a 100644 --- a/test/svcenc/input.c +++ b/examples/svcenc/input.c diff --git a/test/svcenc/main.c b/examples/svcenc/main.c index db53278..db53278 100644 --- a/test/svcenc/main.c +++ b/examples/svcenc/main.c diff --git a/test/svcenc/output.c b/examples/svcenc/output.c index d124a2d..d124a2d 100644 --- a/test/svcenc/output.c +++ b/examples/svcenc/output.c diff --git a/test/svcenc/psnr.c b/examples/svcenc/psnr.c index f207d23..f207d23 100644 --- a/test/svcenc/psnr.c +++ b/examples/svcenc/psnr.c diff --git a/test/svcenc/psnr.h b/examples/svcenc/psnr.h index 51082d2..51082d2 100644 --- a/test/svcenc/psnr.h +++ b/examples/svcenc/psnr.h diff --git a/test/svcenc/recon.c b/examples/svcenc/recon.c index c43d39e..c43d39e 100644 --- a/test/svcenc/recon.c +++ b/examples/svcenc/recon.c diff --git a/examples/svcenc/svcenc.cmake b/examples/svcenc/svcenc.cmake new file mode 100644 index 0000000..9795a90 --- /dev/null +++ b/examples/svcenc/svcenc.cmake @@ -0,0 +1,12 @@ +list( + APPEND + SVCENC_SRCS + "${AVC_ROOT}/examples/svcenc/main.c" + "${AVC_ROOT}/examples/svcenc/input.c" + "${AVC_ROOT}/examples/svcenc/output.c" + "${AVC_ROOT}/examples/svcenc/psnr.c" + "${AVC_ROOT}/examples/svcenc/recon.c") + +libavc_add_executable(svcenc libsvcenc SOURCES ${SVCENC_SRCS} INCLUDES + "${AVC_ROOT}/examples/svcenc/") +target_compile_definitions(svcenc PRIVATE PROFILE_ENABLE MD5_DISABLE) diff --git a/test/decoder/avcdec.cmake b/test/decoder/avcdec.cmake deleted file mode 100644 index c244131..0000000 --- a/test/decoder/avcdec.cmake +++ /dev/null @@ -1,2 +0,0 @@ -libavc_add_executable(avcdec libavcdec SOURCES ${AVC_ROOT}/test/decoder/main.c) -target_compile_definitions(avcdec PRIVATE PROFILE_ENABLE MD5_DISABLE) diff --git a/test/encoder/avcenc.cmake b/test/encoder/avcenc.cmake deleted file mode 100644 index 9fbd565..0000000 --- a/test/encoder/avcenc.cmake +++ /dev/null @@ -1,11 +0,0 @@ -list( - APPEND - AVCENC_SRCS - "${AVC_ROOT}/test/encoder/input.c" - "${AVC_ROOT}/test/encoder/main.c" - "${AVC_ROOT}/test/encoder/output.c" - "${AVC_ROOT}/test/encoder/psnr.c" - "${AVC_ROOT}/test/encoder/recon.c") - -libavc_add_executable(avcenc libavcenc SOURCES ${AVCENC_SRCS}) -target_compile_definitions(avcenc PRIVATE PROFILE_ENABLE MD5_DISABLE) diff --git a/test/encoder/psnr.c b/test/encoder/psnr.c deleted file mode 100644 index 87a03b0..0000000 --- a/test/encoder/psnr.c +++ /dev/null @@ -1,254 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ***************************************************************************** - * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore -*/ - -/*****************************************************************************/ -/* File Includes */ -/*****************************************************************************/ -/* System include files */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> - -/* User include files */ -#include "ih264_typedefs.h" -#include "ih264_defs.h" -#include "iv2.h" -#include "ive2.h" -#include "ih264e.h" -#include "app.h" -#include "psnr.h" - -/*****************************************************************************/ -/* */ -/* Function Name : init_psnr */ -/* */ -/* Description : Initialize PSNR for the Y, U, V component */ -/* */ -/* Inputs : */ -/* */ -/* Globals : */ -/* */ -/* Processing : */ -/* */ -/* Outputs : */ -/* */ -/* Returns : */ -/* */ -/* Issues : */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 12 2005 Ittiam Draft */ -/* */ -/*****************************************************************************/ -void init_psnr(app_ctxt_t *ps_app_ctxt) -{ - ps_app_ctxt->adbl_psnr[0] = 0; - ps_app_ctxt->adbl_psnr[1] = 0; - ps_app_ctxt->adbl_psnr[2] = 0; - ps_app_ctxt->u4_psnr_cnt = 0; -} - - -/*****************************************************************************/ -/* */ -/* Function Name : compute_psnr */ -/* */ -/* Description : Computes the PSNR for the Y, U, V component */ -/* */ -/* Inputs : */ -/* */ -/* Globals : */ -/* */ -/* Processing : */ -/* */ -/* Outputs : */ -/* */ -/* Returns : */ -/* */ -/* Issues : */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 12 2005 Ittiam Draft */ -/* */ -/*****************************************************************************/ -void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t *ps_buf2) -{ - WORD32 i, j; - WORD32 comp; - DOUBLE df_psnr[3]; - WORD32 wd, ht, strd1, strd2; - UWORD8 *pu1_buf1, *pu1_buf2; - WORD32 incr1, incr2; - - printf("\nPicNum %4d\t ", ps_app_ctxt->u4_psnr_cnt); - - for(comp = 0; comp < 3; comp++) - { - df_psnr[comp] = 0; - pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[comp]; - pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[comp]; - wd = ps_buf1->au4_wd[comp]; - ht = ps_buf1->au4_ht[comp]; - strd1 = ps_buf1->au4_strd[comp] - ps_buf1->au4_wd[comp]; - strd2 = ps_buf2->au4_strd[comp] - ps_buf2->au4_wd[comp]; - incr1 = 1; - incr2 = 1; - - if((IV_YUV_420SP_UV == ps_buf1->e_color_fmt) - || (IV_YUV_420SP_VU == ps_buf1->e_color_fmt)) - { - switch(comp) - { - case 0: - pu1_buf1 = ps_buf1->apv_bufs[0]; - break; - case 1: - if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt) - pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[1]; - else - pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[1] + 1; - incr1 = 2; - wd = ps_buf1->au4_wd[0] >> 1; - ht = ps_buf1->au4_ht[0] >> 1; - break; - case 2: - if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt) - pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[1] + 1; - else - pu1_buf1 = ps_buf1->apv_bufs[1]; - incr1 = 2; - wd = ps_buf1->au4_wd[0] >> 1; - ht = ps_buf1->au4_ht[0] >> 1; - strd1 = ps_buf1->au4_strd[1] - ps_buf1->au4_wd[1]; - break; - } - } - if ((IV_YUV_420SP_UV == ps_buf2->e_color_fmt) - || (IV_YUV_420SP_VU == ps_buf2->e_color_fmt)) - { - switch(comp) - { - case 0: - pu1_buf2 = ps_buf2->apv_bufs[0]; - break; - case 1: - if(IV_YUV_420SP_UV == ps_buf2->e_color_fmt) - pu1_buf2 = ps_buf2->apv_bufs[1]; - else - pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[1] + 1; - incr2 = 2; - wd = ps_buf2->au4_wd[0] >> 1; - ht = ps_buf2->au4_ht[0] >> 1; - - break; - case 2: - if(IV_YUV_420SP_UV == ps_buf2->e_color_fmt) - pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[1] + 1; - else - pu1_buf2 = ps_buf2->apv_bufs[1]; - incr2 = 2; - wd = ps_buf2->au4_wd[0] >> 1; - ht = ps_buf2->au4_ht[0] >> 1; - strd2 = ps_buf2->au4_strd[1] - ps_buf2->au4_wd[1]; - - break; - } - } - - for(i = 0; i < ht; i++) - { - for(j = 0; j < wd; j++) - { - WORD32 diff; - diff = (*pu1_buf1 - *pu1_buf2); - pu1_buf1 += incr1; - pu1_buf2 += incr2; - df_psnr[comp] += diff * diff; - } - pu1_buf1 += strd1; - pu1_buf2 += strd2; - } - df_psnr[comp] /= (wd * ht); - if(df_psnr[comp]) - df_psnr[comp] = 20 * log10(255 / sqrt(df_psnr[comp])); - else - df_psnr[comp] = 100; - - ps_app_ctxt->adbl_psnr[comp] += df_psnr[comp]; - switch(comp) - { - case 0: - printf("Y :"); - break; - case 1: - printf("U :"); - break; - case 2: - printf("V :"); - break; - default: - break; - } - printf("%2.2f\t", df_psnr[comp]); - - } - - ps_app_ctxt->u4_psnr_cnt++; -} - - -/*****************************************************************************/ -/* */ -/* Function Name : print_average_psnr */ -/* */ -/* Description : Computes the average PSNR for the Y, U, V component */ -/* */ -/* Inputs : */ -/* */ -/* Globals : */ -/* */ -/* Processing : */ -/* */ -/* Outputs : */ -/* */ -/* Returns : */ -/* */ -/* Issues : */ -/* */ -/* Revision History: */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes made) */ -/* 28 12 2005 Ittiam Draft */ -/* */ -/*****************************************************************************/ -void print_average_psnr(app_ctxt_t *ps_app_ctxt) -{ - printf("\n"); - - printf("Avg PSNR Y : %-2.2f\n", (ps_app_ctxt->adbl_psnr[0] / ps_app_ctxt->u4_psnr_cnt)); - printf("Avg PSNR U : %-2.2f\n", (ps_app_ctxt->adbl_psnr[1] / ps_app_ctxt->u4_psnr_cnt)); - printf("Avg PSNR V : %-2.2f\n", (ps_app_ctxt->adbl_psnr[2] / ps_app_ctxt->u4_psnr_cnt)); -} - diff --git a/test/encoder/psnr.h b/test/encoder/psnr.h deleted file mode 100644 index fd388cf..0000000 --- a/test/encoder/psnr.h +++ /dev/null @@ -1,62 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ***************************************************************************** - * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore -*/ -/****************************************************************************/ -/* */ -/* File Name : psnr.h */ -/* */ -/* Description : Contains functions for psnr computation */ -/* */ -/* List of Functions : ih264e_api_function */ -/* compute_psnr */ -/* print_average_psnr */ -/* Issues / Problems : */ -/* */ -/* Revision History : */ -/* */ -/* DD MM YYYY Author(s) Changes (Describe the changes) */ -/* */ -/****************************************************************************/ -#ifndef PSNR_H -#define PSNR_H - -/*****************************************************************************/ -/* Function Declarations */ -/*****************************************************************************/ -void init_psnr(app_ctxt_t *ps_app_ctxt); - -void compute_psnr(app_ctxt_t *ps_app_ctxt, - iv_raw_buf_t *ps_buf1, - iv_raw_buf_t *ps_buf2); - -void print_average_psnr(app_ctxt_t *ps_app_ctxt); - -#if COMPUTE_PSNR - -#define GET_AVERAGE_PSNR_Y(print) print_average_psnr(print) - -#else /* COMPUTE_PSNR */ - -#define GET_AVERAGE_PSNR_Y(print) 0 - -#endif /* COMPUTE_PSNR */ - -#endif - - diff --git a/test/svcenc/svcenc.cmake b/test/svcenc/svcenc.cmake deleted file mode 100644 index 0ea599f..0000000 --- a/test/svcenc/svcenc.cmake +++ /dev/null @@ -1,12 +0,0 @@ -list( - APPEND - SVCENC_SRCS - "${AVC_ROOT}/test/svcenc/main.c" - "${AVC_ROOT}/test/svcenc/input.c" - "${AVC_ROOT}/test/svcenc/output.c" - "${AVC_ROOT}/test/svcenc/psnr.c" - "${AVC_ROOT}/test/svcenc/recon.c") - -libavc_add_executable(svcenc libsvcenc SOURCES ${SVCENC_SRCS} INCLUDES - "${AVC_ROOT}/test/svcenc/") -target_compile_definitions(svcenc PRIVATE PROFILE_ENABLE MD5_DISABLE) diff --git a/tests/Android.bp b/tests/Android.bp new file mode 100644 index 0000000..656d3b7 --- /dev/null +++ b/tests/Android.bp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "external_libavc_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["external_libavc_license"], +} + +cc_test { + name: "AvcEncTest", + gtest: true, + + srcs : [ "AvcEncTest.cpp" ], + + shared_libs: [ + "libutils", + "liblog" + ], + + static_libs: [ + "libavcenc" + ], + + cflags: [ + "-Wall", + "-Werror", + ], + + sanitize: { + misc_undefined: [ + "signed-integer-overflow", + "unsigned-integer-overflow", + ], + //cfi: true, + }, +} diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml new file mode 100644 index 0000000..9b8d81a --- /dev/null +++ b/tests/AndroidTest.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<configuration description="Test module config for AVC encoder unit tests"> + <option name="test-suite-tag" value="AvcEncTest" /> + <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> + <option name="cleanup" value="true" /> + <option name="push" value="AvcEncTest->/data/local/tmp/AvcEncTest/" /> + </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> + <option name="target" value="host" /> + <option name="config-filename" value="AvcEncTest" /> + <option name="version" value="1.0"/> + </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer"> + <option name="push-all" value="true" /> + <option name="media-folder-name" value="AvcTestRes-1.0"/> + <option name="dynamic-config-module" value="AvcEncTest" /> + </target_preparer> + <test class="com.android.tradefed.testtype.GTest" > + <option name="native-test-device-path" value="/data/local/tmp" /> + <option name="module-name" value="AvcEncTest" /> + <option name="native-test-flag" value="-P /sdcard/test/AvcTestRes-1.0/" /> + </test> +</configuration> diff --git a/tests/AvcEncTest.cmake b/tests/AvcEncTest.cmake new file mode 100644 index 0000000..a61845e --- /dev/null +++ b/tests/AvcEncTest.cmake @@ -0,0 +1,24 @@ +include(ExternalProject) +ExternalProject_Add(googletest + GIT_REPOSITORY https://android.googlesource.com/platform/external/googletest + GIT_TAG main + PREFIX ${AVC_ROOT}/third_party/build/googletest + SOURCE_DIR ${AVC_ROOT}/third_party/googletest + TMP_DIR ${AVC_ROOT}/third_party/build/googletest/tmp + INSTALL_COMMAND "" +) + +list( + APPEND + AVCENCTEST_SRCS + "${AVC_ROOT}/tests/AvcEncTest.cpp") + +libavc_add_executable(AvcEncTest libavcenc + SOURCES ${AVCENCTEST_SRCS} + INCLUDES "${AVC_ROOT}/third_party/googletest/googletest/include") + +target_link_libraries(AvcEncTest + ${AVC_ROOT}/third_party/build/googletest/src/googletest-build/lib/libgtest.a + ${AVC_ROOT}/third_party/build/googletest/src/googletest-build/lib/libgtest_main.a) + +add_dependencies(AvcEncTest googletest) diff --git a/tests/AvcEncTest.cpp b/tests/AvcEncTest.cpp new file mode 100644 index 0000000..83ea700 --- /dev/null +++ b/tests/AvcEncTest.cpp @@ -0,0 +1,1009 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ih264_defs.h" +#include "ih264_typedefs.h" +#include "ih264e.h" +#include "ih264e_error.h" + +#include "TestArgs.h" + +#define MAX_FRAME_HEIGHT 1080 +#define MAX_FRAME_WIDTH 1920 +#define MAX_OUTPUT_BUFFER_SIZE (MAX_FRAME_HEIGHT * MAX_FRAME_WIDTH) + +#define ive_api_function ih264e_api_function + +constexpr int16_t kCompressionRatio = 1; +constexpr size_t kMinQP = 4; +constexpr uint32_t kHeaderLength = 0x800; + +static TestArgs* gArgs = nullptr; + +class AvcEncTest + : public ::testing::TestWithParam<tuple<string, int32_t, int32_t, float, int32_t>> { + private: + void setRawBuf(iv_raw_buf_t* psInpRawBuf, const uint8_t* data); + void setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType); + void setQp(); + void setEncMode(IVE_ENC_MODE_T eEncMode); + void setDimensions(); + void setNumCores(); + void setFrameRate(); + void setIpeParams(); + void setBitRate(); + void setAirParams(); + void setMeParams(); + void setGopParams(); + void setProfileParams(); + void setDeblockParams(); + void setVbvParams(); + void setDefault(); + void setVuiParams(); + void getBufInfo(); + void setSeiMdcvParams(); + void setSeiCllParams(); + void setSeiAveParams(); + void setSeiCcvParams(); + void logVersion(); + bool mHalfPelEnable = true; + bool mQPelEnable = true; + bool mIntra4x4 = true; + bool mEnableFastSad = false; + bool mEnableAltRef = false; + bool mConstrainedIntraFlag = false; + bool mSeiCllFlag = true; + bool mSeiAveFlag = true; + bool mSeiCcvFlag = true; + bool mSeiMdcvFlag = true; + bool mAspectRatioFlag = false; + bool mNalHrdFlag = false; + bool mVclHrdFlag = false; + bool mIsForceIdrEnabled = false; + bool mIsDynamicBitRateChangeEnabled = true; + bool mIsDynamicFrameRateChangeEnabled = true; + uint32_t mAvcEncLevel = 41; + uint32_t mNumMemRecords = 0; + uint32_t mNumCores = 4; + uint32_t mBframes = 0; + uint32_t mSliceParam = 256; + uint32_t mMeSpeedPreset = 100; + uint32_t mIInterval = 1000; + uint32_t mIDRInterval = 60; + uint32_t mDisableDeblockLevel = 0; + uint32_t mIQp = 24; + uint32_t mPQp = 27; + uint32_t mBQp = 29; + uint32_t mIntraRefresh = 30; + uint32_t mSearchRangeX = 16; + uint32_t mSearchRangeY = 16; + uint32_t mForceIdrInterval = 0; // in number of frames + uint32_t mDynamicBitRateInterval = 0; // in number of frames + uint32_t mDynamicFrameRateInterval = 0; // in number of frame + float mFrameRate = 30; + iv_obj_t* mCodecCtx = nullptr; + iv_mem_rec_t* mMemRecords = nullptr; + IVE_AIR_MODE_T mAirMode = IVE_AIR_MODE_NONE; + IVE_SPEED_CONFIG mEncSpeed = IVE_NORMAL; + IVE_RC_MODE_T mRCMode = IVE_RC_STORAGE; + IV_ARCH_T mArch = ARCH_NA; + IVE_SLICE_MODE_T mSliceMode = IVE_SLICE_MODE_NONE; + IV_COLOR_FORMAT_T mIvVideoColorFormat = IV_YUV_420P; + IV_COLOR_FORMAT_T mReconFormat = IV_YUV_420P; + IV_PROFILE_T mProfile = IV_PROFILE_BASE; + + public: + AvcEncTest() + : mInputBuffer(nullptr), mOutputBuffer(nullptr), mFpInput(nullptr), mFpOutput(nullptr) {} + + ~AvcEncTest() { + iv_mem_rec_t* ps_mem_rec = mMemRecords; + for (size_t i = 0; i < mNumMemRecords; ++i) { + if (ps_mem_rec) { + free(ps_mem_rec->pv_base); + } + ++ps_mem_rec; + } + if (mMemRecords) { + free(mMemRecords); + } + mCodecCtx = nullptr; + } + + void SetUp() override { + tuple<string /* fileName */, int32_t /* frameWidth */, int32_t /* frameHeight */, + float /* frameRate */, int32_t /* bitRate */> + params = GetParam(); + mFileName = gArgs->getRes() + get<0>(params); + mFrameWidth = get<1>(params); + mFrameHeight = get<2>(params); + mFrameRate = get<3>(params); + mBitRate = get<4>(params); + mOutFileName = gArgs->getRes() + "out.bin"; + + ASSERT_LE(mFrameWidth, 1080) << "Frame Width <= 1080"; + + ASSERT_LE(mFrameHeight, 1920) << "Frame Height <= 1920"; + + mOutputBufferSize = (mFrameWidth * mFrameHeight * 3 / 2) / kCompressionRatio; + mBitRate = mBitRate * 1024; // Conversion to bytes per sec + + mInputBuffer = (uint8_t*)malloc((mFrameWidth * mFrameHeight * 3) / 2); + ASSERT_NE(mInputBuffer, nullptr) << "Failed to allocate the input buffer!"; + + mOutputBuffer = (uint8_t*)malloc(mOutputBufferSize); + ASSERT_NE(mOutputBuffer, nullptr) << "Failed to allocate the output buffer!"; + + mFpInput = fopen(mFileName.c_str(), "rb"); + ASSERT_NE(mFpInput, nullptr) << "Failed to open the input file: " << mFileName; + + mFpOutput = fopen(mOutFileName.c_str(), "wb"); + ASSERT_NE(mFpOutput, nullptr) << "Failed to open the output file:" << mOutFileName; + + /* Getting Number of MemRecords */ + iv_num_mem_rec_ip_t sNumMemRecIp = {}; + iv_num_mem_rec_op_t sNumMemRecOp = {}; + + sNumMemRecIp.u4_size = sizeof(iv_num_mem_rec_ip_t); + sNumMemRecOp.u4_size = sizeof(iv_num_mem_rec_op_t); + sNumMemRecIp.e_cmd = IV_CMD_GET_NUM_MEM_REC; + + status = ive_api_function(nullptr, &sNumMemRecIp, &sNumMemRecOp); + ASSERT_EQ(status, IV_SUCCESS) << "Error in IV_CMD_GET_NUM_MEM_REC!"; + + mNumMemRecords = sNumMemRecOp.u4_num_mem_rec; + mMemRecords = (iv_mem_rec_t*)malloc(mNumMemRecords * sizeof(iv_mem_rec_t)); + ASSERT_NE(mMemRecords, nullptr) << "Failed to allocate memory to nMemRecords!"; + + iv_mem_rec_t* psMemRec; + psMemRec = mMemRecords; + for (size_t i = 0; i < mNumMemRecords; ++i) { + psMemRec->u4_size = sizeof(iv_mem_rec_t); + psMemRec->pv_base = nullptr; + psMemRec->u4_mem_size = 0; + psMemRec->u4_mem_alignment = 0; + psMemRec->e_mem_type = IV_NA_MEM_TYPE; + ++psMemRec; + } + + /* Getting MemRecords Attributes */ + iv_fill_mem_rec_ip_t sFillMemRecIp = {}; + iv_fill_mem_rec_op_t sFillMemRecOp = {}; + + sFillMemRecIp.u4_size = sizeof(iv_fill_mem_rec_ip_t); + sFillMemRecOp.u4_size = sizeof(iv_fill_mem_rec_op_t); + + sFillMemRecIp.e_cmd = IV_CMD_FILL_NUM_MEM_REC; + sFillMemRecIp.ps_mem_rec = mMemRecords; + sFillMemRecIp.u4_num_mem_rec = mNumMemRecords; + sFillMemRecIp.u4_max_wd = mFrameWidth; + sFillMemRecIp.u4_max_ht = mFrameHeight; + sFillMemRecIp.u4_max_level = mAvcEncLevel; + sFillMemRecIp.e_color_format = IV_YUV_420SP_UV; + sFillMemRecIp.u4_max_ref_cnt = 2; + sFillMemRecIp.u4_max_reorder_cnt = 0; + sFillMemRecIp.u4_max_srch_rng_x = 256; + sFillMemRecIp.u4_max_srch_rng_y = 256; + + status = ive_api_function(nullptr, &sFillMemRecIp, &sFillMemRecOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to fill memory records!"; + + /* Allocating Memory for Mem Records */ + psMemRec = mMemRecords; + for (size_t i = 0; i < mNumMemRecords; ++i) { + posix_memalign(&psMemRec->pv_base, psMemRec->u4_mem_alignment, psMemRec->u4_mem_size); + ASSERT_NE(psMemRec->pv_base, nullptr) + << "Failed to allocate for size " << psMemRec->u4_mem_size; + + ++psMemRec; + } + + /* Codec Instance Creation */ + ive_init_ip_t sInitIp = {}; + ive_init_op_t sInitOp = {}; + + mCodecCtx = (iv_obj_t*)mMemRecords[0].pv_base; + mCodecCtx->u4_size = sizeof(iv_obj_t); + mCodecCtx->pv_fxns = (void*)ive_api_function; + + sInitIp.u4_size = sizeof(ive_init_ip_t); + sInitOp.u4_size = sizeof(ive_init_op_t); + + sInitIp.e_cmd = IV_CMD_INIT; + sInitIp.u4_num_mem_rec = mNumMemRecords; + sInitIp.ps_mem_rec = mMemRecords; + sInitIp.u4_max_wd = mFrameWidth; + sInitIp.u4_max_ht = mFrameHeight; + sInitIp.u4_max_ref_cnt = 2; + sInitIp.u4_max_reorder_cnt = 0; + sInitIp.u4_max_level = mAvcEncLevel; + sInitIp.e_inp_color_fmt = mIvVideoColorFormat; + sInitIp.u4_enable_recon = 0; + sInitIp.e_recon_color_fmt = mReconFormat; + sInitIp.e_rc_mode = mRCMode; + sInitIp.u4_max_framerate = 120000; + sInitIp.u4_max_bitrate = 240000000; + sInitIp.u4_num_bframes = mBframes; + sInitIp.e_content_type = IV_PROGRESSIVE; + sInitIp.u4_max_srch_rng_x = 256; + sInitIp.u4_max_srch_rng_y = 256; + sInitIp.e_slice_mode = mSliceMode; + sInitIp.u4_slice_param = mSliceParam; + sInitIp.e_arch = mArch; + sInitIp.e_soc = SOC_GENERIC; + + status = ive_api_function(mCodecCtx, &sInitIp, &sInitOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to create Codec Instance!"; + + mFrameSize = (mIvVideoColorFormat == IV_YUV_422ILE) + ? (mFrameWidth * mFrameHeight * 2) + : ((mFrameWidth * mFrameHeight * 3) / 2); + + mTotalFrames = getTotalFrames(); + + ASSERT_NO_FATAL_FAILURE(logVersion()); + + ASSERT_NO_FATAL_FAILURE(setDefault()); + + ASSERT_NO_FATAL_FAILURE(getBufInfo()); + + ASSERT_NO_FATAL_FAILURE(setNumCores()); + + ASSERT_NO_FATAL_FAILURE(setDimensions()); + + ASSERT_NO_FATAL_FAILURE(setFrameRate()); + + ASSERT_NO_FATAL_FAILURE(setIpeParams()); + + ASSERT_NO_FATAL_FAILURE(setBitRate()); + + ASSERT_NO_FATAL_FAILURE(setQp()); + + ASSERT_NO_FATAL_FAILURE(setAirParams()); + + ASSERT_NO_FATAL_FAILURE(setVbvParams()); + + ASSERT_NO_FATAL_FAILURE(setMeParams()); + + ASSERT_NO_FATAL_FAILURE(setGopParams()); + + ASSERT_NO_FATAL_FAILURE(setDeblockParams()); + + ASSERT_NO_FATAL_FAILURE(setVuiParams()); + + ASSERT_NO_FATAL_FAILURE(setSeiMdcvParams()); + + ASSERT_NO_FATAL_FAILURE(setSeiCllParams()); + + ASSERT_NO_FATAL_FAILURE(setSeiAveParams()); + + ASSERT_NO_FATAL_FAILURE(setSeiCcvParams()); + + ASSERT_NO_FATAL_FAILURE(setProfileParams()); + + ASSERT_NO_FATAL_FAILURE(setEncMode(IVE_ENC_MODE_PICTURE)); + } + + void TearDown() override { + if (mInputBuffer) free(mInputBuffer); + if (mOutputBuffer) free(mOutputBuffer); + if (mFpInput) fclose(mFpInput); + if (mFpOutput) fclose(mFpOutput); + } + + void encodeFrames(int64_t); + int64_t getTotalFrames(); + int32_t mFrameWidth = MAX_FRAME_WIDTH; + int32_t mFrameHeight = MAX_FRAME_HEIGHT; + int32_t mFrameSize = (mFrameWidth * mFrameHeight * 3) / 2; + int64_t mTotalFrames = 0; + int32_t mBitRate = 256000; + int64_t mOutputBufferSize = MAX_OUTPUT_BUFFER_SIZE; + string mFileName; + string mOutFileName; + uint8_t* mInputBuffer = nullptr; + uint8_t* mOutputBuffer = nullptr; + FILE* mFpInput = nullptr; + FILE* mFpOutput = nullptr; + IV_STATUS_T status; +}; + +void AvcEncTest::setDimensions() { + ive_ctl_set_dimensions_ip_t sDimensionsIp = {}; + ive_ctl_set_dimensions_op_t sDimensionsOp = {}; + + sDimensionsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sDimensionsIp.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS; + sDimensionsIp.u4_ht = mFrameHeight; + sDimensionsIp.u4_wd = mFrameWidth; + + sDimensionsIp.u4_timestamp_high = -1; + sDimensionsIp.u4_timestamp_low = -1; + + sDimensionsIp.u4_size = sizeof(ive_ctl_set_dimensions_ip_t); + sDimensionsOp.u4_size = sizeof(ive_ctl_set_dimensions_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sDimensionsIp, &sDimensionsOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set dimensions!\n"; + + return; +} + +void AvcEncTest::setNumCores() { + ive_ctl_set_num_cores_ip_t sNumCoresIp = {}; + ive_ctl_set_num_cores_op_t sNumCoresOp = {}; + + sNumCoresIp.e_cmd = IVE_CMD_VIDEO_CTL; + sNumCoresIp.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES; + sNumCoresIp.u4_num_cores = mNumCores; + + sNumCoresIp.u4_timestamp_high = -1; + sNumCoresIp.u4_timestamp_low = -1; + + sNumCoresIp.u4_size = sizeof(ive_ctl_set_num_cores_ip_t); + sNumCoresOp.u4_size = sizeof(ive_ctl_set_num_cores_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, (void*)&sNumCoresIp, (void*)&sNumCoresOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set number of cores!\n"; + + return; +} + +void AvcEncTest::setDefault() { + ive_ctl_setdefault_ip_t sDefaultIp = {}; + ive_ctl_setdefault_op_t sDefaultOp = {}; + + sDefaultIp.e_cmd = IVE_CMD_VIDEO_CTL; + sDefaultIp.e_sub_cmd = IVE_CMD_CTL_SETDEFAULT; + + sDefaultIp.u4_timestamp_high = -1; + sDefaultIp.u4_timestamp_low = -1; + + sDefaultIp.u4_size = sizeof(ive_ctl_setdefault_ip_t); + sDefaultOp.u4_size = sizeof(ive_ctl_setdefault_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sDefaultIp, &sDefaultOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set default encoder parameters!\n"; + + return; +} + +void AvcEncTest::getBufInfo() { + ih264e_ctl_getbufinfo_ip_t sGetBufInfoIp = {}; + ih264e_ctl_getbufinfo_op_t sGetBufInfoOp = {}; + + sGetBufInfoIp.s_ive_ip.u4_size = sizeof(ih264e_ctl_getbufinfo_ip_t); + sGetBufInfoOp.s_ive_op.u4_size = sizeof(ih264e_ctl_getbufinfo_op_t); + + sGetBufInfoIp.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + sGetBufInfoIp.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETBUFINFO; + sGetBufInfoIp.s_ive_ip.u4_max_ht = mFrameHeight; + sGetBufInfoIp.s_ive_ip.u4_max_wd = mFrameWidth; + sGetBufInfoIp.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat; + + IV_STATUS_T status = ih264e_api_function(mCodecCtx, &sGetBufInfoIp, &sGetBufInfoOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to get buffer info!\n"; + + return; +} + +void AvcEncTest::setFrameRate() { + ive_ctl_set_frame_rate_ip_t sFrameRateIp = {}; + ive_ctl_set_frame_rate_op_t sFrameRateOp = {}; + + sFrameRateIp.e_cmd = IVE_CMD_VIDEO_CTL; + sFrameRateIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE; + sFrameRateIp.u4_src_frame_rate = mFrameRate; + sFrameRateIp.u4_tgt_frame_rate = mFrameRate; + + sFrameRateIp.u4_timestamp_high = -1; + sFrameRateIp.u4_timestamp_low = -1; + + sFrameRateIp.u4_size = sizeof(ive_ctl_set_frame_rate_ip_t); + sFrameRateOp.u4_size = sizeof(ive_ctl_set_frame_rate_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sFrameRateIp, &sFrameRateOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set frame rate!\n"; + + return; +} + +void AvcEncTest::setIpeParams() { + ive_ctl_set_ipe_params_ip_t sIpeParamsIp = {}; + ive_ctl_set_ipe_params_op_t sIpeParamsOp = {}; + + sIpeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sIpeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS; + sIpeParamsIp.u4_enable_intra_4x4 = mIntra4x4; + sIpeParamsIp.u4_enc_speed_preset = mEncSpeed; + sIpeParamsIp.u4_constrained_intra_pred = mConstrainedIntraFlag; + + sIpeParamsIp.u4_timestamp_high = -1; + sIpeParamsIp.u4_timestamp_low = -1; + + sIpeParamsIp.u4_size = sizeof(ive_ctl_set_ipe_params_ip_t); + sIpeParamsOp.u4_size = sizeof(ive_ctl_set_ipe_params_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sIpeParamsIp, &sIpeParamsOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set IPE params!\n"; + + return; +} + +void AvcEncTest::setBitRate() { + ive_ctl_set_bitrate_ip_t sBitrateIp = {}; + ive_ctl_set_bitrate_op_t sBitrateOp = {}; + + sBitrateIp.e_cmd = IVE_CMD_VIDEO_CTL; + sBitrateIp.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE; + sBitrateIp.u4_target_bitrate = mBitRate; + + sBitrateIp.u4_timestamp_high = -1; + sBitrateIp.u4_timestamp_low = -1; + + sBitrateIp.u4_size = sizeof(ive_ctl_set_bitrate_ip_t); + sBitrateOp.u4_size = sizeof(ive_ctl_set_bitrate_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sBitrateIp, &sBitrateOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set bit rate!\n"; + + return; +} + +void AvcEncTest::setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType) { + ive_ctl_set_frame_type_ip_t sFrameTypeIp = {}; + ive_ctl_set_frame_type_op_t sFrameTypeOp = {}; + + sFrameTypeIp.e_cmd = IVE_CMD_VIDEO_CTL; + sFrameTypeIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE; + sFrameTypeIp.e_frame_type = eFrameType; + + sFrameTypeIp.u4_timestamp_high = -1; + sFrameTypeIp.u4_timestamp_low = -1; + + sFrameTypeIp.u4_size = sizeof(ive_ctl_set_frame_type_ip_t); + sFrameTypeOp.u4_size = sizeof(ive_ctl_set_frame_type_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sFrameTypeIp, &sFrameTypeOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set Frame Type!\n"; + return; +} + +void AvcEncTest::setQp() { + ive_ctl_set_qp_ip_t s_QpIp = {}; + ive_ctl_set_qp_op_t s_QpOp = {}; + + s_QpIp.e_cmd = IVE_CMD_VIDEO_CTL; + s_QpIp.e_sub_cmd = IVE_CMD_CTL_SET_QP; + + s_QpIp.u4_i_qp = mIQp; + s_QpIp.u4_i_qp_max = MAX_H264_QP; + s_QpIp.u4_i_qp_min = kMinQP; + + s_QpIp.u4_p_qp = mPQp; + s_QpIp.u4_p_qp_max = MAX_H264_QP; + s_QpIp.u4_p_qp_min = kMinQP; + + s_QpIp.u4_b_qp = mBQp; + s_QpIp.u4_b_qp_max = MAX_H264_QP; + s_QpIp.u4_b_qp_min = kMinQP; + + s_QpIp.u4_timestamp_high = -1; + s_QpIp.u4_timestamp_low = -1; + + s_QpIp.u4_size = sizeof(ive_ctl_set_qp_ip_t); + s_QpOp.u4_size = sizeof(ive_ctl_set_qp_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &s_QpIp, &s_QpOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set QP!\n"; + + return; +} + +void AvcEncTest::setEncMode(IVE_ENC_MODE_T eEncMode) { + ive_ctl_set_enc_mode_ip_t sEncModeIp = {}; + ive_ctl_set_enc_mode_op_t sEncModeOp = {}; + + sEncModeIp.e_cmd = IVE_CMD_VIDEO_CTL; + sEncModeIp.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE; + sEncModeIp.e_enc_mode = eEncMode; + + sEncModeIp.u4_timestamp_high = -1; + sEncModeIp.u4_timestamp_low = -1; + + sEncModeIp.u4_size = sizeof(ive_ctl_set_enc_mode_ip_t); + sEncModeOp.u4_size = sizeof(ive_ctl_set_enc_mode_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sEncModeIp, &sEncModeOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set encode mode!\n"; + + return; +} + +void AvcEncTest::setVbvParams() { + ive_ctl_set_vbv_params_ip_t sVbvIp = {}; + ive_ctl_set_vbv_params_op_t sVbvOp = {}; + + sVbvIp.e_cmd = IVE_CMD_VIDEO_CTL; + sVbvIp.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS; + sVbvIp.u4_vbv_buf_size = 0; + sVbvIp.u4_vbv_buffer_delay = 1000; + + sVbvIp.u4_timestamp_high = -1; + sVbvIp.u4_timestamp_low = -1; + + sVbvIp.u4_size = sizeof(ive_ctl_set_vbv_params_ip_t); + sVbvOp.u4_size = sizeof(ive_ctl_set_vbv_params_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sVbvIp, &sVbvOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set VBV params!\n"; + + return; +} + +void AvcEncTest::setAirParams() { + ive_ctl_set_air_params_ip_t sAirIp = {}; + ive_ctl_set_air_params_op_t sAirOp = {}; + + sAirIp.e_cmd = IVE_CMD_VIDEO_CTL; + sAirIp.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS; + sAirIp.e_air_mode = mAirMode; + sAirIp.u4_air_refresh_period = mIntraRefresh; + + sAirIp.u4_timestamp_high = -1; + sAirIp.u4_timestamp_low = -1; + + sAirIp.u4_size = sizeof(ive_ctl_set_air_params_ip_t); + sAirOp.u4_size = sizeof(ive_ctl_set_air_params_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sAirIp, &sAirOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set AIR params!\n"; + + return; +} + +void AvcEncTest::setMeParams() { + ive_ctl_set_me_params_ip_t sMeParamsIp = {}; + ive_ctl_set_me_params_op_t sMeParamsOp = {}; + + sMeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sMeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS; + sMeParamsIp.u4_enable_fast_sad = mEnableFastSad; + sMeParamsIp.u4_enable_alt_ref = mEnableAltRef; + + sMeParamsIp.u4_enable_hpel = mHalfPelEnable; + sMeParamsIp.u4_enable_qpel = mQPelEnable; + sMeParamsIp.u4_me_speed_preset = mMeSpeedPreset; + sMeParamsIp.u4_srch_rng_x = mSearchRangeX; + sMeParamsIp.u4_srch_rng_y = mSearchRangeY; + + sMeParamsIp.u4_timestamp_high = -1; + sMeParamsIp.u4_timestamp_low = -1; + + sMeParamsIp.u4_size = sizeof(ive_ctl_set_me_params_ip_t); + sMeParamsOp.u4_size = sizeof(ive_ctl_set_me_params_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sMeParamsIp, &sMeParamsOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set ME params!\n"; + + return; +} + +void AvcEncTest::setGopParams() { + ive_ctl_set_gop_params_ip_t sGopParamsIp = {}; + ive_ctl_set_gop_params_op_t sGopParamsOp = {}; + + sGopParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sGopParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS; + + sGopParamsIp.u4_i_frm_interval = mIInterval; + sGopParamsIp.u4_idr_frm_interval = mIDRInterval; + + sGopParamsIp.u4_timestamp_high = -1; + sGopParamsIp.u4_timestamp_low = -1; + + sGopParamsIp.u4_size = sizeof(ive_ctl_set_gop_params_ip_t); + sGopParamsOp.u4_size = sizeof(ive_ctl_set_gop_params_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sGopParamsIp, &sGopParamsOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set GOP params!\n"; + + return; +} + +void AvcEncTest::setProfileParams() { + ive_ctl_set_profile_params_ip_t sProfileParamsIp = {}; + ive_ctl_set_profile_params_op_t sProfileParamsOp = {}; + + sProfileParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sProfileParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS; + + sProfileParamsIp.e_profile = mProfile; + if (sProfileParamsIp.e_profile == IV_PROFILE_BASE) { + sProfileParamsIp.u4_entropy_coding_mode = 0; + } else { + sProfileParamsIp.u4_entropy_coding_mode = 1; + } + sProfileParamsIp.u4_timestamp_high = -1; + sProfileParamsIp.u4_timestamp_low = -1; + + sProfileParamsIp.u4_size = sizeof(ive_ctl_set_profile_params_ip_t); + sProfileParamsOp.u4_size = sizeof(ive_ctl_set_profile_params_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sProfileParamsIp, &sProfileParamsOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set profile params!\n"; + + return; +} + +void AvcEncTest::setDeblockParams() { + ive_ctl_set_deblock_params_ip_t sDeblockParamsIp = {}; + ive_ctl_set_deblock_params_op_t sDeblockParamsOp = {}; + + sDeblockParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sDeblockParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS; + + sDeblockParamsIp.u4_disable_deblock_level = mDisableDeblockLevel; + + sDeblockParamsIp.u4_timestamp_high = -1; + sDeblockParamsIp.u4_timestamp_low = -1; + + sDeblockParamsIp.u4_size = sizeof(ive_ctl_set_deblock_params_ip_t); + sDeblockParamsOp.u4_size = sizeof(ive_ctl_set_deblock_params_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sDeblockParamsIp, &sDeblockParamsOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set deblock params!\n"; + + return; +} + +void AvcEncTest::setVuiParams() { + ih264e_vui_ip_t sVuiParamsIp = {}; + ih264e_vui_op_t sVuiParamsOp = {}; + + sVuiParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sVuiParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_VUI_PARAMS; + + sVuiParamsIp.u1_aspect_ratio_info_present_flag = mAspectRatioFlag; + sVuiParamsIp.u1_video_signal_type_present_flag = 1; + sVuiParamsIp.u1_colour_description_present_flag = 1; + sVuiParamsIp.u1_nal_hrd_parameters_present_flag = mNalHrdFlag; + sVuiParamsIp.u1_vcl_hrd_parameters_present_flag = mVclHrdFlag; + + sVuiParamsIp.u4_size = sizeof(ih264e_vui_ip_t); + sVuiParamsOp.u4_size = sizeof(ih264e_vui_op_t); + + IV_STATUS_T status = ive_api_function(mCodecCtx, &sVuiParamsIp, &sVuiParamsOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set VUI params!\n"; + + return; +} + +void AvcEncTest::setSeiMdcvParams() { + ih264e_ctl_set_sei_mdcv_params_ip_t sSeiMdcvParamsIp = {}; + ih264e_ctl_set_sei_mdcv_params_op_t sSeiMdcvParamsOp = {}; + + sSeiMdcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiMdcvParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_MDCV_PARAMS; + sSeiMdcvParamsIp.u1_sei_mdcv_params_present_flag = mSeiMdcvFlag; + if (mSeiMdcvFlag) { + for (int i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; ++i4_count) { + sSeiMdcvParamsIp.au2_display_primaries_x[i4_count] = 30000; + sSeiMdcvParamsIp.au2_display_primaries_y[i4_count] = 35000; + } + sSeiMdcvParamsIp.u2_white_point_x = 30000; + sSeiMdcvParamsIp.u2_white_point_y = 35000; + sSeiMdcvParamsIp.u4_max_display_mastering_luminance = 100000000; + sSeiMdcvParamsIp.u4_min_display_mastering_luminance = 50000; + } + + sSeiMdcvParamsIp.u4_timestamp_high = -1; + sSeiMdcvParamsIp.u4_timestamp_low = -1; + + sSeiMdcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_ip_t); + sSeiMdcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_op_t); + IV_STATUS_T status = ih264e_api_function(mCodecCtx, &sSeiMdcvParamsIp, &sSeiMdcvParamsOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set SEI MDCV params!\n"; + + return; +} + +void AvcEncTest::setSeiCllParams() { + ih264e_ctl_set_sei_cll_params_ip_t sSeiCllParamsIp = {}; + ih264e_ctl_set_sei_cll_params_op_t sSeiCllParamsOp = {}; + + sSeiCllParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiCllParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_CLL_PARAMS; + sSeiCllParamsIp.u1_sei_cll_params_present_flag = mSeiCllFlag; + if (mSeiCllFlag) { + sSeiCllParamsIp.u2_max_content_light_level = 0; + sSeiCllParamsIp.u2_max_pic_average_light_level = 0; + } + + sSeiCllParamsIp.u4_timestamp_high = -1; + sSeiCllParamsIp.u4_timestamp_low = -1; + + sSeiCllParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_ip_t); + sSeiCllParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_op_t); + + IV_STATUS_T status = ih264e_api_function(mCodecCtx, &sSeiCllParamsIp, &sSeiCllParamsOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set SEI CLL params!\n"; + + return; +} + +void AvcEncTest::setSeiAveParams() { + ih264e_ctl_set_sei_ave_params_ip_t sSeiAveParamsIp = {}; + ih264e_ctl_set_sei_ave_params_op_t sSeiAveParamsOp = {}; + + sSeiAveParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiAveParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_AVE_PARAMS; + sSeiAveParamsIp.u1_sei_ave_params_present_flag = mSeiAveFlag; + if (mSeiAveFlag) { + sSeiAveParamsIp.u4_ambient_illuminance = 1; + sSeiAveParamsIp.u2_ambient_light_x = 0; + sSeiAveParamsIp.u2_ambient_light_y = 0; + } + + sSeiAveParamsIp.u4_timestamp_high = -1; + sSeiAveParamsIp.u4_timestamp_low = -1; + + sSeiAveParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_ip_t); + sSeiAveParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_op_t); + + IV_STATUS_T status = ih264e_api_function(mCodecCtx, &sSeiAveParamsIp, &sSeiAveParamsOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set SEI AVE params!\n"; + + return; +} + +void AvcEncTest::setSeiCcvParams() { + ih264e_ctl_set_sei_ccv_params_ip_t sSeiCcvParamsIp = {}; + ih264e_ctl_set_sei_ccv_params_op_t sSeiCcvParamsOp = {}; + + sSeiCcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiCcvParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_CCV_PARAMS; + sSeiCcvParamsIp.u1_sei_ccv_params_present_flag = mSeiCcvFlag; + if (mSeiCcvFlag) { + sSeiCcvParamsIp.u1_ccv_cancel_flag = 0; + sSeiCcvParamsIp.u1_ccv_persistence_flag = 1; + sSeiCcvParamsIp.u1_ccv_primaries_present_flag = 1; + sSeiCcvParamsIp.u1_ccv_min_luminance_value_present_flag = 1; + sSeiCcvParamsIp.u1_ccv_max_luminance_value_present_flag = 1; + sSeiCcvParamsIp.u1_ccv_avg_luminance_value_present_flag = 1; + sSeiCcvParamsIp.u1_ccv_reserved_zero_2bits = 0; + for (int i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; ++i4_count) { + sSeiCcvParamsIp.ai4_ccv_primaries_x[i4_count] = 1; + sSeiCcvParamsIp.ai4_ccv_primaries_y[i4_count] = 1; + } + sSeiCcvParamsIp.u4_ccv_min_luminance_value = 1; + sSeiCcvParamsIp.u4_ccv_max_luminance_value = 1; + sSeiCcvParamsIp.u4_ccv_avg_luminance_value = 1; + } + + sSeiCcvParamsIp.u4_timestamp_high = -1; + sSeiCcvParamsIp.u4_timestamp_low = -1; + + sSeiCcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_ip_t); + sSeiCcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_op_t); + + IV_STATUS_T status = ih264e_api_function(mCodecCtx, &sSeiCcvParamsIp, &sSeiCcvParamsOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to set SEI CCV params!\n"; + + return; +} + +void AvcEncTest::logVersion() { + ive_ctl_getversioninfo_ip_t sCtlIp = {}; + ive_ctl_getversioninfo_op_t sCtlOp = {}; + UWORD8 au1Buf[512]; + + sCtlIp.e_cmd = IVE_CMD_VIDEO_CTL; + sCtlIp.e_sub_cmd = IVE_CMD_CTL_GETVERSION; + + sCtlIp.u4_size = sizeof(ive_ctl_getversioninfo_ip_t); + sCtlOp.u4_size = sizeof(ive_ctl_getversioninfo_op_t); + sCtlIp.pu1_version = au1Buf; + sCtlIp.u4_version_bufsize = sizeof(au1Buf); + + IV_STATUS_T status = ive_api_function(mCodecCtx, (void*)&sCtlIp, (void*)&sCtlOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to get encoder version!\n"; + + return; +} + +void AvcEncTest::encodeFrames(int64_t numFramesToEncode) { + ih264e_video_encode_ip_t ih264e_video_encode_ip = {}; + ih264e_video_encode_op_t ih264e_video_encode_op = {}; + + ive_video_encode_ip_t* sEncodeIp = &ih264e_video_encode_ip.s_ive_ip; + ive_video_encode_op_t* sEncodeOp = &ih264e_video_encode_op.s_ive_op; + + uint8_t header[kHeaderLength]; + iv_raw_buf_t* psInpRawBuf = &sEncodeIp->s_inp_buf; + + sEncodeIp->s_out_buf.pv_buf = header; + sEncodeIp->s_out_buf.u4_bytes = 0; + sEncodeIp->s_out_buf.u4_bufsize = kHeaderLength; + sEncodeIp->u4_size = sizeof(ih264e_video_encode_ip_t); + sEncodeOp->u4_size = sizeof(ih264e_video_encode_op_t); + + sEncodeIp->e_cmd = IVE_CMD_VIDEO_ENCODE; + sEncodeIp->pv_bufs = nullptr; + sEncodeIp->pv_mb_info = nullptr; + sEncodeIp->pv_pic_info = nullptr; + sEncodeIp->u4_mb_info_type = 0; + sEncodeIp->u4_pic_info_type = 0; + sEncodeIp->u4_is_last = 0; + sEncodeOp->s_out_buf.pv_buf = nullptr; + + /* Initialize color formats */ + memset(psInpRawBuf, 0, sizeof(iv_raw_buf_t)); + psInpRawBuf->u4_size = sizeof(iv_raw_buf_t); + psInpRawBuf->e_color_fmt = mIvVideoColorFormat; + + IV_STATUS_T status = ive_api_function(mCodecCtx, sEncodeIp, sEncodeOp); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to Initialize Color Formats!\n"; + + uint32_t numFrame = 0; + + while (numFramesToEncode > 0) { + int32_t bytesRead; + bytesRead = fread(mInputBuffer, 1, mFrameSize, mFpInput); + + if (bytesRead != mFrameSize) { + break; + } + + setRawBuf(psInpRawBuf, mInputBuffer); + + sEncodeIp->s_out_buf.pv_buf = mOutputBuffer; + sEncodeIp->s_out_buf.u4_bufsize = mFrameSize; + if (mIsForceIdrEnabled) { + if (numFrame == mForceIdrInterval) { + ASSERT_NO_FATAL_FAILURE(setFrameType(IV_IDR_FRAME)); + } + } + if (mIsDynamicBitRateChangeEnabled) { + if (numFrame == mDynamicBitRateInterval) { + mBitRate *= 2; + } + ASSERT_NO_FATAL_FAILURE(setBitRate()); + } + if (mIsDynamicFrameRateChangeEnabled) { + if (numFrame == mDynamicFrameRateInterval) { + mFrameRate *= 2; + } + ASSERT_NO_FATAL_FAILURE(setFrameRate()); + } + + status = ive_api_function(mCodecCtx, &ih264e_video_encode_ip, &ih264e_video_encode_op); + ASSERT_EQ(status, IV_SUCCESS) << "Failed to encode frame!\n"; + + int32_t numOutputBytes = fwrite((UWORD8*)sEncodeOp->s_out_buf.pv_buf, sizeof(UWORD8), + sEncodeOp->s_out_buf.u4_bytes, mFpOutput); + ASSERT_NE(numOutputBytes, 0) << "Failed to write the output!" << mOutFileName; + + numFramesToEncode--; + numFrame++; + } + + sEncodeIp->u4_is_last = 1; + psInpRawBuf->apv_bufs[0] = nullptr; + psInpRawBuf->apv_bufs[1] = nullptr; + psInpRawBuf->apv_bufs[2] = nullptr; + + status = ive_api_function(mCodecCtx, &ih264e_video_encode_ip, &ih264e_video_encode_op); + ASSERT_EQ(status, IV_SUCCESS) << "Failure after encoding last frame!\n"; + + if (sEncodeOp->output_present) { + int32_t numOutputBytes = fwrite((UWORD8*)sEncodeOp->s_out_buf.pv_buf, sizeof(UWORD8), + sEncodeOp->s_out_buf.u4_bytes, mFpOutput); + ASSERT_NE(numOutputBytes, 0) << "Failed to write the output!" << mOutFileName; + } +} + +void AvcEncTest::setRawBuf(iv_raw_buf_t* psInpRawBuf, const uint8_t* data) { + switch (mIvVideoColorFormat) { + case IV_YUV_420SP_UV: + [[fallthrough]]; + case IV_YUV_420SP_VU: { + uint8_t* yPlane = const_cast<uint8_t*>(data); + uint8_t* uPlane = const_cast<uint8_t*>(data + (mFrameWidth * mFrameHeight)); + int32_t yStride = mFrameWidth; + int32_t uStride = mFrameWidth / 2; + psInpRawBuf->apv_bufs[0] = yPlane; + psInpRawBuf->apv_bufs[1] = uPlane; + + psInpRawBuf->au4_wd[0] = mFrameWidth; + psInpRawBuf->au4_wd[1] = mFrameWidth; + + psInpRawBuf->au4_ht[0] = mFrameHeight; + psInpRawBuf->au4_ht[1] = mFrameHeight / 2; + + psInpRawBuf->au4_strd[0] = yStride; + psInpRawBuf->au4_strd[1] = uStride; + break; + } + case IV_YUV_422ILE: { + uint8_t* yPlane = const_cast<uint8_t*>(data); + psInpRawBuf->apv_bufs[0] = yPlane; + + psInpRawBuf->au4_wd[0] = mFrameWidth * 2; + + psInpRawBuf->au4_ht[0] = mFrameHeight; + + psInpRawBuf->au4_strd[0] = mFrameWidth * 2; + break; + } + case IV_YUV_420P: + [[fallthrough]]; + default: { + uint8_t* yPlane = const_cast<uint8_t*>(data); + uint8_t* uPlane = const_cast<uint8_t*>(data + (mFrameWidth * mFrameHeight)); + uint8_t* vPlane = const_cast<uint8_t*>(data + ((mFrameWidth * mFrameHeight) * 5) / 4); + int32_t yStride = mFrameWidth; + int32_t uStride = mFrameWidth / 2; + int32_t vStride = mFrameWidth / 2; + + psInpRawBuf->apv_bufs[0] = yPlane; + psInpRawBuf->apv_bufs[1] = uPlane; + psInpRawBuf->apv_bufs[2] = vPlane; + + psInpRawBuf->au4_wd[0] = mFrameWidth; + psInpRawBuf->au4_wd[1] = mFrameWidth / 2; + psInpRawBuf->au4_wd[2] = mFrameWidth / 2; + + psInpRawBuf->au4_ht[0] = mFrameHeight; + psInpRawBuf->au4_ht[1] = mFrameHeight / 2; + psInpRawBuf->au4_ht[2] = mFrameHeight / 2; + + psInpRawBuf->au4_strd[0] = yStride; + psInpRawBuf->au4_strd[1] = uStride; + psInpRawBuf->au4_strd[2] = vStride; + break; + } + } + return; +} + +int64_t AvcEncTest::getTotalFrames() { + struct stat buf; + stat(mFileName.c_str(), &buf); + size_t fileSize = buf.st_size; + int64_t totalFrames = (int64_t)(fileSize / mFrameSize); + return totalFrames; +} + +TEST_P(AvcEncTest, EncodeTest) { + ASSERT_NO_FATAL_FAILURE(encodeFrames(mTotalFrames)) << "Failed to Encode: " << mFileName; +} + +INSTANTIATE_TEST_SUITE_P(EncodeTest, AvcEncTest, + ::testing::Values(make_tuple("bbb_352x288_420p_30fps_32frames.yuv", 352, + 288, 30, 2048), + make_tuple("football_qvga.yuv", 320, 240, 30, 1024))); + +int32_t main(int argc, char** argv) { + gArgs = new TestArgs(); + ::testing::AddGlobalTestEnvironment(gArgs); + ::testing::InitGoogleTest(&argc, argv); + uint8_t status = gArgs->initFromOptions(argc, argv); + if (status == 0) { + status = RUN_ALL_TESTS(); + } + return status; +} diff --git a/tests/DynamicConfig.xml b/tests/DynamicConfig.xml new file mode 100644 index 0000000..4d721cf --- /dev/null +++ b/tests/DynamicConfig.xml @@ -0,0 +1,20 @@ +<!-- Copyright (C) 2023 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<dynamicConfig> + <entry key="media_files_url"> + <value>https://storage.googleapis.com/android_media/external/libavc/tests/AvcTestRes-1.0.zip</value> + </entry> +</dynamicConfig> diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..7832d5a --- /dev/null +++ b/tests/README.md @@ -0,0 +1,80 @@ +# AvcEncTest +The AvcEncoder Test Suite validates the Avc encoder. + +## Linux x86/x64 + +### Requirements +- cmake (3.9.1 or above) +- make +- clang (12.0 or above) + +### Steps to build +Clone libavc repository +``` +$ git clone https://android.googlesource.com/platform/external/libavc +``` +Create a directory inside libavc and change directory +``` + $ cd libavc + $ mkdir build + $ cd build +``` + +Build with -DENABLE_TESTS=1. +``` + $ cmake .. -DENABLE_TESTS=1 -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_BUILD_TYPE=Debug + $ make +``` + +Optionally, enable sanitizers by passing -DSANITIZE +``` + $ cmake .. -DENABLE_TESTS=1 -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_BUILD_TYPE=Debug -DSANITIZE=fuzzer-no-link,address,\ + signed-integer-overflow,unsigned-integer-overflow + $ make +``` + +The media files for the tests are present [at](https://storage.googleapis.com/android_media/external/libavc/tests/AvcTestRes-1.0.zip). +Download and extract these the current folder. + +usage: AvcEncTest -P \<path_to_the local folder\> + +``` +$./AvcEncTest -P ./ +``` + +## Android + +Run the following steps to build the test suite: +``` +m AvcEncTest +``` + +To test 64-bit binary push binaries from nativetest64. +``` +adb push ${OUT}/data/nativetest64/AvcEncTest/AvcEncTest /data/local/tmp/ +``` + +To test 32-bit binary push binaries from nativetest. +``` +adb push ${OUT}/data/nativetest/AvcEncTest/AvcEncTest /data/local/tmp/ +``` + +The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/external/libavc/tests/AvcTestRes-1.0.zip) + +Download, unzip and push these files into device for testing. + +``` +adb push AvcTestRes-1.0 /sdcard/test/ +``` + +usage: AvcEncTest -P \<path_to_folder\> +``` +adb shell /data/local/tmp/AvcEncTest -P /sdcard/test/AvcTestRes-1.0/ +``` +Alternatively, the test can also be run using atest command. + +``` +atest AvcEncTest +``` diff --git a/tests/TestArgs.h b/tests/TestArgs.h new file mode 100644 index 0000000..684925c --- /dev/null +++ b/tests/TestArgs.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AVC_ENCODER_TEST_ENVIRONMENT_H__ +#define __AVC_ENCODER_TEST_ENVIRONMENT_H__ + +#include <gtest/gtest.h> +#include <getopt.h> + +using namespace std; + +class TestArgs : public::testing::Environment { + public: + TestArgs() : res("/data/local/tmp/AvcEncTestRes/") {} + + // Parses the command line arguments + int initFromOptions(int argc, char **argv); + + void setRes(const char *_res) { res = _res; } + + const string getRes() const { return res; } + + private: + string res; +}; + +int TestArgs::initFromOptions(int argc, char **argv) { + static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}}; + + while (true) { + int index = 0; + int c = getopt_long(argc, argv, "P:", options, &index); + if (c == -1) { + break; + } + + switch (c) { + case 'P': { + setRes(optarg); + break; + } + default: + break; + } + } + + if (optind < argc) { + fprintf(stderr, + "unrecognized option: %s\n\n" + "usage: %s <gtest options> <test options>\n\n" + "test options are:\n\n" + "-P, --path: Resource files directory location\n", + argv[optind ?: 1], argv[0]); + return 2; + } + return 0; +} + +#endif // __AVC_ENCODER_TEST_ENVIRONMENT_H__ |