Пример #1
0
    def _export_sound(
        export_request: MediaExportRequest,
        sourcedir: Path,
        exportdir: Path,
    ) -> None:
        """
        Convert and export a sound file.

        :param export_request: Export request for a sound file.
        :param sourcedir: Directory where all media assets are mounted. Source subfolder and
                          source filename should be stored in the export request.
        :param exportdir: Directory the resulting file(s) will be exported to. Target subfolder
                          and target filename should be stored in the export request.
        :type export_request: MediaExportRequest
        :type sourcedir: Path
        :type exportdir: Path
        """
        source_file = sourcedir[export_request.get_type().value,
                                export_request.source_filename]

        if source_file.is_file():
            with source_file.open_r() as infile:
                media_file = infile.read()

        else:
            # TODO: Filter files that do not exist out sooner
            return

        from ...service.export.opus.opusenc import encode

        soundata = encode(media_file)

        if isinstance(soundata, (str, int)):
            raise Exception(f"opusenc failed: {soundata}")

        export_file = exportdir[export_request.targetdir,
                                export_request.target_filename]

        with export_file.open_w() as outfile:
            outfile.write(soundata)

        if get_loglevel() <= logging.DEBUG:
            MediaExporter.log_fileinfo(
                source_file, exportdir[export_request.targetdir,
                                       export_request.target_filename])
Пример #2
0
    def _export_blend(export_request: MediaExportRequest,
                      sourcedir: Path,
                      exportdir: Path,
                      blend_mode_count: int = None) -> None:
        """
        Convert and export a blending mode.

        :param export_request: Export request for a blending mask.
        :param sourcedir: Directory where all media assets are mounted. Source subfolder and
                          source filename should be stored in the export request.
        :param exportdir: Directory the resulting file(s) will be exported to. Target subfolder
                          and target filename should be stored in the export request.
        :param blend_mode_count: Number of blending modes extracted from the source file.
        :type export_request: MediaExportRequest
        :type sourcedir: Path
        :type exportdir: Path
        :type blend_mode_count: int
        """
        source_file = sourcedir.joinpath(export_request.source_filename)

        media_file = source_file.open("rb")
        blend_data = Blendomatic(media_file, blend_mode_count)

        from .texture_merge import merge_frames

        textures = blend_data.get_textures()
        for idx, texture in enumerate(textures):
            merge_frames(texture)
            MediaExporter.save_png(
                texture, exportdir[export_request.targetdir],
                f"{export_request.target_filename}{idx}.png")

            if get_loglevel() <= logging.DEBUG:
                MediaExporter.log_fileinfo(
                    source_file,
                    exportdir[export_request.targetdir,
                              f"{export_request.target_filename}{idx}.png"])
Пример #3
0
    def _export_terrain(export_request: MediaExportRequest, sourcedir: Path,
                        exportdir: Path, palettes: dict[int, ColorTable],
                        game_version: GameVersion,
                        compression_level: int) -> None:
        """
        Convert and export a terrain graphics file.

        :param export_request: Export request for a terrain graphics file.
        :param sourcedir: Directory where all media assets are mounted. Source subfolder and
                          source filename should be stored in the export request.
        :param exportdir: Directory the resulting file(s) will be exported to. Target subfolder
                          and target filename should be stored in the export request.
        :param game_version: Game edition and expansion info.
        :param palettes: Palettes used by the game.
        :param compression_level: PNG compression level for the resulting image file.
        :type export_request: MediaExportRequest
        :type sourcedir: Directory
        :type exportdir: Directory
        :type palettes: dict
        :type game_version: GameVersion
        :type compression_level: int
        """
        source_file = sourcedir[export_request.get_type().value,
                                export_request.source_filename]

        if source_file.suffix.lower() == ".slp":
            from ...value_object.read.media.slp import SLP
            media_file = source_file.open("rb")
            image = SLP(media_file.read())

        elif source_file.suffix.lower() == ".dds":
            # TODO: Implement
            pass

        elif source_file.suffix.lower() == ".png":
            from shutil import copyfileobj
            src_path = source_file.open('rb')
            dst_path = exportdir[export_request.targetdir,
                                 export_request.target_filename].open('wb')
            copyfileobj(src_path, dst_path)
            return

        else:
            raise Exception(
                f"Source file {source_file.name} has an unrecognized extension: "
                f"{source_file.suffix.lower()}")

        if game_version.edition.game_id in ("AOC", "SWGB"):
            from .terrain_merge import merge_terrain
            texture = Texture(image, palettes)
            merge_terrain(texture)

        else:
            from .texture_merge import merge_frames
            texture = Texture(image, palettes)
            merge_frames(texture)

        MediaExporter.save_png(
            texture,
            exportdir[export_request.targetdir],
            export_request.target_filename,
            compression_level,
        )

        if get_loglevel() <= logging.DEBUG:
            MediaExporter.log_fileinfo(
                source_file, exportdir[export_request.targetdir,
                                       export_request.target_filename])
Пример #4
0
    def _export_graphics(export_request: MediaExportRequest,
                         sourcedir: Path,
                         exportdir: Path,
                         palettes: dict[int, ColorTable],
                         compression_level: int,
                         cache_info: dict = None) -> None:
        """
        Convert and export a graphics file.

        :param export_request: Export request for a graphics file.
        :param sourcedir: Directory where all media assets are mounted. Source subfolder and
                          source filename should be stored in the export request.
        :param exportdir: Directory the resulting file(s) will be exported to. Target subfolder
                          and target filename should be stored in the export request.
        :param palettes: Palettes used by the game.
        :param compression_level: PNG compression level for the resulting image file.
        :param cache_info: Media cache information with compression parameters from a previous run.
        :type export_request: MediaExportRequest
        :type sourcedir: Path
        :type exportdir: Path
        :type palettes: dict
        :type compression_level: int
        :type cache_info: tuple
        """
        source_file = sourcedir[export_request.get_type().value,
                                export_request.source_filename]

        try:
            media_file = source_file.open("rb")

        except FileNotFoundError:
            if source_file.suffix.lower() == ".smx":
                # Rename extension to SMP and try again
                other_filename = export_request.source_filename[:-1] + "p"
                source_file = sourcedir[export_request.get_type().value,
                                        other_filename]
                export_request.set_source_filename(other_filename)

            media_file = source_file.open("rb")

        if source_file.suffix.lower() == ".slp":
            from ...value_object.read.media.slp import SLP
            image = SLP(media_file.read())

        elif source_file.suffix.lower() == ".smp":
            from ...value_object.read.media.smp import SMP
            image = SMP(media_file.read())

        elif source_file.suffix.lower() == ".smx":
            from ...value_object.read.media.smx import SMX
            image = SMX(media_file.read())

        packer_cache = None
        compr_cache = None
        if cache_info:
            cache_params = cache_info.get(export_request.source_filename, None)

            if cache_params:
                packer_cache = cache_params["packer_settings"]
                compression_level = cache_params["compr_settings"][0]
                compr_cache = cache_params["compr_settings"][1:]

        from .texture_merge import merge_frames

        texture = Texture(image, palettes)
        merge_frames(texture, cache=packer_cache)
        MediaExporter.save_png(texture,
                               exportdir[export_request.targetdir],
                               export_request.target_filename,
                               compression_level=compression_level,
                               cache=compr_cache)
        metadata = {export_request.target_filename: texture.get_metadata()}
        export_request.set_changed()
        export_request.notify_observers(metadata)
        export_request.clear_changed()

        if get_loglevel() <= logging.DEBUG:
            MediaExporter.log_fileinfo(
                source_file, exportdir[export_request.targetdir,
                                       export_request.target_filename])