Esempio n. 1
0
def brieflz_compdecsingle(data):
    import brieflz
    c = brieflz.compress(data)
    compressed = c.do()
    d = brieflz.decompress(compressed, len(compressed))
    decompressed , consumed = d.do()
    return compressed, decompressed
Esempio n. 2
0
def write_languages(
    data: LanguageData,
    f: TextIO,
    strings_obj_path: Optional[str] = None,
    compress_font: bool = False,
) -> None:
    defs = data.defs
    build_version = data.build_version
    combined_sym_list = data.sym_list
    sym_lists_by_font = data.sym_lists_by_font
    font_map = data.font_map

    symbol_conversion_table = build_symbol_conversion_map(combined_sym_list)

    language_codes: List[str] = [lang["languageCode"] for lang in data.langs]
    logging.info(f"Generating block for {language_codes}")

    lang_names = [
        lang.get("languageLocalName", lang["languageCode"])
        for lang in data.langs
    ]

    f.write('#include "Translation_multi.h"')

    f.write(f"\n// ---- {lang_names} ----\n\n")

    max_decompressed_font_size = 0
    if not compress_font:
        font_table_text = ""
        font_section_info_text = (
            "const FontSectionDataInfo FontSectionDataInfos[] = {\n")
        for font, current_sym_list in sym_lists_by_font.items():
            font_table_text += f"const uint8_t font_table_data_{font}[] = {{\n"
            font_table_text += "// 12x16:\n"
            font_table_text += make_font_table_named_cpp(
                None,
                current_sym_list,
                font_map.font12,
                symbol_conversion_table,
            )
            if font != font_tables.NAME_CJK:
                font_table_text += "// 6x8:\n"
                font_table_text += make_font_table_named_cpp(
                    None,
                    current_sym_list,
                    font_map.font06,  # type: ignore[arg-type]
                    symbol_conversion_table,
                )
            font_table_text += f"}}; // font_table_data_{font}\n"
            current_sym_start = combined_sym_list.index(
                current_sym_list[0]) + 2
            font_section_info_text += (
                "  {\n"
                f"    .symbol_start = {current_sym_start},\n"
                f"    .symbol_count = {len(current_sym_list)},\n"
                f"    .data_size = sizeof(font_table_data_{font}),\n"
                "    .data_is_compressed = false,\n"
                f"    .data_ptr = font_table_data_{font},\n"
                "  },\n")

        f.write(font_table_text)
        font_section_info_text += (
            "};\n"
            "const uint8_t FontSectionDataCount = sizeof(FontSectionDataInfos) / sizeof(FontSectionDataInfos[0]);\n\n"
        )
        f.write(font_section_info_text)
        f.write(
            "FontSection DynamicFontSections[4] = {};\n"
            "const FontSection *const FontSections = DynamicFontSections;\n"
            "const uint8_t FontSectionsCount = sizeof(DynamicFontSections) / sizeof(DynamicFontSections[0]);\n"
        )
    else:
        font_section_info_text = (
            "const FontSectionDataInfo FontSectionDataInfos[] = {\n")
        for font, current_sym_list in sym_lists_by_font.items():
            current_sym_start = combined_sym_list.index(
                current_sym_list[0]) + 2
            font_uncompressed = bytearray()
            for sym in current_sym_list:
                font_uncompressed.extend(font_map.font12[sym])
            if font != font_tables.NAME_CJK:
                for sym in current_sym_list:
                    font_uncompressed.extend(
                        font_map.font06[sym])  # type: ignore[arg-type]
            font_compressed = brieflz.compress(bytes(font_uncompressed))
            logging.info(
                f"Font table for {font} compressed from {len(font_uncompressed)} to {len(font_compressed)} bytes (ratio {len(font_compressed) / len(font_uncompressed):.3})"
            )
            max_decompressed_font_size += len(font_uncompressed)
            write_bytes_as_c_array(f, f"font_data_brieflz_{font}",
                                   font_compressed)
            font_section_info_text += (
                "  {\n"
                f"    .symbol_start = {current_sym_start},\n"
                f"    .symbol_count = {len(current_sym_list)},\n"
                f"    .data_size = sizeof(font_data_brieflz_{font}),\n"
                "    .data_is_compressed = true,\n"
                f"    .data_ptr = font_data_brieflz_{font},\n"
                "  },\n")
        font_section_info_text += (
            "};\n"
            "const uint8_t FontSectionDataCount = sizeof(FontSectionDataInfos) / sizeof(FontSectionDataInfos[0]);\n\n"
        )
        f.write(font_section_info_text)
        f.write(
            "FontSection DynamicFontSections[4] = {};\n"
            "const FontSection *const FontSections = DynamicFontSections;\n"
            "const uint8_t FontSectionsCount = sizeof(DynamicFontSections) / sizeof(DynamicFontSections[0]);\n"
        )

    f.write(f"\n// ---- {lang_names} ----\n\n")

    translation_common_text = get_translation_common_text(
        defs, symbol_conversion_table, build_version)
    f.write(translation_common_text)
    f.write(
        f"const bool HasFahrenheit = {('true' if any([lang.get('tempUnitFahrenheit', True) for lang in data.langs]) else 'false')};\n\n"
    )

    max_decompressed_translation_size = 0
    if not strings_obj_path:
        for lang in data.langs:
            lang_code = lang["languageCode"]
            translation_strings_and_indices_text = (
                get_translation_strings_and_indices_text(
                    lang,
                    defs,
                    symbol_conversion_table,
                    suffix=f"_{lang_code}"))
            f.write(translation_strings_and_indices_text)
        f.write("const LanguageMeta LanguageMetas[] = {\n")
        for lang in data.langs:
            lang_code = lang["languageCode"]
            lang_id = get_language_unqiue_id(lang_code)
            f.write(
                "  {\n"
                f"    .uniqueID = {lang_id},\n"
                f"    .translation_data = reinterpret_cast<const uint8_t *>(&translation_{lang_code}),\n"
                f"    .translation_size = sizeof(translation_{lang_code}),\n"
                f"    .translation_is_compressed = false,\n"
                "  },\n")
        f.write("};\n")
    else:
        for lang in data.langs:
            lang_code = lang["languageCode"]
            sym_name = objcopy.cpp_var_to_section_name(
                f"translation_{lang_code}")
            strings_bin = objcopy.get_binary_from_obj(strings_obj_path,
                                                      sym_name)
            if len(strings_bin) == 0:
                raise ValueError(f"Output for {sym_name} is empty")
            max_decompressed_translation_size = max(
                max_decompressed_translation_size, len(strings_bin))
            compressed = brieflz.compress(strings_bin)
            logging.info(
                f"Strings for {lang_code} compressed from {len(strings_bin)} to {len(compressed)} bytes (ratio {len(compressed) / len(strings_bin):.3})"
            )
            write_bytes_as_c_array(f, f"translation_data_brieflz_{lang_code}",
                                   compressed)
        f.write("const LanguageMeta LanguageMetas[] = {\n")
        for lang in data.langs:
            lang_code = lang["languageCode"]
            lang_id = get_language_unqiue_id(lang_code)
            f.write(
                "  {\n"
                f"    .uniqueID = {lang_id},\n"
                f"    .translation_data = translation_data_brieflz_{lang_code},\n"
                f"    .translation_size = sizeof(translation_data_brieflz_{lang_code}),\n"
                f"    .translation_is_compressed = true,\n"
                "  },\n")
        f.write("};\n")
    f.write(
        "const uint8_t LanguageCount = sizeof(LanguageMetas) / sizeof(LanguageMetas[0]);\n\n"
        f"alignas(TranslationData) uint8_t translation_data_out_buffer[{max_decompressed_translation_size + max_decompressed_font_size}];\n"
        "const uint16_t translation_data_out_buffer_size = sizeof(translation_data_out_buffer);\n\n"
    )

    sanity_checks_text = get_translation_sanity_checks_text(defs)
    f.write(sanity_checks_text)
