// Path: src/main/java/bdsup2sub/core/Framerate.java
// public enum Framerate {
//     FPS_23_976(24000.0/1001, 0x10), //24p
//     FPS_23_975(23.975, 0x10),
//     FPS_24(24.0, 0x20),
//     PAL(25.0, 0x30),
//     NTSC(30000.0/1001, 0x40),
//     PAL_I(50.0,0x60),
//     NTSC_I(60000.0/1001, 0x70);
// 
//     private final double value;
//     private final int id;
// 
//     private Framerate(double value, int id) {
//         this.value = value;
//         this.id = id;
//     }
// 
//     public double getValue() {
//         return value;
//     }
// 
//     public int getId() {
//         return id;
//     }
// 
//     public static double valueForId(int id) {
//         for (Framerate framerate : Framerate.values()) {
//             if (id == framerate.getId()) {
//                 return framerate.getValue();
//             }
//         }
//         throw new IllegalArgumentException("Unsupported id: " + id);
//     }
// 
//     public static int idForFramerate(double fps) {
//         for (Framerate framerate : Framerate.values()) {
//             if (fps == framerate.getValue()) {
//                 return framerate.getId();
//             }
//         }
//         throw new IllegalArgumentException("Unsupported framerate: " + fps);
//     }
// }
// 
// Path: src/main/java/bdsup2sub/core/Resolution.java
// public enum Resolution {
//     NTSC {
//         @Override
//         public String toString() {
//             return "NTSC (720x480)";
//         }
// 
//         @Override
//         public String getResolutionNameForXml() {
//             return "480i";
//         }
// 
//         @Override
//         public int[] getDimensions() {
//             return new int[] {720, 480};
//         }
//     },
//     PAL {
//         @Override
//         public String toString() {
//             return "PAL (720x576)";
//         }
// 
//         @Override
//         public String getResolutionNameForXml() {
//             return "576i";
//         }
// 
//         @Override
//         public int[] getDimensions() {
//             return new int[]{720, 576};
//         }
//     },
//     HD_720 {
//         @Override
//         public String toString() {
//             return "720p (1280x720)";
//         }
// 
//         @Override
//         public String getResolutionNameForXml() {
//             return "720p";
//         }
// 
//         @Override
//         public int[] getDimensions() {
//             return new int[]{1280, 720};
//         }
//     },
//     HD_1440x1080 {
//         @Override
//         public String toString() {
//             return "1080p (1440x1080)";
//         }
// 
//         @Override
//         public String getResolutionNameForXml() {
//             return "1440x1080";
//         }
// 
//         @Override
//         public int[] getDimensions() {
//             return new int[]{1440, 1080};
//         }
//     },
//     HD_1080 {
//         @Override
//         public String toString() {
//             return "1080p (1920x1080)";
//         }
// 
//         @Override
//         public String getResolutionNameForXml() {
//             return "1080p";
//         }
// 
//         @Override
//         public int[] getDimensions() {
//             return new int[]{1920, 1080};
//         }
//     };
// 
//     public abstract String getResolutionNameForXml();
//     public abstract int[] getDimensions();
// }


import bdsup2sub.core.Framerate;
import bdsup2sub.core.Resolution;
        }
        if (Math.abs(d - Framerate.PAL_I.getValue()) < 0.001) {
            return Framerate.PAL_I.getValue();
        }
        return d;
    }

    /**
     * Synchronizes a time stamp in 90kHz resolution to the given frame rate.
     */
    public static long syncTimePTS(long timeStamp, double fps, double fpsTrg) {
        long retval;
        // correct time stamps to fit to frames
        if (fps == Framerate.NTSC.getValue() || fps == Framerate.PAL.getValue() || fps == Framerate.FPS_24.getValue()) {
            // NTSC: 90000/(30000/1001) = 3003
            // PAL:  90000/25 = 3600
            // 24Hz: 90000/24 = 3750
            int tpfi = (int)((90000+(fps/2))/fps); // target time per frame in 90kHz
            int tpfh = tpfi/2;
            retval = ((timeStamp + tpfh)/tpfi)*tpfi;
        } else if (fpsTrg == Framerate.FPS_23_976.getValue()) {
            // 90000/(24000/1001) = 3753.75 = 15015/4
            retval = ((((timeStamp + 1877)*4)/15015)*15015)/4;
        } else {
            double tpf = (90000/fpsTrg); // target time per frame in 90kHz
            retval = (long)((long)(timeStamp/tpf)*tpf+0.5);
        }
        return retval;
    }

