bdsup2sub.BDSup2Sub.java Source code

Java tutorial

Introduction

Here is the source code for bdsup2sub.BDSup2Sub.java

Source

/*
 * Copyright 2014 Volker Oth (0xdeadbeef) / Miklos Juhasz (mjuhasz)
 *
 * 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 bdsup2sub;

import bdsup2sub.cli.CommandLineParser;
import bdsup2sub.core.*;
import bdsup2sub.gui.main.MainFrame;
import bdsup2sub.tools.Props;
import bdsup2sub.utils.*;
import org.apache.commons.cli.ParseException;
import org.simplericity.macify.eawt.Application;
import org.simplericity.macify.eawt.DefaultApplication;

import javax.swing.*;
import java.awt.*;
import java.io.File;

import static bdsup2sub.gui.support.GuiUtils.applyGtkThemeWorkarounds;

public class BDSup2Sub {

    private static final Configuration configuration = Configuration.getInstance();
    private static final Logger logger = Logger.getInstance();

    private CommandLineParser options;

    public static void main(String[] args) {
        try {
            new BDSup2Sub().run(args);
        } catch (Exception e) {
            fatalError(e.getMessage());
            System.exit(1);
        }
    }

    private void run(String[] args) {
        parseOptions(args);
        processOptions();
        execute();
    }

    private void parseOptions(String[] args) {
        options = new CommandLineParser();
        try {
            options.parse(args);
        } catch (ParseException e) {
            fatalError(e.getMessage());
            options.printHelp();
            System.exit(1);
        }
    }

    private void processOptions() {
        if (options.isLoadSettings()) {
            configuration.load();
        }
        if (options.getOutputMode().isPresent()) {
            configuration.setOutputMode(options.getOutputMode().get());
        }
        if (options.getResolution().isPresent()) {
            configuration.setConvertResolution(true);
            configuration.setOutputResolution(options.getResolution().get());
        }
        processFrameRate();
        if (options.getDelay().isPresent()) {
            configuration.setDelayPTS((int) SubtitleUtils.syncTimePTS((long) (options.getDelay().get() * 90.0),
                    configuration.getFpsTrg(), configuration.getFpsTrg()));
        }
        if (options.getScalingFilter().isPresent()) {
            configuration.setScalingFilter(options.getScalingFilter().get());
        }
        if (options.getPaletteMode().isPresent()) {
            configuration.setPaletteMode(options.getPaletteMode().get());
        }
        processMinimumDisplayTime();
        if (options.getMaximumTimeDifference().isPresent()) {
            configuration.setMergePTSdiff((int) (options.getMaximumTimeDifference().get() * 90.0 + 0.5));
        }
        processMoveMode();
        if (options.getCropLines().isPresent()) {
            configuration.setCropOffsetY(options.getCropLines().get());
        }
        if (options.getAlphaCropThreshold().isPresent()) {
            configuration.setAlphaCrop(options.getAlphaCropThreshold().get());
        }
        if (options.getScaleX().isPresent() && options.getScaleY().isPresent()) {
            configuration.setApplyFreeScale(true);
            configuration.setFreeScaleFactor(options.getScaleX().get(), options.getScaleY().get());
        }
        if (options.isExportPalette().isPresent()) {
            configuration.setWritePGCEditPalette(options.isExportPalette().get());
        }
        if (options.isExportForcedSubtitlesOnly().isPresent()) {
            configuration.setExportForced(options.isExportForcedSubtitlesOnly().get());
        }
        if (options.getForcedFlagState().isPresent()) {
            configuration.setForceAll(options.getForcedFlagState().get());
        }
        if (options.isSwapCrCb().isPresent()) {
            configuration.setSwapCrCb(options.isSwapCrCb().get());
        }
        if (options.isFixInvisibleFrames().isPresent()) {
            configuration.setFixZeroAlpha(options.isFixInvisibleFrames().get());
        }
        if (options.isVerbose().isPresent()) {
            configuration.setVerbose(options.isVerbose().get());
        }
        if (options.getAlphaThreshold().isPresent()) {
            configuration.setAlphaThreshold(options.getAlphaThreshold().get());
        }
        processLuminanceThreshold();
        if (options.getLanguageIndex().isPresent()) {
            configuration.setLanguageIdx(options.getLanguageIndex().get());
        }
        processPaletteFile();
    }

    private void processFrameRate() {
        boolean targetFramerateDefined = false;
        if (options.isConvertFpsMode()) {
            if (!options.getSourceFrameRate().isPresent()) { // was set to "auto"
                // leave default value
            } else {
                configuration.setFpsSrc(options.getSourceFrameRate().get());
                configuration.setFpsTrg(options.getTargetFrameRate().get());
            }
            // convert framerate from <auto>/fpssrc to fpstrg
            configuration.setConvertFPS(true);
            targetFramerateDefined = true;
        } else if (options.isSynchronizeFpsMode()) {
            if (!options.getTargetFrameRate().isPresent()) { // was set to "keep"
                configuration.setKeepFps(true);
                // use source fps as target fps
            } else {
                // synchronize target framerate to fpstrg
                configuration.setFpsTrg(options.getTargetFrameRate().get());
                targetFramerateDefined = true;
            }
        }
        if (!targetFramerateDefined && options.getResolution().isPresent()) {
            switch (options.getResolution().get()) {
            case PAL:
                configuration.setFpsTrg(Framerate.PAL.getValue());
                break;
            case NTSC:
                configuration.setFpsTrg(Framerate.NTSC.getValue());
                break;
            case HD_720:
                configuration.setFpsTrg(Framerate.FPS_23_976.getValue());
                break;
            case HD_1440x1080:
                configuration.setFpsTrg(Framerate.FPS_23_976.getValue());
                break;
            case HD_1080:
                configuration.setFpsTrg(Framerate.FPS_23_976.getValue());
                break;
            }
        }
        if (!configuration.isKeepFps() && !targetFramerateDefined) {
            configuration
                    .setFpsTrg(SubtitleUtils.getDefaultFramerateForResolution(configuration.getOutputResolution()));
        }
    }

    private void processMinimumDisplayTime() {
        if (options.getMinimumDisplayTime().isPresent()) {
            int tMin = (int) SubtitleUtils.syncTimePTS((long) (options.getMinimumDisplayTime().get() * 90.0),
                    configuration.getFpsTrg(), configuration.getFpsTrg());
            configuration.setMinTimePTS(tMin);
            configuration.setFixShortFrames(true);
        }
    }

    private void processMoveMode() {
        if (options.getMoveModeY().isPresent()) {
            configuration.setMoveModeY(options.getMoveModeY().get());
            configuration.setMoveOffsetY(options.getMoveYOffset());
        }
        if (options.getMoveModeX().isPresent()) {
            configuration.setMoveModeX(options.getMoveModeX().get());
            if (options.getMoveXOffset().isPresent()) {
                configuration.setMoveOffsetX(options.getMoveXOffset().get());
            }
        }
    }

    private void processLuminanceThreshold() {
        int lt[] = configuration.getLuminanceThreshold();
        if (options.getLumLowMedThreshold().isPresent()) {
            lt[1] = options.getLumLowMedThreshold().get();
        }
        if (options.getLumMedHighThreshold().isPresent()) {
            lt[0] = options.getLumMedHighThreshold().get();
        }
        configuration.setLuminanceThreshold(lt);
    }

    private void processPaletteFile() {
        if (options.getPaletteFile() != null) {
            Props colProps = new Props();
            colProps.load(options.getPaletteFile().getAbsolutePath());
            for (int c = 0; c < 15; c++) {
                String s = colProps.get("Color_" + c, "0,0,0");
                String sp[] = s.split(",");
                if (sp.length >= 3) {
                    int red = Integer.valueOf(sp[0].trim()) & 0xff;
                    int green = Integer.valueOf(sp[1].trim()) & 0xff;
                    int blue = Integer.valueOf(sp[2].trim()) & 0xff;
                    Core.getCurrentDVDPalette().setColor(c + 1, new Color(red, green, blue));
                }
            }
        }
    }

    private void execute() {
        if (options.isPrintHelpMode()) {
            options.printHelp();
        } else if (options.isPrintVersionMode()) {
            System.out.println(Constants.APP_NAME + " " + Constants.APP_VERSION);
        } else {
            if (!options.isCliMode()) {
                setupGUI();
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        configuration.setCliMode(false);
                        Application app = new DefaultApplication();
                        MainFrame mainFrame = new MainFrame(options.getInputFile());
                        app.addApplicationListener(mainFrame.getApplicationListener());
                        mainFrame.setVisible(true);
                    }
                });
            } else {
                runCliLoop();
            }
        }
    }

    private static void setupGUI() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            // ignore
        }

        if (PlatformUtils.isLinux()) {
            applyGtkThemeWorkarounds();
        }

        if (PlatformUtils.isMac()) {
            System.setProperty("apple.laf.useScreenMenuBar", "true");
            System.setProperty("com.apple.mrj.application.apple.menu.about.name", Constants.APP_NAME);
        }
    }

    private void runCliLoop() {
        String inputFile = options.getInputFile().getAbsolutePath();
        String outputFile = options.getOutputFile().getAbsolutePath();
        try {
            boolean xml = FilenameUtils.getExtension(inputFile).equalsIgnoreCase("xml");
            boolean idx = FilenameUtils.getExtension(inputFile).equalsIgnoreCase("idx");
            boolean ifo = FilenameUtils.getExtension(inputFile).equalsIgnoreCase("ifo");
            byte id[] = ToolBox.getFileID(inputFile, 4);
            StreamID sid = (id == null) ? StreamID.UNKNOWN : StreamUtils.getStreamID(id);
            if (!idx && !xml && !ifo && sid == StreamID.UNKNOWN) {
                throw new CoreException("File '" + inputFile + "' is not a supported subtitle stream.");
            }
            configuration.setCurrentStreamID(sid);

            // check output file(s)
            File indexFile, subtitleFile;
            if (configuration.getOutputMode() == OutputMode.VOBSUB) {
                indexFile = new File(FilenameUtils.removeExtension(outputFile) + ".idx");
                subtitleFile = new File(FilenameUtils.removeExtension(outputFile) + ".sub");
            } else {
                subtitleFile = new File(FilenameUtils.removeExtension(outputFile) + ".sup");
                indexFile = null;
            }
            if ((indexFile != null && indexFile.exists() && !indexFile.canWrite())
                    || (subtitleFile.exists() && !subtitleFile.canWrite())) {
                throw new CoreException("Target file '" + outputFile + "' is write protected.");
            }

            // read input file
            if (xml || sid == StreamID.XML) {
                Core.readXml(inputFile);
            } else if (idx || sid == StreamID.DVDSUB || sid == StreamID.IDX) {
                Core.readVobSub(inputFile);
            } else if (ifo || sid == StreamID.IFO) {
                Core.readSupIfo(inputFile);
            } else {
                Core.readSup(inputFile);
            }

            Core.scanSubtitles();
            logger.printWarningsAndErrorsAndResetCounters();
            // move captions
            if (configuration.getMoveModeX() != CaptionMoveModeX.KEEP_POSITION
                    || configuration.getMoveModeY() != CaptionMoveModeY.KEEP_POSITION) {
                configuration.setCineBarFactor((1.0 - (16.0 / 9) / options.getScreenRatio()) / 2.0);
                Core.moveAllToBounds();
            }
            // set some values
            if (configuration.isExportForced() && Core.getNumForcedFrames() == 0) {
                throw new CoreException("No forced subtitles found.");
            }
            // write output
            Core.writeSub(outputFile);
        } catch (CoreException ex) {
            logger.error(ex.getMessage());
        } catch (Exception ex) {
            ToolBox.showException(ex);
            logger.error(ex.getMessage());
        }
        // clean up
        logger.printWarningsAndErrorsAndResetCounters();
        Core.exit();

        System.out.println("\nConversion finished.");
        System.exit(0);
    }

    private static void fatalError(String message) {
        Core.exit();
        System.out.println("ERROR: " + message);
        System.exit(1);
    }
}