Esempio n. 3
0
def write_language(
    data: LanguageData,
    f: TextIO,
    strings_bin: Optional[bytes] = None,
    compress_font: bool = False,
) -> None:
    if len(data.langs) > 1:
        raise ValueError("More than 1 languages are provided")
    lang = data.langs[0]
    defs = data.defs
    build_version = data.build_version
    sym_list = data.sym_list
    font_map = data.font_map

    symbol_conversion_table = build_symbol_conversion_map(sym_list)

    language_code: str = lang["languageCode"]
    logging.info(f"Generating block for {language_code}")

    try:
        lang_name = lang["languageLocalName"]
    except KeyError:
        lang_name = language_code

    if strings_bin or compress_font:
        f.write('#include "brieflz.h"\n')

    f.write(f"\n// ---- {lang_name} ----\n\n")

    if not compress_font:
        font_table_text = make_font_table_cpp(sym_list, font_map,
                                              symbol_conversion_table)
        f.write(font_table_text)
        f.write(
            "const FontSection FontSectionsData[] = {\n"
            "  {\n"
            "    .symbol_start = 2,\n"
            f"    .symbol_end = {len(sym_list) + 2},\n"
            "    .font12_start_ptr = USER_FONT_12,\n"
            "    .font06_start_ptr = USER_FONT_6x8,\n"
            "  },\n"
            "};\n"
            "const FontSection *const FontSections = FontSectionsData;\n"
            "const uint8_t FontSectionsCount = sizeof(FontSectionsData) / sizeof(FontSectionsData[0]);\n"
        )
    else:
        font12_uncompressed = bytearray()
        for sym in sym_list:
            font12_uncompressed.extend(font_map.font12[sym])
        font12_compressed = brieflz.compress(bytes(font12_uncompressed))
        logging.info(
            f"Font table 12x16 compressed from {len(font12_uncompressed)} to {len(font12_compressed)} bytes (ratio {len(font12_compressed) / len(font12_uncompressed):.3})"
        )
        write_bytes_as_c_array(f, "font_12x16_brieflz", font12_compressed)
        font_table_text = make_font_table_06_cpp(sym_list, font_map,
                                                 symbol_conversion_table)
        f.write(font_table_text)
        f.write(
            f"static uint8_t font_out_buffer[{len(font12_uncompressed)}];\n"
            "const FontSection FontSectionsData[] = {\n"
            "  {\n"
            "    .symbol_start = 2,\n"
            f"    .symbol_end = {len(sym_list) + 2},\n"
            "    .font12_start_ptr = font_out_buffer,\n"
            "    .font06_start_ptr = USER_FONT_6x8,\n"
            "  },\n"
            "};\n"
            "const FontSection *const FontSections = FontSectionsData;\n"
            "const uint8_t FontSectionsCount = sizeof(FontSectionsData) / sizeof(FontSectionsData[0]);\n"
        )

    f.write(f"\n// ---- {lang_name} ----\n\n")

    translation_common_text = get_translation_common_text(
        defs, symbol_conversion_table, build_version)
    f.write(translation_common_text)
    f.write(
        f"const bool HasFahrenheit = {('true' if lang.get('tempUnitFahrenheit', True) else 'false')};\n\n"
    )

    if not strings_bin:
        translation_strings_and_indices_text = get_translation_strings_and_indices_text(
            lang, defs, symbol_conversion_table)
        f.write(translation_strings_and_indices_text)
        f.write("const TranslationIndexTable *Tr = &translation.indices;\n"
                "const char *TranslationStrings = translation.strings;\n\n")
    else:
        compressed = brieflz.compress(strings_bin)
        logging.info(
            f"Strings compressed from {len(strings_bin)} to {len(compressed)} bytes (ratio {len(compressed) / len(strings_bin):.3})"
        )
        write_bytes_as_c_array(f, "translation_data_brieflz", compressed)
        f.write(
            f"static uint8_t translation_data_out_buffer[{len(strings_bin)}] __attribute__((__aligned__(2)));\n\n"
            "const TranslationIndexTable *Tr = reinterpret_cast<const TranslationIndexTable *>(translation_data_out_buffer);\n"
            "const char *TranslationStrings = reinterpret_cast<const char *>(translation_data_out_buffer) + sizeof(TranslationIndexTable);\n\n"
        )

    if not strings_bin and not compress_font:
        f.write("void prepareTranslations() {}\n\n")
    else:
        f.write("void prepareTranslations() {\n")
        if compress_font:
            f.write(
                "  blz_depack_srcsize(font_12x16_brieflz, font_out_buffer, sizeof(font_12x16_brieflz));\n"
            )
        if strings_bin:
            f.write(
                "  blz_depack_srcsize(translation_data_brieflz, translation_data_out_buffer, sizeof(translation_data_brieflz));\n"
            )
        f.write("}\n\n")

    sanity_checks_text = get_translation_sanity_checks_text(defs)
    f.write(sanity_checks_text)
Esempio n. 4
0
 def test_roundtrip(self):
     packed = brieflz.compress(TEST_DATA)
     depacked = brieflz.depack_srcsize(packed, len(TEST_DATA))
     self.assertEqual(depacked, TEST_DATA)