// Path: src/main/java/bdsup2sub/core/Framerate.java
// public enum Framerate {
//     FPS_23_976(24000.0/1001, 0x10), //24p
//     FPS_23_975(23.975, 0x10),
//     FPS_24(24.0, 0x20),
//     PAL(25.0, 0x30),
//     NTSC(30000.0/1001, 0x40),
//     PAL_I(50.0,0x60),
//     NTSC_I(60000.0/1001, 0x70);
// 
//     private final double value;
//     private final int id;
// 
//     private Framerate(double value, int id) {
//         this.value = value;
//         this.id = id;
//     }
// 
//     public double getValue() {
//         return value;
//     }
// 
//     public int getId() {
//         return id;
//     }
// 
//     public static double valueForId(int id) {
//         for (Framerate framerate : Framerate.values()) {
//             if (id == framerate.getId()) {
//                 return framerate.getValue();
//             }
//         }
//         throw new IllegalArgumentException("Unsupported id: " + id);
//     }
// 
//     public static int idForFramerate(double fps) {
//         for (Framerate framerate : Framerate.values()) {
//             if (fps == framerate.getValue()) {
//                 return framerate.getId();
//             }
//         }
//         throw new IllegalArgumentException("Unsupported framerate: " + fps);
//     }
// }
// 
// Path: src/main/java/bdsup2sub/core/Resolution.java
// public enum Resolution {
//     NTSC {
//         @Override
//         public String toString() {
//             return "NTSC (720x480)";
//         }
// 
//         @Override
//         public String getResolutionNameForXml() {
//             return "480i";
//         }
// 
//         @Override
//         public int[] getDimensions() {
//             return new int[] {720, 480};
//         }
//     },
//     PAL {
//         @Override
//         public String toString() {
//             return "PAL (720x576)";
//         }
// 
//         @Override
//         public String getResolutionNameForXml() {
//             return "576i";
//         }
// 
//         @Override
//         public int[] getDimensions() {
//             return new int[]{720, 576};
//         }
//     },
//     HD_720 {
//         @Override
//         public String toString() {
//             return "720p (1280x720)";
//         }
// 
//         @Override
//         public String getResolutionNameForXml() {
//             return "720p";
//         }
// 
//         @Override
//         public int[] getDimensions() {
//             return new int[]{1280, 720};
//         }
//     },
//     HD_1440x1080 {
//         @Override
//         public String toString() {
//             return "1080p (1440x1080)";
//         }
// 
//         @Override
//         public String getResolutionNameForXml() {
//             return "1440x1080";
//         }
// 
//         @Override
//         public int[] getDimensions() {
//             return new int[]{1440, 1080};
//         }
//     },
//     HD_1080 {
//         @Override
//         public String toString() {
//             return "1080p (1920x1080)";
//         }
// 
//         @Override
//         public String getResolutionNameForXml() {
//             return "1080p";
//         }
// 
//         @Override
//         public int[] getDimensions() {
//             return new int[]{1920, 1080};
//         }
//     };
// 
//     public abstract String getResolutionNameForXml();
//     public abstract int[] getDimensions();
// }


// Path: src/main/java/bdsup2sub/utils/SubtitleUtils.java
import bdsup2sub.core.Framerate;
import bdsup2sub.core.Resolution;

        }
        if (Math.abs(d - Framerate.PAL_I.getValue()) < 0.001) {
            return Framerate.PAL_I.getValue();
        }
        return d;
    }

    /**
     * Synchronizes a time stamp in 90kHz resolution to the given frame rate.
     */
    public static long syncTimePTS(long timeStamp, double fps, double fpsTrg) {
        long retval;
        // correct time stamps to fit to frames
        if (fps == Framerate.NTSC.getValue() || fps == Framerate.PAL.getValue() || fps == Framerate.FPS_24.getValue()) {
            // NTSC: 90000/(30000/1001) = 3003
            // PAL:  90000/25 = 3600
            // 24Hz: 90000/24 = 3750
            int tpfi = (int)((90000+(fps/2))/fps); // target time per frame in 90kHz
            int tpfh = tpfi/2;
            retval = ((timeStamp + tpfh)/tpfi)*tpfi;
        } else if (fpsTrg == Framerate.FPS_23_976.getValue()) {
            // 90000/(24000/1001) = 3753.75 = 15015/4
            retval = ((((timeStamp + 1877)*4)/15015)*15015)/4;
        } else {
            double tpf = (90000/fpsTrg); // target time per frame in 90kHz
            retval = (long)((long)(timeStamp/tpf)*tpf+0.5);
        }
        return retval;
    }

    public static double getDefaultFramerateForResolution(Resolution resolution) {