diff --git a/jpsxdec/TODO.txt b/jpsxdec/TODO.txt index 890ea26..76caab7 100644 --- a/jpsxdec/TODO.txt +++ b/jpsxdec/TODO.txt @@ -182,16 +182,12 @@ Games to investigate * Star Wars - Rebel Assault II * Discworld 2 * BrainDead 13 -* Syphon Filter 3 * Love Games - Wai Wai Tennis [Service Price] [SLPS-01647] INTRO.STR * Fear Effect -* Kowloon's Gate -* Jackie Chan Stuntmaster -* Firemen 2 * Magic the Gathering * Aconcagua ending video * Sentient -* Panekit +* Panekit - Infinitive Crafting Toy Case Replace with a prompt before applying changes diff --git a/jpsxdec/build.xml b/jpsxdec/build.xml index 5b4d7b6..bd30f05 100644 --- a/jpsxdec/build.xml +++ b/jpsxdec/build.xml @@ -9,7 +9,7 @@ - + diff --git a/jpsxdec/doc/CHANGES.txt b/jpsxdec/doc/CHANGES.txt index 00335bf..91e8927 100644 --- a/jpsxdec/doc/CHANGES.txt +++ b/jpsxdec/doc/CHANGES.txt @@ -1,3 +1,16 @@ +v1.04 rev3987 (10 Aug 2020) + - More robust XA audio detection + - Support for saving images as TIFF in Java 9+ + - Ignore silent XA streams + - Improved Tim detection, including + Github issue #29 "TIM image not found in file" by gmarty + Bug fixes: + - Replacing XA with pcm audio doesn't actually make any changes, + broken since v0.99.8 + (Github issue #30 '"-replacexa" command does not work' by ViToTiV) + - Real-time audio player doesn't play tiny clips + - Error when Tim image ends at sector boundary + - Sector type detection issues v1.03 rev3953 (15 Dec 2019) Bug fixes: - Some videos in EA games are still not detected diff --git a/jpsxdec/doc/LICENSE.txt b/jpsxdec/doc/LICENSE.txt index 5192630..cf03200 100644 --- a/jpsxdec/doc/LICENSE.txt +++ b/jpsxdec/doc/LICENSE.txt @@ -1,6 +1,6 @@ jPSXdec: PlayStation 1 Media Decoder/Converter in Java -Copyright (C) 2007-2019 Michael Sabin +Copyright (C) 2007-2020 Michael Sabin All rights reserved. jPSXdec is licensed as a whole under this non-commercial license: diff --git a/jpsxdec/jPSXdec-design.md b/jpsxdec/jPSXdec-design.md index e20d878..a84b903 100644 --- a/jpsxdec/jPSXdec-design.md +++ b/jpsxdec/jPSXdec-design.md @@ -680,6 +680,25 @@ style that makes this easy. Hunting for a solution, I ran across this `ParagraphLayout`, and it has been absolutely brilliant. +# Memory use + +jPSXdec reference graph is fairly simple. + +The root for a disc in memory is `CdFileSectorReader` and `DiscIndex`. +Once a disc is loaded, no memory is allocated or released. +And once the `CdFileSectorReader` is closed and discarded, everything +associated with a disc is freed +(assuming nothing else is holding onto some exposed internal reference). + +The UI is also pretty simple. Most is allocated once and never freed. +The real-time audio/video player is created and freed on every view. + +The only memory growth that could be noticed would come from the +`DiscItemSaverBuilder` used to save every `DiscItem`. Initially each `DiscItems`'s +`DiscItemSaverBuilder` start as `null` and are only allocated when the disc item +is selected in the GUI. But that should be minimal. And once the disc is closed, +those are all freed as well. + # Appendix 1: Adding support for a new game Other than the frame-rate detection limitations, jPSXdec has all the features to diff --git a/jpsxdec/src-lgpl/org/jdesktop/swingx/action/AbstractActionExt.java b/jpsxdec/src-lgpl/org/jdesktop/swingx/action/AbstractActionExt.java index 015d61a..2d1f980 100644 --- a/jpsxdec/src-lgpl/org/jdesktop/swingx/action/AbstractActionExt.java +++ b/jpsxdec/src-lgpl/org/jdesktop/swingx/action/AbstractActionExt.java @@ -236,7 +236,7 @@ public String getName() { public void setMnemonic(String mnemonic) { if (mnemonic != null && mnemonic.length() > 0) { - putValue(Action.MNEMONIC_KEY, new Integer(mnemonic.charAt(0))); + putValue(Action.MNEMONIC_KEY, Integer.valueOf(mnemonic.charAt(0))); } } @@ -256,7 +256,7 @@ public void setMnemonic(String mnemonic) { * @see Action#putValue */ public void setMnemonic(int mnemonic) { - putValue(Action.MNEMONIC_KEY, new Integer(mnemonic)); + putValue(Action.MNEMONIC_KEY, Integer.valueOf(mnemonic)); } /** diff --git a/jpsxdec/src-lgpl/org/jdesktop/swingx/action/ActionContainerFactory.java b/jpsxdec/src-lgpl/org/jdesktop/swingx/action/ActionContainerFactory.java index 32fa345..f8bcccd 100644 --- a/jpsxdec/src-lgpl/org/jdesktop/swingx/action/ActionContainerFactory.java +++ b/jpsxdec/src-lgpl/org/jdesktop/swingx/action/ActionContainerFactory.java @@ -324,7 +324,7 @@ private ButtonGroup getGroup(String groupid, JComponent container) { if (container != null) { intCode ^= container.hashCode(); } - Integer hashCode = new Integer(intCode); + Integer hashCode = Integer.valueOf(intCode); ButtonGroup group = groupMap.get(hashCode); if (group == null) { diff --git a/jpsxdec/src-lgpl/org/jdesktop/swingx/action/BoundAction.java b/jpsxdec/src-lgpl/org/jdesktop/swingx/action/BoundAction.java index 750e9af..1ca08d5 100644 --- a/jpsxdec/src-lgpl/org/jdesktop/swingx/action/BoundAction.java +++ b/jpsxdec/src-lgpl/org/jdesktop/swingx/action/BoundAction.java @@ -106,7 +106,7 @@ public void setCallback(String callback) { // May throw a security exception in an Applet // context. - Object obj = clz.newInstance(); + Object obj = clz.getDeclaredConstructor().newInstance(); registerCallback(obj, elems[1]); } catch (Exception ex) { diff --git a/jpsxdec/src-lgpl/org/jdesktop/swingx/action/ServerAction.java b/jpsxdec/src-lgpl/org/jdesktop/swingx/action/ServerAction.java index 95c274c..0c83b80 100644 --- a/jpsxdec/src-lgpl/org/jdesktop/swingx/action/ServerAction.java +++ b/jpsxdec/src-lgpl/org/jdesktop/swingx/action/ServerAction.java @@ -107,7 +107,7 @@ public String getURL() { @SuppressWarnings("unchecked") private Map getParams() { - return (Map)getValue(PARAMS); + return (Map)getValue(PARAMS); } private void setParams(Map params) { @@ -145,7 +145,7 @@ public Set getParamNames() { @SuppressWarnings("unchecked") private Map getHeaders() { - return (Map)getValue(HEADERS); + return (Map)getValue(HEADERS); } private void setHeaders(Map headers) { diff --git a/jpsxdec/src-lgpl/org/jdesktop/swingx/plaf/basic/core/LazyActionMap.java b/jpsxdec/src-lgpl/org/jdesktop/swingx/plaf/basic/core/LazyActionMap.java index a9f5393..3101db3 100644 --- a/jpsxdec/src-lgpl/org/jdesktop/swingx/plaf/basic/core/LazyActionMap.java +++ b/jpsxdec/src-lgpl/org/jdesktop/swingx/plaf/basic/core/LazyActionMap.java @@ -22,7 +22,6 @@ package org.jdesktop.swingx.plaf.basic.core; -import java.lang.reflect.*; import javax.swing.*; import javax.swing.plaf.*; @@ -35,131 +34,9 @@ * @author Scott Violet */ public class LazyActionMap extends ActionMapUIResource { - /** - * Object to invoke loadActionMap on. This may be - * a Class object. - */ - private transient Object _loader; - - /** - * Installs an ActionMap that will be populated by invoking the - * loadActionMap method on the specified Class - * when necessary. - *

- * This should be used if the ActionMap can be shared. - * - * @param c JComponent to install the ActionMap on. - * @param loaderClass Class object that gets loadActionMap invoked - * on. - * @param defaultsKey Key to use to defaults table to check for - * existing map and what resulting Map will be registered on. - */ - public static void installLazyActionMap(JComponent c, Class loaderClass, - String defaultsKey) { - ActionMap map = (ActionMap)UIManager.get(defaultsKey); - if (map == null) { - map = new LazyActionMap(loaderClass); - UIManager.getLookAndFeelDefaults().put(defaultsKey, map); - } - SwingUtilities.replaceUIActionMap(c, map); - } - - /** - * Returns an ActionMap that will be populated by invoking the - * loadActionMap method on the specified Class - * when necessary. - *

- * This should be used if the ActionMap can be shared. - * - * @param c JComponent to install the ActionMap on. - * @param loaderClass Class object that gets loadActionMap invoked - * on. - * @param defaultsKey Key to use to defaults table to check for - * existing map and what resulting Map will be registered on. - */ - static ActionMap getActionMap(Class loaderClass, - String defaultsKey) { - ActionMap map = (ActionMap)UIManager.get(defaultsKey); - if (map == null) { - map = new LazyActionMap(loaderClass); - UIManager.getLookAndFeelDefaults().put(defaultsKey, map); - } - return map; - } - - - private LazyActionMap(Class loader) { - _loader = loader; - } public void put(Action action) { put(action.getValue(Action.NAME), action); } - public void put(Object key, Action action) { - loadIfNecessary(); - super.put(key, action); - } - - public Action get(Object key) { - loadIfNecessary(); - return super.get(key); - } - - public void remove(Object key) { - loadIfNecessary(); - super.remove(key); - } - - public void clear() { - loadIfNecessary(); - super.clear(); - } - - public Object[] keys() { - loadIfNecessary(); - return super.keys(); - } - - public int size() { - loadIfNecessary(); - return super.size(); - } - - public Object[] allKeys() { - loadIfNecessary(); - return super.allKeys(); - } - - public void setParent(ActionMap map) { - loadIfNecessary(); - super.setParent(map); - } - - @SuppressWarnings("unchecked") - private void loadIfNecessary() { - if (_loader != null) { - Object loader = _loader; - - _loader = null; - Class klass = (Class)loader; - try { - Method method = klass.getDeclaredMethod("loadActionMap", - new Class[] { LazyActionMap.class }); - method.invoke(klass, new Object[] { this }); - } catch (NoSuchMethodException nsme) { - assert false : "LazyActionMap unable to load actions " + - klass; - } catch (IllegalAccessException iae) { - assert false : "LazyActionMap unable to load actions " + - iae; - } catch (InvocationTargetException ite) { - assert false : "LazyActionMap unable to load actions " + - ite; - } catch (IllegalArgumentException iae) { - assert false : "LazyActionMap unable to load actions " + - iae; - } - } - } } diff --git a/jpsxdec/src-lgpl/org/jdesktop/swingx/renderer/JRendererCheckBox.java b/jpsxdec/src-lgpl/org/jdesktop/swingx/renderer/JRendererCheckBox.java index 866776c..dadb0be 100644 --- a/jpsxdec/src-lgpl/org/jdesktop/swingx/renderer/JRendererCheckBox.java +++ b/jpsxdec/src-lgpl/org/jdesktop/swingx/renderer/JRendererCheckBox.java @@ -53,7 +53,7 @@ public Painter getPainter() { * {@inheritDoc} */ public void setPainter(Painter painter) { - Painter old = getPainter(); + Painter old = getPainter(); this.painter = painter; if (painter != null) { // ui maps to !opaque diff --git a/jpsxdec/src-lgpl/org/jdesktop/swingx/renderer/JRendererLabel.java b/jpsxdec/src-lgpl/org/jdesktop/swingx/renderer/JRendererLabel.java index 3affd74..1bad991 100644 --- a/jpsxdec/src-lgpl/org/jdesktop/swingx/renderer/JRendererLabel.java +++ b/jpsxdec/src-lgpl/org/jdesktop/swingx/renderer/JRendererLabel.java @@ -101,7 +101,7 @@ public boolean isOpaque() { * {@inheritDoc} */ public void setPainter(Painter painter) { - Painter old = getPainter(); + Painter old = getPainter(); this.painter = painter; firePropertyChange("painter", old, getPainter()); } diff --git a/jpsxdec/src-lgpl/org/jdesktop/swingx/text/StrictNumberFormatter.java b/jpsxdec/src-lgpl/org/jdesktop/swingx/text/StrictNumberFormatter.java index 2866f02..e31d390 100644 --- a/jpsxdec/src-lgpl/org/jdesktop/swingx/text/StrictNumberFormatter.java +++ b/jpsxdec/src-lgpl/org/jdesktop/swingx/text/StrictNumberFormatter.java @@ -64,7 +64,7 @@ public void setValueClass(Class valueClass) { /** * */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({ "rawtypes" }) private void updateMinMax() { Comparable min = null; Comparable max = null; @@ -93,14 +93,14 @@ private void updateMinMax() { } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({ "rawtypes" }) @Override public void setMaximum(Comparable max) { super.setMaximum(max); this.maxAsBig = max != null ? new BigDecimal(max.toString()) : null; } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({ "rawtypes" }) @Override public void setMinimum(Comparable minimum) { super.setMinimum(minimum); @@ -140,22 +140,22 @@ public Object stringToValue(String text) throws ParseException { private Object convertValueToValueClass(Object value, Class valueClass) { if (valueClass != null && (value instanceof Number)) { if (valueClass == Integer.class) { - return new Integer(((Number)value).intValue()); + return Integer.valueOf(((Number)value).intValue()); } else if (valueClass == Long.class) { - return new Long(((Number)value).longValue()); + return Long.valueOf(((Number)value).longValue()); } else if (valueClass == Float.class) { - return new Float(((Number)value).floatValue()); + return Float.valueOf(((Number)value).floatValue()); } else if (valueClass == Double.class) { - return new Double(((Number)value).doubleValue()); + return Double.valueOf(((Number)value).doubleValue()); } else if (valueClass == Byte.class) { - return new Byte(((Number)value).byteValue()); + return Byte.valueOf(((Number)value).byteValue()); } else if (valueClass == Short.class) { - return new Short(((Number)value).shortValue()); + return Short.valueOf(((Number)value).shortValue()); } } return value; diff --git a/jpsxdec/src-lgpl/org/jdesktop/swingx/util/Utilities.java b/jpsxdec/src-lgpl/org/jdesktop/swingx/util/Utilities.java index f0b31d7..026c945 100644 --- a/jpsxdec/src-lgpl/org/jdesktop/swingx/util/Utilities.java +++ b/jpsxdec/src-lgpl/org/jdesktop/swingx/util/Utilities.java @@ -134,7 +134,7 @@ private Utilities() { /** reference to map that maps allowed key names to their values (String, Integer) and reference to map for mapping of values to their names */ - private static Reference namesAndValues; + private static Reference namesAndValues; /** Get the operating system on which NetBeans is running. * @return one of the OS_* constants (such as {@link #OS_WINNT}) @@ -315,7 +315,7 @@ public static Rectangle getUsableScreenBounds(GraphicsConfiguration gconf) { */ private static synchronized HashMap[] initNameAndValues() { if (namesAndValues != null) { - HashMap[] arr = (HashMap[]) namesAndValues.get(); + HashMap[] arr = namesAndValues.get(); if (arr != null) { return arr; @@ -347,7 +347,7 @@ private static synchronized HashMap[] initNameAndValues() { try { int numb = fields[i].getInt(null); - Integer value = new Integer(numb); + Integer value = Integer.valueOf(numb); names.put(name, value); values.put(value, name); } catch (IllegalArgumentException ex) { @@ -359,18 +359,18 @@ private static synchronized HashMap[] initNameAndValues() { if (names.get("CONTEXT_MENU") == null) { // NOI18N - Integer n = new Integer(0x20C); + Integer n = Integer.valueOf(0x20C); names.put("CONTEXT_MENU", n); // NOI18N values.put(n, "CONTEXT_MENU"); // NOI18N - n = new Integer(0x20D); + n = Integer.valueOf(0x20D); names.put("WINDOWS", n); // NOI18N values.put(n, "WINDOWS"); // NOI18N } HashMap[] arr = { names, values }; - namesAndValues = new SoftReference(arr); + namesAndValues = new SoftReference(arr); return arr; } @@ -390,7 +390,7 @@ public static String keyToString(KeyStroke stroke) { HashMap[] namesAndValues = initNameAndValues(); - String c = (String) namesAndValues[1].get(new Integer(stroke.getKeyCode())); + String c = (String) namesAndValues[1].get(Integer.valueOf(stroke.getKeyCode())); if (c == null) { sb.append(stroke.getKeyChar()); diff --git a/jpsxdec/src/com/jhlabs/awt/ParagraphLayout.java b/jpsxdec/src/com/jhlabs/awt/ParagraphLayout.java index fc16f3c..4e0b764 100644 --- a/jpsxdec/src/com/jhlabs/awt/ParagraphLayout.java +++ b/jpsxdec/src/com/jhlabs/awt/ParagraphLayout.java @@ -27,15 +27,15 @@ public class ParagraphLayout extends ConstraintLayout { public final static int NEW_PARAGRAPH_TOP_VALUE = 2; public final static int NEW_LINE_VALUE = 3; - public final static Integer NEW_PARAGRAPH = new Integer(0x01); - public final static Integer NEW_PARAGRAPH_TOP = new Integer(0x02); - public final static Integer NEW_LINE = new Integer(0x03); - public final static Integer STRETCH_H = new Integer(0x04); - public final static Integer STRETCH_V = new Integer(0x08); - public final static Integer STRETCH_HV = new Integer(0x0c); - public final static Integer NEW_LINE_STRETCH_H = new Integer(0x07); - public final static Integer NEW_LINE_STRETCH_V = new Integer(0x0b); - public final static Integer NEW_LINE_STRETCH_HV = new Integer(0x0f); + public final static Integer NEW_PARAGRAPH = Integer.valueOf(0x01); + public final static Integer NEW_PARAGRAPH_TOP = Integer.valueOf(0x02); + public final static Integer NEW_LINE = Integer.valueOf(0x03); + public final static Integer STRETCH_H = Integer.valueOf(0x04); + public final static Integer STRETCH_V = Integer.valueOf(0x08); + public final static Integer STRETCH_HV = Integer.valueOf(0x0c); + public final static Integer NEW_LINE_STRETCH_H = Integer.valueOf(0x07); + public final static Integer NEW_LINE_STRETCH_V = Integer.valueOf(0x0b); + public final static Integer NEW_LINE_STRETCH_HV = Integer.valueOf(0x0f); protected int hGapMajor, vGapMajor; protected int hGapMinor, vGapMinor; diff --git a/jpsxdec/src/com/l2fprod/common/swing/PercentLayout.java b/jpsxdec/src/com/l2fprod/common/swing/PercentLayout.java index ca5a7eb..4bd50e8 100644 --- a/jpsxdec/src/com/l2fprod/common/swing/PercentLayout.java +++ b/jpsxdec/src/com/l2fprod/common/swing/PercentLayout.java @@ -68,7 +68,7 @@ private Constraint(Object value) { static class NumberConstraint extends Constraint { public NumberConstraint(int d) { - this(new Integer(d)); + this(Integer.valueOf(d)); } public NumberConstraint(Integer d) { super(d); @@ -340,7 +340,7 @@ public void layoutContainer(Container parent) { Constraint constraint = (Constraint)m_ComponentToConstraint.get(components[i]); if (constraint == REMAINING_SPACE) { - remaining.add(new Integer(i)); + remaining.add(Integer.valueOf(i)); sizes[i] = 0; } } diff --git a/jpsxdec/src/com/l2fprod/common/swing/PercentLayoutAnimator.java b/jpsxdec/src/com/l2fprod/common/swing/PercentLayoutAnimator.java index 9f27116..7f5a630 100644 --- a/jpsxdec/src/com/l2fprod/common/swing/PercentLayoutAnimator.java +++ b/jpsxdec/src/com/l2fprod/common/swing/PercentLayoutAnimator.java @@ -70,8 +70,8 @@ protected void complete() { public void actionPerformed(ActionEvent e) { boolean allCompleted = true; - for (Iterator iter = tasks.iterator(); iter.hasNext();) { - PercentTask element = (PercentTask)iter.next(); + for (Iterator iter = tasks.iterator(); iter.hasNext();) { + PercentTask element = iter.next(); if (!element.isCompleted()) { allCompleted = false; element.execute(); diff --git a/jpsxdec/src/com/l2fprod/common/swing/plaf/AbstractComponentAddon.java b/jpsxdec/src/com/l2fprod/common/swing/plaf/AbstractComponentAddon.java index 71f6cfa..f39999f 100644 --- a/jpsxdec/src/com/l2fprod/common/swing/plaf/AbstractComponentAddon.java +++ b/jpsxdec/src/com/l2fprod/common/swing/plaf/AbstractComponentAddon.java @@ -144,8 +144,8 @@ private Object[] getDefaults(LookAndFeelAddons addon) { */ protected void addResource(List defaults, String bundleName) { ResourceBundle bundle = ResourceBundle.getBundle(bundleName); - for (Enumeration keys = bundle.getKeys(); keys.hasMoreElements(); ) { - String key = (String)keys.nextElement(); + for (Enumeration keys = bundle.getKeys(); keys.hasMoreElements(); ) { + String key = keys.nextElement(); defaults.add(key); defaults.add(bundle.getObject(key)); } diff --git a/jpsxdec/src/com/l2fprod/common/swing/plaf/LookAndFeelAddons.java b/jpsxdec/src/com/l2fprod/common/swing/plaf/LookAndFeelAddons.java index 4bac639..c062b33 100644 --- a/jpsxdec/src/com/l2fprod/common/swing/plaf/LookAndFeelAddons.java +++ b/jpsxdec/src/com/l2fprod/common/swing/plaf/LookAndFeelAddons.java @@ -82,11 +82,7 @@ public class LookAndFeelAddons { try { setAddon(addonClassname); setTrackingLookAndFeelChanges(true); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -94,15 +90,15 @@ public class LookAndFeelAddons { private static LookAndFeelAddons currentAddon; public void initialize() { - for (Iterator iter = contributedComponents.iterator(); iter.hasNext();) { - ComponentAddon addon = (ComponentAddon)iter.next(); + for (Iterator iter = contributedComponents.iterator(); iter.hasNext();) { + ComponentAddon addon = iter.next(); addon.initialize(this); } } public void uninitialize() { - for (Iterator iter = contributedComponents.iterator(); iter.hasNext();) { - ComponentAddon addon = (ComponentAddon)iter.next(); + for (Iterator iter = contributedComponents.iterator(); iter.hasNext();) { + ComponentAddon addon = iter.next(); addon.uninitialize(this); } } @@ -136,14 +132,13 @@ public void unloadDefaults(Object[] keysAndValues) { } public static void setAddon(String addonClassName) - throws InstantiationException, IllegalAccessException, - ClassNotFoundException { + throws Exception { setAddon(Class.forName(addonClassName)); } - public static void setAddon(Class addonClass) throws InstantiationException, - IllegalAccessException { - LookAndFeelAddons addon = (LookAndFeelAddons)addonClass.newInstance(); + public static void setAddon(Class addonClass) throws InstantiationException, + Exception { + LookAndFeelAddons addon = (LookAndFeelAddons)addonClass.getDeclaredConstructor().newInstance(); setAddon(addon); } @@ -261,7 +256,7 @@ public static ComponentUI getUI(JComponent component, Class expectedUIClass) { // solve issue with ClassLoader not able to find classes String uiClassname = (String)UIManager.get(component.getUIClassID()); try { - Class uiClass = Class.forName(uiClassname); + Class uiClass = Class.forName(uiClassname); UIManager.put(uiClassname, uiClass); } catch (Exception e) { // we ignore the ClassNotFoundException diff --git a/jpsxdec/src/com/l2fprod/common/swing/plaf/windows/WindowsDirectoryChooserUI.java b/jpsxdec/src/com/l2fprod/common/swing/plaf/windows/WindowsDirectoryChooserUI.java index 4348202..1ea0423 100644 --- a/jpsxdec/src/com/l2fprod/common/swing/plaf/windows/WindowsDirectoryChooserUI.java +++ b/jpsxdec/src/com/l2fprod/common/swing/plaf/windows/WindowsDirectoryChooserUI.java @@ -504,9 +504,10 @@ public void treeExpanded(TreeExpansionEvent event) { } } + @SuppressWarnings("unchecked") private void enqueueChildren(FileTreeNode node) { - for (Enumeration e = node.children(); e.hasMoreElements();) { - addToQueue((FileTreeNode)e.nextElement(), tree); + for (Enumeration e = node.children(); e.hasMoreElements();) { + addToQueue(e.nextElement(), tree); } } @@ -607,7 +608,7 @@ public String toString() { } } - private class FileTreeNode extends LazyMutableTreeNode implements Comparable { + private class FileTreeNode extends LazyMutableTreeNode implements Comparable { public FileTreeNode(File file) { super(file); diff --git a/jpsxdec/src/jpsxdec/Main.java b/jpsxdec/src/jpsxdec/Main.java index 2d89a95..bd7b66a 100644 --- a/jpsxdec/src/jpsxdec/Main.java +++ b/jpsxdec/src/jpsxdec/Main.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -90,7 +90,7 @@ public static void loadDefaultLogger() { loadLoggerConfigResource(Main.class, "LogToFile.properties"); } - public static void loadLoggerConfigResource(@Nonnull Class referenceClass, + public static void loadLoggerConfigResource(@Nonnull Class referenceClass, @Nonnull String sLogFileResource) { InputStream is = referenceClass.getResourceAsStream(sLogFileResource); diff --git a/jpsxdec/src/jpsxdec/Version.java b/jpsxdec/src/jpsxdec/Version.java index afabccd..0fe1e6c 100644 --- a/jpsxdec/src/jpsxdec/Version.java +++ b/jpsxdec/src/jpsxdec/Version.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -39,7 +39,7 @@ public class Version { - public final static String Version = "1.03 (beta)"; + public final static String Version = "1.04 (beta)"; public final static String IndexHeader = "[jPSXdec v"+Version+"]"; } diff --git a/jpsxdec/src/jpsxdec/adpcm/AdpcmContext.java b/jpsxdec/src/jpsxdec/adpcm/AdpcmContext.java index f9a8114..7c8fd50 100644 --- a/jpsxdec/src/jpsxdec/adpcm/AdpcmContext.java +++ b/jpsxdec/src/jpsxdec/adpcm/AdpcmContext.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/AudioShortReader.java b/jpsxdec/src/jpsxdec/adpcm/AudioShortReader.java index 8e5e09e..460486c 100644 --- a/jpsxdec/src/jpsxdec/adpcm/AudioShortReader.java +++ b/jpsxdec/src/jpsxdec/adpcm/AudioShortReader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/IAdpcmSoundUnit.java b/jpsxdec/src/jpsxdec/adpcm/IAdpcmSoundUnit.java index eb4c422..705e7d5 100644 --- a/jpsxdec/src/jpsxdec/adpcm/IAdpcmSoundUnit.java +++ b/jpsxdec/src/jpsxdec/adpcm/IAdpcmSoundUnit.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/IContextCopier.java b/jpsxdec/src/jpsxdec/adpcm/IContextCopier.java index ae70175..1b47434 100644 --- a/jpsxdec/src/jpsxdec/adpcm/IContextCopier.java +++ b/jpsxdec/src/jpsxdec/adpcm/IContextCopier.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/K0K1Filter.java b/jpsxdec/src/jpsxdec/adpcm/K0K1Filter.java index 7c9723d..0805ccc 100644 --- a/jpsxdec/src/jpsxdec/adpcm/K0K1Filter.java +++ b/jpsxdec/src/jpsxdec/adpcm/K0K1Filter.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/PSoundPpl.java b/jpsxdec/src/jpsxdec/adpcm/PSoundPpl.java index f0bf544..c22a71a 100644 --- a/jpsxdec/src/jpsxdec/adpcm/PSoundPpl.java +++ b/jpsxdec/src/jpsxdec/adpcm/PSoundPpl.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/SoundUnitDecoder.java b/jpsxdec/src/jpsxdec/adpcm/SoundUnitDecoder.java index 3cb53a0..5805c2c 100644 --- a/jpsxdec/src/jpsxdec/adpcm/SoundUnitDecoder.java +++ b/jpsxdec/src/jpsxdec/adpcm/SoundUnitDecoder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/SoundUnitEncoder.java b/jpsxdec/src/jpsxdec/adpcm/SoundUnitEncoder.java index 2bce70a..90d5a40 100644 --- a/jpsxdec/src/jpsxdec/adpcm/SoundUnitEncoder.java +++ b/jpsxdec/src/jpsxdec/adpcm/SoundUnitEncoder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmDecoder.java b/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmDecoder.java index 5473b0c..0c4bc11 100644 --- a/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmDecoder.java +++ b/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmDecoder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmEncoder.java b/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmEncoder.java index 0e8f25b..bb448e2 100644 --- a/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmEncoder.java +++ b/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmEncoder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmSoundUnit.java b/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmSoundUnit.java index cb4c5b7..e601863 100644 --- a/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmSoundUnit.java +++ b/jpsxdec/src/jpsxdec/adpcm/SpuAdpcmSoundUnit.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/VagWriter.java b/jpsxdec/src/jpsxdec/adpcm/VagWriter.java index efd796b..0df4c5c 100644 --- a/jpsxdec/src/jpsxdec/adpcm/VagWriter.java +++ b/jpsxdec/src/jpsxdec/adpcm/VagWriter.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/XaAdpcmDecoder.java b/jpsxdec/src/jpsxdec/adpcm/XaAdpcmDecoder.java index ad9f63e..aafa15b 100644 --- a/jpsxdec/src/jpsxdec/adpcm/XaAdpcmDecoder.java +++ b/jpsxdec/src/jpsxdec/adpcm/XaAdpcmDecoder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/XaAdpcmEncoder.java b/jpsxdec/src/jpsxdec/adpcm/XaAdpcmEncoder.java index 18bd915..6109838 100644 --- a/jpsxdec/src/jpsxdec/adpcm/XaAdpcmEncoder.java +++ b/jpsxdec/src/jpsxdec/adpcm/XaAdpcmEncoder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/adpcm/XaAdpcmSoundUnit.java b/jpsxdec/src/jpsxdec/adpcm/XaAdpcmSoundUnit.java index 53b2223..177a808 100644 --- a/jpsxdec/src/jpsxdec/adpcm/XaAdpcmSoundUnit.java +++ b/jpsxdec/src/jpsxdec/adpcm/XaAdpcmSoundUnit.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cdreaders/CdFileSectorReader.java b/jpsxdec/src/jpsxdec/cdreaders/CdFileSectorReader.java index 996d4f9..2b22291 100644 --- a/jpsxdec/src/jpsxdec/cdreaders/CdFileSectorReader.java +++ b/jpsxdec/src/jpsxdec/cdreaders/CdFileSectorReader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -72,6 +72,55 @@ public class CdFileSectorReader implements Closeable { private static final int DEFAULT_SECTOR_BUFFER_COUNT = 16; + public static CdFileSectorReader open(@Nonnull String sDiscImageFileName) + throws CdFileNotFoundException, FileTooSmallToIdentifyException, CdReadException + { + return open(new File(sDiscImageFileName)); + } + + public static CdFileSectorReader open(@Nonnull File discImageFile) + throws CdFileNotFoundException, FileTooSmallToIdentifyException, CdReadException + { + return new CdFileSectorReader(discImageFile); + } + + public static CdFileSectorReader open(@Nonnull File discImageFile, boolean blnAllowWrites) + throws CdFileNotFoundException, FileTooSmallToIdentifyException, CdReadException + { + return new CdFileSectorReader(discImageFile, blnAllowWrites); + } + + public static CdFileSectorReader open(@Nonnull File discImageFile, boolean blnAllowWrites, int iSectorsToBuffer) + throws CdFileNotFoundException, FileTooSmallToIdentifyException, CdReadException + { + return new CdFileSectorReader(discImageFile, blnAllowWrites, iSectorsToBuffer); + } + + public static CdFileSectorReader openWithSectorSize(@Nonnull File discImageFile, int iSectorSize) + throws CdFileNotFoundException, FileTooSmallToIdentifyException, CdReadException + { + return new CdFileSectorReader(discImageFile, iSectorSize); + } + + public static CdFileSectorReader openWithSectorSize(@Nonnull File discImageFile, int iSectorSize, boolean blnAllowWrites, int iSectorsToBuffer) + throws CdFileNotFoundException, FileTooSmallToIdentifyException, CdReadException + { + return new CdFileSectorReader(discImageFile, iSectorSize, blnAllowWrites, iSectorsToBuffer); + } + + public static CdFileSectorReader deserialize(@Nonnull String sSerialization, boolean blnAllowWrites) + throws LocalizedDeserializationFail, CdFileNotFoundException, CdReadException + { + return new CdFileSectorReader(sSerialization, blnAllowWrites); + } + + public static CdFileSectorReader deserialize(@Nonnull String sSerialization, boolean blnAllowWrites, int iSectorsToBuffer) + throws LocalizedDeserializationFail, CdFileNotFoundException, CdReadException + { + return new CdFileSectorReader(sSerialization, blnAllowWrites, iSectorsToBuffer); + } + + /** Exception if a CD file is not found or cannot be opened. */ public static class CdFileNotFoundException extends FileNotFoundException { @@ -159,7 +208,7 @@ public File getFile() { @Nonnull private RandomAccessFile _inputFile; @Nonnull - private final File _sourceFile; + private final File _discImageFile; /** Creates sectors from the data based on the type of disc image it is. */ @Nonnull private final SectorFactory _sectorFactory; @@ -179,32 +228,33 @@ public File getFile() { /* Constructors --------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ - public CdFileSectorReader(@Nonnull File inputFile) + /** Tries to guess the sector size. */ + private CdFileSectorReader(@Nonnull File discImageFile) throws CdFileNotFoundException, FileTooSmallToIdentifyException, CdReadException { - this(inputFile, false, DEFAULT_SECTOR_BUFFER_COUNT); + this(discImageFile, false, DEFAULT_SECTOR_BUFFER_COUNT); } - public CdFileSectorReader(@Nonnull File inputFile, boolean blnAllowWrites) + /** Tries to guess the sector size. */ + private CdFileSectorReader(@Nonnull File discImageFile, boolean blnAllowWrites) throws CdFileNotFoundException, FileTooSmallToIdentifyException, CdReadException { - this(inputFile, blnAllowWrites, DEFAULT_SECTOR_BUFFER_COUNT); + this(discImageFile, blnAllowWrites, DEFAULT_SECTOR_BUFFER_COUNT); } - /** Opens a CD file for reading. Tries to guess the CD size. */ - public CdFileSectorReader(@Nonnull File sourceFile, - boolean blnAllowWrites, int iSectorsToBuffer) + /** Tries to guess the sector size. */ + private CdFileSectorReader(@Nonnull File discImageFile, boolean blnAllowWrites, int iSectorsToBuffer) throws CdFileNotFoundException, FileTooSmallToIdentifyException, CdReadException { - LOG.info(sourceFile.getPath()); + LOG.info(discImageFile.getPath()); - _sourceFile = sourceFile; + _discImageFile = discImageFile; _iSectorsToCache = iSectorsToBuffer; try { - _inputFile = new RandomAccessFile(sourceFile, blnAllowWrites ? "rw" : "r"); + _inputFile = new RandomAccessFile(discImageFile, blnAllowWrites ? "rw" : "r"); } catch (FileNotFoundException ex) { - throw new CdFileNotFoundException(sourceFile, ex); + throw new CdFileNotFoundException(discImageFile, ex); } boolean blnExceptionThrown = true; @@ -236,7 +286,7 @@ public CdFileSectorReader(@Nonnull File sourceFile, } } catch (IOException ex) { - throw new CdReadException(sourceFile, ex); + throw new CdReadException(discImageFile, ex); } _sectorFactory = factory; @@ -252,28 +302,27 @@ public CdFileSectorReader(@Nonnull File sourceFile, _sectorFactory.get1stSectorOffset()); } - public CdFileSectorReader(@Nonnull File inputFile, int iSectorSize) + /** Uses the given sector size. */ + private CdFileSectorReader(@Nonnull File discImageFile, int iSectorSize) throws CdFileNotFoundException, FileTooSmallToIdentifyException, CdReadException { - this(inputFile, iSectorSize, false, DEFAULT_SECTOR_BUFFER_COUNT); + this(discImageFile, iSectorSize, false, DEFAULT_SECTOR_BUFFER_COUNT); } - /** Opens a CD file for reading using the provided sector size. - * @throws FileTooSmallToIdentifyException If the disc image doesn't match the sector size. - */ - public CdFileSectorReader(@Nonnull File sourceFile, - int iSectorSize, boolean blnAllowWrites, int iSectorsToBuffer) + /** Uses the given sector size. */ + private CdFileSectorReader(@Nonnull File discImageFile, int iSectorSize, + boolean blnAllowWrites, int iSectorsToBuffer) throws CdFileNotFoundException, FileTooSmallToIdentifyException, CdReadException { - LOG.info(sourceFile.getPath()); + LOG.info(discImageFile.getPath()); - _sourceFile = sourceFile; + _discImageFile = discImageFile; _iSectorsToCache = iSectorsToBuffer; try { - _inputFile = new RandomAccessFile(sourceFile, blnAllowWrites ? "rw" : "r"); + _inputFile = new RandomAccessFile(discImageFile, blnAllowWrites ? "rw" : "r"); } catch (FileNotFoundException ex) { - throw new CdFileNotFoundException(sourceFile, ex); + throw new CdFileNotFoundException(discImageFile, ex); } boolean blnExceptionThrown = true; @@ -296,7 +345,7 @@ public CdFileSectorReader(@Nonnull File sourceFile, } blnExceptionThrown = false; } catch (IOException ex) { - throw new CdReadException(sourceFile, ex); + throw new CdReadException(discImageFile, ex); } finally { if (blnExceptionThrown) IO.closeSilently(_inputFile, LOG); @@ -309,13 +358,15 @@ public CdFileSectorReader(@Nonnull File sourceFile, _sectorFactory.get1stSectorOffset()); } - public CdFileSectorReader(@Nonnull String sSerialization, boolean blnAllowWrites) + /** Deserializes the CD. */ + private CdFileSectorReader(@Nonnull String sSerialization, boolean blnAllowWrites) throws LocalizedDeserializationFail, CdFileNotFoundException, CdReadException { this(sSerialization, blnAllowWrites, DEFAULT_SECTOR_BUFFER_COUNT); } - public CdFileSectorReader(@Nonnull String sSerialization, boolean blnAllowWrites, int iSectorsToBuffer) + /** Deserializes the CD. */ + private CdFileSectorReader(@Nonnull String sSerialization, boolean blnAllowWrites, int iSectorsToBuffer) throws LocalizedDeserializationFail, CdFileNotFoundException, CdReadException { String[] asValues = Misc.regex(DESERIALIZATION, sSerialization); @@ -347,12 +398,12 @@ public CdFileSectorReader(@Nonnull String sSerialization, boolean blnAllowWrites throw new LocalizedDeserializationFail(I.CD_DESERIALIZE_FAIL(sSerialization), ex); } - _sourceFile = new File(asValues[1]); + _discImageFile = new File(asValues[1]); try { - _inputFile = new RandomAccessFile(_sourceFile, blnAllowWrites ? "rw" : "r"); + _inputFile = new RandomAccessFile(_discImageFile, blnAllowWrites ? "rw" : "r"); } catch (FileNotFoundException ex) { - throw new CdFileNotFoundException(_sourceFile, ex); + throw new CdFileNotFoundException(_discImageFile, ex); } _iSectorsToCache = iSectorsToBuffer; @@ -366,12 +417,29 @@ public CdFileSectorReader(@Nonnull String sSerialization, boolean blnAllowWrites } + /** Fake constructor for testing. + * Ideally we'd use an interface for the CD sector reader which this class + * would implement, then tests could create a fake/mock CD sector reader + * to use for testing. But that ended up being a lot of work for little + * benefit. However, if any other kind of CD sector reader is added, + * then we would want to switch to the interface design. */ + protected CdFileSectorReader(File discImageFile, + RandomAccessFile inputFile, + int iSectorCount) + { + _inputFile = inputFile; + _discImageFile = discImageFile; + _sectorFactory = null; + _iSectorCount = iSectorCount; + } + + private int calculateSectorCount() throws CdReadException { try { return (int)((_inputFile.length() - _sectorFactory.get1stSectorOffset()) / _sectorFactory.getRawSectorSize()); } catch (IOException ex) { - throw new CdReadException(_sourceFile, ex); + throw new CdReadException(_discImageFile, ex); } } @@ -385,7 +453,7 @@ private int calculateSectorCount() throws CdReadException { public @Nonnull String serialize() { return String.format(SERIALIZATION, - _sourceFile.getPath(), + _discImageFile.getPath(), _sectorFactory.getRawSectorSize(), _iSectorCount, _sectorFactory.get1stSectorOffset()); @@ -430,7 +498,7 @@ public boolean hasSectorHeader() { } public @Nonnull File getSourceFile() { - return _sourceFile; + return _discImageFile; } /** Returns the actual offset in bytes from the start of the source file @@ -467,7 +535,7 @@ public int getSectorCount() { if (iBytesRead < _sectorFactory.getRawSectorSize()) throw new RuntimeException("Should have already verified this should not happen"); } catch (IOException ex) { - throw new CdReadException(_sourceFile, ex); + throw new CdReadException(_discImageFile, ex); } // made sure everything is good before we save the cache @@ -501,7 +569,7 @@ void writeSector(int iSector, @Nonnull byte[] abSrcUserData) // clearing the cache could be done here, but it wouldn't // affect anything that has already been read (which is most things) } catch (IOException ex) { - throw new CdWriteException(_sourceFile, ex); + throw new CdWriteException(_discImageFile, ex); } } @@ -555,9 +623,9 @@ public void applyPatches(@Nonnull ProgressLogger pl) void reopenForWriting() throws CdReopenException { try { _inputFile.close(); // expose close exception - _inputFile = new RandomAccessFile(_sourceFile, "rw"); + _inputFile = new RandomAccessFile(_discImageFile, "rw"); } catch (IOException ex) { - throw new CdReopenException(_sourceFile, ex); + throw new CdReopenException(_discImageFile, ex); } } @@ -646,8 +714,8 @@ public Cd2336Factory(@Nonnull RandomAccessFile cdFile) { if (isXaSector(cdFile, lngSectStart, abTestSectorData)) { // we've found an XA audio sector - // maybe try to find another just to be sure? + // now find another just to be sure // only check up to 146 sectors because, if the sector size is actually 2352, // then around 147, the offset difference adds up to another whole 2352 sector // this also avoids loop-around collision with 2448 sector size @@ -678,7 +746,7 @@ private static boolean isXaSector(@Nonnull RandomAccessFile cdFile, cdFile.seek(lngSectorStart); IO.readByteArray(cdFile, abReusableBuffer); CdSector cdSector = new CdSector2336(0, abReusableBuffer, 0, lngSectorStart); - XaAnalysis xa = XaAnalysis.analyze(cdSector, 254); + XaAnalysis xa = XaAnalysis.analyze(cdSector, CdSector.MAX_VALID_CHANNEL); return (xa != null && xa.iProbability == 100); } diff --git a/jpsxdec/src/jpsxdec/cdreaders/CdRiffHeader.java b/jpsxdec/src/jpsxdec/cdreaders/CdRiffHeader.java index 0af3dae..47da0fd 100644 --- a/jpsxdec/src/jpsxdec/cdreaders/CdRiffHeader.java +++ b/jpsxdec/src/jpsxdec/cdreaders/CdRiffHeader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cdreaders/CdSector.java b/jpsxdec/src/jpsxdec/cdreaders/CdSector.java index 55415cd..9b539ed 100644 --- a/jpsxdec/src/jpsxdec/cdreaders/CdSector.java +++ b/jpsxdec/src/jpsxdec/cdreaders/CdSector.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -64,6 +64,16 @@ public abstract class CdSector { /** CD audio sector payload size: 2352. */ public final static int SECTOR_USER_DATA_SIZE_CD_AUDIO = 2352; + /** Maximum channel number (inclusive) that will be considered for + * XA sector. + * My understanding is channel is technically supposed to be + * between 0 and 31. Some games seem to use values outside of that range + * for both valid and null XA audio sectors. + * Ace Combat 3 has several AUDIO sectors with channel 255 + * that seem to be "null" sectors, so all other values will be valid. */ + public static final int MAX_VALID_CHANNEL = 254; + + public enum Type { CD_AUDIO(SECTOR_USER_DATA_SIZE_CD_AUDIO), UNKNOWN2048(SECTOR_USER_DATA_SIZE_MODE1_MODE2FORM1), diff --git a/jpsxdec/src/jpsxdec/cdreaders/CdSector2048.java b/jpsxdec/src/jpsxdec/cdreaders/CdSector2048.java index 0f5cee3..3a70023 100644 --- a/jpsxdec/src/jpsxdec/cdreaders/CdSector2048.java +++ b/jpsxdec/src/jpsxdec/cdreaders/CdSector2048.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cdreaders/CdSector2336.java b/jpsxdec/src/jpsxdec/cdreaders/CdSector2336.java index 6421bb9..56677e7 100644 --- a/jpsxdec/src/jpsxdec/cdreaders/CdSector2336.java +++ b/jpsxdec/src/jpsxdec/cdreaders/CdSector2336.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cdreaders/CdSector2352.java b/jpsxdec/src/jpsxdec/cdreaders/CdSector2352.java index ceaec40..2526fce 100644 --- a/jpsxdec/src/jpsxdec/cdreaders/CdSector2352.java +++ b/jpsxdec/src/jpsxdec/cdreaders/CdSector2352.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cdreaders/CdSectorHeader.java b/jpsxdec/src/jpsxdec/cdreaders/CdSectorHeader.java index ca5da62..9f0b9f4 100644 --- a/jpsxdec/src/jpsxdec/cdreaders/CdSectorHeader.java +++ b/jpsxdec/src/jpsxdec/cdreaders/CdSectorHeader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cdreaders/CdSectorXaSubHeader.java b/jpsxdec/src/jpsxdec/cdreaders/CdSectorXaSubHeader.java index 5e0a5ed..91b9675 100644 --- a/jpsxdec/src/jpsxdec/cdreaders/CdSectorXaSubHeader.java +++ b/jpsxdec/src/jpsxdec/cdreaders/CdSectorXaSubHeader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -279,17 +279,17 @@ public static class SubMode { _iSubmode = i; } - /**'M'*/public static final int MASK_EOF_MARKER = 0x80; + /**'F'*/public static final int MASK_END_OF_FILE = 0x80; /**'R'*/public static final int MASK_REAL_TIME = 0x40; /**'2'*/public static final int MASK_FORM = 0x20; /**'T'*/public static final int MASK_TRIGGER = 0x10; /**'D'*/public static final int MASK_DATA = 0x08; /**'A'*/public static final int MASK_AUDIO = 0x04; /**'V'*/public static final int MASK_VIDEO = 0x02; - /**'E'*/public static final int MASK_END_AUDIO = 1; + /**'E'*/public static final int MASK_END_OF_RECORD = 1; /** bit 7: 0 for all sectors except last sector of a file. */ - public boolean getEofMarker() { return (_iSubmode & 0x80) != 0; } + public boolean getEndOfFile() { return (_iSubmode & 0x80) != 0; } /** bit 6: 1 for real time mode. */ public boolean getRealTime() { return (_iSubmode & 0x40) != 0; } /** bit 5: 1 for Form 1, 2 for Form 2. */ @@ -305,8 +305,8 @@ public static class SubMode { /** bit 1: 1 for video sector. * (should be) Mutually exclusive with bits 3 and 2. */ public boolean getVideo() { return (_iSubmode & 0x02) != 0; } - /** bit 0: identifies end of audio frame */ - public boolean getEndAudio() { return (_iSubmode & 1) != 0; } + /** bit 0: identifies end of record. */ + public boolean getEndOfRecord() { return (_iSubmode & 1) != 0; } /** Returns the submode bits masked against the given value. */ public int mask(int i) { @@ -330,14 +330,14 @@ public boolean isValid() { /** * Return 8 character string representing the 8 bit flags: *
-         * M - EOF marker
-         * R - Real-time
-         * 2 - Form 1/2
-         * T - Trigger
-         * D - Data
-         * A - Audio
-         * V - Video
-         * E - End audio
+         * F - End of file (EOF)
+         * R - Real-time (RT)
+         * 2 - Form 1/2 (F)
+         * T - Trigger (T)
+         * D - Data (D)
+         * A - Audio (A)
+         * V - Video (V)
+         * E - End of record (EOR)
          *
*/ @Override @@ -372,14 +372,14 @@ public String toString() { "-R-T", "-R2-", "-R2T", - "M---", - "M--T", - "M-2-", - "M-2T", - "MR--", - "MR-T", - "MR2-", - "MR2T", + "F---", + "F--T", + "F-2-", + "F-2T", + "FR--", + "FR-T", + "FR2-", + "FR2T", }; } @@ -402,7 +402,7 @@ public static class CodingInfo { /** bits 3,2: 00=37.8kHz (A,B format) * 01=18.9kHz */ - public int getSampleRate() { return (_iCodinginfo & 0x04) == 0 ? 37800 : 18900; } + public int getSamplesPerSecond() { return (_iCodinginfo & 0x04) == 0 ? 37800 : 18900; } /** bits 1,0: 00=mono 01=stereo, * other values reserved */ @@ -426,7 +426,7 @@ public String toString() { sb.append((_iCodinginfo & 2) == 0 ? " " : "! "); sb.append(getBitsPerSample()).append(" bits/sample"); sb.append((_iCodinginfo & 8) == 0 ? " " : "! "); - sb.append(getSampleRate()).append(" samples/sec"); + sb.append(getSamplesPerSecond()).append("Hz"); if ((_iCodinginfo & 32) != 0) sb.append('!'); return sb.toString(); } diff --git a/jpsxdec/src/jpsxdec/cdreaders/DiscPatcher.java b/jpsxdec/src/jpsxdec/cdreaders/DiscPatcher.java index a03f497..89402c2 100644 --- a/jpsxdec/src/jpsxdec/cdreaders/DiscPatcher.java +++ b/jpsxdec/src/jpsxdec/cdreaders/DiscPatcher.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cdreaders/XaAnalysis.java b/jpsxdec/src/jpsxdec/cdreaders/XaAnalysis.java index 40a0ff7..0a9108c 100644 --- a/jpsxdec/src/jpsxdec/cdreaders/XaAnalysis.java +++ b/jpsxdec/src/jpsxdec/cdreaders/XaAnalysis.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -76,14 +76,13 @@ private XaAnalysis(int iSamplesPerSecond, int iBitsPerSample, CdSectorXaSubHeader sh = cdSector.getSubHeader(); if (sh == null) return null; - if (sh.getSubMode().mask(CdSectorXaSubHeader.SubMode.MASK_FORM | CdSectorXaSubHeader.SubMode.MASK_AUDIO) != - (CdSectorXaSubHeader.SubMode.MASK_FORM | CdSectorXaSubHeader.SubMode.MASK_AUDIO)) return null; - // Ace Combat 3 has several sectors with channel 255 - // They seem to be "null" sectors + if (sh.getSubMode().mask(CdSectorXaSubHeader.SubMode.MASK_FORM | CdSectorXaSubHeader.SubMode.MASK_AUDIO | CdSectorXaSubHeader.SubMode.MASK_REAL_TIME) != + (CdSectorXaSubHeader.SubMode.MASK_FORM | CdSectorXaSubHeader.SubMode.MASK_AUDIO | CdSectorXaSubHeader.SubMode.MASK_REAL_TIME)) + return null; if (sh.getChannel() < 0 || sh.getChannel() > iMaxValidChannel) return null; boolean blnStereo = sh.getCodingInfo().isStereo(); - int iSamplesPerSecond = sh.getCodingInfo().getSampleRate(); + int iSamplesPerSecond = sh.getCodingInfo().getSamplesPerSecond(); int iBitsPerSample = sh.getCodingInfo().getBitsPerSample(); // TODO: check Sound Parameters values that the index is valid diff --git a/jpsxdec/src/jpsxdec/cmdline/Command.java b/jpsxdec/src/jpsxdec/cmdline/Command.java index d83dce0..4ce4fb4 100644 --- a/jpsxdec/src/jpsxdec/cmdline/Command.java +++ b/jpsxdec/src/jpsxdec/cmdline/Command.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cmdline/CommandLine.java b/jpsxdec/src/jpsxdec/cmdline/CommandLine.java index 40596b4..9a3588e 100644 --- a/jpsxdec/src/jpsxdec/cmdline/CommandLine.java +++ b/jpsxdec/src/jpsxdec/cmdline/CommandLine.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -189,7 +189,7 @@ private static void createAndSaveIndex(@CheckForNull String sDiscFile, throw new CommandLineException(I.CMD_COMMAND_NEEDS_DISC()); Feedback.println(I.IO_OPENING_FILE(sDiscFile)); try { - CdFileSectorReader cd = new CdFileSectorReader(new File(sDiscFile)); + CdFileSectorReader cd = CdFileSectorReader.open(sDiscFile); Feedback.println(I.CMD_DISC_IDENTIFIED(cd.getTypeDescription())); return cd; } catch (CdFileSectorReader.CdFileNotFoundException ex) { diff --git a/jpsxdec/src/jpsxdec/cmdline/CommandLineException.java b/jpsxdec/src/jpsxdec/cmdline/CommandLineException.java index 2e0d5f1..e49c86b 100644 --- a/jpsxdec/src/jpsxdec/cmdline/CommandLineException.java +++ b/jpsxdec/src/jpsxdec/cmdline/CommandLineException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cmdline/Command_CopySect.java b/jpsxdec/src/jpsxdec/cmdline/Command_CopySect.java index 4531da2..0b62a43 100644 --- a/jpsxdec/src/jpsxdec/cmdline/Command_CopySect.java +++ b/jpsxdec/src/jpsxdec/cmdline/Command_CopySect.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cmdline/Command_Items.java b/jpsxdec/src/jpsxdec/cmdline/Command_Items.java index bff767f..cece820 100644 --- a/jpsxdec/src/jpsxdec/cmdline/Command_Items.java +++ b/jpsxdec/src/jpsxdec/cmdline/Command_Items.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cmdline/Command_SectorDump.java b/jpsxdec/src/jpsxdec/cmdline/Command_SectorDump.java index abc71a9..79ffb51 100644 --- a/jpsxdec/src/jpsxdec/cmdline/Command_SectorDump.java +++ b/jpsxdec/src/jpsxdec/cmdline/Command_SectorDump.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/cmdline/Command_Static.java b/jpsxdec/src/jpsxdec/cmdline/Command_Static.java index 3183777..8ce1aed 100644 --- a/jpsxdec/src/jpsxdec/cmdline/Command_Static.java +++ b/jpsxdec/src/jpsxdec/cmdline/Command_Static.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -164,6 +164,7 @@ public void execute(@Nonnull ArgParser ap) throws CommandLineException { // build pipeline AutowireVDP pipeline = setupPipeline(iWidth, iHeight, outputFormat, sFileBaseName, quality.value, upsample.value, log); + pipeline.setFileListener(fileAndIssueListener); // read input file byte[] abFileData; diff --git a/jpsxdec/src/jpsxdec/cmdline/Command_Visualize.java b/jpsxdec/src/jpsxdec/cmdline/Command_Visualize.java index 1097df2..3bee6df 100644 --- a/jpsxdec/src/jpsxdec/cmdline/Command_Visualize.java +++ b/jpsxdec/src/jpsxdec/cmdline/Command_Visualize.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -185,9 +185,9 @@ public void execute(@Nonnull ArgParser ap) throws CommandLineException { } } - private final HashMap colorLookup = new HashMap(); + private final HashMap, Color> colorLookup = new HashMap, Color>(); - private @Nonnull Color classToColor(@Nonnull Class c) { + private @Nonnull Color classToColor(@Nonnull Class c) { Color color = colorLookup.get(c.getClass()); if (color == null) { int iClr = c.getName().hashCode(); diff --git a/jpsxdec/src/jpsxdec/cmdline/SectorCopy.java b/jpsxdec/src/jpsxdec/cmdline/SectorCopy.java index 2959c68..1d46ce8 100644 --- a/jpsxdec/src/jpsxdec/cmdline/SectorCopy.java +++ b/jpsxdec/src/jpsxdec/cmdline/SectorCopy.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -67,8 +67,8 @@ public static void sectorCopy(@Nonnull String sSource, @Nonnull String sDest, IOException // closing discs { - CdFileSectorReader src = new CdFileSectorReader(new File(sSource)); - CdFileSectorReader dest = new CdFileSectorReader(new File(sDest), true); + CdFileSectorReader src = CdFileSectorReader.open(sSource); + CdFileSectorReader dest = CdFileSectorReader.open(new File(sDest), true); if (src.getSectorCount() > dest.getSectorCount()) throw new IllegalArgumentException("Source file is larger than dest file"); diff --git a/jpsxdec/src/jpsxdec/cmdline/SectorCounter.java b/jpsxdec/src/jpsxdec/cmdline/SectorCounter.java index 025bdf5..b1c36f9 100644 --- a/jpsxdec/src/jpsxdec/cmdline/SectorCounter.java +++ b/jpsxdec/src/jpsxdec/cmdline/SectorCounter.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/discitems/CombinedBuilderListener.java b/jpsxdec/src/jpsxdec/discitems/CombinedBuilderListener.java index d4a1830..e08e7f7 100644 --- a/jpsxdec/src/jpsxdec/discitems/CombinedBuilderListener.java +++ b/jpsxdec/src/jpsxdec/discitems/CombinedBuilderListener.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -51,7 +51,7 @@ public class CombinedBuilderListener { private final ArrayList _controlsListening = new ArrayList(); /** Class of {@link DiscItemSaverBuilder} that will be accepted. */ @Nonnull - private final Class _cls; + private final Class _cls; /** Current {@link DiscItemSaverBuilder} that is being listened to. */ @Nonnull private T _saverBuilder; diff --git a/jpsxdec/src/jpsxdec/discitems/DemuxedSectorInputStream.java b/jpsxdec/src/jpsxdec/discitems/DemuxedSectorInputStream.java index 27ace04..78a6d33 100644 --- a/jpsxdec/src/jpsxdec/discitems/DemuxedSectorInputStream.java +++ b/jpsxdec/src/jpsxdec/discitems/DemuxedSectorInputStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/discitems/DiscItem.java b/jpsxdec/src/jpsxdec/discitems/DiscItem.java index a741539..c0c084d 100644 --- a/jpsxdec/src/jpsxdec/discitems/DiscItem.java +++ b/jpsxdec/src/jpsxdec/discitems/DiscItem.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/discitems/DiscItemSaverBuilder.java b/jpsxdec/src/jpsxdec/discitems/DiscItemSaverBuilder.java index 3d7d4bd..44e1c7c 100644 --- a/jpsxdec/src/jpsxdec/discitems/DiscItemSaverBuilder.java +++ b/jpsxdec/src/jpsxdec/discitems/DiscItemSaverBuilder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/discitems/DiscItemSaverBuilderGui.java b/jpsxdec/src/jpsxdec/discitems/DiscItemSaverBuilderGui.java index f2390f5..2111e24 100644 --- a/jpsxdec/src/jpsxdec/discitems/DiscItemSaverBuilderGui.java +++ b/jpsxdec/src/jpsxdec/discitems/DiscItemSaverBuilderGui.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/discitems/IndexId.java b/jpsxdec/src/jpsxdec/discitems/IndexId.java index f747b5a..bf7b2ba 100644 --- a/jpsxdec/src/jpsxdec/discitems/IndexId.java +++ b/jpsxdec/src/jpsxdec/discitems/IndexId.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/discitems/ParagraphPanel.java b/jpsxdec/src/jpsxdec/discitems/ParagraphPanel.java index 067ed95..2804764 100644 --- a/jpsxdec/src/jpsxdec/discitems/ParagraphPanel.java +++ b/jpsxdec/src/jpsxdec/discitems/ParagraphPanel.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/discitems/SerializedDiscItem.java b/jpsxdec/src/jpsxdec/discitems/SerializedDiscItem.java index 1318515..2f30bc9 100644 --- a/jpsxdec/src/jpsxdec/discitems/SerializedDiscItem.java +++ b/jpsxdec/src/jpsxdec/discitems/SerializedDiscItem.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/formats/JavaAudioFormat.java b/jpsxdec/src/jpsxdec/formats/JavaAudioFormat.java index 0c4e78b..e6f9097 100644 --- a/jpsxdec/src/jpsxdec/formats/JavaAudioFormat.java +++ b/jpsxdec/src/jpsxdec/formats/JavaAudioFormat.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/formats/JavaImageFormat.java b/jpsxdec/src/jpsxdec/formats/JavaImageFormat.java index 18800b8..cd6ddf4 100644 --- a/jpsxdec/src/jpsxdec/formats/JavaImageFormat.java +++ b/jpsxdec/src/jpsxdec/formats/JavaImageFormat.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -45,18 +45,26 @@ /** Keeps track of Java framework's image formats. */ public enum JavaImageFormat { - PNG("png", true, true), - BMP("bmp", true, false), // Java doesn't support bmp with alpha channel - GIF("gif", false, false); + PNG("png", "png", "png", true, true), + BMP("bmp", "bmp", "bmp", true, false), // Java doesn't support bmp with alpha channel + GIF("gif", "gif", "gif", false, false), + TIFF("tiff", "tif", "tif", true, false); + @Nonnull + private final String _sUiId; + @Nonnull + private final String _sImageIOid; @Nonnull private final String _sExtension; private final boolean _blnTrueColor; private final boolean _blnAlpha; private final boolean _blnAvailable; - JavaImageFormat(@Nonnull String id, boolean blnTrueColor, boolean blnAlpha) { - _sExtension = id; + JavaImageFormat(@Nonnull String sUiId, @Nonnull String sImageIOid, @Nonnull String sExtension, boolean blnTrueColor, boolean blnAlpha) { + _sUiId = sUiId; + _sImageIOid = sImageIOid; + _sExtension = sExtension; + _blnTrueColor = blnTrueColor; _blnAlpha = blnAlpha; @@ -64,7 +72,7 @@ public enum JavaImageFormat { boolean blnAvailable = false; for (String s : asValues) { - if (s.equalsIgnoreCase(id)) { + if (s.equalsIgnoreCase(_sImageIOid)) { blnAvailable = true; break; } @@ -72,10 +80,14 @@ public enum JavaImageFormat { _blnAvailable = blnAvailable; } + public @Nonnull String getUiId() { + return _sUiId; + } + /** Unique id identifying this image format. * Also the id used for ImageIO operations. */ - public @Nonnull String getId() { - return _sExtension; + public @Nonnull String getImageIOid() { + return _sImageIOid; } public @Nonnull String getExtension() { @@ -96,7 +108,7 @@ public boolean hasAlpha() { @Override public String toString() { - return _sExtension; + return _sUiId; } public static @Nonnull List getAvailable() { diff --git a/jpsxdec/src/jpsxdec/formats/RGB.java b/jpsxdec/src/jpsxdec/formats/RGB.java index f2ac3b5..677d672 100644 --- a/jpsxdec/src/jpsxdec/formats/RGB.java +++ b/jpsxdec/src/jpsxdec/formats/RGB.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/formats/Rec601YCbCr.java b/jpsxdec/src/jpsxdec/formats/Rec601YCbCr.java index ab3b051..bebabca 100644 --- a/jpsxdec/src/jpsxdec/formats/Rec601YCbCr.java +++ b/jpsxdec/src/jpsxdec/formats/Rec601YCbCr.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/formats/RgbIntImage.java b/jpsxdec/src/jpsxdec/formats/RgbIntImage.java index efa697c..cac7a75 100644 --- a/jpsxdec/src/jpsxdec/formats/RgbIntImage.java +++ b/jpsxdec/src/jpsxdec/formats/RgbIntImage.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/formats/YCbCrImage.java b/jpsxdec/src/jpsxdec/formats/YCbCrImage.java index 55d64a0..76f2b12 100644 --- a/jpsxdec/src/jpsxdec/formats/YCbCrImage.java +++ b/jpsxdec/src/jpsxdec/formats/YCbCrImage.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/gui/BetterFileChooser.java b/jpsxdec/src/jpsxdec/gui/BetterFileChooser.java index e0e2e36..da5895b 100644 --- a/jpsxdec/src/jpsxdec/gui/BetterFileChooser.java +++ b/jpsxdec/src/jpsxdec/gui/BetterFileChooser.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/gui/Gui.java b/jpsxdec/src/jpsxdec/gui/Gui.java index 421e59c..265eb36 100644 --- a/jpsxdec/src/jpsxdec/gui/Gui.java +++ b/jpsxdec/src/jpsxdec/gui/Gui.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -375,7 +375,7 @@ private void openDisc(@Nonnull File file) { _settings.setImageDir(dir.getAbsolutePath()); try { - CdFileSectorReader cd = new CdFileSectorReader(file); + CdFileSectorReader cd = CdFileSectorReader.open(file); if (!cd.hasSectorHeader()) JOptionPane.showMessageDialog(this, I.GUI_DISC_NO_RAW_HEADERS_WARNING()); diff --git a/jpsxdec/src/jpsxdec/gui/GuiFileFilters.java b/jpsxdec/src/jpsxdec/gui/GuiFileFilters.java index 9d09430..143769f 100644 --- a/jpsxdec/src/jpsxdec/gui/GuiFileFilters.java +++ b/jpsxdec/src/jpsxdec/gui/GuiFileFilters.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/gui/GuiSettings.java b/jpsxdec/src/jpsxdec/gui/GuiSettings.java index 4b508c5..145da66 100644 --- a/jpsxdec/src/jpsxdec/gui/GuiSettings.java +++ b/jpsxdec/src/jpsxdec/gui/GuiSettings.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/gui/GuiTree.java b/jpsxdec/src/jpsxdec/gui/GuiTree.java index b0be0ed..bbc6461 100644 --- a/jpsxdec/src/jpsxdec/gui/GuiTree.java +++ b/jpsxdec/src/jpsxdec/gui/GuiTree.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -199,10 +199,10 @@ String val(TreeItem item) { }; @Nonnull - private final Class _type; + private final Class _type; @Nonnull private final ILocalizedMessage _str; - private COLUMNS(@Nonnull Class type, @Nonnull ILocalizedMessage str) { + private COLUMNS(@Nonnull Class type, @Nonnull ILocalizedMessage str) { _type = type; _str = str; } diff --git a/jpsxdec/src/jpsxdec/gui/IndexingGui.java b/jpsxdec/src/jpsxdec/gui/IndexingGui.java index 2211ebb..49c36b1 100644 --- a/jpsxdec/src/jpsxdec/gui/IndexingGui.java +++ b/jpsxdec/src/jpsxdec/gui/IndexingGui.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/gui/SavingGui.java b/jpsxdec/src/jpsxdec/gui/SavingGui.java index af57975..92de152 100644 --- a/jpsxdec/src/jpsxdec/gui/SavingGui.java +++ b/jpsxdec/src/jpsxdec/gui/SavingGui.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/gui/SavingGuiTable.java b/jpsxdec/src/jpsxdec/gui/SavingGuiTable.java index 5da0220..0791eee 100644 --- a/jpsxdec/src/jpsxdec/gui/SavingGuiTable.java +++ b/jpsxdec/src/jpsxdec/gui/SavingGuiTable.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -80,10 +80,10 @@ private static enum COLUMNS { }; @Nonnull - private final Class _type; + private final Class _type; @Nonnull private final ILocalizedMessage _name; - COLUMNS(@Nonnull Class type, @Nonnull ILocalizedMessage name) { + COLUMNS(@Nonnull Class type, @Nonnull ILocalizedMessage name) { _type = type; _name = name; } diff --git a/jpsxdec/src/jpsxdec/gui/SavingGuiTask.java b/jpsxdec/src/jpsxdec/gui/SavingGuiTask.java index 707044c..94ddd79 100644 --- a/jpsxdec/src/jpsxdec/gui/SavingGuiTask.java +++ b/jpsxdec/src/jpsxdec/gui/SavingGuiTask.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/Bundle.java b/jpsxdec/src/jpsxdec/i18n/Bundle.java index 82517c1..07ea1c4 100644 --- a/jpsxdec/src/jpsxdec/i18n/Bundle.java +++ b/jpsxdec/src/jpsxdec/i18n/Bundle.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/FeedbackStream.java b/jpsxdec/src/jpsxdec/i18n/FeedbackStream.java index a6070ef..4bc40d2 100644 --- a/jpsxdec/src/jpsxdec/i18n/FeedbackStream.java +++ b/jpsxdec/src/jpsxdec/i18n/FeedbackStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/I.java b/jpsxdec/src/jpsxdec/i18n/I.java index cb4ca90..3198b63 100644 --- a/jpsxdec/src/jpsxdec/i18n/I.java +++ b/jpsxdec/src/jpsxdec/i18n/I.java @@ -2619,7 +2619,7 @@
partial header (2336 bytes/sector) format
*/ public static @Nonnull ILocalizedMessage CMD_VOLUME_PERCENT(double volumeLevelPercent) { - return msg("CMD_VOLUME_PERCENT", "Volume: {0,number,#%}%", volumeLevelPercent); + return new _PlaceholderMessage("Volume: {0,number,#%}", volumeLevelPercent); } /** diff --git a/jpsxdec/src/jpsxdec/i18n/ILocalizedMessage.java b/jpsxdec/src/jpsxdec/i18n/ILocalizedMessage.java index ac8f896..95014e1 100644 --- a/jpsxdec/src/jpsxdec/i18n/ILocalizedMessage.java +++ b/jpsxdec/src/jpsxdec/i18n/ILocalizedMessage.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/LocalizedMessage.java b/jpsxdec/src/jpsxdec/i18n/LocalizedMessage.java index 67b85b9..a2b494f 100644 --- a/jpsxdec/src/jpsxdec/i18n/LocalizedMessage.java +++ b/jpsxdec/src/jpsxdec/i18n/LocalizedMessage.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/MiscResources.java b/jpsxdec/src/jpsxdec/i18n/MiscResources.java index 85e02cc..313893c 100644 --- a/jpsxdec/src/jpsxdec/i18n/MiscResources.java +++ b/jpsxdec/src/jpsxdec/i18n/MiscResources.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/MiscResources_es.java b/jpsxdec/src/jpsxdec/i18n/MiscResources_es.java index 3eee24a..62bc66a 100644 --- a/jpsxdec/src/jpsxdec/i18n/MiscResources_es.java +++ b/jpsxdec/src/jpsxdec/i18n/MiscResources_es.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/MiscResources_it.java b/jpsxdec/src/jpsxdec/i18n/MiscResources_it.java index 312dbb6..0a99bb3 100644 --- a/jpsxdec/src/jpsxdec/i18n/MiscResources_it.java +++ b/jpsxdec/src/jpsxdec/i18n/MiscResources_it.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/TabularFeedback.java b/jpsxdec/src/jpsxdec/i18n/TabularFeedback.java index 523fe0d..63b42df 100644 --- a/jpsxdec/src/jpsxdec/i18n/TabularFeedback.java +++ b/jpsxdec/src/jpsxdec/i18n/TabularFeedback.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/UnlocalizedMessage.java b/jpsxdec/src/jpsxdec/i18n/UnlocalizedMessage.java index 6cbd9b1..d29cad2 100644 --- a/jpsxdec/src/jpsxdec/i18n/UnlocalizedMessage.java +++ b/jpsxdec/src/jpsxdec/i18n/UnlocalizedMessage.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/_PlaceholderMessage.java b/jpsxdec/src/jpsxdec/i18n/_PlaceholderMessage.java index dffa415..68eb527 100644 --- a/jpsxdec/src/jpsxdec/i18n/_PlaceholderMessage.java +++ b/jpsxdec/src/jpsxdec/i18n/_PlaceholderMessage.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/exception/ILocalizedException.java b/jpsxdec/src/jpsxdec/i18n/exception/ILocalizedException.java index 2b54a39..0dbf0e8 100644 --- a/jpsxdec/src/jpsxdec/i18n/exception/ILocalizedException.java +++ b/jpsxdec/src/jpsxdec/i18n/exception/ILocalizedException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2018-2019 Michael Sabin + * Copyright (C) 2018-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/exception/LocalizedDeserializationFail.java b/jpsxdec/src/jpsxdec/i18n/exception/LocalizedDeserializationFail.java index 3a90445..2de8d2f 100644 --- a/jpsxdec/src/jpsxdec/i18n/exception/LocalizedDeserializationFail.java +++ b/jpsxdec/src/jpsxdec/i18n/exception/LocalizedDeserializationFail.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/exception/LocalizedException.java b/jpsxdec/src/jpsxdec/i18n/exception/LocalizedException.java index a82a4fc..508bfd6 100644 --- a/jpsxdec/src/jpsxdec/i18n/exception/LocalizedException.java +++ b/jpsxdec/src/jpsxdec/i18n/exception/LocalizedException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/exception/LocalizedFileNotFoundException.java b/jpsxdec/src/jpsxdec/i18n/exception/LocalizedFileNotFoundException.java index 68ada5b..80e1cd3 100644 --- a/jpsxdec/src/jpsxdec/i18n/exception/LocalizedFileNotFoundException.java +++ b/jpsxdec/src/jpsxdec/i18n/exception/LocalizedFileNotFoundException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/exception/LocalizedIncompatibleException.java b/jpsxdec/src/jpsxdec/i18n/exception/LocalizedIncompatibleException.java index f79819a..315abef 100644 --- a/jpsxdec/src/jpsxdec/i18n/exception/LocalizedIncompatibleException.java +++ b/jpsxdec/src/jpsxdec/i18n/exception/LocalizedIncompatibleException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/exception/LoggedFailure.java b/jpsxdec/src/jpsxdec/i18n/exception/LoggedFailure.java index 24e4fc0..75f391b 100644 --- a/jpsxdec/src/jpsxdec/i18n/exception/LoggedFailure.java +++ b/jpsxdec/src/jpsxdec/i18n/exception/LoggedFailure.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/log/ConsoleProgressLogger.java b/jpsxdec/src/jpsxdec/i18n/log/ConsoleProgressLogger.java index d848242..cdc95f5 100644 --- a/jpsxdec/src/jpsxdec/i18n/log/ConsoleProgressLogger.java +++ b/jpsxdec/src/jpsxdec/i18n/log/ConsoleProgressLogger.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/log/DebugFormatter.java b/jpsxdec/src/jpsxdec/i18n/log/DebugFormatter.java index 57f879a..8201dce 100644 --- a/jpsxdec/src/jpsxdec/i18n/log/DebugFormatter.java +++ b/jpsxdec/src/jpsxdec/i18n/log/DebugFormatter.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/log/DebugLogger.java b/jpsxdec/src/jpsxdec/i18n/log/DebugLogger.java index 351ae3e..e9eeae1 100644 --- a/jpsxdec/src/jpsxdec/i18n/log/DebugLogger.java +++ b/jpsxdec/src/jpsxdec/i18n/log/DebugLogger.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/log/ILocalizedLogger.java b/jpsxdec/src/jpsxdec/i18n/log/ILocalizedLogger.java index 8cb3498..30e966e 100644 --- a/jpsxdec/src/jpsxdec/i18n/log/ILocalizedLogger.java +++ b/jpsxdec/src/jpsxdec/i18n/log/ILocalizedLogger.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/log/ProgressLogger.java b/jpsxdec/src/jpsxdec/i18n/log/ProgressLogger.java index 1ff4506..3709023 100644 --- a/jpsxdec/src/jpsxdec/i18n/log/ProgressLogger.java +++ b/jpsxdec/src/jpsxdec/i18n/log/ProgressLogger.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/log/ShouldNotLog.java b/jpsxdec/src/jpsxdec/i18n/log/ShouldNotLog.java index f7875ba..0b5c783 100644 --- a/jpsxdec/src/jpsxdec/i18n/log/ShouldNotLog.java +++ b/jpsxdec/src/jpsxdec/i18n/log/ShouldNotLog.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/i18n/log/UserFriendlyLogger.java b/jpsxdec/src/jpsxdec/i18n/log/UserFriendlyLogger.java index 6d29c99..afa46b9 100644 --- a/jpsxdec/src/jpsxdec/i18n/log/UserFriendlyLogger.java +++ b/jpsxdec/src/jpsxdec/i18n/log/UserFriendlyLogger.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/indexing/DiscIndex.java b/jpsxdec/src/jpsxdec/indexing/DiscIndex.java index 3dbc978..45deeaf 100644 --- a/jpsxdec/src/jpsxdec/indexing/DiscIndex.java +++ b/jpsxdec/src/jpsxdec/indexing/DiscIndex.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -45,6 +45,7 @@ import java.io.InputStreamReader; import java.io.PrintStream; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -185,7 +186,7 @@ public DiscIndex(@Nonnull CdFileSectorReader cdReader, @Nonnull final ProgressLo // sort the numbered index list according to the start sector & hierarchy level Collections.sort(_iterate, SORT_BY_SECTOR_HIERARHCY); - _root = buildTree(_iterate); + _root = buildTree(_iterate, indexers); // copy the items to the hash int iIndex = 0; @@ -215,11 +216,16 @@ public DiscIndex(@Nonnull CdFileSectorReader cdReader, @Nonnull final ProgressLo } - private @Nonnull ArrayList buildTree(@Nonnull Collection allItems) { + private static @Nonnull ArrayList buildTree(@Nonnull Collection allItems, + @Nonnull Collection indexers) + { ArrayList rootItems = new ArrayList(); - for (DiscItem child : allItems) { + ItemLoop: + for (Iterator iterator = allItems.iterator(); iterator.hasNext();) { + DiscItem child = iterator.next(); + DiscItem bestParent = null; int iBestParentRating = 0; for (DiscItem parent : allItems) { @@ -229,11 +235,21 @@ public DiscIndex(@Nonnull CdFileSectorReader cdReader, @Nonnull final ProgressLo iBestParentRating = iRating; } } - if (bestParent == null) + + for (DiscIndexer indexer : indexers) { + if (indexer.filterChild(bestParent, child)) { + LOG.log(Level.INFO, "Filtered child item {0}", child); + iterator.remove(); + continue ItemLoop; + } + } + + if (bestParent == null) { rootItems.add(child); - else + } else { if (!bestParent.addChild(child)) throw new RuntimeException(bestParent + " should have accepted " + child); + } } IndexId id = new IndexId(0); @@ -330,13 +346,6 @@ private DiscIndex(@Nonnull String sIndexFile, @CheckForNull CdFileSectorReader c } catch (FileNotFoundException ex) { throw new IndexNotFoundException(indexFile, ex); } - BufferedReader reader; - try { - reader = new BufferedReader(new InputStreamReader(fis, "UTF-8")); - } catch (UnsupportedEncodingException ex) { - IO.closeSilently(fis, LOG); - throw new RuntimeException("Every implementation of the Java platform is required to support UTF-8", ex); - } String sSourceCdLine = null; ArrayList serializedLines = new ArrayList(); @@ -346,6 +355,7 @@ private DiscIndex(@Nonnull String sIndexFile, @CheckForNull CdFileSectorReader c // Only check that: // * header is correct // * there is 1 and only 1 serialized CD line + BufferedReader reader = new BufferedReader(new InputStreamReader(fis, Charset.forName("UTF-8"))); try { // make sure the first line matches the current version String sLine; @@ -405,7 +415,7 @@ private DiscIndex(@Nonnull String sIndexFile, @CheckForNull CdFileSectorReader c } _sourceCD = cdReader; } else { - _sourceCD = new CdFileSectorReader(sSourceCdLine, blnAllowWrites); + _sourceCD = CdFileSectorReader.deserialize(sSourceCdLine, blnAllowWrites); } } diff --git a/jpsxdec/src/jpsxdec/indexing/DiscIndexer.java b/jpsxdec/src/jpsxdec/indexing/DiscIndexer.java index 2896af6..60d2a5f 100644 --- a/jpsxdec/src/jpsxdec/indexing/DiscIndexer.java +++ b/jpsxdec/src/jpsxdec/indexing/DiscIndexer.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -51,16 +51,14 @@ import jpsxdec.i18n.exception.LocalizedDeserializationFail; import jpsxdec.i18n.log.ILocalizedLogger; import jpsxdec.modules.SectorClaimSystem; -import jpsxdec.modules.ac3.DiscIndexerAceCombat3Video; import jpsxdec.modules.crusader.DiscIndexerCrusader; -import jpsxdec.modules.dredd.DiscIndexerDredd; import jpsxdec.modules.eavideo.DiscIndexerEAVideo; import jpsxdec.modules.iso9660.DiscIndexerISO9660; import jpsxdec.modules.policenauts.DiscIndexerPolicenauts; import jpsxdec.modules.spu.DiscIndexerSpu; import jpsxdec.modules.square.DiscIndexerSquareAudio; -import jpsxdec.modules.strvideo.DiscIndexerStrVideo; import jpsxdec.modules.tim.DiscIndexerTim; +import jpsxdec.modules.video.sectorbased.DiscIndexerSectorBasedVideo; import jpsxdec.modules.xa.DiscIndexerXaAudio; /** Superclass of all disc indexers. @@ -75,12 +73,10 @@ public abstract class DiscIndexer { new DiscIndexerISO9660(log), new DiscIndexerSquareAudio(log), new DiscIndexerTim(), - new DiscIndexerStrVideo(log), - new DiscIndexerAceCombat3Video(log), + new DiscIndexerSectorBasedVideo(log), new DiscIndexerXaAudio(log), new DiscIndexerPolicenauts(), new DiscIndexerCrusader(log), - new DiscIndexerDredd(log), new DiscIndexerEAVideo(), }; ArrayList indexers = new ArrayList(Arrays.asList(coreIndexers)); @@ -123,10 +119,19 @@ final protected void addDiscItem(@Nonnull DiscItem discItem) { abstract public @CheckForNull DiscItem deserializeLineRead(@Nonnull SerializedDiscItem fields) throws LocalizedDeserializationFail; + /** Called after the entire disc has been scanned. + * Indexers can add, remove, or change disc items. */ abstract public void listPostProcessing(@Nonnull Collection allItems); + /** Called for each disc item before it is added to a parent item. + * Parent will be null if the child will be added to the root of the tree. + * This was initially added to filter out silent XA streams not associated with a video. */ + abstract public boolean filterChild(@CheckForNull DiscItem parent, @Nonnull DiscItem child); + /** Called after the entire indexing process is complete. The DiscIndex * will not be changing any further, but indexers can tweak individual items - * as necessary. */ + * as necessary. + * This was initially added so the ISO9660 indexer can set the name of the index + * to the name of the disc found in the filesystem. */ abstract public void indexGenerated(@Nonnull DiscIndex index); // TODO consider not having a dependency on DiscIndex } diff --git a/jpsxdec/src/jpsxdec/iso9660/DateAndTimeFormat.java b/jpsxdec/src/jpsxdec/iso9660/DateAndTimeFormat.java index 054a4a2..2e9ed84 100644 --- a/jpsxdec/src/jpsxdec/iso9660/DateAndTimeFormat.java +++ b/jpsxdec/src/jpsxdec/iso9660/DateAndTimeFormat.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/iso9660/DirectoryRecord.java b/jpsxdec/src/jpsxdec/iso9660/DirectoryRecord.java index e7e4a9c..ea8275a 100644 --- a/jpsxdec/src/jpsxdec/iso9660/DirectoryRecord.java +++ b/jpsxdec/src/jpsxdec/iso9660/DirectoryRecord.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/iso9660/ISO9660File.java b/jpsxdec/src/jpsxdec/iso9660/ISO9660File.java index fdf4b1f..764f609 100644 --- a/jpsxdec/src/jpsxdec/iso9660/ISO9660File.java +++ b/jpsxdec/src/jpsxdec/iso9660/ISO9660File.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/iso9660/ISO9660Struct.java b/jpsxdec/src/jpsxdec/iso9660/ISO9660Struct.java index 2ae67e3..cf04e99 100644 --- a/jpsxdec/src/jpsxdec/iso9660/ISO9660Struct.java +++ b/jpsxdec/src/jpsxdec/iso9660/ISO9660Struct.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/iso9660/PathTableBE.java b/jpsxdec/src/jpsxdec/iso9660/PathTableBE.java index 6d9f524..34a6adf 100644 --- a/jpsxdec/src/jpsxdec/iso9660/PathTableBE.java +++ b/jpsxdec/src/jpsxdec/iso9660/PathTableBE.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/iso9660/PathTableRecordBE.java b/jpsxdec/src/jpsxdec/iso9660/PathTableRecordBE.java index 810dad4..c9178b9 100644 --- a/jpsxdec/src/jpsxdec/iso9660/PathTableRecordBE.java +++ b/jpsxdec/src/jpsxdec/iso9660/PathTableRecordBE.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/iso9660/RecordingDateAndTime.java b/jpsxdec/src/jpsxdec/iso9660/RecordingDateAndTime.java index 31c3360..1f416ea 100644 --- a/jpsxdec/src/jpsxdec/iso9660/RecordingDateAndTime.java +++ b/jpsxdec/src/jpsxdec/iso9660/RecordingDateAndTime.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/iso9660/VolumePrimaryDescriptor.java b/jpsxdec/src/jpsxdec/iso9660/VolumePrimaryDescriptor.java index 4cdf3c0..e095313 100644 --- a/jpsxdec/src/jpsxdec/iso9660/VolumePrimaryDescriptor.java +++ b/jpsxdec/src/jpsxdec/iso9660/VolumePrimaryDescriptor.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/CdSectorDemuxPiece.java b/jpsxdec/src/jpsxdec/modules/CdSectorDemuxPiece.java index 5400a93..fbc018a 100644 --- a/jpsxdec/src/jpsxdec/modules/CdSectorDemuxPiece.java +++ b/jpsxdec/src/jpsxdec/modules/CdSectorDemuxPiece.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2018-2019 Michael Sabin + * Copyright (C) 2018-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/IIdentifiedSector.java b/jpsxdec/src/jpsxdec/modules/IIdentifiedSector.java index 47ddf9f..1e58dd2 100644 --- a/jpsxdec/src/jpsxdec/modules/IIdentifiedSector.java +++ b/jpsxdec/src/jpsxdec/modules/IIdentifiedSector.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/IdentifiedSector.java b/jpsxdec/src/jpsxdec/modules/IdentifiedSector.java index 354179a..3c3cc94 100644 --- a/jpsxdec/src/jpsxdec/modules/IdentifiedSector.java +++ b/jpsxdec/src/jpsxdec/modules/IdentifiedSector.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -45,19 +45,24 @@ * with special meaning. */ public abstract class IdentifiedSector implements IIdentifiedSector { - /** Convenience function to check that, if the sector has a sub header, - * the submode bits are as expected. - * @return true if the sector does not have a sub header, - * or the sub header submode bits match the expected bits after - * being masked - */ - final protected boolean subModeMaskMatch(int iMask, int iExpected) { + /** Convenience function to check that the sector has a sub header, + * and the submode bits are as expected. */ + final protected boolean subModeExistsAndMaskEquals(int iMask, int iExpected) { CdSectorXaSubHeader sh = _sourceCdSector.getSubHeader(); if (sh == null) - return true; + return false; return sh.getSubMode().mask(iMask) == iExpected; } + /** Convenience function to check that the sector has a sub header, + * and the submode bits are NOT as expected. */ + final protected boolean subModeExistsAndMaskDoesNotEqual(int iMask, int iExpected) { + CdSectorXaSubHeader sh = _sourceCdSector.getSubHeader(); + if (sh == null) + return false; + return sh.getSubMode().mask(iMask) != iExpected; + } + @Nonnull private final CdSector _sourceCdSector; diff --git a/jpsxdec/src/jpsxdec/modules/SectorClaimSystem.java b/jpsxdec/src/jpsxdec/modules/SectorClaimSystem.java index 72ef6c1..8cd6546 100644 --- a/jpsxdec/src/jpsxdec/modules/SectorClaimSystem.java +++ b/jpsxdec/src/jpsxdec/modules/SectorClaimSystem.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/SectorClaimToUnidentifiedSector.java b/jpsxdec/src/jpsxdec/modules/SectorClaimToUnidentifiedSector.java index 13b2804..8635175 100644 --- a/jpsxdec/src/jpsxdec/modules/SectorClaimToUnidentifiedSector.java +++ b/jpsxdec/src/jpsxdec/modules/SectorClaimToUnidentifiedSector.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/UnidentifiedSector.java b/jpsxdec/src/jpsxdec/modules/UnidentifiedSector.java index 9e644ef..fec8980 100644 --- a/jpsxdec/src/jpsxdec/modules/UnidentifiedSector.java +++ b/jpsxdec/src/jpsxdec/modules/UnidentifiedSector.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/ac3/Ac3AddResult.java b/jpsxdec/src/jpsxdec/modules/ac3/Ac3AddResult.java index c54a9c4..83eba72 100644 --- a/jpsxdec/src/jpsxdec/modules/ac3/Ac3AddResult.java +++ b/jpsxdec/src/jpsxdec/modules/ac3/Ac3AddResult.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/ac3/Ac3Demuxer.java b/jpsxdec/src/jpsxdec/modules/ac3/Ac3Demuxer.java index d4e9052..fe2fde8 100644 --- a/jpsxdec/src/jpsxdec/modules/ac3/Ac3Demuxer.java +++ b/jpsxdec/src/jpsxdec/modules/ac3/Ac3Demuxer.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/ac3/DemuxedAc3Frame.java b/jpsxdec/src/jpsxdec/modules/ac3/DemuxedAc3Frame.java index 49f959e..9db4f3e 100644 --- a/jpsxdec/src/jpsxdec/modules/ac3/DemuxedAc3Frame.java +++ b/jpsxdec/src/jpsxdec/modules/ac3/DemuxedAc3Frame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/ac3/DiscIndexerAceCombat3Video.java b/jpsxdec/src/jpsxdec/modules/ac3/DiscIndexerAceCombat3Video.java index b7da693..37160f4 100644 --- a/jpsxdec/src/jpsxdec/modules/ac3/DiscIndexerAceCombat3Video.java +++ b/jpsxdec/src/jpsxdec/modules/ac3/DiscIndexerAceCombat3Video.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -37,10 +37,7 @@ package jpsxdec.modules.ac3; -import java.util.ArrayList; -import java.util.Collection; import java.util.TreeMap; -import java.util.logging.Logger; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import jpsxdec.cdreaders.CdFileSectorReader; @@ -49,21 +46,18 @@ import jpsxdec.i18n.exception.LocalizedDeserializationFail; import jpsxdec.i18n.exception.LoggedFailure; import jpsxdec.i18n.log.ILocalizedLogger; -import jpsxdec.indexing.DiscIndex; -import jpsxdec.indexing.DiscIndexer; import jpsxdec.modules.SectorClaimSystem; -import jpsxdec.modules.strvideo.DiscIndexerStrVideo; import jpsxdec.modules.video.framenumber.HeaderFrameNumber; import jpsxdec.modules.video.framenumber.IndexSectorFrameNumber; +import jpsxdec.modules.video.sectorbased.DiscIndexerSectorBasedVideo; import jpsxdec.modules.video.sectorbased.SectorBasedVideoInfoBuilder; /** Searches for Ace Combat 3: Electrosphere video streams. * Only case I've seen that video streams are interleaved. */ -public class DiscIndexerAceCombat3Video extends DiscIndexer implements SectorClaimToSectorAc3Video.Listener +public class DiscIndexerAceCombat3Video extends DiscIndexerSectorBasedVideo.SubIndexer + implements SectorClaimToSectorAc3Video.Listener { - private static final Logger LOG = Logger.getLogger(DiscIndexerAceCombat3Video.class.getName()); - private static class VidBuilder { @Nonnull @@ -149,8 +143,7 @@ public void endVideo() { return; DiscItemAceCombat3VideoStream video = _videoBuilder.endOfMovie(_indexer.getCd()); - _indexer._completedVideos.add(video); - _indexer.addDiscItem(video); + _indexer.addVideo(video); _videoBuilder = null; } @@ -161,7 +154,6 @@ public void endVideo() { @Nonnull private final ILocalizedLogger _errLog; private final TreeMap _activeStreams = new TreeMap(); - private final Collection _completedVideos = new ArrayList(); public DiscIndexerAceCombat3Video(@Nonnull ILocalizedLogger errLog) { _errLog = errLog; @@ -204,14 +196,4 @@ public void endOfSectors(@Nonnull ILocalizedLogger log) { _activeStreams.clear(); } - @Override - public void listPostProcessing(@Nonnull Collection allItems) { - if (_completedVideos.size() > 0) - DiscIndexerStrVideo.audioSplit(_completedVideos, allItems); - } - - @Override - public void indexGenerated(@Nonnull DiscIndex index) { - } - } diff --git a/jpsxdec/src/jpsxdec/modules/ac3/DiscItemAceCombat3VideoStream.java b/jpsxdec/src/jpsxdec/modules/ac3/DiscItemAceCombat3VideoStream.java index ee39ea1..2d79f7d 100644 --- a/jpsxdec/src/jpsxdec/modules/ac3/DiscItemAceCombat3VideoStream.java +++ b/jpsxdec/src/jpsxdec/modules/ac3/DiscItemAceCombat3VideoStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/ac3/SectorAc3VideoToDemuxedAc3Frame.java b/jpsxdec/src/jpsxdec/modules/ac3/SectorAc3VideoToDemuxedAc3Frame.java index 5702247..b13e2fd 100644 --- a/jpsxdec/src/jpsxdec/modules/ac3/SectorAc3VideoToDemuxedAc3Frame.java +++ b/jpsxdec/src/jpsxdec/modules/ac3/SectorAc3VideoToDemuxedAc3Frame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/ac3/SectorAceCombat3Video.java b/jpsxdec/src/jpsxdec/modules/ac3/SectorAceCombat3Video.java index f9f605e..cfc3822 100644 --- a/jpsxdec/src/jpsxdec/modules/ac3/SectorAceCombat3Video.java +++ b/jpsxdec/src/jpsxdec/modules/ac3/SectorAceCombat3Video.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/ac3/SectorClaimToSectorAc3Video.java b/jpsxdec/src/jpsxdec/modules/ac3/SectorClaimToSectorAc3Video.java index 3abe06d..00bf58d 100644 --- a/jpsxdec/src/jpsxdec/modules/ac3/SectorClaimToSectorAc3Video.java +++ b/jpsxdec/src/jpsxdec/modules/ac3/SectorClaimToSectorAc3Video.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/aconcagua/AconcaguaDemuxer.java b/jpsxdec/src/jpsxdec/modules/aconcagua/AconcaguaDemuxer.java index af0c037..53e8e7a 100644 --- a/jpsxdec/src/jpsxdec/modules/aconcagua/AconcaguaDemuxer.java +++ b/jpsxdec/src/jpsxdec/modules/aconcagua/AconcaguaDemuxer.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/aconcagua/BitStreamUncompressor_Aconcagua.java b/jpsxdec/src/jpsxdec/modules/aconcagua/BitStreamUncompressor_Aconcagua.java index 53bc253..bd77a6f 100644 --- a/jpsxdec/src/jpsxdec/modules/aconcagua/BitStreamUncompressor_Aconcagua.java +++ b/jpsxdec/src/jpsxdec/modules/aconcagua/BitStreamUncompressor_Aconcagua.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -205,7 +205,7 @@ * Having said all that, we all make poor design decisions in our lives. Trying * to spin up your own version of some other program because you could do it * better--only to be wrong, but you're stuck with it now. It happens to all of - * us. I'm sure someone in the devolpment team wished they could go back and do + * us. I'm sure someone in the development team wished they could go back and do * it differently. */ public class BitStreamUncompressor_Aconcagua implements MdecInputStream { diff --git a/jpsxdec/src/jpsxdec/modules/aconcagua/DcTable.java b/jpsxdec/src/jpsxdec/modules/aconcagua/DcTable.java index bec3706..e7e727a 100644 --- a/jpsxdec/src/jpsxdec/modules/aconcagua/DcTable.java +++ b/jpsxdec/src/jpsxdec/modules/aconcagua/DcTable.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/aconcagua/DemuxedAconcaguaFrame.java b/jpsxdec/src/jpsxdec/modules/aconcagua/DemuxedAconcaguaFrame.java index 4bcaffb..b7e4556 100644 --- a/jpsxdec/src/jpsxdec/modules/aconcagua/DemuxedAconcaguaFrame.java +++ b/jpsxdec/src/jpsxdec/modules/aconcagua/DemuxedAconcaguaFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/aconcagua/InstructionTable.java b/jpsxdec/src/jpsxdec/modules/aconcagua/InstructionTable.java index 3c4ffa0..ac844f7 100644 --- a/jpsxdec/src/jpsxdec/modules/aconcagua/InstructionTable.java +++ b/jpsxdec/src/jpsxdec/modules/aconcagua/InstructionTable.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/aconcagua/SectorAconcaguaVideo.java b/jpsxdec/src/jpsxdec/modules/aconcagua/SectorAconcaguaVideo.java index 24be20a..675aace 100644 --- a/jpsxdec/src/jpsxdec/modules/aconcagua/SectorAconcaguaVideo.java +++ b/jpsxdec/src/jpsxdec/modules/aconcagua/SectorAconcaguaVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/aconcagua/ZeroRunLengthAcTables.java b/jpsxdec/src/jpsxdec/modules/aconcagua/ZeroRunLengthAcTables.java index 795bbb7..7904397 100644 --- a/jpsxdec/src/jpsxdec/modules/aconcagua/ZeroRunLengthAcTables.java +++ b/jpsxdec/src/jpsxdec/modules/aconcagua/ZeroRunLengthAcTables.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/cdaudio/SectorCdAudio.java b/jpsxdec/src/jpsxdec/modules/cdaudio/SectorCdAudio.java index 9f657a3..2fee51d 100644 --- a/jpsxdec/src/jpsxdec/modules/cdaudio/SectorCdAudio.java +++ b/jpsxdec/src/jpsxdec/modules/cdaudio/SectorCdAudio.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/cdaudio/SectorClaimToSectorCdAudio.java b/jpsxdec/src/jpsxdec/modules/cdaudio/SectorClaimToSectorCdAudio.java index 7806b03..b93702b 100644 --- a/jpsxdec/src/jpsxdec/modules/cdaudio/SectorClaimToSectorCdAudio.java +++ b/jpsxdec/src/jpsxdec/modules/cdaudio/SectorClaimToSectorCdAudio.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/crusader/CrusaderDemuxPiece.java b/jpsxdec/src/jpsxdec/modules/crusader/CrusaderDemuxPiece.java index 462e406..401435e 100644 --- a/jpsxdec/src/jpsxdec/modules/crusader/CrusaderDemuxPiece.java +++ b/jpsxdec/src/jpsxdec/modules/crusader/CrusaderDemuxPiece.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/crusader/CrusaderPacketHeaderReader.java b/jpsxdec/src/jpsxdec/modules/crusader/CrusaderPacketHeaderReader.java index 5f0d6c6..9fbf844 100644 --- a/jpsxdec/src/jpsxdec/modules/crusader/CrusaderPacketHeaderReader.java +++ b/jpsxdec/src/jpsxdec/modules/crusader/CrusaderPacketHeaderReader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/crusader/CrusaderPacketToFrameAndAudio.java b/jpsxdec/src/jpsxdec/modules/crusader/CrusaderPacketToFrameAndAudio.java index c186f11..0ed58c4 100644 --- a/jpsxdec/src/jpsxdec/modules/crusader/CrusaderPacketToFrameAndAudio.java +++ b/jpsxdec/src/jpsxdec/modules/crusader/CrusaderPacketToFrameAndAudio.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/crusader/CrusaderSectorToCrusaderPacket.java b/jpsxdec/src/jpsxdec/modules/crusader/CrusaderSectorToCrusaderPacket.java index 623917e..3107568 100644 --- a/jpsxdec/src/jpsxdec/modules/crusader/CrusaderSectorToCrusaderPacket.java +++ b/jpsxdec/src/jpsxdec/modules/crusader/CrusaderSectorToCrusaderPacket.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/crusader/DemuxedCrusaderFrame.java b/jpsxdec/src/jpsxdec/modules/crusader/DemuxedCrusaderFrame.java index 294994b..0409f07 100644 --- a/jpsxdec/src/jpsxdec/modules/crusader/DemuxedCrusaderFrame.java +++ b/jpsxdec/src/jpsxdec/modules/crusader/DemuxedCrusaderFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/crusader/DiscIndexerCrusader.java b/jpsxdec/src/jpsxdec/modules/crusader/DiscIndexerCrusader.java index f098eec..0bd7533 100644 --- a/jpsxdec/src/jpsxdec/modules/crusader/DiscIndexerCrusader.java +++ b/jpsxdec/src/jpsxdec/modules/crusader/DiscIndexerCrusader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -317,10 +317,6 @@ public void endOfSectors(@Nonnull ILocalizedLogger log) throws LoggedFailure { } } - @Override - public void listPostProcessing(@Nonnull Collection allItems) { - } - @Override public @CheckForNull DiscItem deserializeLineRead(@Nonnull SerializedDiscItem fields) throws LocalizedDeserializationFail @@ -330,6 +326,13 @@ public void listPostProcessing(@Nonnull Collection allItems) { return null; } + @Override + public void listPostProcessing(@Nonnull Collection allItems) { + } + @Override + public boolean filterChild(DiscItem parent, DiscItem child) { + return false; + } @Override public void indexGenerated(@Nonnull DiscIndex index) { } diff --git a/jpsxdec/src/jpsxdec/modules/crusader/DiscItemCrusader.java b/jpsxdec/src/jpsxdec/modules/crusader/DiscItemCrusader.java index fdfa123..340f7e5 100644 --- a/jpsxdec/src/jpsxdec/modules/crusader/DiscItemCrusader.java +++ b/jpsxdec/src/jpsxdec/modules/crusader/DiscItemCrusader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/crusader/SectorClaimToSectorCrusader.java b/jpsxdec/src/jpsxdec/modules/crusader/SectorClaimToSectorCrusader.java index 564e2f5..ae07125 100644 --- a/jpsxdec/src/jpsxdec/modules/crusader/SectorClaimToSectorCrusader.java +++ b/jpsxdec/src/jpsxdec/modules/crusader/SectorClaimToSectorCrusader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/crusader/SectorCrusader.java b/jpsxdec/src/jpsxdec/modules/crusader/SectorCrusader.java index ef8be8c..c1c7244 100644 --- a/jpsxdec/src/jpsxdec/modules/crusader/SectorCrusader.java +++ b/jpsxdec/src/jpsxdec/modules/crusader/SectorCrusader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/dredd/DemuxedDreddFrame.java b/jpsxdec/src/jpsxdec/modules/dredd/DemuxedDreddFrame.java index 9063f64..771ef13 100644 --- a/jpsxdec/src/jpsxdec/modules/dredd/DemuxedDreddFrame.java +++ b/jpsxdec/src/jpsxdec/modules/dredd/DemuxedDreddFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/dredd/DiscIndexerDredd.java b/jpsxdec/src/jpsxdec/modules/dredd/DiscIndexerDredd.java index 726c7c8..f214274 100644 --- a/jpsxdec/src/jpsxdec/modules/dredd/DiscIndexerDredd.java +++ b/jpsxdec/src/jpsxdec/modules/dredd/DiscIndexerDredd.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -37,8 +37,6 @@ package jpsxdec.modules.dredd; -import java.util.ArrayList; -import java.util.Collection; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import jpsxdec.cdreaders.CdFileSectorReader; @@ -46,15 +44,14 @@ import jpsxdec.discitems.SerializedDiscItem; import jpsxdec.i18n.exception.LocalizedDeserializationFail; import jpsxdec.i18n.log.ILocalizedLogger; -import jpsxdec.indexing.DiscIndex; -import jpsxdec.indexing.DiscIndexer; import jpsxdec.modules.SectorClaimSystem; -import jpsxdec.modules.strvideo.DiscIndexerStrVideo; import jpsxdec.modules.video.framenumber.IndexSectorFrameNumber; +import jpsxdec.modules.video.sectorbased.DiscIndexerSectorBasedVideo; import jpsxdec.modules.video.sectorbased.SectorBasedVideoInfoBuilder; -public class DiscIndexerDredd extends DiscIndexer implements SectorClaimToDreddFrame.Listener +public class DiscIndexerDredd extends DiscIndexerSectorBasedVideo.SubIndexer + implements SectorClaimToDreddFrame.Listener { private static class VidBuilder { @@ -93,17 +90,9 @@ public boolean addFrame(@Nonnull DemuxedDreddFrame frame) { } - @Nonnull - private final ILocalizedLogger _errLog; - private final Collection _completedVideos = new ArrayList(); @CheckForNull private VidBuilder _videoBuilder; - - public DiscIndexerDredd(@Nonnull ILocalizedLogger errLog) { - _errLog = errLog; - } - @Override public void attachToSectorClaimer(@Nonnull SectorClaimSystem scs) { SectorClaimToDreddFrame s2df = scs.getClaimer(SectorClaimToDreddFrame.class); @@ -132,8 +121,7 @@ public void videoBreak(ILocalizedLogger log) { return; DiscItemDreddVideoStream video = _videoBuilder.endOfMovie(getCd()); - _completedVideos.add(video); - addDiscItem(video); + addVideo(video); _videoBuilder = null; } @@ -141,15 +129,5 @@ public void endOfSectors(ILocalizedLogger log) { videoBreak(log); } - @Override - public void listPostProcessing(@Nonnull Collection allItems) { - if (_completedVideos.size() > 0) - DiscIndexerStrVideo.audioSplit(_completedVideos, allItems); - } - - @Override - public void indexGenerated(@Nonnull DiscIndex index) { - } - } diff --git a/jpsxdec/src/jpsxdec/modules/dredd/DiscItemDreddVideoStream.java b/jpsxdec/src/jpsxdec/modules/dredd/DiscItemDreddVideoStream.java index 912c449..97ea8ba 100644 --- a/jpsxdec/src/jpsxdec/modules/dredd/DiscItemDreddVideoStream.java +++ b/jpsxdec/src/jpsxdec/modules/dredd/DiscItemDreddVideoStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/dredd/DreddDemuxer.java b/jpsxdec/src/jpsxdec/modules/dredd/DreddDemuxer.java index dba312e..cf9eccf 100644 --- a/jpsxdec/src/jpsxdec/modules/dredd/DreddDemuxer.java +++ b/jpsxdec/src/jpsxdec/modules/dredd/DreddDemuxer.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -195,7 +195,7 @@ private static boolean commonSectorCheck(@Nonnull CdSector cdSector) { if (sh == null) return false; if (sh.getFileNumber() != 1 || sh.getChannel() != 2) return false; - if (sh.getSubMode().mask(~CdSectorXaSubHeader.SubMode.MASK_EOF_MARKER) != CdSectorXaSubHeader.SubMode.MASK_DATA) + if (sh.getSubMode().mask(~CdSectorXaSubHeader.SubMode.MASK_END_OF_FILE) != CdSectorXaSubHeader.SubMode.MASK_DATA) return false; return true; } diff --git a/jpsxdec/src/jpsxdec/modules/dredd/SectorClaimToDreddFrame.java b/jpsxdec/src/jpsxdec/modules/dredd/SectorClaimToDreddFrame.java index 28f52e2..ea7f019 100644 --- a/jpsxdec/src/jpsxdec/modules/dredd/SectorClaimToDreddFrame.java +++ b/jpsxdec/src/jpsxdec/modules/dredd/SectorClaimToDreddFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -131,7 +131,7 @@ public void sectorRead(@Nonnull SectorClaimSystem.ClaimableSector cs, // the only way to know a video ends is by the EOF marker CdSectorXaSubHeader sh = cs.getSector().getSubHeader(); if (sh != null && - sh.getSubMode().mask(CdSectorXaSubHeader.SubMode.MASK_EOF_MARKER) != 0) + sh.getSubMode().mask(CdSectorXaSubHeader.SubMode.MASK_END_OF_FILE) != 0) { if (_listener != null) _listener.videoBreak(log); diff --git a/jpsxdec/src/jpsxdec/modules/dredd/SectorDreddVideo.java b/jpsxdec/src/jpsxdec/modules/dredd/SectorDreddVideo.java index 639d62c..ef21e46 100644 --- a/jpsxdec/src/jpsxdec/modules/dredd/SectorDreddVideo.java +++ b/jpsxdec/src/jpsxdec/modules/dredd/SectorDreddVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/eavideo/BitStreamUncompressor_EA.java b/jpsxdec/src/jpsxdec/modules/eavideo/BitStreamUncompressor_EA.java index 266415b..9869a05 100644 --- a/jpsxdec/src/jpsxdec/modules/eavideo/BitStreamUncompressor_EA.java +++ b/jpsxdec/src/jpsxdec/modules/eavideo/BitStreamUncompressor_EA.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/eavideo/DemuxedEAFrame.java b/jpsxdec/src/jpsxdec/modules/eavideo/DemuxedEAFrame.java index 30f34f1..ccc3884 100644 --- a/jpsxdec/src/jpsxdec/modules/eavideo/DemuxedEAFrame.java +++ b/jpsxdec/src/jpsxdec/modules/eavideo/DemuxedEAFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/eavideo/DiscIndexerEAVideo.java b/jpsxdec/src/jpsxdec/modules/eavideo/DiscIndexerEAVideo.java index 79bb91e..0540f9d 100644 --- a/jpsxdec/src/jpsxdec/modules/eavideo/DiscIndexerEAVideo.java +++ b/jpsxdec/src/jpsxdec/modules/eavideo/DiscIndexerEAVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -75,7 +75,10 @@ public void attachToSectorClaimer(@Nonnull SectorClaimSystem scs) { @Override public void listPostProcessing(@Nonnull Collection allItems) { } - + @Override + public boolean filterChild(DiscItem parent, DiscItem child) { + return false; + } @Override public void indexGenerated(@Nonnull DiscIndex index) { } diff --git a/jpsxdec/src/jpsxdec/modules/eavideo/DiscItemEAVideo.java b/jpsxdec/src/jpsxdec/modules/eavideo/DiscItemEAVideo.java index f70238a..88f1696 100644 --- a/jpsxdec/src/jpsxdec/modules/eavideo/DiscItemEAVideo.java +++ b/jpsxdec/src/jpsxdec/modules/eavideo/DiscItemEAVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoPacket.java b/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoPacket.java index a5cb5b5..56dc49d 100644 --- a/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoPacket.java +++ b/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoPacket.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoPacketSectors.java b/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoPacketSectors.java index 8560d93..93a4cd1 100644 --- a/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoPacketSectors.java +++ b/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoPacketSectors.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoStreamReader.java b/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoStreamReader.java index 5d44633..cd4b946 100644 --- a/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoStreamReader.java +++ b/jpsxdec/src/jpsxdec/modules/eavideo/EAVideoStreamReader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/eavideo/SectorClaimToEAVideo.java b/jpsxdec/src/jpsxdec/modules/eavideo/SectorClaimToEAVideo.java index eefb41f..2ffa480 100644 --- a/jpsxdec/src/jpsxdec/modules/eavideo/SectorClaimToEAVideo.java +++ b/jpsxdec/src/jpsxdec/modules/eavideo/SectorClaimToEAVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/eavideo/SectorEAVideo.java b/jpsxdec/src/jpsxdec/modules/eavideo/SectorEAVideo.java index cc3123d..f17992a 100644 --- a/jpsxdec/src/jpsxdec/modules/eavideo/SectorEAVideo.java +++ b/jpsxdec/src/jpsxdec/modules/eavideo/SectorEAVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/granturismo/GranTurismoDemuxer.java b/jpsxdec/src/jpsxdec/modules/granturismo/GranTurismoDemuxer.java index 3563039..1bfbfe4 100644 --- a/jpsxdec/src/jpsxdec/modules/granturismo/GranTurismoDemuxer.java +++ b/jpsxdec/src/jpsxdec/modules/granturismo/GranTurismoDemuxer.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/granturismo/SectorGTVideo.java b/jpsxdec/src/jpsxdec/modules/granturismo/SectorGTVideo.java index 6f9314c..28b8d73 100644 --- a/jpsxdec/src/jpsxdec/modules/granturismo/SectorGTVideo.java +++ b/jpsxdec/src/jpsxdec/modules/granturismo/SectorGTVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -83,8 +83,8 @@ public SectorGTVideo(@Nonnull CdSector cdSector) { _header = new VideoSectorCommon16byteHeader(cdSector); if (isSuperInvalidElseReset()) return; - // only if it has a sector header should we check if it reports DATA - if (subModeMaskMatch(SubMode.MASK_DATA, 0)) + // the DATA flag should be set + if (subModeExistsAndMaskDoesNotEqual(SubMode.MASK_DATA, SubMode.MASK_DATA)) return; if (_header.lngMagic != GT_MAGIC) diff --git a/jpsxdec/src/jpsxdec/modules/iso9660/DiscIndexerISO9660.java b/jpsxdec/src/jpsxdec/modules/iso9660/DiscIndexerISO9660.java index 3bbd44e..21c5566 100644 --- a/jpsxdec/src/jpsxdec/modules/iso9660/DiscIndexerISO9660.java +++ b/jpsxdec/src/jpsxdec/modules/iso9660/DiscIndexerISO9660.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -326,5 +326,9 @@ private void addFileDiscItem(int iStartSector, int iEndSector, @Nonnull File fil @Override public void listPostProcessing(Collection allItems) { } + @Override + public boolean filterChild(DiscItem parent, DiscItem child) { + return false; + } } diff --git a/jpsxdec/src/jpsxdec/modules/iso9660/DiscItemISO9660File.java b/jpsxdec/src/jpsxdec/modules/iso9660/DiscItemISO9660File.java index c1e8ab1..f30ba23 100644 --- a/jpsxdec/src/jpsxdec/modules/iso9660/DiscItemISO9660File.java +++ b/jpsxdec/src/jpsxdec/modules/iso9660/DiscItemISO9660File.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/iso9660/SectorClaimToSectorISO9660.java b/jpsxdec/src/jpsxdec/modules/iso9660/SectorClaimToSectorISO9660.java index 2a68564..5e073e9 100644 --- a/jpsxdec/src/jpsxdec/modules/iso9660/SectorClaimToSectorISO9660.java +++ b/jpsxdec/src/jpsxdec/modules/iso9660/SectorClaimToSectorISO9660.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/iso9660/SectorISO9660DirectoryRecords.java b/jpsxdec/src/jpsxdec/modules/iso9660/SectorISO9660DirectoryRecords.java index 7bdf317..4775160 100644 --- a/jpsxdec/src/jpsxdec/modules/iso9660/SectorISO9660DirectoryRecords.java +++ b/jpsxdec/src/jpsxdec/modules/iso9660/SectorISO9660DirectoryRecords.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/iso9660/SectorISO9660VolumePrimaryDescriptor.java b/jpsxdec/src/jpsxdec/modules/iso9660/SectorISO9660VolumePrimaryDescriptor.java index 4ef4842..2448df3 100644 --- a/jpsxdec/src/jpsxdec/modules/iso9660/SectorISO9660VolumePrimaryDescriptor.java +++ b/jpsxdec/src/jpsxdec/modules/iso9660/SectorISO9660VolumePrimaryDescriptor.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/player/AudioPlayerSectorTimedWriter.java b/jpsxdec/src/jpsxdec/modules/player/AudioPlayerSectorTimedWriter.java index 40e8e38..1a52cbc 100644 --- a/jpsxdec/src/jpsxdec/modules/player/AudioPlayerSectorTimedWriter.java +++ b/jpsxdec/src/jpsxdec/modules/player/AudioPlayerSectorTimedWriter.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/player/MediaPlayer.java b/jpsxdec/src/jpsxdec/modules/player/MediaPlayer.java index a3c1516..be01bf7 100644 --- a/jpsxdec/src/jpsxdec/modules/player/MediaPlayer.java +++ b/jpsxdec/src/jpsxdec/modules/player/MediaPlayer.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/player/WrapIOException.java b/jpsxdec/src/jpsxdec/modules/player/WrapIOException.java index d4dbc07..681e578 100644 --- a/jpsxdec/src/jpsxdec/modules/player/WrapIOException.java +++ b/jpsxdec/src/jpsxdec/modules/player/WrapIOException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/policenauts/DemuxedPolicenautsFrame.java b/jpsxdec/src/jpsxdec/modules/policenauts/DemuxedPolicenautsFrame.java index c6158b8..1c9b967 100644 --- a/jpsxdec/src/jpsxdec/modules/policenauts/DemuxedPolicenautsFrame.java +++ b/jpsxdec/src/jpsxdec/modules/policenauts/DemuxedPolicenautsFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/policenauts/DiscIndexerPolicenauts.java b/jpsxdec/src/jpsxdec/modules/policenauts/DiscIndexerPolicenauts.java index 97c9ea3..829b9cb 100644 --- a/jpsxdec/src/jpsxdec/modules/policenauts/DiscIndexerPolicenauts.java +++ b/jpsxdec/src/jpsxdec/modules/policenauts/DiscIndexerPolicenauts.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -157,7 +157,10 @@ public void endOfSectors(@Nonnull ILocalizedLogger log) { @Override public void listPostProcessing(@Nonnull Collection allItems) { } - + @Override + public boolean filterChild(DiscItem parent, DiscItem child) { + return false; + } @Override public void indexGenerated(@Nonnull DiscIndex index) { } diff --git a/jpsxdec/src/jpsxdec/modules/policenauts/DiscItemPolicenauts.java b/jpsxdec/src/jpsxdec/modules/policenauts/DiscItemPolicenauts.java index 235db5e..d339c17 100644 --- a/jpsxdec/src/jpsxdec/modules/policenauts/DiscItemPolicenauts.java +++ b/jpsxdec/src/jpsxdec/modules/policenauts/DiscItemPolicenauts.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/policenauts/KlbsStreamReader.java b/jpsxdec/src/jpsxdec/modules/policenauts/KlbsStreamReader.java index ad6b3b6..9c75ada 100644 --- a/jpsxdec/src/jpsxdec/modules/policenauts/KlbsStreamReader.java +++ b/jpsxdec/src/jpsxdec/modules/policenauts/KlbsStreamReader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/policenauts/SPacket.java b/jpsxdec/src/jpsxdec/modules/policenauts/SPacket.java index e7c62e3..1825caa 100644 --- a/jpsxdec/src/jpsxdec/modules/policenauts/SPacket.java +++ b/jpsxdec/src/jpsxdec/modules/policenauts/SPacket.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/policenauts/SPacketData.java b/jpsxdec/src/jpsxdec/modules/policenauts/SPacketData.java index fd4168b..7f3678f 100644 --- a/jpsxdec/src/jpsxdec/modules/policenauts/SPacketData.java +++ b/jpsxdec/src/jpsxdec/modules/policenauts/SPacketData.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/policenauts/SPacketPos.java b/jpsxdec/src/jpsxdec/modules/policenauts/SPacketPos.java index 604dc09..c0b4268 100644 --- a/jpsxdec/src/jpsxdec/modules/policenauts/SPacketPos.java +++ b/jpsxdec/src/jpsxdec/modules/policenauts/SPacketPos.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/policenauts/SectorClaimToPolicenauts.java b/jpsxdec/src/jpsxdec/modules/policenauts/SectorClaimToPolicenauts.java index 775c268..0235013 100644 --- a/jpsxdec/src/jpsxdec/modules/policenauts/SectorClaimToPolicenauts.java +++ b/jpsxdec/src/jpsxdec/modules/policenauts/SectorClaimToPolicenauts.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/policenauts/SectorPN_KLBS.java b/jpsxdec/src/jpsxdec/modules/policenauts/SectorPN_KLBS.java index c2e1a7b..729aee5 100644 --- a/jpsxdec/src/jpsxdec/modules/policenauts/SectorPN_KLBS.java +++ b/jpsxdec/src/jpsxdec/modules/policenauts/SectorPN_KLBS.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/policenauts/SectorPN_VMNK.java b/jpsxdec/src/jpsxdec/modules/policenauts/SectorPN_VMNK.java index 1003135..6f4a2b0 100644 --- a/jpsxdec/src/jpsxdec/modules/policenauts/SectorPN_VMNK.java +++ b/jpsxdec/src/jpsxdec/modules/policenauts/SectorPN_VMNK.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/policenauts/SectorPolicenauts.java b/jpsxdec/src/jpsxdec/modules/policenauts/SectorPolicenauts.java index 31cc275..0627a70 100644 --- a/jpsxdec/src/jpsxdec/modules/policenauts/SectorPolicenauts.java +++ b/jpsxdec/src/jpsxdec/modules/policenauts/SectorPolicenauts.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/sharedaudio/AudioSaverBuilder.java b/jpsxdec/src/jpsxdec/modules/sharedaudio/AudioSaverBuilder.java index b609e99..56727aa 100644 --- a/jpsxdec/src/jpsxdec/modules/sharedaudio/AudioSaverBuilder.java +++ b/jpsxdec/src/jpsxdec/modules/sharedaudio/AudioSaverBuilder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/sharedaudio/AudioSaverBuilderGui.java b/jpsxdec/src/jpsxdec/modules/sharedaudio/AudioSaverBuilderGui.java index e8f76c9..88f3147 100644 --- a/jpsxdec/src/jpsxdec/modules/sharedaudio/AudioSaverBuilderGui.java +++ b/jpsxdec/src/jpsxdec/modules/sharedaudio/AudioSaverBuilderGui.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/sharedaudio/DecodedAudioPacket.java b/jpsxdec/src/jpsxdec/modules/sharedaudio/DecodedAudioPacket.java index 0882122..96b609f 100644 --- a/jpsxdec/src/jpsxdec/modules/sharedaudio/DecodedAudioPacket.java +++ b/jpsxdec/src/jpsxdec/modules/sharedaudio/DecodedAudioPacket.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/sharedaudio/DiscItemAudioStream.java b/jpsxdec/src/jpsxdec/modules/sharedaudio/DiscItemAudioStream.java index 2c8fd59..069eb9b 100644 --- a/jpsxdec/src/jpsxdec/modules/sharedaudio/DiscItemAudioStream.java +++ b/jpsxdec/src/jpsxdec/modules/sharedaudio/DiscItemAudioStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/sharedaudio/ISectorAudioDecoder.java b/jpsxdec/src/jpsxdec/modules/sharedaudio/ISectorAudioDecoder.java index ed39367..179f339 100644 --- a/jpsxdec/src/jpsxdec/modules/sharedaudio/ISectorAudioDecoder.java +++ b/jpsxdec/src/jpsxdec/modules/sharedaudio/ISectorAudioDecoder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/spu/DiscIndexerSpu.java b/jpsxdec/src/jpsxdec/modules/spu/DiscIndexerSpu.java index ade640c..a4d912b 100644 --- a/jpsxdec/src/jpsxdec/modules/spu/DiscIndexerSpu.java +++ b/jpsxdec/src/jpsxdec/modules/spu/DiscIndexerSpu.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -78,7 +78,10 @@ public void attachToSectorClaimer(@Nonnull SectorClaimSystem scs) { @Override public void listPostProcessing(@Nonnull Collection allItems) { } - + @Override + public boolean filterChild(DiscItem parent, DiscItem child) { + return false; + } @Override public void indexGenerated(@Nonnull DiscIndex index) { } diff --git a/jpsxdec/src/jpsxdec/modules/spu/DiscItemSpu.java b/jpsxdec/src/jpsxdec/modules/spu/DiscItemSpu.java index bdc3b74..02b1f40 100644 --- a/jpsxdec/src/jpsxdec/modules/spu/DiscItemSpu.java +++ b/jpsxdec/src/jpsxdec/modules/spu/DiscItemSpu.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/spu/SpuSaverBuilder.java b/jpsxdec/src/jpsxdec/modules/spu/SpuSaverBuilder.java index 02f97e4..1077894 100644 --- a/jpsxdec/src/jpsxdec/modules/spu/SpuSaverBuilder.java +++ b/jpsxdec/src/jpsxdec/modules/spu/SpuSaverBuilder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/spu/SpuSaverBuilderGui.java b/jpsxdec/src/jpsxdec/modules/spu/SpuSaverBuilderGui.java index a0ed3eb..d73db4f 100644 --- a/jpsxdec/src/jpsxdec/modules/spu/SpuSaverBuilderGui.java +++ b/jpsxdec/src/jpsxdec/modules/spu/SpuSaverBuilderGui.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/square/DiscIndexerSquareAudio.java b/jpsxdec/src/jpsxdec/modules/square/DiscIndexerSquareAudio.java index 48e2fef..d5b67e5 100644 --- a/jpsxdec/src/jpsxdec/modules/square/DiscIndexerSquareAudio.java +++ b/jpsxdec/src/jpsxdec/modules/square/DiscIndexerSquareAudio.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -162,6 +162,10 @@ public void endOfSectors(@Nonnull ILocalizedLogger log) { public void listPostProcessing(Collection allItems) { } @Override + public boolean filterChild(DiscItem parent, DiscItem child) { + return false; + } + @Override public void indexGenerated(DiscIndex index) { } diff --git a/jpsxdec/src/jpsxdec/modules/square/DiscItemSquareAudioStream.java b/jpsxdec/src/jpsxdec/modules/square/DiscItemSquareAudioStream.java index 48dd8df..62fa4dd 100644 --- a/jpsxdec/src/jpsxdec/modules/square/DiscItemSquareAudioStream.java +++ b/jpsxdec/src/jpsxdec/modules/square/DiscItemSquareAudioStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/square/FF9Demuxer.java b/jpsxdec/src/jpsxdec/modules/square/FF9Demuxer.java index 7f89bbb..37edef5 100644 --- a/jpsxdec/src/jpsxdec/modules/square/FF9Demuxer.java +++ b/jpsxdec/src/jpsxdec/modules/square/FF9Demuxer.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2018-2019 Michael Sabin + * Copyright (C) 2018-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/square/ISquareAudioSector.java b/jpsxdec/src/jpsxdec/modules/square/ISquareAudioSector.java index 9f2dd32..5bd871d 100644 --- a/jpsxdec/src/jpsxdec/modules/square/ISquareAudioSector.java +++ b/jpsxdec/src/jpsxdec/modules/square/ISquareAudioSector.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/square/SectorChronoXAudio.java b/jpsxdec/src/jpsxdec/modules/square/SectorChronoXAudio.java index 688f533..daf21ff 100644 --- a/jpsxdec/src/jpsxdec/modules/square/SectorChronoXAudio.java +++ b/jpsxdec/src/jpsxdec/modules/square/SectorChronoXAudio.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -87,7 +87,8 @@ public SectorChronoXAudio(@Nonnull CdSector cdSector) { // since all Chrono Cross movie sectors are in Mode 2 Form 1, we can // still decode the movie even if there is no raw sector header. - if (!subModeMaskMatch(SubMode.MASK_DATA | SubMode.MASK_FORM, SubMode.MASK_DATA)) + // DATA must be set, and FORM must not be set + if (subModeExistsAndMaskDoesNotEqual(SubMode.MASK_DATA | SubMode.MASK_FORM, SubMode.MASK_DATA)) return; // make sure the magic nubmer is correct diff --git a/jpsxdec/src/jpsxdec/modules/square/SectorChronoXVideo.java b/jpsxdec/src/jpsxdec/modules/square/SectorChronoXVideo.java index 3b0e6b0..6e8bb9f 100644 --- a/jpsxdec/src/jpsxdec/modules/square/SectorChronoXVideo.java +++ b/jpsxdec/src/jpsxdec/modules/square/SectorChronoXVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -75,7 +75,7 @@ public SectorChronoXVideo(@Nonnull CdSector cdSector) { if (isSuperInvalidElseReset()) return; // only if it has a sector header should we check if it reports DATA or VIDEO - if (subModeMaskMatch(SubMode.MASK_DATA | SubMode.MASK_VIDEO, 0)) + if (subModeExistsAndMaskEquals(SubMode.MASK_DATA | SubMode.MASK_VIDEO, 0)) return; if (_header.lngMagic != CHRONO_CROSS_VIDEO_CHUNK_MAGIC1 && diff --git a/jpsxdec/src/jpsxdec/modules/square/SectorChronoXVideoNull.java b/jpsxdec/src/jpsxdec/modules/square/SectorChronoXVideoNull.java index 820fafc..76e81f1 100644 --- a/jpsxdec/src/jpsxdec/modules/square/SectorChronoXVideoNull.java +++ b/jpsxdec/src/jpsxdec/modules/square/SectorChronoXVideoNull.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -58,7 +58,7 @@ public SectorChronoXVideoNull(@Nonnull CdSector cdSector) { if (cdSector.isCdAudioSector()) return; // only if it has a sector header should we check if it reports DATA or VIDEO - if (subModeMaskMatch(SubMode.MASK_DATA | SubMode.MASK_VIDEO, 0)) + if (subModeExistsAndMaskEquals(SubMode.MASK_DATA | SubMode.MASK_VIDEO, 0)) return; _lngMagic = cdSector.readUInt32LE(0); diff --git a/jpsxdec/src/jpsxdec/modules/square/SectorClaimToSquareAudioSector.java b/jpsxdec/src/jpsxdec/modules/square/SectorClaimToSquareAudioSector.java index 3c2e4b1..aef728a 100644 --- a/jpsxdec/src/jpsxdec/modules/square/SectorClaimToSquareAudioSector.java +++ b/jpsxdec/src/jpsxdec/modules/square/SectorClaimToSquareAudioSector.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/square/SectorFF8.java b/jpsxdec/src/jpsxdec/modules/square/SectorFF8.java index b41bdc0..12b2e1d 100644 --- a/jpsxdec/src/jpsxdec/modules/square/SectorFF8.java +++ b/jpsxdec/src/jpsxdec/modules/square/SectorFF8.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -64,8 +64,8 @@ public SectorFF8(@Nonnull CdSector cdSector) { if (cdSector.isCdAudioSector()) return; - // both audio and video sectors are flagged as data - if (!subModeMaskMatch(SubMode.MASK_DATA, SubMode.MASK_DATA)) + // both audio and video sectors are flagged as DATA + if (subModeExistsAndMaskDoesNotEqual(SubMode.MASK_DATA, SubMode.MASK_DATA)) return; char c; diff --git a/jpsxdec/src/jpsxdec/modules/square/SectorFF9.java b/jpsxdec/src/jpsxdec/modules/square/SectorFF9.java index 1cfc776..3be9f3b 100644 --- a/jpsxdec/src/jpsxdec/modules/square/SectorFF9.java +++ b/jpsxdec/src/jpsxdec/modules/square/SectorFF9.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/square/SquareAKAOstruct.java b/jpsxdec/src/jpsxdec/modules/square/SquareAKAOstruct.java index 5a80781..f78f916 100644 --- a/jpsxdec/src/jpsxdec/modules/square/SquareAKAOstruct.java +++ b/jpsxdec/src/jpsxdec/modules/square/SquareAKAOstruct.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorPair.java b/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorPair.java index 37cf0da..cdbaf4f 100644 --- a/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorPair.java +++ b/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorPair.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorPairToAudioPacket.java b/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorPairToAudioPacket.java index 7a78c60..46ff4e1 100644 --- a/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorPairToAudioPacket.java +++ b/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorPairToAudioPacket.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorToSquareAudioSectorPair.java b/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorToSquareAudioSectorPair.java index c47abfa..0c3176e 100644 --- a/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorToSquareAudioSectorPair.java +++ b/jpsxdec/src/jpsxdec/modules/square/SquareAudioSectorToSquareAudioSectorPair.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/DiscIndexerStrVideo.java b/jpsxdec/src/jpsxdec/modules/strvideo/DiscIndexerStrVideo.java index 2c6a2df..83ed860 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/DiscIndexerStrVideo.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/DiscIndexerStrVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -37,11 +37,6 @@ package jpsxdec.modules.strvideo; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import jpsxdec.cdreaders.CdFileSectorReader; @@ -49,18 +44,17 @@ import jpsxdec.discitems.SerializedDiscItem; import jpsxdec.i18n.exception.LocalizedDeserializationFail; import jpsxdec.i18n.log.ILocalizedLogger; -import jpsxdec.indexing.DiscIndex; -import jpsxdec.indexing.DiscIndexer; import jpsxdec.modules.SectorClaimSystem; import jpsxdec.modules.video.framenumber.HeaderFrameNumber; import jpsxdec.modules.video.framenumber.IndexSectorFrameNumber; import jpsxdec.modules.video.sectorbased.DemuxedFrameWithNumberAndDims; +import jpsxdec.modules.video.sectorbased.DiscIndexerSectorBasedVideo; import jpsxdec.modules.video.sectorbased.DiscItemSectorBasedVideoStream; import jpsxdec.modules.video.sectorbased.SectorBasedVideoInfoBuilder; -import jpsxdec.modules.xa.DiscItemXaAudioStream; /** Searches for most common video streams. */ -public class DiscIndexerStrVideo extends DiscIndexer implements DemuxedFrameWithNumberAndDims.Listener +public class DiscIndexerStrVideo extends DiscIndexerSectorBasedVideo.SubIndexer + implements DemuxedFrameWithNumberAndDims.Listener { /** Builds a single stream. */ @@ -120,17 +114,10 @@ public boolean addFrame(@Nonnull DemuxedFrameWithNumberAndDims frame) { } - @Nonnull - private final ILocalizedLogger _errLog; - private final Collection _completedVideos = new ArrayList(); private final StrVideoSectorToDemuxedStrFrame _videoDemuxer = new StrVideoSectorToDemuxedStrFrame(this); @CheckForNull private VidBuilder _videoBuilder; - public DiscIndexerStrVideo(@Nonnull ILocalizedLogger errLog) { - _errLog = errLog; - } - @Override public @CheckForNull DiscItem deserializeLineRead(@Nonnull SerializedDiscItem fields) throws LocalizedDeserializationFail @@ -157,65 +144,11 @@ private void endOfVideo(@Nonnull ILocalizedLogger log) { return; DiscItemSectorBasedVideoStream video = _videoBuilder.endOfMovie(getCd()); - _completedVideos.add(video); - addDiscItem(video); + addVideo(video); _videoBuilder = null; } public void endOfSectors(@Nonnull ILocalizedLogger log) { endOfVideo(log); } - - @Override - public void listPostProcessing(@Nonnull Collection allItems) { - if (_completedVideos.size() > 0) - audioSplit(_completedVideos, allItems); - } - - // TODO probably should move this to a shared place - public static void audioSplit(@Nonnull Collection videos, - @Nonnull Collection allItems) - { - List added = new ArrayList(); - - for (Iterator it = allItems.iterator(); it.hasNext();) { - DiscItem item = it.next(); - if (item instanceof DiscItemXaAudioStream) { - DiscItemXaAudioStream audio = (DiscItemXaAudioStream) item; - for (DiscItemSectorBasedVideoStream video : videos) { - int iSector = video.findAudioSplitPoint(audio); - if (iSector >= 0) { - DiscItemXaAudioStream[] aoSplit = audio.split(iSector); - it.remove(); - added.add(aoSplit[0]); - added.add(aoSplit[1]); - break; // will continue later with split items - } - } - } - } - - // now process the new items - for (ListIterator it = added.listIterator(); it.hasNext();) { - DiscItemXaAudioStream audio = it.next(); - for (DiscItemSectorBasedVideoStream video : videos) { - int iSector = video.findAudioSplitPoint(audio); - if (iSector >= 0) { - DiscItemXaAudioStream[] aoSplit = audio.split(iSector); - it.remove(); - it.add(aoSplit[0]); - it.add(aoSplit[1]); - it.previous(); // jump to before the split items - it.previous(); - break; // will continue with split items - } - } - } - allItems.addAll(added); - } - - @Override - public void indexGenerated(@Nonnull DiscIndex index) { - } - } diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/DiscItemStrVideoStream.java b/jpsxdec/src/jpsxdec/modules/strvideo/DiscItemStrVideoStream.java index 20a347a..bc80e9a 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/DiscItemStrVideoStream.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/DiscItemStrVideoStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/SectorAliceNullVideo.java b/jpsxdec/src/jpsxdec/modules/strvideo/SectorAliceNullVideo.java index fe6d028..c7fdf36 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/SectorAliceNullVideo.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/SectorAliceNullVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -68,7 +68,7 @@ public SectorAliceNullVideo(@Nonnull CdSector cdSector) { if (cdSector.isCdAudioSector()) return; // only if it has a sector header should we check if it reports DATA or VIDEO - if (subModeMaskMatch(SubMode.MASK_DATA | SubMode.MASK_VIDEO, 0)) + if (subModeExistsAndMaskEquals(SubMode.MASK_DATA | SubMode.MASK_VIDEO, 0)) return; if (_header.lngMagic != ALICE_VIDEO_SECTOR_MAGIC) diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/SectorAliceVideo.java b/jpsxdec/src/jpsxdec/modules/strvideo/SectorAliceVideo.java index dc4ac38..925b052 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/SectorAliceVideo.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/SectorAliceVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/SectorClaimToStrVideoSector.java b/jpsxdec/src/jpsxdec/modules/strvideo/SectorClaimToStrVideoSector.java index fa09971..94f6a27 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/SectorClaimToStrVideoSector.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/SectorClaimToStrVideoSector.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/SectorFF7Video.java b/jpsxdec/src/jpsxdec/modules/strvideo/SectorFF7Video.java index 0dab7a4..8094712 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/SectorFF7Video.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/SectorFF7Video.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -71,9 +71,9 @@ public SectorFF7Video(@Nonnull CdSector cdSector) { _header = new VideoSectorCommon16byteHeader(cdSector); if (isSuperInvalidElseReset()) return; - // SubMode flags "--FT-A--" should never be set + // SubMode flags "--2T-A--" should never be set // at least 1 movie doesn't have audio, video, or data flags set - if (!subModeMaskMatch(SubMode.MASK_FORM | SubMode.MASK_TRIGGER | SubMode.MASK_AUDIO, 0)) + if (subModeExistsAndMaskDoesNotEqual(SubMode.MASK_FORM | SubMode.MASK_TRIGGER | SubMode.MASK_AUDIO, 0)) return; if (_header.lngMagic != SectorStrVideo.VIDEO_SECTOR_MAGIC) return; diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/SectorIkiVideo.java b/jpsxdec/src/jpsxdec/modules/strvideo/SectorIkiVideo.java index d9b02ab..566511c 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/SectorIkiVideo.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/SectorIkiVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -74,7 +74,7 @@ public SectorIkiVideo(@Nonnull CdSector cdSector) { if (isSuperInvalidElseReset()) return; // only if it has a sector header should we check if it reports DATA or VIDEO - if (subModeMaskMatch(SubMode.MASK_DATA | SubMode.MASK_VIDEO, 0)) + if (subModeExistsAndMaskEquals(SubMode.MASK_DATA | SubMode.MASK_VIDEO, 0)) return; if (_header.lngMagic != SectorStrVideo.VIDEO_SECTOR_MAGIC) return; diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/SectorLainVideo.java b/jpsxdec/src/jpsxdec/modules/strvideo/SectorLainVideo.java index 72cd617..e7b6a5d 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/SectorLainVideo.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/SectorLainVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -72,8 +72,8 @@ public SectorLainVideo(@Nonnull CdSector cdSector) { _header = new VideoSectorCommon16byteHeader(cdSector); if (isSuperInvalidElseReset()) return; - // only if it has a sector header should we check if it reports DATA or VIDEO - if (subModeMaskMatch(SubMode.MASK_DATA | SubMode.MASK_VIDEO, 0)) + // if it has a sector header, make sure DATA flag are set + if (subModeExistsAndMaskDoesNotEqual(SubMode.MASK_DATA, SubMode.MASK_DATA)) return; if (_header.lngMagic != SectorStrVideo.VIDEO_SECTOR_MAGIC) return; diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/SectorReBoot.java b/jpsxdec/src/jpsxdec/modules/strvideo/SectorReBoot.java index 02703ac..4a84fd6 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/SectorReBoot.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/SectorReBoot.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/SectorStarbladeAlphaGalaxian3.java b/jpsxdec/src/jpsxdec/modules/strvideo/SectorStarbladeAlphaGalaxian3.java index 9004209..e240d28 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/SectorStarbladeAlphaGalaxian3.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/SectorStarbladeAlphaGalaxian3.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/SectorStrVideo.java b/jpsxdec/src/jpsxdec/modules/strvideo/SectorStrVideo.java index ad37c91..7e98599 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/SectorStrVideo.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/SectorStrVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/strvideo/StrVideoSectorToDemuxedStrFrame.java b/jpsxdec/src/jpsxdec/modules/strvideo/StrVideoSectorToDemuxedStrFrame.java index 86b6b05..f702bd2 100644 --- a/jpsxdec/src/jpsxdec/modules/strvideo/StrVideoSectorToDemuxedStrFrame.java +++ b/jpsxdec/src/jpsxdec/modules/strvideo/StrVideoSectorToDemuxedStrFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/tim/DiscIndexerTim.java b/jpsxdec/src/jpsxdec/modules/tim/DiscIndexerTim.java index 52164c9..2d9fffb 100644 --- a/jpsxdec/src/jpsxdec/modules/tim/DiscIndexerTim.java +++ b/jpsxdec/src/jpsxdec/modules/tim/DiscIndexerTim.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -82,7 +82,7 @@ public void attachToSectorClaimer(@Nonnull SectorClaimSystem scs) { @CheckForNull private DemuxPushInputStream _stream; - public void feedSector(CdSector sector) { + public void feedSector(@Nonnull CdSector sector) { CdSectorDemuxPiece piece = new CdSectorDemuxPiece(sector); if (_stream == null) _stream = new DemuxPushInputStream(piece); @@ -186,7 +186,10 @@ private void addTim(@Nonnull TimInfo tim) { @Override public void listPostProcessing(@Nonnull Collection allItems) { } - + @Override + public boolean filterChild(DiscItem parent, DiscItem child) { + return false; + } @Override public void indexGenerated(@Nonnull DiscIndex index) { } diff --git a/jpsxdec/src/jpsxdec/modules/tim/DiscItemTim.java b/jpsxdec/src/jpsxdec/modules/tim/DiscItemTim.java index 204510d..6a1a845 100644 --- a/jpsxdec/src/jpsxdec/modules/tim/DiscItemTim.java +++ b/jpsxdec/src/jpsxdec/modules/tim/DiscItemTim.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/tim/TimPaletteSelector.java b/jpsxdec/src/jpsxdec/modules/tim/TimPaletteSelector.java index 26cdd08..cd9b110 100644 --- a/jpsxdec/src/jpsxdec/modules/tim/TimPaletteSelector.java +++ b/jpsxdec/src/jpsxdec/modules/tim/TimPaletteSelector.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -79,8 +79,8 @@ protected void paintChildren(Graphics g) { int iWidth = this.getWidth() - 4; int iHeight = this.getHeight() - 4; - double dblHScale = iWidth / (double)_tim.getWidth(); - double dblVScale = iHeight / (double)_tim.getHeight(); + double dblHScale = iWidth / (double)_tim.getPixelWidth(); + double dblVScale = iHeight / (double)_tim.getPixelHeight(); double dblScale; if (dblHScale < dblVScale) @@ -90,8 +90,8 @@ protected void paintChildren(Graphics g) { if (dblScale > 2) dblScale = 2; - iWidth = (int)(_tim.getWidth() * dblScale); - iHeight = (int)(_tim.getHeight() * dblScale); + iWidth = (int)(_tim.getPixelWidth() * dblScale); + iHeight = (int)(_tim.getPixelHeight() * dblScale); BufferedImage bi = _tim.toBufferedImage(_iPalette); diff --git a/jpsxdec/src/jpsxdec/modules/tim/TimSaverBuilder.java b/jpsxdec/src/jpsxdec/modules/tim/TimSaverBuilder.java index df08271..4411e25 100644 --- a/jpsxdec/src/jpsxdec/modules/tim/TimSaverBuilder.java +++ b/jpsxdec/src/jpsxdec/modules/tim/TimSaverBuilder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -63,6 +63,7 @@ import jpsxdec.i18n.TabularFeedback; import jpsxdec.i18n.TabularFeedback.Cell; import jpsxdec.i18n.UnlocalizedMessage; +import jpsxdec.i18n._PlaceholderMessage; import jpsxdec.i18n.exception.LocalizedFileNotFoundException; import jpsxdec.i18n.exception.LoggedFailure; import jpsxdec.i18n.log.ILocalizedLogger; @@ -92,11 +93,11 @@ private TimSaveFormat(@Nonnull JavaImageFormat eJavaFmt) { _javaFmt = eJavaFmt; } - private @Nonnull String getId() { + private @Nonnull String getUiId() { if (_javaFmt == null) return "tim"; else - return _javaFmt.getId(); + return _javaFmt.getUiId(); } /** @throws UnsupportedOperationException if this is {@link #TIM}. */ @@ -277,7 +278,7 @@ else if (sStartFile == sEndFile) private @CheckForNull TimSaveFormat fromCmdLine(@Nonnull String sCmdLine) { for (TimSaveFormat fmt : _validFormats) { - if (fmt.getId().equalsIgnoreCase(sCmdLine)) + if (fmt.getUiId().equalsIgnoreCase(sCmdLine)) return fmt; } return null; @@ -408,6 +409,9 @@ private void startSaveTim(@Nonnull ProgressLogger pl, @CheckForNull File outputD throw new LoggedFailure(pl, Level.SEVERE, I.TIM_DATA_NOT_FOUND(), ex); } + if (tim.timHasIssues()) { + pl.log(Level.WARNING, new _PlaceholderMessage("Adapting for inconsistencies in Tim image {0}", tim)); + } pl.event(I.IO_WRITING_FILE(outputFile.getName())); try { IO.makeDirsForFile(outputFile); @@ -455,7 +459,7 @@ public void startSaveImage(@Nonnull ProgressLogger pl, @CheckForNull File output pl.event(I.IO_WRITING_FILE(f.toString())); IO.makeDirsForFile(f); try { - boolean blnOk = ImageIO.write(bi, _imageFormat.getId(), f); + boolean blnOk = ImageIO.write(bi, _imageFormat.getImageIOid(), f); if (blnOk) addGeneratedFile(f); else diff --git a/jpsxdec/src/jpsxdec/modules/tim/TimSaverBuilderGui.java b/jpsxdec/src/jpsxdec/modules/tim/TimSaverBuilderGui.java index 40d5e43..247f2ab 100644 --- a/jpsxdec/src/jpsxdec/modules/tim/TimSaverBuilderGui.java +++ b/jpsxdec/src/jpsxdec/modules/tim/TimSaverBuilderGui.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/AudioStreamsCombiner.java b/jpsxdec/src/jpsxdec/modules/video/AudioStreamsCombiner.java index e8617ca..039b193 100644 --- a/jpsxdec/src/jpsxdec/modules/video/AudioStreamsCombiner.java +++ b/jpsxdec/src/jpsxdec/modules/video/AudioStreamsCombiner.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/Dimensions.java b/jpsxdec/src/jpsxdec/modules/video/Dimensions.java index d0878ae..ed7f3e3 100644 --- a/jpsxdec/src/jpsxdec/modules/video/Dimensions.java +++ b/jpsxdec/src/jpsxdec/modules/video/Dimensions.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/DiscItemVideoStream.java b/jpsxdec/src/jpsxdec/modules/video/DiscItemVideoStream.java index 0f635ca..697caba 100644 --- a/jpsxdec/src/jpsxdec/modules/video/DiscItemVideoStream.java +++ b/jpsxdec/src/jpsxdec/modules/video/DiscItemVideoStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/IDemuxedFrame.java b/jpsxdec/src/jpsxdec/modules/video/IDemuxedFrame.java index a15f6f0..3771f15 100644 --- a/jpsxdec/src/jpsxdec/modules/video/IDemuxedFrame.java +++ b/jpsxdec/src/jpsxdec/modules/video/IDemuxedFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/ISectorClaimToDemuxedFrame.java b/jpsxdec/src/jpsxdec/modules/video/ISectorClaimToDemuxedFrame.java index cd6bfdb..5e7aeb8 100644 --- a/jpsxdec/src/jpsxdec/modules/video/ISectorClaimToDemuxedFrame.java +++ b/jpsxdec/src/jpsxdec/modules/video/ISectorClaimToDemuxedFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/ParallelAudio.java b/jpsxdec/src/jpsxdec/modules/video/ParallelAudio.java index bbdabff..aa201d5 100644 --- a/jpsxdec/src/jpsxdec/modules/video/ParallelAudio.java +++ b/jpsxdec/src/jpsxdec/modules/video/ParallelAudio.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/framenumber/FormattedFrameNumber.java b/jpsxdec/src/jpsxdec/modules/video/framenumber/FormattedFrameNumber.java index 33bef5d..453d89a 100644 --- a/jpsxdec/src/jpsxdec/modules/video/framenumber/FormattedFrameNumber.java +++ b/jpsxdec/src/jpsxdec/modules/video/framenumber/FormattedFrameNumber.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameCompareIs.java b/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameCompareIs.java index 0524a14..11497c6 100644 --- a/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameCompareIs.java +++ b/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameCompareIs.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameLookup.java b/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameLookup.java index 4d90841..6cf5e9f 100644 --- a/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameLookup.java +++ b/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameLookup.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameNumber.java b/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameNumber.java index badb02a..e2eb9a6 100644 --- a/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameNumber.java +++ b/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameNumber.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameNumberNumber.java b/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameNumberNumber.java index d5a2517..6526b4c 100644 --- a/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameNumberNumber.java +++ b/jpsxdec/src/jpsxdec/modules/video/framenumber/FrameNumberNumber.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/framenumber/HeaderFrameNumber.java b/jpsxdec/src/jpsxdec/modules/video/framenumber/HeaderFrameNumber.java index 04bafaa..28d8fc3 100644 --- a/jpsxdec/src/jpsxdec/modules/video/framenumber/HeaderFrameNumber.java +++ b/jpsxdec/src/jpsxdec/modules/video/framenumber/HeaderFrameNumber.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/framenumber/IFrameNumberFormatter.java b/jpsxdec/src/jpsxdec/modules/video/framenumber/IFrameNumberFormatter.java index 2b1a5f4..2df82ee 100644 --- a/jpsxdec/src/jpsxdec/modules/video/framenumber/IFrameNumberFormatter.java +++ b/jpsxdec/src/jpsxdec/modules/video/framenumber/IFrameNumberFormatter.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/framenumber/IFrameNumberFormatterWithHeader.java b/jpsxdec/src/jpsxdec/modules/video/framenumber/IFrameNumberFormatterWithHeader.java index 9f53983..27c8533 100644 --- a/jpsxdec/src/jpsxdec/modules/video/framenumber/IFrameNumberFormatterWithHeader.java +++ b/jpsxdec/src/jpsxdec/modules/video/framenumber/IFrameNumberFormatterWithHeader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/framenumber/IndexSectorFrameNumber.java b/jpsxdec/src/jpsxdec/modules/video/framenumber/IndexSectorFrameNumber.java index c754fde..0f3ef83 100644 --- a/jpsxdec/src/jpsxdec/modules/video/framenumber/IndexSectorFrameNumber.java +++ b/jpsxdec/src/jpsxdec/modules/video/framenumber/IndexSectorFrameNumber.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/packetbased/DiscItemPacketBasedVideoStream.java b/jpsxdec/src/jpsxdec/modules/video/packetbased/DiscItemPacketBasedVideoStream.java index ebddcb3..aa0c2fc 100644 --- a/jpsxdec/src/jpsxdec/modules/video/packetbased/DiscItemPacketBasedVideoStream.java +++ b/jpsxdec/src/jpsxdec/modules/video/packetbased/DiscItemPacketBasedVideoStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/packetbased/PacketBasedVideoSaverBuilder.java b/jpsxdec/src/jpsxdec/modules/video/packetbased/PacketBasedVideoSaverBuilder.java index b5b6831..02f0021 100644 --- a/jpsxdec/src/jpsxdec/modules/video/packetbased/PacketBasedVideoSaverBuilder.java +++ b/jpsxdec/src/jpsxdec/modules/video/packetbased/PacketBasedVideoSaverBuilder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/packetbased/PacketBasedVideoSaverBuilderGui.java b/jpsxdec/src/jpsxdec/modules/video/packetbased/PacketBasedVideoSaverBuilderGui.java index cf7e0bf..4a69405 100644 --- a/jpsxdec/src/jpsxdec/modules/video/packetbased/PacketBasedVideoSaverBuilderGui.java +++ b/jpsxdec/src/jpsxdec/modules/video/packetbased/PacketBasedVideoSaverBuilderGui.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/packetbased/SectorClaimToAudioAndFrame.java b/jpsxdec/src/jpsxdec/modules/video/packetbased/SectorClaimToAudioAndFrame.java index 6b0d988..1a97912 100644 --- a/jpsxdec/src/jpsxdec/modules/video/packetbased/SectorClaimToAudioAndFrame.java +++ b/jpsxdec/src/jpsxdec/modules/video/packetbased/SectorClaimToAudioAndFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFrameFull.java b/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFrameFull.java index d7122f3..b80937f 100644 --- a/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFrameFull.java +++ b/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFrameFull.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFramePartial.java b/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFramePartial.java index c578943..c7c844e 100644 --- a/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFramePartial.java +++ b/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFramePartial.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFrames.java b/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFrames.java index 1794ee1..339b91c 100644 --- a/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFrames.java +++ b/jpsxdec/src/jpsxdec/modules/video/replace/ReplaceFrames.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/save/AudioSync.java b/jpsxdec/src/jpsxdec/modules/video/save/AudioSync.java index 67afd45..f11cb7b 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/AudioSync.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/AudioSync.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/save/AudioVideoSync.java b/jpsxdec/src/jpsxdec/modules/video/save/AudioVideoSync.java index 55ef159..bbbdb21 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/AudioVideoSync.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/AudioVideoSync.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/save/AutowireVDP.java b/jpsxdec/src/jpsxdec/modules/video/save/AutowireVDP.java index 63f0921..cb0486b 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/AutowireVDP.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/AutowireVDP.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/save/Frame2Bitstream.java b/jpsxdec/src/jpsxdec/modules/video/save/Frame2Bitstream.java index 1957ff2..c57cf90 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/Frame2Bitstream.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/Frame2Bitstream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/save/MdecDecodeQuality.java b/jpsxdec/src/jpsxdec/modules/video/save/MdecDecodeQuality.java index 08b5ef4..14e22cd 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/MdecDecodeQuality.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/MdecDecodeQuality.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/save/VDP.java b/jpsxdec/src/jpsxdec/modules/video/save/VDP.java index 068071e..428ba84 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/VDP.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/VDP.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -428,7 +428,7 @@ public static class Decoded2JavaImage implements IDecodedListener { @Nonnull private final VideoFileNameFormatter _formatter; @Nonnull - private final String _sFmt; + private final String _sImageIOid; @Nonnull private final BufferedImage _rgbImg; @Nonnull @@ -438,7 +438,7 @@ public static class Decoded2JavaImage implements IDecodedListener { public Decoded2JavaImage(@Nonnull VideoFileNameFormatter formatter, @Nonnull JavaImageFormat eFmt, int iWidth, int iHeight, @Nonnull ILocalizedLogger log) { _formatter = formatter; - _sFmt = eFmt.getId(); + _sImageIOid = eFmt.getImageIOid(); _rgbImg = new BufferedImage(iWidth, iHeight, BufferedImage.TYPE_INT_RGB); _log = log; } @@ -459,7 +459,7 @@ public void decoded(@Nonnull MdecDecoder decoder, @CheckForNull FormattedFrameNu } try { - if (ImageIO.write(_rgbImg, _sFmt, f)) { + if (ImageIO.write(_rgbImg, _sImageIOid, f)) { if (_fileGenListener != null) _fileGenListener.fileGenerated(f); } else { diff --git a/jpsxdec/src/jpsxdec/modules/video/save/VideoFileNameFormatter.java b/jpsxdec/src/jpsxdec/modules/video/save/VideoFileNameFormatter.java index 45b3fe4..37610a1 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/VideoFileNameFormatter.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/VideoFileNameFormatter.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/save/VideoFormat.java b/jpsxdec/src/jpsxdec/modules/video/save/VideoFormat.java index afea025..2b94f04 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/VideoFormat.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/VideoFormat.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -39,6 +39,7 @@ import java.util.ArrayList; import java.util.List; +import jpsxdec.i18n._PlaceholderMessage; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import jpsxdec.formats.JavaImageFormat; @@ -86,6 +87,11 @@ public enum VideoFormat { { public String getExtension() { return "." + JavaImageFormat.BMP.getExtension(); } }, + IMGSEQ_TIFF(new _PlaceholderMessage("Image sequence: tiff"), new _PlaceholderMessage("tif"), + JavaImageFormat.TIFF) + { + public String getExtension() { return "." + JavaImageFormat.TIFF.getExtension(); } + }, IMGSEQ_BITSTREAM(I.VID_IMG_SEQ_BS_DESCRIPTION(), I.VID_IMG_SEQ_BS_COMMAND()) { public String getExtension() { return ".bs"; } public int getDecodeQualityCount() { return 0; } diff --git a/jpsxdec/src/jpsxdec/modules/video/save/VideoSaver.java b/jpsxdec/src/jpsxdec/modules/video/save/VideoSaver.java index 94136c0..980c2c4 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/VideoSaver.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/VideoSaver.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -126,7 +126,8 @@ public VideoSaver(@Nonnull DiscItemVideoStream vidItem, } break; case IMGSEQ_BMP: - case IMGSEQ_PNG: { + case IMGSEQ_PNG: + case IMGSEQ_TIFF: { addBitstream2Mdec(); addMdec2Decoded(log); JavaImageFormat javaImgFmt = _videoFormat.getImgFmt(); diff --git a/jpsxdec/src/jpsxdec/modules/video/save/VideoSaverBuilder.java b/jpsxdec/src/jpsxdec/modules/video/save/VideoSaverBuilder.java index be2b5a7..8ba2bd8 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/VideoSaverBuilder.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/VideoSaverBuilder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/save/VideoSaverPanel.java b/jpsxdec/src/jpsxdec/modules/video/save/VideoSaverPanel.java index 4501bc3..5d9f664 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/VideoSaverPanel.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/VideoSaverPanel.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/save/VideoSync.java b/jpsxdec/src/jpsxdec/modules/video/save/VideoSync.java index a6abb16..48603c2 100644 --- a/jpsxdec/src/jpsxdec/modules/video/save/VideoSync.java +++ b/jpsxdec/src/jpsxdec/modules/video/save/VideoSync.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/DemuxedFrameWithNumberAndDims.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/DemuxedFrameWithNumberAndDims.java index 2450092..cc1b249 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/DemuxedFrameWithNumberAndDims.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/DemuxedFrameWithNumberAndDims.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/DiscIndexerSectorBasedVideo.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/DiscIndexerSectorBasedVideo.java new file mode 100644 index 0000000..af1371e --- /dev/null +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/DiscIndexerSectorBasedVideo.java @@ -0,0 +1,183 @@ +/* + * jPSXdec: PlayStation 1 Media Decoder/Converter in Java + * Copyright (C) 2020 Michael Sabin + * All rights reserved. + * + * Redistribution and use of the jPSXdec code or any derivative works are + * permitted provided that the following conditions are met: + * + * * Redistributions may not be sold, nor may they be used in commercial + * or revenue-generating business activities. + * + * * Redistributions that are modified from the original source must + * include the complete source code, including the source code for all + * components used by a binary built from the modified sources. However, as + * a special exception, the source code distributed need not include + * anything that is normally distributed (in either source or binary form) + * with the major components (compiler, kernel, and so on) of the operating + * system on which the executable runs, unless that component itself + * accompanies the executable. + * + * * Redistributions must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package jpsxdec.modules.video.sectorbased; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import jpsxdec.cdreaders.CdFileSectorReader; +import jpsxdec.discitems.DiscItem; +import jpsxdec.discitems.SerializedDiscItem; +import jpsxdec.i18n.exception.LocalizedDeserializationFail; +import jpsxdec.i18n.log.ILocalizedLogger; +import jpsxdec.indexing.DiscIndex; +import jpsxdec.indexing.DiscIndexer; +import jpsxdec.modules.SectorClaimSystem; +import jpsxdec.modules.ac3.DiscIndexerAceCombat3Video; +import jpsxdec.modules.dredd.DiscIndexerDredd; +import jpsxdec.modules.strvideo.DiscIndexerStrVideo; +import jpsxdec.modules.xa.DiscItemXaAudioStream; + +/** Manages all sector-based video indexing since they all share common + * post-processing. */ +public class DiscIndexerSectorBasedVideo extends DiscIndexer { + + private static final Logger LOG = Logger.getLogger(DiscIndexerSectorBasedVideo.class.getName()); + + public static abstract class SubIndexer { + + private DiscIndexerSectorBasedVideo _parentIndexer; + + final protected void addVideo(@Nonnull DiscItemSectorBasedVideoStream video) { + _parentIndexer._completedVideos.add(video); + _parentIndexer.addDiscItem(video); + } + + final protected @Nonnull CdFileSectorReader getCd() { + return _parentIndexer.getCd(); + } + + abstract public void attachToSectorClaimer(@Nonnull SectorClaimSystem scs); + + abstract public @CheckForNull DiscItem deserializeLineRead(@Nonnull SerializedDiscItem fields) throws LocalizedDeserializationFail; + } + + private final Collection _completedVideos = new ArrayList(); + @Nonnull + private final SubIndexer[] _sectorBasedVideoIndexers; + + public DiscIndexerSectorBasedVideo(@Nonnull ILocalizedLogger log) { + _sectorBasedVideoIndexers = new SubIndexer[] { + new DiscIndexerStrVideo(), + new DiscIndexerAceCombat3Video(log), + new DiscIndexerDredd(), + }; + + for (SubIndexer vidIndexer : _sectorBasedVideoIndexers) { + vidIndexer._parentIndexer = this; + } + } + + @Override + public void attachToSectorClaimer(@Nonnull SectorClaimSystem scs) { + for (SubIndexer indexer : _sectorBasedVideoIndexers) { + indexer.attachToSectorClaimer(scs); + } + } + + @Override + public @CheckForNull DiscItem deserializeLineRead(@Nonnull SerializedDiscItem fields) throws LocalizedDeserializationFail { + for (SubIndexer indexer : _sectorBasedVideoIndexers) { + DiscItem item = indexer.deserializeLineRead(fields); + if (item != null) + return item; + } + return null; + } + + @Override + public void listPostProcessing(@Nonnull Collection allItems) { + if (!_completedVideos.isEmpty()) + audioSplit(_completedVideos, allItems); + } + + @Override + public boolean filterChild(@CheckForNull DiscItem parent, @Nonnull DiscItem child) { + + boolean blnIsSilentXa = (child instanceof DiscItemXaAudioStream) && + (!(parent instanceof DiscItemSectorBasedVideoStream)) && + ((DiscItemXaAudioStream) child).isConfirmedToBeSilent(); + if (blnIsSilentXa) + LOG.log(Level.INFO, "Discarding silent XA {0}", child); + return blnIsSilentXa; + } + + private static void audioSplit(@Nonnull Collection videos, + @Nonnull Collection allItems) + { + List added = new ArrayList(); + + for (Iterator it = allItems.iterator(); it.hasNext();) { + DiscItem item = it.next(); + if (item instanceof DiscItemXaAudioStream) { + DiscItemXaAudioStream audio = (DiscItemXaAudioStream) item; + for (DiscItemSectorBasedVideoStream video : videos) { + int iSector = video.findAudioSplitPoint(audio); + if (iSector >= 0) { + DiscItemXaAudioStream[] aoSplit = audio.split(iSector); + it.remove(); + added.add(aoSplit[0]); + added.add(aoSplit[1]); + break; // will process new items later + } + } + } + } + + // now process the new items + for (ListIterator it = added.listIterator(); it.hasNext();) { + DiscItemXaAudioStream audio = it.next(); + for (DiscItemSectorBasedVideoStream video : videos) { + int iSector = video.findAudioSplitPoint(audio); + if (iSector >= 0) { + // split the already split item + DiscItemXaAudioStream[] aoSplit = audio.split(iSector); + it.remove(); + it.add(aoSplit[0]); + it.add(aoSplit[1]); + it.previous(); // backup to before the new split items + it.previous(); + break; // continue processing at split items + } + } + } + allItems.addAll(added); + } + + + @Override + public void indexGenerated(@Nonnull DiscIndex index) { + } + +} diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/DiscItemSectorBasedVideoStream.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/DiscItemSectorBasedVideoStream.java index 0ac3a45..d450ea1 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/DiscItemSectorBasedVideoStream.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/DiscItemSectorBasedVideoStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/ISelfDemuxingVideoSector.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/ISelfDemuxingVideoSector.java index 8017191..3535ba1 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/ISelfDemuxingVideoSector.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/ISelfDemuxingVideoSector.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2018-2019 Michael Sabin + * Copyright (C) 2018-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/IVideoSectorWithFrameNumber.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/IVideoSectorWithFrameNumber.java index 3b3cb00..fdf7887 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/IVideoSectorWithFrameNumber.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/IVideoSectorWithFrameNumber.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorAbstractVideo.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorAbstractVideo.java index 7e4a5a7..4d8a535 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorAbstractVideo.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorAbstractVideo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedFrameBuilder.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedFrameBuilder.java index 4842889..f392000 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedFrameBuilder.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedFrameBuilder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedFrameReplace.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedFrameReplace.java index 6c68731..11f3844 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedFrameReplace.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedFrameReplace.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoInfo.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoInfo.java index 2ec2403..3810daa 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoInfo.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoInfo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoInfoBuilder.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoInfoBuilder.java index 46dd31f..d242342 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoInfoBuilder.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoInfoBuilder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoSaverBuilder.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoSaverBuilder.java index 628f00d..a921db4 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoSaverBuilder.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoSaverBuilder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoSaverBuilderGui.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoSaverBuilderGui.java index 98243dd..3da1d08 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoSaverBuilderGui.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/SectorBasedVideoSaverBuilderGui.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -122,16 +122,16 @@ public Object get(SectorBasedVideoSaverBuilder bldr, int i) { public void set(SectorBasedVideoSaverBuilder bldr, int i, Object val) {} @Nonnull - private final Class _type; + private final Class _type; @Nonnull private final ILocalizedMessage _name; - private COLUMNS(@Nonnull Class type, @Nonnull ILocalizedMessage name) { + private COLUMNS(@Nonnull Class type, @Nonnull ILocalizedMessage name) { _type = type; _name = name; } - final public Class type() { return _type; }; + final public Class type() { return _type; }; @Override final public String toString() { return _name.getLocalizedMessage(); } } diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorCommon16byteHeader.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorCommon16byteHeader.java index aa45080..f57623e 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorCommon16byteHeader.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorCommon16byteHeader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorIdentifier.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorIdentifier.java index d75c899..7262aba 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorIdentifier.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorIdentifier.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2018-2019 Michael Sabin + * Copyright (C) 2018-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorWithFrameNumberDemuxer.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorWithFrameNumberDemuxer.java index 879c9eb..dece952 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorWithFrameNumberDemuxer.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/VideoSectorWithFrameNumberDemuxer.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/InconsistentFrameSequence.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/InconsistentFrameSequence.java index c049d13..f52823d 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/InconsistentFrameSequence.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/InconsistentFrameSequence.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/StrFrameRateCalc.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/StrFrameRateCalc.java index fb45133..7d6cc09 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/StrFrameRateCalc.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/StrFrameRateCalc.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/WholeNumberSectorsPerFrame.java b/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/WholeNumberSectorsPerFrame.java index 115235c..def65f3 100644 --- a/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/WholeNumberSectorsPerFrame.java +++ b/jpsxdec/src/jpsxdec/modules/video/sectorbased/fps/WholeNumberSectorsPerFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/modules/xa/DiscIndexerXaAudio.java b/jpsxdec/src/jpsxdec/modules/xa/DiscIndexerXaAudio.java index 53ff48a..af76a96 100644 --- a/jpsxdec/src/jpsxdec/modules/xa/DiscIndexerXaAudio.java +++ b/jpsxdec/src/jpsxdec/modules/xa/DiscIndexerXaAudio.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -37,12 +37,16 @@ package jpsxdec.modules.xa; +import java.util.BitSet; import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; import java.util.logging.Level; -import java.util.logging.Logger; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import jpsxdec.cdreaders.CdSector; +import jpsxdec.cdreaders.CdSectorXaSubHeader; import jpsxdec.discitems.DiscItem; import jpsxdec.discitems.SerializedDiscItem; import jpsxdec.i18n.I; @@ -51,14 +55,13 @@ import jpsxdec.indexing.DiscIndex; import jpsxdec.indexing.DiscIndexer; import jpsxdec.modules.SectorClaimSystem; +import jpsxdec.util.Misc; /** Watches for XA audio streams. * Tracks the channel numbers and maintains all the XA streams. * Adds them to the media list as they end. */ public class DiscIndexerXaAudio extends DiscIndexer implements SectorClaimToSectorXaAudio.Listener { - private static final Logger LOG = Logger.getLogger(DiscIndexerXaAudio.class.getName()); - @Nonnull private final ILocalizedLogger _errLog; @@ -69,9 +72,12 @@ public DiscIndexerXaAudio(@Nonnull ILocalizedLogger errLog) { @Override public void listPostProcessing(Collection allItems) { } - @Override - public void indexGenerated(DiscIndex index) { + public boolean filterChild(DiscItem parent, DiscItem child) { + return false; + } + @Override + public void indexGenerated(@Nonnull DiscIndex index) { } /** Tracks the indexing of one audio stream in one channel. */ @@ -80,21 +86,15 @@ private static class AudioStreamIndex { /** First sector of the audio stream. */ private final int _iStartSector; - /** Last sector before {@link #_currentXA} that was a part of this stream. */ - @CheckForNull - private SectorXaAudio _previousXA; - /** Last sector (or 'current' sector, if you will) that was a part of this stream. - * Is never null. */ @Nonnull - private SectorXaAudio _currentXA; + private final XaAudioFormat _format; - /** Get the last (or 'current') sector that was part of this stream. - * May be null. */ - public @Nonnull SectorXaAudio getCurrent() { return _currentXA; } + private final BitSet _sectorsWithAudio = new BitSet(); + private int _iSectorCount; + private int _iEndSector; /** Number of sectors between XA sectors that are part of this stream. - * Should only ever be 1, 2, 4, 8, 16, or 32 - * (enforced by {@link SectorXAAudio#matchesPrevious(jpsxdec.sectors.IdentifiedSector)}). + * Should only ever be 1, 2, 4, 8, 16, or 32. * Is -1 until 2nd sector is discovered. */ private int _iAudioStride = -1; @@ -102,8 +102,11 @@ private static class AudioStreamIndex { private final ILocalizedLogger _errLog; public AudioStreamIndex(@Nonnull SectorXaAudio first, @Nonnull ILocalizedLogger errLog) { - _currentXA = first; - _iStartSector = first.getSectorNumber(); + _format = new XaAudioFormat(first); + _iEndSector = _iStartSector = first.getSectorNumber(); + _iSectorCount = 1; + if (!first.isSilent()) + _sectorsWithAudio.set(0); _errLog = errLog; } @@ -111,47 +114,101 @@ public AudioStreamIndex(@Nonnull SectorXaAudio first, @Nonnull ILocalizedLogger * @return true if the sector was accepted as part of this stream, * or false if the stream is finished. */ - public boolean sectorRead(@Nonnull SectorXaAudio newCurrent) { + public boolean sectorRead(@Nonnull SectorXaAudio nextXa) { - if (!newCurrent.matchesPrevious(_currentXA)) + if (!_format.equals(new XaAudioFormat(nextXa))) return false; + int iStride = nextXa.getSectorNumber() - _iEndSector; + + if (iStride != 1) { + int iDiscSpeed = _format.calculateDiscSpeed(iStride); + if (iDiscSpeed < 0) + return false; + } + // check the stride - int iStride = newCurrent.getSectorNumber() - _currentXA.getSectorNumber(); if (_iAudioStride < 0) _iAudioStride = iStride; else if (iStride != _iAudioStride) return false; - _previousXA = _currentXA; - _currentXA = newCurrent; + _iEndSector = nextXa.getSectorNumber(); + if (!nextXa.isSilent()) + _sectorsWithAudio.set(_iSectorCount); + + _iSectorCount++; return true; // the sector was accepted } public void createMediaItem(@Nonnull DiscIndexerXaAudio adder) { - if (_previousXA == null && _currentXA.isSilent()) { - _errLog.log(Level.INFO, I.IGNORING_SILENT_XA_SECTOR(_iStartSector, _currentXA.getChannel())); + if (_iSectorCount == 1 && _sectorsWithAudio.isEmpty()) { + _errLog.log(Level.INFO, I.IGNORING_SILENT_XA_SECTOR(_iStartSector, _format.iChannel)); return; } adder.addDiscItem(new DiscItemXaAudioStream( adder.getCd(), - _iStartSector, _currentXA.getSectorNumber(), - _currentXA.getChannel(), - _currentXA.getSamplesPerSecond(), - _currentXA.isStereo(), _currentXA.getAdpcmBitsPerSample(), - _iAudioStride)); + _iStartSector, _iEndSector, + _format, + _iAudioStride, + _sectorsWithAudio)); } public boolean ended(int iSectorNum) { return (_iAudioStride >= 0) && - (iSectorNum > _currentXA.getSectorNumber() + _iAudioStride); + (iSectorNum > _iEndSector + _iAudioStride); } } + private static class FileChannel implements Comparable { + public final int iFileNumber; + public final int iChanel; - private final AudioStreamIndex[] _aoChannels = - new AudioStreamIndex[SectorXaAudio.MAX_VALID_CHANNEL+1]; + public FileChannel(int iFileNumber, int iChanel) { + this.iFileNumber = iFileNumber; + this.iChanel = iChanel; + } + + public FileChannel(@Nonnull SectorXaAudio xaSector) { + this.iFileNumber = xaSector.getFileNumber(); + this.iChanel = xaSector.getChannel(); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + this.iFileNumber; + hash = 89 * hash + this.iChanel; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + FileChannel other = (FileChannel) obj; + return this.iFileNumber == other.iFileNumber && + this.iChanel == other.iChanel; + } + + @Override + public int compareTo(FileChannel o) { + int i = Misc.intCompare(iFileNumber, o.iFileNumber); + return i != 0 ? i : Misc.intCompare(iChanel, o.iChanel); + } + + @Override + public String toString() { + return "File:" + iFileNumber + " Channel:" + iChanel; + } + + } + + private final TreeMap _channels + = new TreeMap(); @Override public @CheckForNull DiscItem deserializeLineRead(@Nonnull SerializedDiscItem serial) @@ -174,43 +231,47 @@ public void feedXaSector(@Nonnull CdSector cdSector, @Nonnull ILocalizedLogger log) { if (xaSector != null) { - AudioStreamIndex audStream = _aoChannels[xaSector.getChannel()]; + FileChannel fc = new FileChannel(xaSector); + AudioStreamIndex audStream = _channels.get(fc); if (audStream == null) { - _aoChannels[xaSector.getChannel()] = new AudioStreamIndex(xaSector, _errLog); + _channels.put(fc, new AudioStreamIndex(xaSector, _errLog)); } else if (!audStream.sectorRead(xaSector)) { audStream.createMediaItem(this); - _aoChannels[xaSector.getChannel()] = new AudioStreamIndex(xaSector, _errLog); + _channels.put(fc, new AudioStreamIndex(xaSector, _errLog)); } } // check for streams that are beyond their stride and close them - for (int i = 0; i < _aoChannels.length; i++) { - AudioStreamIndex s = _aoChannels[i]; + Iterator> it = _channels.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry channelStream = it.next(); + AudioStreamIndex s = channelStream.getValue(); if (s != null && s.ended(cdSector.getSectorIndexFromStart())) { s.createMediaItem(this); - _aoChannels[i] = null; + it.remove(); } } - } - public void xaEof(int iChannel) { - // if the sector's EOF bit was set, this stream is closed + + // if the sector's EOF bit was set, that channel's stream is closed // this is important for many games - if (iChannel < _aoChannels.length) { - AudioStreamIndex audStream = _aoChannels[iChannel]; + CdSectorXaSubHeader sh = cdSector.getSubHeader(); + if (sh != null && sh.getSubMode().getEndOfFile() && + sh.getChannel() <= CdSector.MAX_VALID_CHANNEL) + { + FileChannel fc = new FileChannel(sh.getFileNumber(), sh.getChannel()); + AudioStreamIndex audStream = _channels.get(fc); if (audStream != null) { audStream.createMediaItem(this); - _aoChannels[iChannel] = null; + _channels.remove(fc); } } } + public void endOfSectors(@Nonnull ILocalizedLogger log) { - for (int i = 0; i < _aoChannels.length; i++) { - AudioStreamIndex audStream = _aoChannels[i]; - if (audStream != null) { - audStream.createMediaItem(this); - _aoChannels[i] = null; - } + for (AudioStreamIndex audStream : _channels.values()) { + audStream.createMediaItem(this); } + _channels.clear(); } } diff --git a/jpsxdec/src/jpsxdec/modules/xa/DiscItemXaAudioStream.java b/jpsxdec/src/jpsxdec/modules/xa/DiscItemXaAudioStream.java index a1686f4..2570065 100644 --- a/jpsxdec/src/jpsxdec/modules/xa/DiscItemXaAudioStream.java +++ b/jpsxdec/src/jpsxdec/modules/xa/DiscItemXaAudioStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -40,9 +40,11 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.util.BitSet; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; @@ -72,29 +74,14 @@ /** Represents a series of XA ADPCM sectors that combine to make an audio stream. */ public class DiscItemXaAudioStream extends DiscItemAudioStream { - /** Type identifier for this disc item. */ - public static final String TYPE_ID = "XA"; - /** Serialization key for Channel. */ - private final static String CHANNEL_KEY = "Channel"; + private static final Logger LOG = Logger.getLogger(DiscItemXaAudioStream.class.getName()); - /** CD stream channel number. Should be between 0 and 31, inclusive. */ - private final int _iChannel; - - /** Serialization key for sample rate. */ - private static final String SAMPLES_PER_SEC_KEY = "Samples/Sec"; - /** Sample rate of the audio stream. Should be either 37800 or 18900. */ - private final int _iSampleFramesPerSecond; - - /** Serialization key for stereo. */ - private static final String STEREO_KEY = "Stereo?"; - /** If the audio is in stereo. */ - private final boolean _blnIsStereo; + /** Type identifier for this disc item. */ + public static final String TYPE_ID = "XA"; - /** Serialization key for bits/sample. */ - private final static String BITSPERSAMPLE_KEY = "Bits/Sample"; - /** ADPCM bits per sample that the audio is encoded as. Should be 4 or 8. */ - private final int _iBitsPerSample; + @Nonnull + private final XaAudioFormat _format; /** Serialization key for audio sector stride. */ private final static String STRIDE_KEY = "Sector stride"; @@ -114,30 +101,24 @@ public class DiscItemXaAudioStream extends DiscItemAudioStream { * or invalid (sector stride is 1) * */ - private int _iDiscSpeed; + private final int _iDiscSpeed; + + @CheckForNull + private final BitSet _sectorsWithAudio; public DiscItemXaAudioStream(@Nonnull CdFileSectorReader cd, int iStartSector, int iEndSector, - int iChannel, int iSamplesPerSecond, - boolean blnIsStereo, int iBitsPerSample, - int iStride) + @Nonnull XaAudioFormat format, + int iStride, + @CheckForNull BitSet sectorsWithAudio) { super(cd, iStartSector, iEndSector); - if (iChannel < 0 || iChannel > SectorXaAudio.MAX_VALID_CHANNEL) throw new IllegalArgumentException( - "Channel " + iChannel + " is not between 0 and " + SectorXaAudio.MAX_VALID_CHANNEL); - if (iBitsPerSample != 4 && iBitsPerSample != 8) - throw new IllegalArgumentException("Bits/sample " + iBitsPerSample + " is not 4 or 8"); - if (iSamplesPerSecond != 37800 && iSamplesPerSecond != 18900) - throw new IllegalArgumentException(); if (iStride != -1 && iStride != 1 && iStride != 2 && iStride != 4 && iStride != 8 && iStride != 16 && iStride != 32) throw new IllegalArgumentException("Illegal audio sector stride " + iStride); - - _iSampleFramesPerSecond = iSamplesPerSecond; - _blnIsStereo = blnIsStereo; - _iChannel = iChannel; - _iBitsPerSample = iBitsPerSample; + + _format = format; _iSectorStride = iStride; // if there is no sector stride (iStride == -1, 1 sector long) @@ -145,25 +126,24 @@ public DiscItemXaAudioStream(@Nonnull CdFileSectorReader cd, if (_iSectorStride == -1 || _iSectorStride == 1) { _iDiscSpeed = -1; } else { - _iDiscSpeed = SectorXaAudio.calculateDiscSpeed(_iSampleFramesPerSecond, _blnIsStereo, _iBitsPerSample, _iSectorStride); + _iDiscSpeed = _format.calculateDiscSpeed(_iSectorStride); if (_iDiscSpeed < 1) throw new RuntimeException(String.format( "Disc speed calc doesn't add up: Samples/sec %d Stereo %s Bits/sample %s Stride %d", - _iSampleFramesPerSecond, String.valueOf(_blnIsStereo), - _iBitsPerSample, _iSectorStride)); + _format.iSampleFramesPerSecond, String.valueOf(_format.blnIsStereo), + _format.iBitsPerSample, _iSectorStride)); } + + _sectorsWithAudio = sectorsWithAudio; } public DiscItemXaAudioStream(@Nonnull CdFileSectorReader cd, @Nonnull SerializedDiscItem fields) throws LocalizedDeserializationFail { super(cd, fields); - - _blnIsStereo = fields.getYesNo(STEREO_KEY); - _iSampleFramesPerSecond = fields.getInt(SAMPLES_PER_SEC_KEY); - _iChannel = fields.getInt(CHANNEL_KEY); - _iBitsPerSample = fields.getInt(BITSPERSAMPLE_KEY); + _format = new XaAudioFormat(fields); + _iSectorStride = fields.getInt(STRIDE_KEY); if (_iSectorStride != -1 && _iSectorStride != 1 && _iSectorStride != 2 && _iSectorStride != 4 && _iSectorStride != 8 && _iSectorStride != 16 && _iSectorStride != 32) @@ -177,16 +157,16 @@ else if ("2x".equals(sDiscSpeed)) else if ("?".equals(sDiscSpeed)) _iDiscSpeed = -1; else throw new LocalizedDeserializationFail(I.FIELD_HAS_INVALID_VALUE_STR(DISC_SPEED_KEY, sDiscSpeed)); + + _sectorsWithAudio = null; } @Override public @Nonnull SerializedDiscItem serialize() { SerializedDiscItem fields = super.serialize(); - fields.addNumber(CHANNEL_KEY, _iChannel); - fields.addYesNo(STEREO_KEY, _blnIsStereo); - fields.addNumber(SAMPLES_PER_SEC_KEY, _iSampleFramesPerSecond); - fields.addNumber(BITSPERSAMPLE_KEY, _iBitsPerSample); + _format.serialize(fields); + fields.addNumber(STRIDE_KEY, _iSectorStride); switch (_iDiscSpeed) { case 1: fields.addString(DISC_SPEED_KEY, "1x"); break; @@ -206,11 +186,12 @@ else if ("?".equals(sDiscSpeed)) } public int getChannel() { - return _iChannel; + return _format.iChannel; } - + + @Override public boolean isStereo() { - return _blnIsStereo; + return _format.blnIsStereo; } public int getSectorStride() { @@ -228,16 +209,12 @@ public int getDiscSpeed() { @Override public @Nonnull ILocalizedMessage getInterestingDescription() { Date secs = Misc.dateFromSeconds(Math.max((int)getApproxDuration(), 1)); - return I.GUI_AUDIO_DESCRIPTION(secs, _iSampleFramesPerSecond, _blnIsStereo ? 2 : 1); + return I.GUI_AUDIO_DESCRIPTION(secs, _format.iSampleFramesPerSecond, _format.blnIsStereo ? 2 : 1); } - + @Override public int getSampleFramesPerSecond() { - return _iSampleFramesPerSecond; - } - - public int getAdpcmBitsPerSample() { - return _iBitsPerSample; + return _format.iSampleFramesPerSecond; } public int getPresentationStartSector() { @@ -246,46 +223,79 @@ public int getPresentationStartSector() { @Override public double getApproxDuration() { - return getSampleFrameCount() / (double)_iSampleFramesPerSecond; + return getSampleFrameCount() / (double)_format.iSampleFramesPerSecond; } public long getSampleFrameCount() { int iAudioSectorCount = getAudioSectorCount(); return (long)iAudioSectorCount * - XaAdpcmDecoder.pcmSampleFramesGeneratedFromXaAdpcmSector(_iBitsPerSample, _blnIsStereo); + XaAdpcmDecoder.pcmSampleFramesGeneratedFromXaAdpcmSector(_format.iBitsPerSample, _format.blnIsStereo); } private int getAudioSectorCount() { + return calculateAudioSectorCount(getSectorLength(), _iSectorStride); + } + + private static int calculateAudioSectorCount(int iSectorLength, int iSectorStride) { int iAudioSectorCount; - int iSectorLength = getSectorLength(); if (iSectorLength == 1) iAudioSectorCount = 1; else { - assert _iSectorStride > 0; - iAudioSectorCount = getSectorLength() / _iSectorStride + 1; + assert iSectorStride > 0; + iAudioSectorCount = iSectorLength / iSectorStride + 1; } return iAudioSectorCount; } + public boolean isConfirmedToBeSilent() { + if (_sectorsWithAudio == null) + return false; // without the bitset, we can't confirm if it is silent + return _sectorsWithAudio.isEmpty(); + } + + @Override + public String toString() { + if (isConfirmedToBeSilent()) + return super.toString() + " // (SILENT)"; + else + return super.toString(); + } + public @Nonnull ISectorAudioDecoder makeDecoder(double dblVolume) { return new XAConverter(dblVolume); } public @Nonnull XaAdpcmDecoder makeXaDecoder(double dblVolume) { - return new XaAdpcmDecoder(getAdpcmBitsPerSample(), + return new XaAdpcmDecoder(_format.iBitsPerSample, isStereo(), dblVolume); } + /** Returns an array with 2 elements. */ public @Nonnull DiscItemXaAudioStream[] split(int iBeforeSector) { if (iBeforeSector <= getStartSector() || iBeforeSector > getEndSector()) throw new IllegalArgumentException("Split sector outside the bounds of XA audio stream"); int iFirstEnd = iBeforeSector - ((iBeforeSector - getStartSector()-1) % _iSectorStride) - 1; int iSecondStart = iBeforeSector + (_iSectorStride - (iBeforeSector - getStartSector()-1) % _iSectorStride) - 1; + + BitSet firstSectorsWithAudio = null; + BitSet secondSectorsWithAudio = null; + if (_sectorsWithAudio != null) { + int iSectorsInFirst = calculateAudioSectorCount(iFirstEnd - getStartSector() + 1, _iSectorStride); + if (iSectorsInFirst >= _sectorsWithAudio.length()) { + firstSectorsWithAudio = _sectorsWithAudio; + secondSectorsWithAudio = new BitSet(); + } else { + firstSectorsWithAudio = _sectorsWithAudio.get(0, iSectorsInFirst); + secondSectorsWithAudio = _sectorsWithAudio.get(iSectorsInFirst, _sectorsWithAudio.length()); + } + } + + DiscItemXaAudioStream first = new DiscItemXaAudioStream(getSourceCd(), getStartSector(), iFirstEnd, - _iChannel, _iSampleFramesPerSecond, _blnIsStereo, _iBitsPerSample, _iSectorStride); + _format, _iSectorStride, firstSectorsWithAudio); DiscItemXaAudioStream second = new DiscItemXaAudioStream(getSourceCd(), iSecondStart, getEndSector(), - _iChannel, _iSampleFramesPerSecond, _blnIsStereo, _iBitsPerSample, _iSectorStride); + _format, _iSectorStride, secondSectorsWithAudio); return new DiscItemXaAudioStream[] { first, second }; } @@ -302,7 +312,7 @@ public void replaceXa(@Nonnull ProgressLogger pl, @Nonnull File audioFile) AudioInputStream ais = AudioSystem.getAudioInputStream(audioFile); try { AudioFormat fmt = ais.getFormat(); - boolean blnFormatEquals = Math.abs(fmt.getSampleRate() - _iSampleFramesPerSecond) < 1f; + boolean blnFormatEquals = Math.abs(fmt.getSampleRate() - _format.iSampleFramesPerSecond) < 1f; blnFormatEquals &= ( isStereo() && (fmt.getChannels() == 2) ) || ( !isStereo() && (fmt.getChannels() == 1) ); @@ -318,34 +328,38 @@ public void replaceXa(@Nonnull ProgressLogger pl, @Nonnull File audioFile) XaAdpcmEncoder encoder; try { - encoder = new XaAdpcmEncoder(ais, _iBitsPerSample); + encoder = new XaAdpcmEncoder(ais, _format.iBitsPerSample); } catch (IncompatibleException ex) { throw new RuntimeException("This should have been checked above", ex); } - SectorClaimSystem it = createClaimSystem(); - pl.progressStart(getSectorLength()); - for (int iSector = 0; it.hasNext(); iSector++) { - IIdentifiedSector origIdSect = it.next(pl).getClaimer(); - if (origIdSect instanceof SectorXaAudio && isPartOfStream((SectorXaAudio)origIdSect)) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - long lngSampleFramesReadBefore = encoder.getSampleFramesRead(); - pl.log(Level.INFO, I.WRITING_SAMPLES_TO_SECTOR(lngSampleFramesReadBefore, origIdSect.toString())); - // don't care if encoder is eof - // if (encoder.isEof()) ... - pl.log(Level.INFO, I.CMD_PATCHING_SECTOR_DESCRIPTION(origIdSect.toString())); - if (pl.isSeekingEvent()) - pl.event(I.CMD_PATCHING_SECTOR_NUMBER(origIdSect.getSectorNumber())); - CdSector origSect = origIdSect.getCdSector(); - getSourceCd().addPatch(origSect.getSectorIndexFromStart(), 0, baos.toByteArray()); - - pl.progressUpdate(iSector); + try { + SectorClaimSystem it = createClaimSystem(); + pl.progressStart(getSectorLength()); + for (int iSector = 0; it.hasNext(); iSector++) { + IIdentifiedSector origIdSect = it.next(pl).getClaimer(); + if (origIdSect instanceof SectorXaAudio && isPartOfStream((SectorXaAudio)origIdSect)) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + long lngSampleFramesReadBefore = encoder.getSampleFramesRead(); + pl.log(Level.INFO, I.WRITING_SAMPLES_TO_SECTOR(lngSampleFramesReadBefore, origIdSect.toString())); + encoder.encode1Sector(baos); + assert !encoder.isEof(); + pl.log(Level.INFO, I.CMD_PATCHING_SECTOR_DESCRIPTION(origIdSect.toString())); + if (pl.isSeekingEvent()) + pl.event(I.CMD_PATCHING_SECTOR_NUMBER(origIdSect.getSectorNumber())); + CdSector origSect = origIdSect.getCdSector(); + getSourceCd().addPatch(origSect.getSectorIndexFromStart(), 0, baos.toByteArray()); + + pl.progressUpdate(iSector); + } } + it.close(pl); + pl.progressEnd(); + } finally { + IO.closeSilently(encoder, LOG); } - it.close(pl); - pl.progressEnd(); } finally { - IO.closeSilently(ais, Logger.getLogger(DiscItemXaAudioStream.class.getName())); + IO.closeSilently(ais, LOG); } } @@ -361,15 +375,15 @@ public void replaceXa(@Nonnull ProgressLogger pl, @Nonnull DiscItemXaAudioStream // if missing sector? no, that's not right unless the index is busted if (getSampleFramesPerSecond() != other.getSampleFramesPerSecond() || - _blnIsStereo != other._blnIsStereo || - _iBitsPerSample != other._iBitsPerSample || + _format.blnIsStereo != other._format.blnIsStereo || + _format.iBitsPerSample != other._format.iBitsPerSample || getAudioSectorCount() != other.getAudioSectorCount()) { // Don't want to use sector length in case one of them consists of // all adjacent sectors and the other one doesn't throw new LocalizedIncompatibleException(I.XA_REPLACE_FORMAT_MISMATCH( - other._iBitsPerSample, other.getSampleFrameCount(),other._blnIsStereo ? 2 : 1,other.getSampleFramesPerSecond(), - _iBitsPerSample, getSampleFrameCount(), _blnIsStereo ? 2 : 1, getSampleFramesPerSecond())); + other._format.iBitsPerSample, other.getSampleFrameCount(),other._format.blnIsStereo ? 2 : 1,other.getSampleFramesPerSecond(), + _format.iBitsPerSample, getSampleFrameCount(), _format.blnIsStereo ? 2 : 1, getSampleFramesPerSecond())); } // there should be no missing XA sectors in either of these items // if there are, the index is out of sync with the actual disc @@ -415,7 +429,7 @@ private class XAConverter implements ISectorAudioDecoder { public XAConverter(double dblVolume) { __xa2ap = new SectorXaAudioToAudioPacket( DiscItemXaAudioStream.this.makeXaDecoder(dblVolume), - _iSampleFramesPerSecond, _iChannel, + _format.iSampleFramesPerSecond, _format.iFileNumber, _format.iChannel, DiscItemXaAudioStream.this.getStartSector(), DiscItemXaAudioStream.this.getEndSector()); } @@ -434,7 +448,7 @@ public double getVolume() { } public int getSampleFramesPerSecond() { - return _iSampleFramesPerSecond; + return _format.iSampleFramesPerSecond; } public @Nonnull AudioFormat getOutputFormat() { @@ -462,9 +476,7 @@ public int getDiscSpeed() { public boolean isPartOfStream(@Nonnull SectorXaAudio xaSector) { return xaSector.getSectorNumber() >= getStartSector() && xaSector.getSectorNumber() <= getEndSector() && - xaSector.getAdpcmBitsPerSample() == _iBitsPerSample && - xaSector.getChannel() == _iChannel && - xaSector.isStereo() == _blnIsStereo; + _format.equals(new XaAudioFormat(xaSector)); } } diff --git a/jpsxdec/src/jpsxdec/modules/xa/SectorClaimToSectorXaAudio.java b/jpsxdec/src/jpsxdec/modules/xa/SectorClaimToSectorXaAudio.java index 183f762..1f470b5 100644 --- a/jpsxdec/src/jpsxdec/modules/xa/SectorClaimToSectorXaAudio.java +++ b/jpsxdec/src/jpsxdec/modules/xa/SectorClaimToSectorXaAudio.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -42,7 +42,6 @@ import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import jpsxdec.cdreaders.CdSector; -import jpsxdec.cdreaders.CdSectorXaSubHeader; import jpsxdec.i18n.exception.LoggedFailure; import jpsxdec.i18n.log.ILocalizedLogger; import jpsxdec.modules.SectorClaimSystem; @@ -55,9 +54,7 @@ void feedXaSector(@Nonnull CdSector cdSector, @CheckForNull SectorXaAudio xaSector, @Nonnull ILocalizedLogger log) throws LoggedFailure; - void xaEof(int iChannel); - - public void endOfSectors(@Nonnull ILocalizedLogger log); + void endOfSectors(@Nonnull ILocalizedLogger log); } private final ArrayList _listeners = new ArrayList(); @@ -97,17 +94,6 @@ public void sectorRead(@Nonnull SectorClaimSystem.ClaimableSector cs, throw new SectorClaimSystem.ClaimerFailure(ex); } } - - CdSectorXaSubHeader sh = cdSector.getSubHeader(); - if (sh != null && sh.getSubMode().getEofMarker() && - sh.getChannel() <= SectorXaAudio.MAX_VALID_CHANNEL) - { - // if the sector's EOF bit was set, this stream is closed - // this is important for many games - for (Listener listener : _listeners) { - listener.xaEof(sh.getChannel()); - } - } } } diff --git a/jpsxdec/src/jpsxdec/modules/xa/SectorXaAudio.java b/jpsxdec/src/jpsxdec/modules/xa/SectorXaAudio.java index 8729773..a57d588 100644 --- a/jpsxdec/src/jpsxdec/modules/xa/SectorXaAudio.java +++ b/jpsxdec/src/jpsxdec/modules/xa/SectorXaAudio.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -43,7 +43,6 @@ import jpsxdec.cdreaders.CdSector; import jpsxdec.cdreaders.CdSectorXaSubHeader; import jpsxdec.cdreaders.XaAnalysis; -import jpsxdec.modules.IIdentifiedSector; import jpsxdec.modules.IdentifiedSector; import jpsxdec.util.ByteArrayFPIS; @@ -51,14 +50,6 @@ /** Standard audio sector for XA. */ public class SectorXaAudio extends IdentifiedSector { - /** Maximum channel number (inclusive) that will be considered for - * XA sector. - * My understanding is channel is technically supposed to be - * between 0 and 31. Some games seem to use values outside of that range - * for both valid and null XA audio sectors. */ - public static final int MAX_VALID_CHANNEL = 254; - - private int _iSamplesPerSecond; private int _iBitsPerSample; private boolean _blnStereo; @@ -68,7 +59,7 @@ public SectorXaAudio(@Nonnull CdSector cdSector) { super(cdSector); if (isSuperInvalidElseReset()) return; - XaAnalysis analysis = XaAnalysis.analyze(cdSector, MAX_VALID_CHANNEL); + XaAnalysis analysis = XaAnalysis.analyze(cdSector, CdSector.MAX_VALID_CHANNEL); if (analysis == null) return; @@ -81,6 +72,12 @@ public SectorXaAudio(@Nonnull CdSector cdSector) { setProbability(analysis.iProbability); } + public int getFileNumber() { + CdSectorXaSubHeader sh = getCdSector().getSubHeader(); + assert sh != null; + return sh.getFileNumber(); + } + public int getChannel() { CdSectorXaSubHeader sh = getCdSector().getSubHeader(); assert sh != null; @@ -157,26 +154,6 @@ public String toString() { return sb.toString(); } - public boolean matchesPrevious(@Nonnull IIdentifiedSector prevSect) { - if (!(prevSect instanceof SectorXaAudio)) - return false; - - SectorXaAudio prevXA = (SectorXaAudio)prevSect; - - if (getChannel() != prevXA.getChannel() || - getAdpcmBitsPerSample() != prevXA.getAdpcmBitsPerSample() || - getSamplesPerSecond() != prevXA.getSamplesPerSecond() || - isStereo() != prevXA.isStereo()) - return false; - int iStride = getSectorNumber() - prevSect.getSectorNumber(); - if (iStride == 1) - return true; - if (calculateDiscSpeed(_iSamplesPerSecond, _blnStereo, _iBitsPerSample, iStride) > 0) - return true; - else - return false; - } - /** Checks if the sector doesn't generate any sound. Note that this * does not mean, if the sector was decoded as part of an ADPCM stream, * that it would actually produce only silence. Because ADPCM uses prior @@ -201,80 +178,6 @@ public boolean isSilent() { return true; } - /** Return 1 for 1x, 2 for 2x, or -1 for impossible. - *
-     * Disc Speed = ( Samples/sec * Mono/Stereo * Stride * Bits/sample ) / 16128
-     *
-     * Samples/sec  Mono/Stereo  Bits/sample  Stride  Disc Speed
-     *   18900           1           4          2      invalid
-     *   18900           1           4          4      invalid
-     *   18900           1           4          8      invalid
-     *   18900           1           4          16       75    "Level C"
-     *   18900           1           4          32       150   "Level C"
-     *
-     *   18900           1           8          2      invalid
-     *   18900           1           8          4        150   "Level A"
-     *   18900           1           8          8        75    "Level A"
-     *   18900           1           8          16     invalid
-     *   18900           1           8          32     invalid
-     *
-     *   18900           2           4          2      invalid
-     *   18900           2           4          4      invalid
-     *   18900           2           4          8        75    "Level C"
-     *   18900           2           4          16       150   "Level C"
-     *   18900           2           4          32     invalid
-     *
-     *   18900           2           8          2      invalid
-     *   18900           2           8          4        75    "Level A"
-     *   18900           2           8          8        150   "Level A"
-     *   18900           2           8          16     invalid
-     *   18900           2           8          32     invalid
-     *
-     *   37800           1           4          2      invalid
-     *   37800           1           4          4      invalid
-     *   37800           1           4          8        75    "Level B"
-     *   37800           1           4          16       150   "Level B"
-     *   37800           1           4          32     invalid
-     *
-     *   37800           1           8          2      invalid
-     *   37800           1           8          4        75    "Level A"
-     *   37800           1           8          8        150   "Level A"
-     *   37800           1           8          16     invalid
-     *   37800           1           8          32     invalid
-     *
-     *   37800           2           4          2      invalid
-     *   37800           2           4          4        75    "Level B"
-     *   37800           2           4          8        150   "Level B"
-     *   37800           2           4          16     invalid
-     *   37800           2           4          32     invalid
-     *
-     *   37800           2           8          2        75    "Level A"
-     *   37800           2           8          4        150   "Level A"
-     *   37800           2           8          8      invalid
-     *   37800           2           8          16     invalid
-     *   37800           2           8          32     invalid
-     *
*/ - public static int calculateDiscSpeed(int iSamplesPerSecond, - boolean blnStereo, - int iBitsPerSample, - int iSectorStride) - { - if (iSectorStride < 1) - return -1; - - int iDiscSpeed_x_16128 = iSamplesPerSecond * - (blnStereo ? 2 : 1) * - iSectorStride * - iBitsPerSample; - - if (iDiscSpeed_x_16128 == 75 * 16128) - return 1; // 1x = 75 sectors/sec - else if (iDiscSpeed_x_16128 == 150 * 16128) - return 2; // 2x = 150 sectors/sec - else - return -1; - } - public int getErrorCount() { return _iErrors; } diff --git a/jpsxdec/src/jpsxdec/modules/xa/SectorXaAudioToAudioPacket.java b/jpsxdec/src/jpsxdec/modules/xa/SectorXaAudioToAudioPacket.java index d497393..38e6b25 100644 --- a/jpsxdec/src/jpsxdec/modules/xa/SectorXaAudioToAudioPacket.java +++ b/jpsxdec/src/jpsxdec/modules/xa/SectorXaAudioToAudioPacket.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -59,6 +59,7 @@ public class SectorXaAudioToAudioPacket implements SectorClaimToSectorXaAudio.Li @Nonnull private final XaAdpcmDecoder _decoder; private final ByteArrayOutputStream _tempBuffer = new ByteArrayOutputStream(); + private final int _iFileNumber; private final int _iChannel; private final int _iSampleFramesPerSecond; @Nonnull @@ -68,11 +69,13 @@ public class SectorXaAudioToAudioPacket implements SectorClaimToSectorXaAudio.Li private final int _iStartSector; private final int _iEndSectorInclusive; - public SectorXaAudioToAudioPacket(@Nonnull XaAdpcmDecoder decoder, int iSampleFramesPerSecond, int iChannel, + public SectorXaAudioToAudioPacket(@Nonnull XaAdpcmDecoder decoder, int iSampleFramesPerSecond, + int iFileNumber, int iChannel, int iStartSector, int iEndSectorInclusive) { _decoder = decoder; _audioFormat = decoder.getOutputFormat(iSampleFramesPerSecond); _iSampleFramesPerSecond = iSampleFramesPerSecond; + _iFileNumber = iFileNumber; _iChannel = iChannel; _iStartSector = iStartSector; _iEndSectorInclusive = iEndSectorInclusive; @@ -92,7 +95,8 @@ public void feedXaSector(@Nonnull CdSector cdSector, if (xaSector == null) return; - if (xaSector.getChannel() != _iChannel || + if (xaSector.getFileNumber() != _iFileNumber || + xaSector.getChannel() != _iChannel || xaSector.getAdpcmBitsPerSample() != _decoder.getAdpcmBitsPerSample() || xaSector.isStereo() != _decoder.isStereo() || xaSector.getSamplesPerSecond() != _iSampleFramesPerSecond) @@ -119,7 +123,7 @@ public void feedXaSector(@Nonnull CdSector cdSector, _listener.audioPacketComplete(packet, log); } } - public void xaEof(int iChannel) { + public void xaEof(int iFileNumber, int iChannel) { } public void endOfSectors(@Nonnull ILocalizedLogger log) { } diff --git a/jpsxdec/src/jpsxdec/modules/xa/SectorXaNull.java b/jpsxdec/src/jpsxdec/modules/xa/SectorXaNull.java index bb20a1d..ec2d62a 100644 --- a/jpsxdec/src/jpsxdec/modules/xa/SectorXaNull.java +++ b/jpsxdec/src/jpsxdec/modules/xa/SectorXaNull.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -64,17 +64,14 @@ public SectorXaNull(@Nonnull CdSector cdSector) { // if it's not flagged as a null sector... SubMode sm = sh.getSubMode(); - if (sm.getAudio() || sm.getVideo() || sm.getData()) - { + if (sm.getAudio() || sm.getVideo() || sm.getData()) { // if it's flagged as an audio sector, then it's not a null sector - if (!sm.getAudio()) return; + if (!sm.getAudio()) + return; // if it has a valid channel number, then it's not a null sector - if (sh.getChannel() >= 0 || sh.getChannel() < 32) { + if (sh.getChannel() >= 0 || sh.getChannel() < CdSector.MAX_VALID_CHANNEL) return; - // Ace Combat 3 has several AUDIO sectors with channel 255 - // that seem to be "null" sectors - } } setProbability(100); diff --git a/jpsxdec/src/jpsxdec/modules/xa/XaAudioFormat.java b/jpsxdec/src/jpsxdec/modules/xa/XaAudioFormat.java new file mode 100644 index 0000000..7c7c29b --- /dev/null +++ b/jpsxdec/src/jpsxdec/modules/xa/XaAudioFormat.java @@ -0,0 +1,243 @@ +/* + * jPSXdec: PlayStation 1 Media Decoder/Converter in Java + * Copyright (C) 2019-2020 Michael Sabin + * All rights reserved. + * + * Redistribution and use of the jPSXdec code or any derivative works are + * permitted provided that the following conditions are met: + * + * * Redistributions may not be sold, nor may they be used in commercial + * or revenue-generating business activities. + * + * * Redistributions that are modified from the original source must + * include the complete source code, including the source code for all + * components used by a binary built from the modified sources. However, as + * a special exception, the source code distributed need not include + * anything that is normally distributed (in either source or binary form) + * with the major components (compiler, kernel, and so on) of the operating + * system on which the executable runs, unless that component itself + * accompanies the executable. + * + * * Redistributions must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package jpsxdec.modules.xa; + +import javax.annotation.Nonnull; +import jpsxdec.cdreaders.CdSector; +import jpsxdec.discitems.SerializedDiscItem; +import jpsxdec.i18n.I; +import jpsxdec.i18n.exception.LocalizedDeserializationFail; + + +public class XaAudioFormat { + + /** Serialization key for File. */ + private final static String FILE_NUMBER_KEY = "File"; + + public final int iFileNumber; + + /** Serialization key for Channel. */ + private final static String CHANNEL_KEY = "Channel"; + + /** CD stream channel number. */ + public final int iChannel; + + /** Serialization key for sample rate. */ + private static final String SAMPLES_PER_SEC_KEY = "Samples/Sec"; + /** Sample rate of the audio stream. Should be either 37800 or 18900. */ + public final int iSampleFramesPerSecond; + + /** Serialization key for bits/sample. */ + private final static String BITSPERSAMPLE_KEY = "Bits/Sample"; + /** ADPCM bits per sample that the audio is encoded as. Should be 4 or 8. */ + public final int iBitsPerSample; + + /** Serialization key for stereo. */ + private static final String STEREO_KEY = "Stereo?"; + /** If the audio is in stereo. */ + public final boolean blnIsStereo; + + public XaAudioFormat(int iFileNumber, int iChannel, int iSampleFramesPerSecond, int iBitsPerSample, boolean blnIsStereo) { + if (!validChannel(iChannel)) + throw new IllegalArgumentException("Channel " + iChannel + " is not between 0 and " + CdSector.MAX_VALID_CHANNEL); + if (!validFileNumber(iFileNumber)) + throw new IllegalArgumentException("Invalid file number " + iFileNumber); + if (!validBitsPerSample(iBitsPerSample)) + throw new IllegalArgumentException("Bits/sample " + iBitsPerSample + " is not 4 or 8"); + if (!validSampleFramesPerSecond(iSampleFramesPerSecond)) + throw new IllegalArgumentException(); + + this.iFileNumber = iFileNumber; + this.iChannel = iChannel; + this.iSampleFramesPerSecond = iSampleFramesPerSecond; + this.iBitsPerSample = iBitsPerSample; + this.blnIsStereo = blnIsStereo; + } + + public XaAudioFormat(@Nonnull SectorXaAudio xa) { + this(xa.getFileNumber(), xa.getChannel(), xa.getSamplesPerSecond(), xa.getAdpcmBitsPerSample(), xa.isStereo()); + } + + public XaAudioFormat(@Nonnull SerializedDiscItem fields) throws LocalizedDeserializationFail { + blnIsStereo = fields.getYesNo(STEREO_KEY); + iSampleFramesPerSecond = fields.getInt(SAMPLES_PER_SEC_KEY); + iChannel = fields.getInt(CHANNEL_KEY); + iFileNumber = fields.getInt(FILE_NUMBER_KEY); + iBitsPerSample = fields.getInt(BITSPERSAMPLE_KEY); + + if (!validChannel(iChannel)) + throw new LocalizedDeserializationFail(I.FIELD_HAS_INVALID_VALUE_NUM(CHANNEL_KEY, iChannel)); + if (!validFileNumber(iFileNumber)) + throw new LocalizedDeserializationFail(I.FIELD_HAS_INVALID_VALUE_NUM(FILE_NUMBER_KEY, iFileNumber)); + if (!validBitsPerSample(iBitsPerSample)) + throw new LocalizedDeserializationFail(I.FIELD_HAS_INVALID_VALUE_NUM(BITSPERSAMPLE_KEY, iBitsPerSample)); + if (!validSampleFramesPerSecond(iSampleFramesPerSecond)) + throw new LocalizedDeserializationFail(I.FIELD_HAS_INVALID_VALUE_NUM(SAMPLES_PER_SEC_KEY, iSampleFramesPerSecond)); + } + + public static boolean validChannel(int iChannel) { + return iChannel >= 0 && iChannel <= CdSector.MAX_VALID_CHANNEL; + } + + public static boolean validFileNumber(int iFileNumber) { + return iFileNumber >= 0 && iFileNumber <= 255; + } + + public static boolean validBitsPerSample(int iBitsPerSample) { + return iBitsPerSample == 4 || iBitsPerSample == 8; + } + + public static boolean validSampleFramesPerSecond(int iSampleFramesPerSecond) { + return iSampleFramesPerSecond == 18900 || iSampleFramesPerSecond == 37800; + } + + public void serialize(@Nonnull SerializedDiscItem fields) { + fields.addNumber(FILE_NUMBER_KEY, iFileNumber); + fields.addNumber(CHANNEL_KEY, iChannel); + fields.addYesNo(STEREO_KEY, blnIsStereo); + fields.addNumber(SAMPLES_PER_SEC_KEY, iSampleFramesPerSecond); + fields.addNumber(BITSPERSAMPLE_KEY, iBitsPerSample); + } + + @Override + public int hashCode() { + int hash = 3; + hash = 11 * hash + this.iFileNumber; + hash = 11 * hash + this.iChannel; + hash = 11 * hash + this.iSampleFramesPerSecond; + hash = 11 * hash + this.iBitsPerSample; + hash = 11 * hash + (this.blnIsStereo ? 1 : 0); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + + XaAudioFormat other = (XaAudioFormat) obj; + return this.iFileNumber == other.iFileNumber && + this.iChannel == other.iChannel && + this.iSampleFramesPerSecond == other.iSampleFramesPerSecond && + this.iBitsPerSample == other.iBitsPerSample && + this.blnIsStereo == other.blnIsStereo; + } + + public int calculateDiscSpeed(int iSectorStride) { + return calculateDiscSpeed(iSampleFramesPerSecond, blnIsStereo, iBitsPerSample, iSectorStride); + } + + + /** Return 1 for 1x, 2 for 2x, or -1 for impossible. + *
+     * Disc Speed = ( Samples/sec * Mono/Stereo * Stride * Bits/sample ) / 16128
+     *
+     * Samples/sec  Mono/Stereo  Bits/sample  Stride  Disc Speed
+     *   18900           1           4          2      invalid
+     *   18900           1           4          4      invalid
+     *   18900           1           4          8      invalid
+     *   18900           1           4          16       75    "Level C"
+     *   18900           1           4          32       150   "Level C"
+     *
+     *   18900           1           8          2      invalid
+     *   18900           1           8          4        150   "Level A"
+     *   18900           1           8          8        75    "Level A"
+     *   18900           1           8          16     invalid
+     *   18900           1           8          32     invalid
+     *
+     *   18900           2           4          2      invalid
+     *   18900           2           4          4      invalid
+     *   18900           2           4          8        75    "Level C"
+     *   18900           2           4          16       150   "Level C"
+     *   18900           2           4          32     invalid
+     *
+     *   18900           2           8          2      invalid
+     *   18900           2           8          4        75    "Level A"
+     *   18900           2           8          8        150   "Level A"
+     *   18900           2           8          16     invalid
+     *   18900           2           8          32     invalid
+     *
+     *   37800           1           4          2      invalid
+     *   37800           1           4          4      invalid
+     *   37800           1           4          8        75    "Level B"
+     *   37800           1           4          16       150   "Level B"
+     *   37800           1           4          32     invalid
+     *
+     *   37800           1           8          2      invalid
+     *   37800           1           8          4        75    "Level A"
+     *   37800           1           8          8        150   "Level A"
+     *   37800           1           8          16     invalid
+     *   37800           1           8          32     invalid
+     *
+     *   37800           2           4          2      invalid
+     *   37800           2           4          4        75    "Level B"
+     *   37800           2           4          8        150   "Level B"
+     *   37800           2           4          16     invalid
+     *   37800           2           4          32     invalid
+     *
+     *   37800           2           8          2        75    "Level A"
+     *   37800           2           8          4        150   "Level A"
+     *   37800           2           8          8      invalid
+     *   37800           2           8          16     invalid
+     *   37800           2           8          32     invalid
+     *
*/ + private static int calculateDiscSpeed(int iSamplesPerSecond, + boolean blnStereo, + int iBitsPerSample, + int iSectorStride) + { + if (iSectorStride < 1) + return -1; + + int iDiscSpeed_x_16128 = iSamplesPerSecond * + (blnStereo ? 2 : 1) * + iSectorStride * + iBitsPerSample; + + if (iDiscSpeed_x_16128 == 75 * 16128) + return 1; // 1x = 75 sectors/sec + else if (iDiscSpeed_x_16128 == 150 * 16128) + return 2; // 2x = 150 sectors/sec + else + return -1; + } + + +} diff --git a/jpsxdec/src/jpsxdec/psxvideo/PsxRgb.java b/jpsxdec/src/jpsxdec/psxvideo/PsxRgb.java new file mode 100644 index 0000000..3952f90 --- /dev/null +++ b/jpsxdec/src/jpsxdec/psxvideo/PsxRgb.java @@ -0,0 +1,218 @@ +/* + * jPSXdec: PlayStation 1 Media Decoder/Converter in Java + * Copyright (C) 2020 Michael Sabin + * All rights reserved. + * + * Redistribution and use of the jPSXdec code or any derivative works are + * permitted provided that the following conditions are met: + * + * * Redistributions may not be sold, nor may they be used in commercial + * or revenue-generating business activities. + * + * * Redistributions that are modified from the original source must + * include the complete source code, including the source code for all + * components used by a binary built from the modified sources. However, as + * a special exception, the source code distributed need not include + * anything that is normally distributed (in either source or binary form) + * with the major components (compiler, kernel, and so on) of the operating + * system on which the executable runs, unless that component itself + * accompanies the executable. + * + * * Redistributions must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package jpsxdec.psxvideo; + +import java.util.Arrays; +import javax.annotation.Nonnull; + + +public class PsxRgb { + + public static final int PSX_VRAM_WORD_WIDTH = 1024; + public static final int PSX_VRAM_HEIGHT = 512; + + /** Works the same as + *
+     * int CONVERT_5_TO_8_BIT(int i) {
+     *   return (int)Math.round((double)i / 31.0);
+     * }
+     * 
*/ + private static final int[] CONVERT_5_TO_8_BIT = new int[/*32*/] { + 0, 8, 16, 25, 33, 41, 49, 58, + 66, 74, 82, 90, 99, 107, 115, 123, + 132, 140, 148, 156, 165, 173, 181, 189, + 197, 206, 214, 222, 230, 239, 247, 255 + }; + static { assert CONVERT_5_TO_8_BIT.length == 32; } + + public static int psxABGR1555toARGB8888(byte b8first, byte b8second, int iAlphaValue) { + int iPsx16 = ((b8first & 0xff)) | ((b8second & 0xff) << 8); + return psxABGR1555toARGB8888(iPsx16, iAlphaValue); + } + + /** PlayStation 16-bit ABGR1555 to ARGB8888. */ + public static int psxABGR1555toARGB8888(int i16, int iAlphaValue) { + int b = CONVERT_5_TO_8_BIT[(i16 >>> 10) & 0x1F]; + int g = CONVERT_5_TO_8_BIT[(i16 >>> 5) & 0x1F]; + int r = CONVERT_5_TO_8_BIT[(i16 ) & 0x1F]; + int a; + + if (r == 0 && g == 0 && b == 0) { + if ((i16 & 0x8000) == 0) + // black, and the alpha bit is NOT set + a = (byte)0; // totally transparent + else + // black, and the alpha bit IS set + a = (byte)255; // totally opaque + } else { + if ((i16 & 0x8000) == 0) + // some color, and the alpha bit is NOT set + a = (byte)255; // totally opaque + else + // some color, and the alpha bit IS set + a = (byte)iAlphaValue; // some variance of transparency + } + + return a << 24 | r << 16 | g << 8 | b; + } + + + /** Works the same as + *
+     * int CONVERT_8_TO_5_BIT(int i) {
+     *   return (int)Math.round(i*255/31.0);
+     * }
+     * 
*/ + private static final int[] CONVERT_8_TO_5_BIT = { + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 13, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, + 18, 18, 18, 18, 18, 18, 18, 18, 18, + 19, 19, 19, 19, 19, 19, 19, 19, + 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, + 22, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, + 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, + 27, 27, 27, 27, 27, 27, 27, 27, 27, + 28, 28, 28, 28, 28, 28, 28, 28, + 29, 29, 29, 29, 29, 29, 29, 29, + 30, 30, 30, 30, 30, 30, 30, 30, + 31, 31, 31, 31, 31, + }; static { assert CONVERT_8_TO_5_BIT.length == 256; } + + /** ARGB8888 to PlayStation 16-bit ABGR1555. */ + public static short ARGB8888toPsxABGR1555(int i) { + int a = (i >>> 24) & 0xFF; + int r = CONVERT_8_TO_5_BIT[(i >>> 16) & 0xFF]; + int g = CONVERT_8_TO_5_BIT[(i >>> 8) & 0xFF]; + int b = CONVERT_8_TO_5_BIT[(i ) & 0xFF]; + int bgr = (b << 10) | (g << 5) | r; + if (a == 0) { + // if totally transparent + bgr = 0; + a = 0; + } else if (a == 255) { + // if totally opaque + if (bgr == 0) // if totally opaque & black + a = 1; + else // if totally opaque & not black + a = 0; + } else { + // if partially transparent + a = 1; + } + return (short)((a << 15) | bgr); + } + + + /** Works the same as + *
+     * byte CONVERT_4_TO_8_BIT(int i) {
+     *   return (byte)Math.round(i*15/255.0);
+     * }
+     * 
*/ + private static final byte[] CONVERT_4_TO_8_BIT = + { + (byte) 0, (byte) 17, (byte) 34, (byte) 51, + (byte) 68, (byte) 85, (byte)102, (byte)119, + (byte)136, (byte)153, (byte)170, (byte)187, + (byte)204, (byte)221, (byte)238, (byte)255, + }; + static { assert CONVERT_4_TO_8_BIT.length == 16; } + + private static final byte[] GRAY_16_PALETTE = build16GrayRgbaPalette(); + private static @Nonnull byte[] build16GrayRgbaPalette() { + byte[] abPalette = new byte[4*16]; + for (int i = 0; i < 16; i++) { + byte bClr = CONVERT_4_TO_8_BIT[i]; + abPalette[i*4+0] = bClr; // r + abPalette[i*4+1] = bClr; // g + abPalette[i*4+2] = bClr; // b + abPalette[i*4+3] = (byte)255; // a + } + return abPalette; + } + public static @Nonnull byte[] get16GrayRgbaPalette() { + return Arrays.copyOf(GRAY_16_PALETTE, GRAY_16_PALETTE.length); + } + /** Fills buffer with RGBA8888 grayscale values (no transparency). + * Assumes buffer is 16*4 bytes long. */ + public static void fill16GrayRgbaPalette(@Nonnull byte[] abPalette) { + System.arraycopy(GRAY_16_PALETTE, 0, abPalette, 0, GRAY_16_PALETTE.length); + } + + private static final byte[] GRAY_256_PALETTE = build256GrayRgbaPalette(); + private static @Nonnull byte[] build256GrayRgbaPalette() { + byte[] abPalette = new byte[4*256]; + for (int i = 0; i < 256; i++) { + byte bClr = (byte)i; + abPalette[i*4+0] = bClr; // r + abPalette[i*4+1] = bClr; // g + abPalette[i*4+2] = bClr; // b + abPalette[i*4+3] = (byte)255; // a + } + return abPalette; + } + public static @Nonnull byte[] get256GrayRgbaPalette() { + return Arrays.copyOf(GRAY_256_PALETTE, GRAY_256_PALETTE.length); + } + /** Fills buffer with RGBA8888 grayscale values. + * Assumes buffer is 256*4 bytes long. */ + public static void fill256GrayRgbaPalette(@Nonnull byte[] abPalette) { + System.arraycopy(GRAY_256_PALETTE, 0, abPalette, 0, GRAY_256_PALETTE.length); + } + +} diff --git a/jpsxdec/src/jpsxdec/psxvideo/PsxYCbCr.java b/jpsxdec/src/jpsxdec/psxvideo/PsxYCbCr.java index c8e6685..1a174b1 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/PsxYCbCr.java +++ b/jpsxdec/src/jpsxdec/psxvideo/PsxYCbCr.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/PsxYCbCr_int.java b/jpsxdec/src/jpsxdec/psxvideo/PsxYCbCr_int.java index bd6f306..db6f505 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/PsxYCbCr_int.java +++ b/jpsxdec/src/jpsxdec/psxvideo/PsxYCbCr_int.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ArrayBitReader.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ArrayBitReader.java index 6a0120c..95638b5 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ArrayBitReader.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ArrayBitReader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamCode.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamCode.java index 0a9ad33..8a30dc8 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamCode.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamCode.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamCompressor.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamCompressor.java index 78bd08c..aef7aa9 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamCompressor.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamCompressor.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamDebugging.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamDebugging.java index f3dfd14..51bc25c 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamDebugging.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamDebugging.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor.java index e9abb1a..208766a 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_Iki.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_Iki.java index 55648c0..4804b5e 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_Iki.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_Iki.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_Lain.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_Lain.java index cfe1c71..df9d44d 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_Lain.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_Lain.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv1.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv1.java index f444b63..12290ab 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv1.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv1.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv2.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv2.java index 5af6c0c..2006f52 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv2.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv2.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv3.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv3.java index 1bd3357..b404d51 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv3.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamUncompressor_STRv3.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamWriter.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamWriter.java index 9544db5..2a5507d 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamWriter.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/BitStreamWriter.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/StrHeader.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/StrHeader.java index 1b1feb2..f99ec7e 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/StrHeader.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/StrHeader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAc.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAc.java index 06fed3e..e4cef4a 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAc.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAc.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAcLookup.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAcLookup.java index 4f4d239..d124092 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAcLookup.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAcLookup.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAcLookup_STR.java b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAcLookup_STR.java index 1be77d6..dc718c4 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAcLookup_STR.java +++ b/jpsxdec/src/jpsxdec/psxvideo/bitstreams/ZeroRunLengthAcLookup_STR.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/encode/MacroBlockEncoder.java b/jpsxdec/src/jpsxdec/psxvideo/encode/MacroBlockEncoder.java index 9172932..be1d74c 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/encode/MacroBlockEncoder.java +++ b/jpsxdec/src/jpsxdec/psxvideo/encode/MacroBlockEncoder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/encode/MdecEncoder.java b/jpsxdec/src/jpsxdec/psxvideo/encode/MdecEncoder.java index fd07a0f..e762e17 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/encode/MdecEncoder.java +++ b/jpsxdec/src/jpsxdec/psxvideo/encode/MdecEncoder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/encode/ParsedMdecImage.java b/jpsxdec/src/jpsxdec/psxvideo/encode/ParsedMdecImage.java index 64f9653..248754a 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/encode/ParsedMdecImage.java +++ b/jpsxdec/src/jpsxdec/psxvideo/encode/ParsedMdecImage.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/encode/PsxYCbCrImage.java b/jpsxdec/src/jpsxdec/psxvideo/encode/PsxYCbCrImage.java index 65c4121..ee8aa80 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/encode/PsxYCbCrImage.java +++ b/jpsxdec/src/jpsxdec/psxvideo/encode/PsxYCbCrImage.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/Ac0Checker.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/Ac0Checker.java index 10c964e..e55e6fa 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/Ac0Checker.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/Ac0Checker.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/Calc.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/Calc.java index 2fc8dae..cb22fd1 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/Calc.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/Calc.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/ChromaUpsample.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/ChromaUpsample.java index 41c77e9..9d86650 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/ChromaUpsample.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/ChromaUpsample.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecBlock.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecBlock.java index 43c0e6d..b6f490b 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecBlock.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecBlock.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecCode.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecCode.java index b3f003e..a5a9eac 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecCode.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecCode.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecContext.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecContext.java index 3685c96..0f7422a 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecContext.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecContext.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder.java index 00028e1..292ff81 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder_double.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder_double.java index 6d6c9e5..2062247 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder_double.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder_double.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder_int.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder_int.java index 5fa6eae..7eafcc1 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder_int.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecDecoder_int.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecException.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecException.java index 77e4e34..e311cc4 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecException.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecInputStream.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecInputStream.java index 553f4ef..f443d0d 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecInputStream.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecInputStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecInputStreamReader.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecInputStreamReader.java index b62ff66..74b2641 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecInputStreamReader.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/MdecInputStreamReader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/IDCT_double.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/IDCT_double.java index 7f0101c..fb4cea1 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/IDCT_double.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/IDCT_double.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/IDCT_int.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/IDCT_int.java index ffc09f9..6e2c728 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/IDCT_int.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/IDCT_int.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/NaiveIDCT.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/NaiveIDCT.java index 403bca9..41a75b9 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/NaiveIDCT.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/NaiveIDCT.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/PsxMdecIDCT_double.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/PsxMdecIDCT_double.java index b441f67..618dce1 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/PsxMdecIDCT_double.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/PsxMdecIDCT_double.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/PsxMdecIDCT_int.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/PsxMdecIDCT_int.java index 448830b..530347d 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/PsxMdecIDCT_int.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/PsxMdecIDCT_int.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/SimpleIDCT.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/SimpleIDCT.java index 68e7e4f..1b39ab6 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/SimpleIDCT.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/idct/SimpleIDCT.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/Component.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/Component.java index e7f908b..58d69ab 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/Component.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/Component.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/HuffmanTable.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/HuffmanTable.java index 98e601d..307b610 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/HuffmanTable.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/HuffmanTable.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/JpegBitOutputStream.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/JpegBitOutputStream.java index e727f30..c864aa0 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/JpegBitOutputStream.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/JpegBitOutputStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/Mdec2Jpeg.java b/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/Mdec2Jpeg.java index 3ec0427..479dfed 100644 --- a/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/Mdec2Jpeg.java +++ b/jpsxdec/src/jpsxdec/psxvideo/mdec/tojpeg/Mdec2Jpeg.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/tim/CLUT.java b/jpsxdec/src/jpsxdec/tim/CLUT.java index 5d732ac..dc0e002 100644 --- a/jpsxdec/src/jpsxdec/tim/CLUT.java +++ b/jpsxdec/src/jpsxdec/tim/CLUT.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -40,79 +40,62 @@ import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import javax.annotation.Nonnull; -import jpsxdec.util.BinaryDataNotRecognized; +import jpsxdec.psxvideo.PsxRgb; import jpsxdec.util.IO; /** The TIM Color Lookup Table (CLUT). */ class CLUT { - /** Size of the CLUT header in bytes. */ + /** + * Size of the CLUT header in bytes. + */ public final static int HEADER_SIZE = 12; - /** Dimensions of the CLUT in pixels. */ - private final int _iClutWidth, _iClutHeight; - /** X position of the CLUT in pixels. - * Not sure how it is used in the PSX, but it is often 0. */ - private final int _iClutX; - /** Y position of the CLUT in pixels. - * Not sure how it is used in the PSX, but it is often 0. */ - private final int _iClutY; - /** Tim ABGR1555. */ + /** + * Dimensions of the CLUT in pixels. + * CLUTs are always 16 bits-per-pixel, so the width in the header is the pixel width. + */ + private final int _iClutPixelWidth, _iClutPixelHeight; + + /** + * X,Y position of the CLUT in pixels. + * This can be used to indicate where to copy the CLUT into the VRAM. + */ + private final int _iClutX, _iClutY; + + /** + * Tim 16 bit pixels ABGR1555. + */ @Nonnull final short[] _asiColorData; - /** Read a CLUT from an InputStream. */ - public CLUT(@Nonnull InputStream is) throws IOException, BinaryDataNotRecognized { - long lngLength = IO.readUInt32LE(is); - if (lngLength == 0) throw new BinaryDataNotRecognized(); - _iClutX = IO.readUInt16LE(is); - _iClutY = IO.readUInt16LE(is); - _iClutWidth = IO.readUInt16LE(is); - if (_iClutWidth == 0) throw new BinaryDataNotRecognized(); - _iClutHeight = IO.readUInt16LE(is); - if (_iClutHeight == 0) throw new BinaryDataNotRecognized(); - - if (lngLength != calculateLength()) - throw new BinaryDataNotRecognized(); - - _asiColorData = new short[_iClutWidth * _iClutHeight]; - for (int i = 0; i < _asiColorData.length; i++) - _asiColorData[i] = IO.readSInt16LE(is); - } - - /** Create a CLUT based on a ready-made CLUT palette. */ - public CLUT(@Nonnull short[] asiPalette, int iX, int iY, int iPixelWidth) { - if (iX < 0 || iY < 0) - throw new IllegalArgumentException("Invalid CLUT X,Y (" + iX + ", " + iY + ")"); - if (iPixelWidth < 1) - throw new IllegalArgumentException("Invalid CLUT width " + iPixelWidth); - if (asiPalette.length % iPixelWidth != 0) - throw new IllegalArgumentException("CLUT size "+asiPalette.length+ - " not divisible by CLUT width "+iPixelWidth); + CLUT(@Nonnull short[] asiPalette, int iX, int iY, int iPixelWidth, int iPixelHeight) { + // The caller should validate the parameters _asiColorData = asiPalette; _iClutX = iX; _iClutY = iY; - _iClutWidth = iPixelWidth; - _iClutHeight = asiPalette.length / _iClutWidth; + _iClutPixelWidth = iPixelWidth; + _iClutPixelHeight = iPixelHeight; } /** Write the CLUT to a stream. */ public void write(@Nonnull OutputStream os) throws IOException { - IO.writeInt32LE(os, calculateLength()); + IO.writeInt32LE(os, calculateClutSizeInBytes()); IO.writeInt16LE(os, _iClutX); IO.writeInt16LE(os, _iClutY); - IO.writeInt16LE(os, _iClutWidth); - IO.writeInt16LE(os, _iClutHeight); + IO.writeInt16LE(os, _iClutPixelWidth); + IO.writeInt16LE(os, _iClutPixelHeight); for (short i : _asiColorData) IO.writeInt16LE(os, i); } - /** Returns the length of the CLUT structure in bytes. */ - private long calculateLength() { - return _iClutWidth * _iClutHeight * 2 + 12; + /** + * Returns the length of the CLUT structure in bytes. + */ + private int calculateClutSizeInBytes() { + return _asiColorData.length * 2 + HEADER_SIZE; } /** Returns Tim ABGR1555 color value. */ @@ -133,17 +116,11 @@ public int getY() { return _iClutY; } - /** Returns width of the CLUT in pixels. - * This is useful to know for some strange Tims found in the wild. */ - public int getWidth() { - return _iClutWidth; - } - public @Nonnull BufferedImage toBufferedImage() { - BufferedImage bi = new BufferedImage(_iClutWidth, _iClutHeight, BufferedImage.TYPE_INT_ARGB); + BufferedImage bi = new BufferedImage(_iClutPixelWidth, _iClutPixelHeight, BufferedImage.TYPE_INT_ARGB); int[] aiBufferArgb = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData(); for (int i = 0; i < aiBufferArgb.length; i++) { - aiBufferArgb[i] = Tim.color16toColor32(_asiColorData[i]); + aiBufferArgb[i] = PsxRgb.psxABGR1555toARGB8888(_asiColorData[i], Tim.SEMI_TRANSPARENT); } return bi; } @@ -151,12 +128,12 @@ public int getWidth() { @Override public String toString() { return String.format( - "%dx%d xy(%d, %d) Len:%d", - _iClutWidth, - _iClutHeight, + "%dx%d xy(%d, %d) Size:%d", + _iClutPixelWidth, + _iClutPixelHeight, _iClutX, _iClutY, - calculateLength()); + calculateClutSizeInBytes()); } } diff --git a/jpsxdec/src/jpsxdec/tim/CreateTim.java b/jpsxdec/src/jpsxdec/tim/CreateTim.java index 02398ec..9a9b060 100644 --- a/jpsxdec/src/jpsxdec/tim/CreateTim.java +++ b/jpsxdec/src/jpsxdec/tim/CreateTim.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -44,205 +44,154 @@ import java.io.IOException; import java.io.InputStream; import java.util.Arrays; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; +import jpsxdec.psxvideo.PsxRgb; import jpsxdec.util.BinaryDataNotRecognized; import jpsxdec.util.IO; +import jpsxdec.util.IncompatibleException; /** Private functions to generate a {@link Tim} image. */ class CreateTim { - private static final Logger LOG = Logger.getLogger(CreateTim.class.getName()); - - - /** Quickly reads a stream to determine if the data is a Tim image. - * @return info about the Tim image, otherwise null. */ - public static @CheckForNull TimInfo isTim(@Nonnull InputStream inStream) + /** + * Quickly reads a stream to determine if the data is a Tim image. + * @return info about the Tim image, otherwise null. + */ + public static @CheckForNull TimInfo isTim(@Nonnull InputStream inStream) throws EOFException, IOException { - // tag - if (IO.readUInt8(inStream) != Tim.TAG_MAGIC) + TimValidator validator = new TimValidator(); + + if (!validator.tagIsValid(inStream)) return null; - // version - if (IO.readUInt8(inStream) != Tim.VERSION_0) + if (!validator.versionIsValid(inStream)) return null; - // unkn 1 - if (IO.readUInt16LE(inStream) != 0) + if (!validator.unknownIsValid(inStream)) return null; - - int iBpp_blnHasColorLookupTbl = IO.readUInt16LE(inStream); - if ((iBpp_blnHasColorLookupTbl & 0xFFF4) != 0) + if (!validator.bppAndClutIsValid(inStream)) return null; - // unkn 2 - if (IO.readUInt16LE(inStream) != 0) + if (!validator.unknownIsValid(inStream)) return null; - //------------------------------------------------- - - int iBitsPerPixel = Tim.BITS_PER_PIX[iBpp_blnHasColorLookupTbl & 3]; - - final int iPaletteCount; - // has CLUT - if ((iBpp_blnHasColorLookupTbl & 8) != 0) { - - long lngLength = IO.readUInt32LE(inStream); - if (lngLength <= 0) + int iPaletteCount; + if (validator.hasClut()) { + if (!validator.clutByteSizeIsValid(inStream)) return null; - - // clut x,y - IO.skip(inStream, 4); - - int iClutWidth = IO.readUInt16LE(inStream); - if (iClutWidth == 0) + if (!validator.clutXisValid(inStream)) return null; - - int iClutHeight = IO.readUInt16LE(inStream); - if (iClutHeight == 0) + if (!validator.clutYisValid(inStream)) return null; - - if (lngLength != (iClutWidth * iClutHeight * 2 + 12)) + if (!validator.clutPixelWidthIsValid(inStream)) + return null; + if (!validator.clutPixelHeightIsValid(inStream)) return null; - // User CUE reported an issue with some strange TIM images from - // "Guardian's Crusade" that report 16 bits-per-pixel, but also - // have a CLUT (bug "JPSXDEC-4"). - // See read() for more details. - if (iBitsPerPixel == 16) { - if (iClutWidth < 256) - iBitsPerPixel = 4; - else - iBitsPerPixel = 8; - LOG.log(Level.WARNING, "TIM reports 16 bits/pixel, but it also has a CLUT. Assuming {0,number,#} bits/pixel", iBitsPerPixel); - } else if (iBitsPerPixel == 24) { - LOG.log(Level.WARNING, "TIM reports 24 bits/pixel, but it also has a CLUT. Assuming 8 bits/pixel"); - iBitsPerPixel = 8; - } + if (!validator.clutIsConsistent()) + return null; - iPaletteCount = (iClutWidth * iClutHeight) / (1 << iBitsPerPixel); + IO.skip(inStream, validator.getClutImageDataByteSize()); - IO.skip(inStream, iClutWidth * iClutHeight * 2); - } else { + iPaletteCount = Tim.calcPaletteCount(validator.getClutImageDataWordSize(), validator.getBitPerPixel()); + } else { iPaletteCount = 1; } - long lngImageLength = IO.readUInt32LE(inStream); - if (lngImageLength == 0) - return null; - - // image x,y - IO.skip(inStream, 4); - int iImageWordWidth = IO.readUInt16LE(inStream); - if (iImageWordWidth == 0) + if (!validator.timByteSizeIsValid(inStream)) return null; - - int iImageHeight = IO.readUInt16LE(inStream); - if (iImageHeight == 0) + if (!validator.timXisValid(inStream)) return null; - - if (lngImageLength != iImageWordWidth * iImageHeight * 2 + 12) + if (!validator.timYisValid(inStream)) + return null; + if (!validator.wordWidthIsValid(inStream)) + return null; + if (!validator.pixelHeightIsValid(inStream)) return null; - IO.skip(inStream, (iImageWordWidth * iImageHeight) * 2); + TimValidator.TimConsistency consistency = validator.timIsConsistent(); + if (consistency == TimValidator.TimConsistency.INCONSISTENT) + return null; - int iPixelWidth; - switch (iBitsPerPixel) { - case 4: iPixelWidth = iImageWordWidth * 2 * 2; break; - case 8: iPixelWidth = iImageWordWidth * 2 ; break; - case 16: iPixelWidth = iImageWordWidth ; break; - case 24: iPixelWidth = iImageWordWidth * 2 / 3; break; - default: throw new RuntimeException("Impossible Tim BPP " + iBitsPerPixel); - } + IO.skip(inStream, validator.getImageDataByteSize()); - return new TimInfo(iPaletteCount, iBitsPerPixel, iPixelWidth, iImageHeight); + return new TimInfo(iPaletteCount, validator.getBitPerPixel(), + validator.getPixelWidth(), validator.getPixelHeight()); } - - /** Parse and deserialize a TIM file from a stream. */ + + /** + * Parse and deserialize a TIM file from a stream. + */ public static @Nonnull Tim read(@Nonnull InputStream inStream) throws EOFException, IOException, BinaryDataNotRecognized { - final boolean DBG = false; - int iTag = IO.readUInt8(inStream); - if (DBG) System.err.println(String.format("%02x", iTag)); - if (iTag != Tim.TAG_MAGIC) // 0x10 - throw new BinaryDataNotRecognized(); + TimValidator validator = new TimValidator(); - int iVersion = IO.readUInt8(inStream); - if (DBG) System.err.println(String.format("%02x", iVersion)); - if (iVersion != Tim.VERSION_0) + if (!validator.tagIsValid(inStream)) throw new BinaryDataNotRecognized(); - - int iUnknown1 = IO.readUInt16LE(inStream); - if (DBG) System.err.println(String.format("%04x", iUnknown1)); - if (iUnknown1 != 0) + if (!validator.versionIsValid(inStream)) throw new BinaryDataNotRecognized(); - - int iBpp_blnHasColorLookupTbl = IO.readUInt16LE(inStream); - if (DBG) System.err.println(String.format("%04x", iBpp_blnHasColorLookupTbl)); - if ((iBpp_blnHasColorLookupTbl & 0xFFF4) != 0) + if (!validator.unknownIsValid(inStream)) throw new BinaryDataNotRecognized(); - - int iUnknown2 = IO.readUInt16LE(inStream); - if (DBG) System.err.println(String.format("%04x", iUnknown2)); - if (iUnknown2 != 0) + if (!validator.bppAndClutIsValid(inStream)) + throw new BinaryDataNotRecognized(); + if (!validator.unknownIsValid(inStream)) throw new BinaryDataNotRecognized(); - - //------------------------------------------------- - - boolean blnHasColorLookupTable = (iBpp_blnHasColorLookupTbl & 0x8) != 0; - int iBitsPerPixel = Tim.BITS_PER_PIX[iBpp_blnHasColorLookupTbl & 3]; CLUT clut = null; - if (blnHasColorLookupTable) { - clut = new CLUT(inStream); - // User CUE reported an issue with some strange TIM images from - // "Guardian's Crusade" that report 16 bits-per-pixel, but also - // have a CLUT (bug "JPSXDEC-4"). - // Turns out the image data was actually 4 or 8 bits-per-pixels. - // The CLUT width seemed to correlate with the bits-per-pixel - // (width < 256 : 4 bits/pixel, width >= 256 : 8 bits/pixel) - // No clear way to handle this case, so we'll change the code - // to at least handle these unique images the best we can. - if (iBitsPerPixel == 16) { - if (clut.getWidth() < 256) - iBitsPerPixel = 4; - else - iBitsPerPixel = 8; - LOG.log(Level.WARNING, "TIM reports 16 bits/pixel, but it also has a CLUT. Assuming {0,number,#} bits/pixel", iBitsPerPixel); - } else if (iBitsPerPixel == 24) { - LOG.log(Level.WARNING, "TIM reports 24 bits/pixel, but it also has a CLUT. Assuming 8 bits/pixel"); - iBitsPerPixel = 8; - } - } - - long lngImageLength = IO.readUInt32LE(inStream); - if (lngImageLength == 0) throw new BinaryDataNotRecognized(); - int iTimX = IO.readUInt16LE(inStream); - int iTimY = IO.readUInt16LE(inStream); - int iImageWordWidth = IO.readUInt16LE(inStream); - if (iImageWordWidth == 0) throw new BinaryDataNotRecognized(); - int iPixelHeight = IO.readUInt16LE(inStream); - if (iPixelHeight == 0) throw new BinaryDataNotRecognized(); + if (validator.hasClut()) { + if (!validator.clutByteSizeIsValid(inStream)) + throw new BinaryDataNotRecognized(); + if (!validator.clutXisValid(inStream)) + throw new BinaryDataNotRecognized(); + if (!validator.clutYisValid(inStream)) + throw new BinaryDataNotRecognized(); + if (!validator.clutPixelWidthIsValid(inStream)) + throw new BinaryDataNotRecognized(); + if (!validator.clutPixelHeightIsValid(inStream)) + throw new BinaryDataNotRecognized(); + + if (!validator.clutIsConsistent()) + throw new BinaryDataNotRecognized(); + + short[] asiColorData = new short[validator.getClutImageDataWordSize()]; + for (int i = 0; i < asiColorData.length; i++) + asiColorData[i] = IO.readSInt16LE(inStream); + + clut = new CLUT(asiColorData, validator.getClutX(), validator.getClutY(), validator.getClutPixelWidth(), validator.getClutPixelHeight()); + } - if (lngImageLength != iImageWordWidth * iPixelHeight * 2 + Tim.HEADER_SIZE) + if (!validator.timByteSizeIsValid(inStream)) + throw new BinaryDataNotRecognized(); + if (!validator.timXisValid(inStream)) + throw new BinaryDataNotRecognized(); + if (!validator.timYisValid(inStream)) + throw new BinaryDataNotRecognized(); + if (!validator.wordWidthIsValid(inStream)) + throw new BinaryDataNotRecognized(); + if (!validator.pixelHeightIsValid(inStream)) throw new BinaryDataNotRecognized(); - byte[] abImageData = IO.readByteArray(inStream, (iImageWordWidth * iPixelHeight) * 2); + TimValidator.TimConsistency consistency = validator.timIsConsistent(); - int iPixelWidth; - switch (iBitsPerPixel) { - case 4: iPixelWidth = iImageWordWidth * 2 * 2; break; - case 8: iPixelWidth = iImageWordWidth * 2 ; break; - case 16: iPixelWidth = iImageWordWidth ; break; - case 24: iPixelWidth = iImageWordWidth * 2 / 3; break; - default: throw new RuntimeException("Impossible Tim BPP " + iBitsPerPixel); - } - return new Tim(abImageData, iTimX, iTimY, iPixelWidth, iPixelHeight, iBitsPerPixel, clut); + if (consistency == TimValidator.TimConsistency.INCONSISTENT) + throw new BinaryDataNotRecognized(); + + byte[] abImageData = IO.readByteArray(inStream, validator.getImageDataByteSize()); + return new Tim(abImageData, validator.getTimX(), validator.getTimY(), + validator.getWordWidth(), validator.getPixelHeight(), + validator.getBitPerPixel(), clut, + consistency == TimValidator.TimConsistency.INCONSISTENT_BUT_VALID); } - - /** Creates a TIM with the same or similar color-model of a {@link BufferedImage}. + + /** + * Creates a TIM with the same or similar color-model of a {@link BufferedImage}. + * + * {@link BufferedImage} bpp map: + * {@code 32 -> 16} (no CLUT) + * {@code 8 -> 8} (256 color CLUT) + * {@code 4 -> 4} (16 color CLUT) + * * @param iTimX Tim X coordinate. * @param iTimY Tim Y coordinate. * @param iClutX CLUT X coordinate. @@ -252,67 +201,82 @@ class CreateTim { int iTimX, int iTimY, int iClutX, int iClutY) { - int iSrcBpp = findBitsPerPixel(bi); + final int iSrcBpp = findBitsPerPixel(bi); + + int iTargetBpp; + if (iSrcBpp == 32) - iSrcBpp = 16; // use 16 BPP (instead of 24) since it's the most common - else if (iSrcBpp == 4 && bi.getWidth() % 4 != 0) { - LOG.warning("Trying to create 4bpp Tim with width not divisible by 4. Converting to 8bpp."); - iSrcBpp = 8; // 4bpp width must be divisible by 4, so try the next higher bpp - } + // use 16 BPP (instead of 24) since it's the most common + // if 24 bpp is needed, use other function + iTargetBpp = 16; + else + iTargetBpp = iSrcBpp; - if (iSrcBpp == 8 && bi.getWidth() % 2 != 0) { - LOG.warning("Trying to create 8bpp Tim with uneven width. Converting to 16bpp."); - iSrcBpp = 16; // 16bpp is the only one that might allow for an even width (untested) + try { + return create(bi, iTargetBpp, iTimX, iTimY, iClutX, iClutY); + } catch (IncompatibleException ex) { + throw new RuntimeException("Should not happen", ex); } - return create(bi, iSrcBpp, iTimX, iTimY, iClutX, iClutY); } - /** Creates a TIM from a BufferedImage with the specified bits-per-pixel. - * @throws IllegalArgumentException if anything is weird. + /** + * Creates a TIM from a BufferedImage with the specified bits-per-pixel. + * * @param iBitsPerPixel 4, 8, 16, or 24. * @param iTimX Tim X coordinate. * @param iTimY Tim Y coordinate. * @param iClutX CLUT X coordinate. Ignored if bpp is 16 or 24. - * @param iClutY CLUT Y coordinate. Ignored if bpp is 16 or 24. */ + * @param iClutY CLUT Y coordinate. Ignored if bpp is 16 or 24. + * + * @throws IncompatibleException if unable to convert an 8 bpp {@link BufferedImage} + * to a 4 bpp Tim because there are too many colors used. + */ public static @Nonnull Tim create(@Nonnull BufferedImage bi, int iBitsPerPixel, int iTimX, int iTimY, int iClutX, int iClutY) + throws IncompatibleException { - int iPaletteLength; - switch (iBitsPerPixel) { - case 16: return create16(bi, iTimX, iTimY); - case 24: return create24(bi, iTimX, iTimY); + TimValidator validator = new TimValidator(); + if (!validator.bppIsValid(iBitsPerPixel)) + throw new IllegalArgumentException(); + if (!validator.timXisValid(iTimX)) + throw new IllegalArgumentException(); + if (!validator.timYisValid(iTimY)) + throw new IllegalArgumentException(); + if (!validator.pixelWidthIsValid(bi.getWidth())) + throw new IllegalArgumentException(); + if (!validator.pixelHeightIsValid(bi.getHeight())) + throw new IllegalArgumentException(); + int iPaletteLength; + switch (validator.getBitPerPixel()) { + case 16: return create16(bi, validator); + case 24: return create24(bi, validator); case 4: - if (bi.getWidth() % 4 != 0) - throw new IllegalArgumentException( - "Image width ("+bi.getWidth()+") is not divisible by 4 so cannot be converted to 4bpp Tim"); iPaletteLength = 16; break; case 8: - if (bi.getWidth() % 2 != 0) - throw new IllegalArgumentException( - "Image width ("+bi.getWidth()+") is not divisible by 2 so cannot be converted to 8bpp Tim"); iPaletteLength = 256; break; - - default: throw new IllegalArgumentException("Invalid bits per pixel " + iBitsPerPixel); + default: throw new RuntimeException(); } final int iSrcBpp = findBitsPerPixel(bi); Tim tim; - if (iSrcBpp <= iBitsPerPixel) { + if (iSrcBpp <= validator.getBitPerPixel()) { // src = 4, dest = 4 // src = 4, dest = 8 // src = 8, dest = 8 IndexColorModel icm = (IndexColorModel) bi.getColorModel(); short[] asiClut = extractPalette(icm, iPaletteLength); - CLUT clut = new CLUT(asiClut, iClutX, iClutY, iPaletteLength); + CLUT clut = new CLUT(asiClut, validator.getClutX(), validator.getClutY(), iPaletteLength, 1); - byte[] abIndexes = extractIndexes(bi, iBitsPerPixel == 4); - tim = new Tim(abIndexes, iTimX, iTimY, bi.getWidth(), bi.getHeight(), iBitsPerPixel, clut); + byte[] abIndexes = extractIndexes(bi, validator.getBitPerPixel() == 4); + tim = new Tim(abIndexes, validator.getTimX(), validator.getTimY(), + validator.getWordWidth(), validator.getPixelHeight(), + validator.getBitPerPixel(), clut); } else if (iSrcBpp == 8) { // src = 8, dest = 4 @@ -328,7 +292,7 @@ else if (iSrcBpp == 4 && bi.getWidth() % 4 != 0) { aiMapper[iIdx] = iNewPalSize; iNewPalSize++; if (iNewPalSize > 16) - throw new IllegalArgumentException("Unable to fit image into 16 colors"); + throw new IncompatibleException("Unable to fit image into 16 colors"); } } @@ -348,33 +312,44 @@ else if (iSrcBpp == 4 && bi.getWidth() % 4 != 0) { icm.getRGBs(ai256Palette); short[] asiClut = new short[16]; for (int i = 0; i < iNewPalSize; i++) { - asiClut[i] = color32toColor16(ai256Palette[aiMapper[i]]); + asiClut[i] = PsxRgb.ARGB8888toPsxABGR1555(ai256Palette[aiMapper[i]]); } - CLUT clut = new CLUT(asiClut, iClutX, iClutY, iPaletteLength); + CLUT clut = new CLUT(asiClut, validator.getClutX(), validator.getClutY(), iPaletteLength, 1); - tim = new Tim(abTimImg, iTimX, iTimY, bi.getWidth(), bi.getHeight(), iBitsPerPixel, clut); + tim = new Tim(abTimImg, validator.getTimX(), validator.getTimY(), validator.getWordWidth(), validator.getPixelHeight(), validator.getBitPerPixel(), clut); } else { // src = 32, dest = 4 // src = 32, dest = 8 - tim = createPalettedTim(bi, iBitsPerPixel == 4, iTimX, iTimY, iClutX, iClutY); + tim = createPalettedTim(bi, validator.getBitPerPixel() == 4, validator); } return tim; } - /** Create a TIM image with a custom CLUT. + /** + * Create a TIM image with a custom CLUT. * This is the most advanced method of creating a TIM image. - * It allows one to create a TIM with multiple CLUT palettes. + * It allows you to create a TIM with multiple CLUT palettes. + * * @param iTimX Tim X coordinate. * @param iTimY Tim Y coordinate. * @param iClutX CLUT X coordinate. * @param iClutY CLUT Y coordinate. - * @param iBitsPerPixel Either 4 or 8. */ + * @param iBitsPerPixel Either 4 or 8. + * + * @throws IllegalArgumentException if + * the {@link BufferedImage} does not have an {@link IndexColorModel}, + * or the colors of the palette indexes in the {@link BufferedImage} do not match the first palette in the CLUT. + */ public static @Nonnull Tim create(@Nonnull BufferedImage bi, int iTimX, int iTimY, @Nonnull BufferedImage clutImg, int iClutX, int iClutY, int iBitsPerPixel) { + TimValidator validator = new TimValidator(); + if (!validator.bppIsValid(iBitsPerPixel, true)) + throw new IllegalArgumentException(); + int iPaletteSize; if (iBitsPerPixel == 4) iPaletteSize = 16; @@ -383,6 +358,24 @@ else if (iBitsPerPixel == 8) else throw new IllegalArgumentException("Unable to create a paletted Tim with " + iBitsPerPixel + " bpp"); + if (!validator.clutXisValid(iClutX)) + throw new IllegalArgumentException(); + if (!validator.clutYisValid(iClutY)) + throw new IllegalArgumentException(); + if (!validator.clutPixelWidthIsValid(clutImg.getWidth())) + throw new IllegalArgumentException(); + if (!validator.clutPixelHeightIsValid(clutImg.getHeight())) + throw new IllegalArgumentException(); + + if (!validator.timXisValid(iTimX)) + throw new IllegalArgumentException(); + if (!validator.timYisValid(iTimY)) + throw new IllegalArgumentException(); + if (!validator.pixelWidthIsValid(bi.getWidth())) + throw new IllegalArgumentException(); + if (!validator.pixelHeightIsValid(bi.getHeight())) + throw new IllegalArgumentException(); + ColorModel cm = bi.getColorModel(); if (!(cm instanceof IndexColorModel)) throw new IllegalArgumentException("Image must have IndexColorModel"); @@ -391,8 +384,6 @@ else if (iBitsPerPixel == 8) int[] aiPaletteArgb = new int[iPaletteSize]; icm.getRGBs(aiPaletteArgb); - int iWidth = bi.getWidth(), iHeight = bi.getHeight(); - // verify that the image palette matches the clut first palette int[] aiClut = clutImg.getRGB(0, 0, clutImg.getWidth(), clutImg.getHeight(), null, 0, clutImg.getWidth()); for (int i = 0; i < aiPaletteArgb.length; i++) { @@ -403,12 +394,12 @@ else if (iBitsPerPixel == 8) // convert the 32bit RGBA8888 palette into TIM 16bit ABGR1555 short[] asiClut = new short[aiClut.length]; for (int i = 0; i < aiClut.length; i++) { - asiClut[i] = color32toColor16(aiClut[i]); + asiClut[i] = PsxRgb.ARGB8888toPsxABGR1555(aiClut[i]); } - CLUT c = new CLUT(asiClut, iClutX, iClutY, clutImg.getWidth()); + CLUT clut = new CLUT(asiClut, validator.getClutX(), validator.getClutY(), validator.getClutPixelWidth(), validator.getClutPixelHeight()); byte[] abTimImg = extractIndexes(bi, iBitsPerPixel == 4); - return new Tim(abTimImg, iTimX, iTimY, iWidth, iHeight, iBitsPerPixel, c); + return new Tim(abTimImg, validator.getTimX(), validator.getTimY(), validator.getWordWidth(), validator.getPixelHeight(), validator.getBitPerPixel(), clut); } //-------------------------------------------------------------------------- @@ -475,61 +466,53 @@ else if (iPaletteSize <= 256) // convert the 32bit ARGB8888 palette into TIM 16bit ABGR1555 short[] asiClut = new short[aiPalette.length]; for (int i = 0; i < aiPalette.length; i++) { - asiClut[i] = color32toColor16(aiPalette[i]); + asiClut[i] = PsxRgb.ARGB8888toPsxABGR1555(aiPalette[i]); } return asiClut; } /** Convert image to 16 bpp Tim. */ - private static @Nonnull Tim create16(@Nonnull BufferedImage bi, int iTimX, int iTimY) { + private static @Nonnull Tim create16(@Nonnull BufferedImage bi, @Nonnull TimValidator validator) { int[] aiArgb = bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), null, 0, bi.getWidth()); byte[] abTim16 = new byte[aiArgb.length * 2]; for (int i = 0, o = 0; i < aiArgb.length; i++, o+=2) { int iArgb = aiArgb[i]; - short siTimAbgr = color32toColor16(iArgb); + short siTimAbgr = PsxRgb.ARGB8888toPsxABGR1555(iArgb); IO.writeInt16LE(abTim16, o, siTimAbgr); } - return new Tim(abTim16, iTimX, iTimY, bi.getWidth(), bi.getHeight(), 16, null); + return new Tim(abTim16, validator.getTimX(), validator.getTimY(), validator.getWordWidth(), validator.getPixelHeight(), 16, null); } /** Convert image to 24 bpp Tim. */ - private static @Nonnull Tim create24(@Nonnull BufferedImage bi, int iTimX, int iTimY) { - final int iWidth = bi.getWidth(), iHeight = bi.getHeight(); - int[] aiArgb = bi.getRGB(0, 0, iWidth, iHeight, null, 0, iWidth); - byte[] abTim24; - if (iWidth % 2 != 0) - throw new IllegalArgumentException("24-bit Tim must have even width"); - abTim24 = new byte[aiArgb.length * 3]; + private static @Nonnull Tim create24(@Nonnull BufferedImage bi, @Nonnull TimValidator validator) { + int[] aiArgb = bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), null, 0, bi.getWidth()); + byte[] abTim24 = new byte[aiArgb.length * 3]; for (int i = 0, o = 0; i < aiArgb.length; i++, o+=3) { int iArgb = aiArgb[i]; abTim24[o+0]= (byte)(iArgb >> 16); abTim24[o+1]= (byte)(iArgb >> 8); abTim24[o+2]= (byte)(iArgb ); } - return new Tim(abTim24, iTimX, iTimY, iWidth, iHeight, 24, null); + return new Tim(abTim24, validator.getTimX(), validator.getTimY(), validator.getWordWidth(), validator.getPixelHeight(), 24, null); } - /** Manually generates a palette from the image. + /** + * Manually generates a palette from the image. * Ignores its {@link IndexColorModel} if it has one. * @throws IllegalArgumentException if the image has too many colors to fit into the palette. */ private static @Nonnull Tim createPalettedTim(@Nonnull BufferedImage bi, boolean bln4bppOrNot8bpp, - int iTimX, int iTimY, - int iClutX, int iClutY) + @Nonnull TimValidator validator) { - final int iWidth = bi.getWidth(), iHeight = bi.getHeight(); - int iPaletteSize; if (bln4bppOrNot8bpp) { - assert iWidth % 4 == 0; // should be checked by caller iPaletteSize = 16; } else { - assert iWidth % 2 == 0; // should be checked by caller iPaletteSize = 256; } - int[] aiArgb = bi.getRGB(0, 0, iWidth, iHeight, null, 0, iWidth); + int[] aiArgb = bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), null, 0, bi.getWidth()); PaletteMaker pal = new PaletteMaker(aiArgb, iPaletteSize); @@ -552,9 +535,10 @@ else if (iPaletteSize <= 256) abTimImg[o] = (byte)iPaletteIdx; } - CLUT clut = pal.makeClut(iClutX, iClutY); + CLUT clut = pal.makeClut(validator.getClutX(), validator.getClutY()); - return new Tim(abTimImg, iTimX, iTimY, iWidth, iHeight, bln4bppOrNot8bpp ? 4 : 8, clut); + int iBpp = bln4bppOrNot8bpp ? 4 : 8; + return new Tim(abTimImg, validator.getTimX(), validator.getTimY(), validator.getWordWidth(), validator.getPixelHeight(), iBpp, clut); } /** Little class to break up the palette generation logic in @@ -588,7 +572,7 @@ public PaletteMaker(@Nonnull int[] aiArgb, int iPaletteSize) { // make 2 copies of the image data converted to Tim 16bpp _asiTim16Image = new short[aiArgb.length]; for (int i = 0; i < aiArgb.length; i++) { - _asiTim16Image[i] = color32toColor16(aiArgb[i]); + _asiTim16Image[i] = PsxRgb.ARGB8888toPsxABGR1555(aiArgb[i]); } // using copyof seems to be faster than .clone() // and faster than copying the values in the for loop @@ -621,74 +605,8 @@ public int getPixelPaletteIndex(int iPixelIndex) { } public @Nonnull CLUT makeClut(int iClutX, int iClutY) { - return new CLUT(_asiPalette, iClutX, iClutY, _asiPalette.length); + return new CLUT(_asiPalette, iClutX, iClutY, _asiPalette.length, 1); } } - /** Works the same as - *
-     * int CONVERT_8_TO_5_BIT(int i) {
-     *   return (int)Math.round(i*255/31.0);
-     * }
-     * 
*/ - private static final int[] CONVERT_8_TO_5_BIT = - { - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 13, - 14, 14, 14, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 15, - 16, 16, 16, 16, 16, 16, 16, 16, - 17, 17, 17, 17, 17, 17, 17, 17, - 18, 18, 18, 18, 18, 18, 18, 18, 18, - 19, 19, 19, 19, 19, 19, 19, 19, - 20, 20, 20, 20, 20, 20, 20, 20, - 21, 21, 21, 21, 21, 21, 21, 21, - 22, 22, 22, 22, 22, 22, 22, 22, 22, - 23, 23, 23, 23, 23, 23, 23, 23, - 24, 24, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 25, 25, 25, - 26, 26, 26, 26, 26, 26, 26, 26, - 27, 27, 27, 27, 27, 27, 27, 27, 27, - 28, 28, 28, 28, 28, 28, 28, 28, - 29, 29, 29, 29, 29, 29, 29, 29, - 30, 30, 30, 30, 30, 30, 30, 30, - 31, 31, 31, 31, 31, - }; static { assert CONVERT_8_TO_5_BIT.length == 256; } - - /** ARGB8888 to Tim ABGR1555. */ - private static short color32toColor16(int i) { - int a = (i >>> 24) & 0xFF; - int r = CONVERT_8_TO_5_BIT[(i >>> 16) & 0xFF]; - int g = CONVERT_8_TO_5_BIT[(i >>> 8) & 0xFF]; - int b = CONVERT_8_TO_5_BIT[(i ) & 0xFF]; - int bgr = (b << 10) | (g << 5) | r; - if (a == 0) { - // if totally transparent - bgr = 0; - a = 0; - } else if (a == 255) { - // if totally opaque - if (bgr == 0) // if totally opaque & black - a = 1; - else // if totally opaque & not black - a = 0; - } else { - // if partially transparent - a = 1; - } - return (short)((a << 15) | bgr); - } - } diff --git a/jpsxdec/src/jpsxdec/tim/Tim.java b/jpsxdec/src/jpsxdec/tim/Tim.java index 814366c..32b5b06 100644 --- a/jpsxdec/src/jpsxdec/tim/Tim.java +++ b/jpsxdec/src/jpsxdec/tim/Tim.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -56,8 +56,10 @@ import java.io.OutputStream; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; +import jpsxdec.psxvideo.PsxRgb; import jpsxdec.util.BinaryDataNotRecognized; import jpsxdec.util.IO; +import jpsxdec.util.IncompatibleException; /** The PlayStation 1 TIM image. Used in many PlayStation games. * This is based on the excellent Q-gears documentation here: @@ -73,8 +75,6 @@ public class Tim { /** The Tim semi-transparent alpha bit will be converted to this 8-bit alpha value. */ public static final int SEMI_TRANSPARENT = 254; - /** I believe this is the smallest possible size of a Tim file. 1x1 pixels. */ - public static final int MINIMUM_TIM_SIZE = 22; /** Quickly reads a stream to determine if the data is a Tim image. * @return info about the Tim image, otherwise null. */ @@ -91,19 +91,13 @@ public class Tim { return CreateTim.read(inStream); } - /** Creates a TIM with the same or similar color-model of a BufferedImage. - * TODO Disabled because I don't think it generates them properly!!!! - * More investigation necessary | - */ - private static @Nonnull Tim create(@Nonnull BufferedImage bi) { - return CreateTim.create(bi, 0, 0, 0, 0); - } - - /** Creates a TIM with the same or similar color-model of a {@link BufferedImage}. + /** + * Creates a TIM with the same or similar color-model of a {@link BufferedImage}. * @param iTimX Tim X coordinate. * @param iTimY Tim Y coordinate. * @param iClutX CLUT X coordinate. - * @param iClutY CLUT Y coordinate. */ + * @param iClutY CLUT Y coordinate. + */ public static @Nonnull Tim create(@Nonnull BufferedImage bi, int iTimX, int iTimY, int iClutX, int iClutY) @@ -111,93 +105,60 @@ public class Tim { return CreateTim.create(bi, iTimX, iTimY, iClutX, iClutY); } - /** Creates a TIM from a BufferedImage with the specified bits-per-pixel. - * @throws IllegalArgumentException if anything is weird. - * @param iBitsPerPixel 4, 8, 16, or 24. */ - public static @Nonnull Tim create(@Nonnull BufferedImage bi, int iBitsPerPixel) { - return CreateTim.create(bi, iBitsPerPixel, 0, 0, 0, 0); - } - - /** Creates a TIM from a BufferedImage with the specified bits-per-pixel. - * @throws IllegalArgumentException if anything is weird. + /** + * Creates a TIM from a BufferedImage with the specified bits-per-pixel. * @param iBitsPerPixel 4, 8, 16, or 24. - * @param iTimX Tim X coordinate. - * @param iTimY Tim Y coordinate. - * @param iClutX CLUT X coordinate. Ignored if bpp is 16 or 24. - * @param iClutY CLUT Y coordinate. Ignored if bpp is 16 or 24. */ - public static @Nonnull Tim create(@Nonnull BufferedImage bi, int iBitsPerPixel, - int iTimX, int iTimY, - int iClutX, int iClutY) - { - return CreateTim.create(bi, iBitsPerPixel, iTimX, iTimY, iClutX, iClutY); - } - - /** Create a TIM image with a custom CLUT. - * This is the most advanced method of creating a TIM image. - * It allows one to create a TIM with multiple CLUT palettes. - * @param iBitsPerPixel Either 4 or 8. */ - public static @Nonnull Tim create(@Nonnull BufferedImage bi, - @Nonnull BufferedImage clutImg, - int iBitsPerPixel) - { - return CreateTim.create(bi, 0, 0, clutImg, 0, 0, iBitsPerPixel); - } - - /** Create a TIM image with a custom CLUT. - * This is the most advanced method of creating a TIM image. - * It allows one to create a TIM with multiple CLUT palettes. - * @param iTimX Tim X coordinate. - * @param iTimY Tim Y coordinate. - * @param iClutX CLUT X coordinate. - * @param iClutY CLUT Y coordinate. - * @param iBitsPerPixel Either 4 or 8. */ - public static @Nonnull Tim create(@Nonnull BufferedImage bi, int iTimX, int iTimY, - @Nonnull BufferedImage clutImg, int iClutX, int iClutY, - int iBitsPerPixel) - { - return CreateTim.create(bi, iTimX, iTimY, clutImg, iClutX, iClutY, iBitsPerPixel); + * + * @throws IncompatibleException if unable to convert an 8 bpp {@link BufferedImage} + * to a 4 bpp Tim because there are too many colors used. + */ + public static @Nonnull Tim create(@Nonnull BufferedImage bi, int iBitsPerPixel) throws IncompatibleException { + return CreateTim.create(bi, iBitsPerPixel, 0, 0, 0, 0); } //-------------------------------------------------------------------------- - //-- Fields ---------------------------------------------------------------- + //-- Constants ------------------------------------------------------------- //-------------------------------------------------------------------------- - /** Convert the 2-bit value found in the Tim header to its bits-per-pixel. - *
-     * 00b = 4
-     * 01b = 8
-     * 10b = 16
-     * 11b = 24
-     * 
- */ - static final int[] BITS_PER_PIX = new int[/*4*/] { 4, 8, 16, 24 }; - /** Size of the Tim header in bytes. */ static final int HEADER_SIZE = 12; /** Magic 8-bit value at the start of Tim. */ static final int TAG_MAGIC = 0x10; - /** All Tims are version 0. */ + /** All Tim images are version 0. */ static final int VERSION_0 = 0; - + + /** I believe this is the smallest possible size of a Tim file. 1x1 pixels, no CLUT. */ + public static final int MINIMUM_TIM_SIZE = HEADER_SIZE + 10; + + //-------------------------------------------------------------------------- + //-- Fields ---------------------------------------------------------------- + //-------------------------------------------------------------------------- + + private final int _iBitsPerPixel; + /** The color lookup table for the TIM. null if none. */ @CheckForNull private final CLUT _clut; - - /** X position of the Tim in pixels. - * Not sure how it is used in the PSX, but it is often 0. */ - private final int _iTimX; - /** Y position of the Tim in pixels. - * Not sure how it is used in the PSX, but it is often 0. */ - private final int _iTimY; - /** Width of the image in pixels. */ - private final int _iPixelWidth; - /** Height of the image in pixels. */ + + /** + * Position of the Tim in pixels. + * This can be used to indicate the location the image should be copied to in the VRAM. + */ + private final int _iTimX, _iTimY; + + /** + * Width of the image in words (2 bytes). + * The pixel width is calculated with {@link #_iBitsPerPixel}. + */ + private final int _iWordWidth; + /** + * Height of the image in pixels. + */ private final int _iPixelHeight; - /** 4, 8, 16, or 24. */ - private final int _iBitsPerPixel; - /** The raw image data of the TIM. Data differs depending on bits-per-pixel: + /** + * The raw image data of the TIM. Data differs depending on bits-per-pixel: *
    *
  • 4bpp : 16 color paletted image, two 4-bit palette indexes per byte, * in the order of 1/0, 3/2, etc @@ -209,43 +170,32 @@ public class Tim { */ @Nonnull private final byte[] _abImageData; - - //-------------------------------------------------------------------------- - //-- Constructors ---------------------------------------------------------- - //-------------------------------------------------------------------------- + + private final boolean _blnTimHasIssues; + + //.......................................................................... - /** Create a TIM image with the given data. - * @param abTimImageData Raw Tim image data (stored directly). - * @param iTimX X position of the Tim image. - * @param iTimY Y position of the Tim image. - * @param iBitsPerPixel 4, 8, 16, or 24. - * @param clut Can be null if no color look-up table. - */ Tim(@Nonnull byte[] abTimImageData, int iTimX, int iTimY, - int iPixelWidth, int iPixelHeight, int iBitsPerPixel, + int iWordWidth, int iPixelHeight, int iBitsPerPixel, @CheckForNull CLUT clut) { - if (iPixelWidth < 1 || iPixelHeight < 1) - throw new IllegalArgumentException("Invalid dimensions " + iPixelWidth + "x" + iPixelHeight); - if (iTimX < 0 || iTimY < 0) - throw new IllegalArgumentException("Invalid Tim X,Y (" + iTimX + ", " + iTimY + ")"); - _iPixelWidth = iPixelWidth; - _iPixelHeight = iPixelHeight; + this(abTimImageData, iTimX, iTimY, iWordWidth, iPixelHeight, iBitsPerPixel, clut, false); + } + + Tim(@Nonnull byte[] abTimImageData, int iTimX, int iTimY, + int iWordWidth, int iPixelHeight, int iBitsPerPixel, + @CheckForNull CLUT clut, boolean blnTimHasIssues) + { + // The caller should validate the parameters + _abImageData = abTimImageData; _iTimX = iTimX; _iTimY = iTimY; - _abImageData = abTimImageData; + _iWordWidth = iWordWidth; + _iPixelHeight = iPixelHeight; _iBitsPerPixel = iBitsPerPixel; _clut = clut; - switch (iBitsPerPixel) { - case 4: case 8: case 16: case 24: break; - default: throw new IllegalArgumentException("Invalid bits-per-pixel " + iBitsPerPixel); - } - int iExpectedDataSize = calculateImageWordWidth() * _iPixelHeight * 2; - if (iExpectedDataSize != abTimImageData.length) - throw new IllegalArgumentException( - "Data size " + abTimImageData.length + - " != expected size " + iExpectedDataSize); + _blnTimHasIssues = blnTimHasIssues; } @@ -253,42 +203,65 @@ public class Tim { //-- Public functions ------------------------------------------------------ //-------------------------------------------------------------------------- - /** Bits-per-pixel: 4, 8, 16, or 24. */ + /** + * Bits-per-pixel: 4, 8, 16, or 24. + */ public int getBitsPerPixel() { return _iBitsPerPixel; } - /** If the TIM is paletted and has a CLUT, returns the number of CLUT + /** + * If the TIM is paletted and has a CLUT, returns the number of CLUT * palettes. Otherwise if the TIM is paletted and has not CLUT, or if the * TIM is true-color, returns 1. *

    * Each TIM file can have multiple palettes. The TIM data doesn't even - * have to use these palettes for drawing, but they usually do. */ + * need to use these palettes for drawing, but they usually do. + */ public int getPaletteCount() { - if ((_iBitsPerPixel == 4 || _iBitsPerPixel == 8) && _clut != null) { - int iColorsForBitsPerPixel = (1 << _iBitsPerPixel); - return _clut.getPaletteLength() / iColorsForBitsPerPixel; + if (_clut == null) + return 1; + return calcPaletteCount(_clut._asiColorData.length, _iBitsPerPixel); + } + + static int calcPaletteCount(int iClutColorDataLength, int iBitsPerPixel) { + if (iBitsPerPixel == 4 || iBitsPerPixel == 8) { + int iColorsForBitsPerPixel = 1 << iBitsPerPixel; + return iClutColorDataLength / iColorsForBitsPerPixel; } else { return 1; } } /** Width of TIM in pixels. */ - public int getWidth() { - return _iPixelWidth; + public int getPixelWidth() { + return calculatePixelWidth(_iWordWidth, _iBitsPerPixel); } - + + static int calculatePixelWidth(int iWordWidth, int iBitsPerPixel) { + switch (iBitsPerPixel) { + case 4: return iWordWidth * 2 * 2; + case 8: return iWordWidth * 2 ; + case 16: return iWordWidth ; + case 24: return iWordWidth * 2 / 3; + default: throw new RuntimeException("Impossible Tim BPP " + iBitsPerPixel); + } + } + /** Height of TIM in pixels. */ - public int getHeight() { + public int getPixelHeight() { return _iPixelHeight; } - /** Note: The Java API to save a {@link BufferedImage} to the disk + /** + * Note!: The Java API to save a {@link BufferedImage} to the disk * may change the palette order and indexes in the saved image. + * * @param iPalette Which palette to use for the decoded image. - * @see #getPaletteCount() */ + * + * @see #getPaletteCount() + */ public @Nonnull BufferedImage toBufferedImage(int iPalette) { - if (iPalette < 0 || iPalette >= getPaletteCount()) throw new IllegalArgumentException("Palette index "+iPalette+" out of bounds"); @@ -297,13 +270,15 @@ public int getHeight() { case 8: return toBi8(iPalette); case 16: return toBi16(); case 24: return toBi24(); - default: - throw new IllegalStateException("Impossible Tim BPP " + _iBitsPerPixel); + default:throw new RuntimeException(); } } - /** Converts the CLUT (color lookup table) to a {@link BufferedImage}. - * @return null if image has no CLUT. */ + /** + * Converts the CLUT (color lookup table) to a {@link BufferedImage}. + * + * @return null if image has no CLUT. + */ public @CheckForNull BufferedImage getClutImage() { if (_clut != null) return _clut.toBufferedImage(); @@ -311,30 +286,52 @@ public int getHeight() { return null; } - /** Tries to replace this TIM's image data and palette data (if it has a CLUT) + /** + * If the Tim has inconsistent data, but is still usable. + */ + public boolean timHasIssues() { + return _blnTimHasIssues; + } + + /** + * Tries to replace this TIM's image data and palette data (if it has a CLUT) * with the image data of the buffered image. - * @throws IllegalArgumentException if the BufferedImage data is incompatible. + * + * @throws IncompatibleException if the BufferedImage data is incompatible. */ - public void replaceImageData(@Nonnull BufferedImage bi) { + public void replaceImageData(@Nonnull BufferedImage bi) throws IncompatibleException { Tim newTim = create(bi, _iBitsPerPixel); - System.arraycopy(newTim._abImageData, 0, _abImageData, 0, _abImageData.length); + + // if this has a CLUT, then the newly created tim should also have a CLUT if (_clut != null) { - // if this has a CLUT, then the newly created tim should also have a CLUT + if (newTim._clut == null) + throw new IncompatibleException(); + assert _clut._asiColorData.length == newTim._clut._asiColorData.length; System.arraycopy(newTim._clut._asiColorData, 0, _clut._asiColorData, 0, _clut._asiColorData.length); + } else { + if (newTim._clut != null) + throw new IncompatibleException(); } + + assert _abImageData.length == newTim._abImageData.length; + System.arraycopy(newTim._abImageData, 0, _abImageData, 0, _abImageData.length); } - /** Tries to replace this TIM's image data and palette data + /** + * Tries to replace this TIM's image data and palette data * with the image data of the buffered image and CLUT. - * @throws IllegalArgumentException if the BufferedImage data is incompatible - * or there is no CLUT. + * @throws IncompatibleException if the BufferedImage data is incompatible + * or there is no CLUT. */ - public void replaceImageData(@Nonnull BufferedImage bi, @Nonnull BufferedImage clut) { + public void replaceImageData(@Nonnull BufferedImage bi, @Nonnull BufferedImage clut) throws IncompatibleException { if (_clut == null) - throw new IllegalArgumentException("Can't change the CLUT when Tim doesn't have a CLUT"); + throw new IncompatibleException("Can't change the CLUT when Tim doesn't have a CLUT"); + Tim newTim = CreateTim.create(bi, _iTimX, _iTimY, clut, _clut.getX(), _clut.getY(), _iBitsPerPixel); + + assert _abImageData.length == newTim._abImageData.length; System.arraycopy(newTim._abImageData, 0, _abImageData, 0, _abImageData.length); - // if this has a CLUT, then the newly created tim should also have a CLUT + assert _clut._asiColorData.length == newTim._clut._asiColorData.length; System.arraycopy(newTim._clut._asiColorData, 0, _clut._asiColorData, 0, _clut._asiColorData.length); } @@ -349,16 +346,15 @@ public void write(@Nonnull OutputStream os) throws IOException { if (_clut != null) _clut.write(os); - IO.writeInt32LE(os, calculateImageLength()); + IO.writeInt32LE(os, calculateByteSize()); IO.writeInt16LE(os, _iTimX); IO.writeInt16LE(os, _iTimY); - IO.writeInt16LE(os, calculateImageWordWidth()); + IO.writeInt16LE(os, _iWordWidth); IO.writeInt16LE(os, _iPixelHeight); os.write(_abImageData); } - /** Sorta the opposite of {@link #BITS_PER_PIX}. */ private int calculateBpp_HasCLUT() { int iBitsPerPixReverseLookup; switch (_iBitsPerPixel) { @@ -376,19 +372,8 @@ private int calculateBpp_HasCLUT() { } /** Size of the Tim structure in bytes. */ - private long calculateImageLength() { - return calculateImageWordWidth() * _iPixelHeight * 2 + HEADER_SIZE; - } - - /** Width of the image data in 16-bit values. */ - private int calculateImageWordWidth() { - switch (_iBitsPerPixel) { - case 4: return _iPixelWidth / 2 / 2; - case 8: return _iPixelWidth / 2; - case 16:return _iPixelWidth; - case 24:return _iPixelWidth * 3 / 2; - default: throw new IllegalStateException("Invalid bits-per-pixel " + _iBitsPerPixel); - } + private int calculateByteSize() { + return HEADER_SIZE + _abImageData.length; } public enum Mismatch { @@ -407,8 +392,8 @@ public enum Mismatch { * only the properties of them. * @return null if both Tims have exactly the same properties. */ public @CheckForNull Mismatch matches(@Nonnull Tim other) { - if (getWidth() != other.getWidth() || - getWidth() != other.getWidth()) + if (_iWordWidth != other._iWordWidth || + getPixelHeight() != other.getPixelHeight()) return Mismatch.Dimensions; if (getBitsPerPixel() != other.getBitsPerPixel()) return Mismatch.BitsPerPixel; @@ -428,78 +413,49 @@ public enum Mismatch { } return null; } - + @Override public String toString() { String s = String.format( - "%dx%d %dbpp xy(%d, %d) WWidth:%d Len:%d", - _iPixelWidth, - _iPixelHeight, - _iBitsPerPixel, + "%dx%d %dbpp xy(%d, %d) WordWidth:%d Size:", + getPixelWidth(), + getPixelHeight(), + getBitsPerPixel(), _iTimX, _iTimY, - calculateImageWordWidth(), - calculateImageLength()); - if (_clut == null) - return s; - else - return s + " CLUT[" + _clut + "]"; - } - - //-------------------------------------------------------------------------- - //-- Private functions ----------------------------------------------------- - //-------------------------------------------------------------------------- + _iWordWidth); + StringBuilder sb = new StringBuilder(s); + int iActualByteSize = calculateByteSize(); + int iRequiredByteSize = _iWordWidth * 2 * _iPixelHeight + HEADER_SIZE; - /** Works the same as - *

    -     * byte CONVERT_4_TO_8_BIT(int i) {
    -     *   return (byte)Math.round(i*15/255.0);
    -     * }
    -     * 
    */ - private static final byte[] CONVERT_4_TO_8_BIT = - { - (byte) 0, (byte) 17, (byte) 34, (byte) 51, - (byte) 68, (byte) 85, (byte)102, (byte)119, - (byte)136, (byte)153, (byte)170, (byte)187, - (byte)204, (byte)221, (byte)238, (byte)255, - }; - static { assert CONVERT_4_TO_8_BIT.length == 16; } - - /** Fills buffer with RGBA8888 grayscale values. - * Assumes buffer is 16*4 bytes long. */ - private static void build16GrayRgbaPalette(@Nonnull byte[] abPalette) { - for (int i = 0; i < 16; i++) { - byte bClr = CONVERT_4_TO_8_BIT[i]; - abPalette[i*4+0] = bClr; // r - abPalette[i*4+1] = bClr; // g - abPalette[i*4+2] = bClr; // b - abPalette[i*4+3] = (byte)255; // a + if (iActualByteSize == iRequiredByteSize) { + sb.append(iActualByteSize); + } else { + sb.append(String.format("%d=%d+%d", iActualByteSize, iRequiredByteSize, iActualByteSize - iRequiredByteSize)); } - } - - /** Fills buffer with RGBA8888 grayscale values. - * Assumes buffer is 256*4 bytes long. */ - private static void build256GrayRgbaPalette(@Nonnull byte[] abPalette) { - for (int i = 0; i < 256; i++) { - byte bClr = (byte)i; - abPalette[i*4+0] = bClr; // r - abPalette[i*4+1] = bClr; // g - abPalette[i*4+2] = bClr; // b - abPalette[i*4+3] = (byte)255; // a + + if (_clut != null) { + sb.append(" CLUT[").append(_clut).append("]"); } + + return sb.toString(); } + + //-------------------------------------------------------------------------- - /** Convert this 4 bpp Tim to a BufferedImage. */ + /** + * Convert this 4 bpp Tim to a BufferedImage with 16 color palette. + */ private @Nonnull BufferedImage toBi4(int iPalette) { byte[] abRgbaPalette = new byte[16 * 4]; if (_clut == null) { - build16GrayRgbaPalette(abRgbaPalette); + PsxRgb.fill16GrayRgbaPalette(abRgbaPalette); } else { // convert CLUT to array of RGBA bytes for (int i = iPalette * 16, o = 0; o < abRgbaPalette.length; i++, o+=4) { - int iArgb = color16toColor32(_clut.getColor(i)); + int iArgb = PsxRgb.psxABGR1555toARGB8888(_clut.getColor(i), SEMI_TRANSPARENT); abRgbaPalette[o+0] = (byte)(iArgb >> 16); abRgbaPalette[o+1] = (byte)(iArgb >> 8); abRgbaPalette[o+2] = (byte)(iArgb ); @@ -510,7 +466,7 @@ private static void build256GrayRgbaPalette(@Nonnull byte[] abPalette) { IndexColorModel cm = new IndexColorModel(4, 16, abRgbaPalette, 0, true); WritableRaster raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, - _iPixelWidth, _iPixelHeight, + getPixelWidth(), getPixelHeight(), 1, 4, null); byte[] abBufferPackedIndexes = ((DataBufferByte)raster.getDataBuffer()).getData(); for (int i = 0; i < abBufferPackedIndexes.length; i++) { @@ -525,11 +481,11 @@ private static void build256GrayRgbaPalette(@Nonnull byte[] abPalette) { private @Nonnull BufferedImage toBi8(int iPalette) { byte[] abRgbaPalette = new byte[256 * 4]; if (_clut == null) { - build256GrayRgbaPalette(abRgbaPalette); + PsxRgb.fill256GrayRgbaPalette(abRgbaPalette); } else { // convert CLUT to array of RGBA bytes for (int i = iPalette * 256, o = 0; o < abRgbaPalette.length; i++, o+=4) { - int iArgb = color16toColor32(_clut.getColor(i)); + int iArgb = PsxRgb.psxABGR1555toARGB8888(_clut.getColor(i), SEMI_TRANSPARENT); abRgbaPalette[o+0] = (byte)(iArgb >> 16); abRgbaPalette[o+1] = (byte)(iArgb >> 8); abRgbaPalette[o+2] = (byte)(iArgb ); @@ -539,8 +495,8 @@ private static void build256GrayRgbaPalette(@Nonnull byte[] abPalette) { IndexColorModel cm = new IndexColorModel(8, 256, abRgbaPalette, 0, true); SampleModel sm = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, - _iPixelWidth, _iPixelHeight, - 1, _iPixelWidth, + getPixelWidth(), getPixelHeight(), + 1, getPixelWidth(), new int[] {0}); WritableRaster raster = Raster.createWritableRaster(sm, null); @@ -557,14 +513,10 @@ private static void build256GrayRgbaPalette(@Nonnull byte[] abPalette) { ColorModel cm = new ComponentColorModel(cs, aiBits, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); - int iScanlineStride = _iPixelWidth * 3; - // TODO: Need to check this logic - if (iScanlineStride % 2 != 0) - iScanlineStride++; - + WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, - _iPixelWidth, _iPixelHeight, - iScanlineStride, 3, + getPixelWidth(), getPixelHeight(), + getPixelWidth() * 3, 3, aiChannelIdxes, null); byte[] abBufferRgb = ((DataBufferByte)raster.getDataBuffer()).getData(); System.arraycopy(_abImageData, 0, abBufferRgb, 0, abBufferRgb.length); @@ -573,53 +525,14 @@ private static void build256GrayRgbaPalette(@Nonnull byte[] abPalette) { /** Convert this 16 bpp Tim to a BufferedImage. */ private @Nonnull BufferedImage toBi16() { - BufferedImage bi = new BufferedImage(_iPixelWidth, _iPixelHeight, BufferedImage.TYPE_INT_ARGB); + BufferedImage bi = new BufferedImage(getPixelWidth(), getPixelHeight(), BufferedImage.TYPE_INT_ARGB); int[] aiBufferRgba = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData(); // convert 16-bit ABGR1555 image data to 32-bit ARGB8888 for (int i = 0, o = 0; o < aiBufferRgba.length; i+=2, o++) { int iColor16 = IO.readUInt16LE(_abImageData, i); - aiBufferRgba[o] = color16toColor32(iColor16); + aiBufferRgba[o] = PsxRgb.psxABGR1555toARGB8888(iColor16, SEMI_TRANSPARENT); } return bi; } - /** Works the same as - *
    -     * int CONVERT_5_TO_8_BIT(int i) {
    -     *   return (int)Math.round((double)i / 31.0);
    -     * }
    -     * 
    */ - private static final int[] CONVERT_5_TO_8_BIT = new int[/*32*/] - { 0, 8, 16, 25, 33, 41, 49, 58, - 66, 74, 82, 90, 99, 107, 115, 123, - 132, 140, 148, 156, 165, 173, 181, 189, - 197, 206, 214, 222, 230, 239, 247, 255 }; - static { assert CONVERT_5_TO_8_BIT.length == 32; } - - /** Tim ABGR1555 to ARGB8888. */ - static int color16toColor32(int i16) { - int b = CONVERT_5_TO_8_BIT[(i16 >>> 10) & 0x1F]; - int g = CONVERT_5_TO_8_BIT[(i16 >>> 5) & 0x1F]; - int r = CONVERT_5_TO_8_BIT[(i16 ) & 0x1F]; - int a; - - if (r == 0 && g == 0 && b == 0) { - if ((i16 & 0x8000) == 0) - // black, and the alpha bit is NOT set - a = (byte)0; // totally transparent - else - // black, and the alpha bit IS set - a = (byte)255; // totally opaque - } else { - if ((i16 & 0x8000) == 0) - // some color, and the alpha bit is NOT set - a = (byte)255; // totally opaque - else - // some color, and the alpha bit IS set - a = (byte)SEMI_TRANSPARENT; // some variance of transparency - } - - return a << 24 | r << 16 | g << 8 | b; - } - } diff --git a/jpsxdec/src/jpsxdec/tim/TimInfo.java b/jpsxdec/src/jpsxdec/tim/TimInfo.java index 134c254..c1b3cb3 100644 --- a/jpsxdec/src/jpsxdec/tim/TimInfo.java +++ b/jpsxdec/src/jpsxdec/tim/TimInfo.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/tim/TimValidator.java b/jpsxdec/src/jpsxdec/tim/TimValidator.java new file mode 100644 index 0000000..fb8b3cb --- /dev/null +++ b/jpsxdec/src/jpsxdec/tim/TimValidator.java @@ -0,0 +1,392 @@ +/* + * jPSXdec: PlayStation 1 Media Decoder/Converter in Java + * Copyright (C) 2020 Michael Sabin + * All rights reserved. + * + * Redistribution and use of the jPSXdec code or any derivative works are + * permitted provided that the following conditions are met: + * + * * Redistributions may not be sold, nor may they be used in commercial + * or revenue-generating business activities. + * + * * Redistributions that are modified from the original source must + * include the complete source code, including the source code for all + * components used by a binary built from the modified sources. However, as + * a special exception, the source code distributed need not include + * anything that is normally distributed (in either source or binary form) + * with the major components (compiler, kernel, and so on) of the operating + * system on which the executable runs, unless that component itself + * accompanies the executable. + * + * * Redistributions must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package jpsxdec.tim; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.Nonnull; +import jpsxdec.util.IO; + +/** + * Combination builder and validator. + */ +public class TimValidator { + + private static final Logger LOG = Logger.getLogger(TimValidator.class.getName()); + + /** + * The PSX VRAM pixel word width is 1024, but some Tim images have even longer + * width. So be flexible, but don't allow for huge sizes. + */ + private static final int MAX_TIM_WORD_WIDTH = 16384; + /** + * The PSX VRAM pixel height is 512, but some Tim images have even higher + * heights. So be flexible, but don't allow for huge sizes. + */ + private static final int MAX_TIM_HEIGHT = 8192; + + + public boolean tagIsValid(@Nonnull InputStream is) throws EOFException, IOException { + return IO.readUInt8(is) == Tim.TAG_MAGIC; // 0x10 + } + + public boolean versionIsValid(@Nonnull InputStream is) throws EOFException, IOException { + return IO.readUInt8(is) == Tim.VERSION_0; + } + + public boolean unknownIsValid(@Nonnull InputStream is) throws EOFException, IOException { + return IO.readUInt16LE(is) == 0; + } + + private int _iBitsPerPixel = -1; + private boolean _blnHasClut; + + public boolean bppAndClutIsValid(@Nonnull InputStream is) throws EOFException, IOException { + int iBpp_hasClut = IO.readUInt16LE(is); + if ((iBpp_hasClut & 0xFFF4) != 0) + return false; + + _blnHasClut = (iBpp_hasClut & 0x8) != 0; + /* + Convert the 2-bit value found in the Tim header to its bits-per-pixel. + 00b = 4 + 01b = 8 + 10b = 16 + 11b = 24 + */ + switch (iBpp_hasClut & 3) { + case 0: _iBitsPerPixel = 4; break; + case 1: _iBitsPerPixel = 8; break; + case 2: _iBitsPerPixel = 16; break; + case 3: _iBitsPerPixel = 24; break; + default: throw new RuntimeException(); + } + return true; + } + public boolean bppIsValid(int iBitsPerPixel) { + return bppIsValid(iBitsPerPixel, + iBitsPerPixel == 4 || iBitsPerPixel == 8); + } + public boolean bppIsValid(int iBitsPerPixel, boolean blnHasClut) { + // It's possible that 24 bits-per-pixel has a CLUT + + switch (iBitsPerPixel) { + case 4: case 8: case 16: case 24: + _iBitsPerPixel = iBitsPerPixel; + break; + default: + return false; + } + + _blnHasClut = blnHasClut; + + return true; + } + public int getBitPerPixel() { + return _iBitsPerPixel; + } + public boolean hasClut() { + return _blnHasClut; + } + + + /** + * Size of the Tim image data and header, excluding the CLUT. + */ + private int _iTimByteSize = -1; + public boolean timByteSizeIsValid(@Nonnull InputStream is) throws EOFException, IOException { + + final int MAX_POSSIBLE_TIM_DATA_SIZE = MAX_TIM_WORD_WIDTH * 2 * MAX_TIM_HEIGHT + Tim.HEADER_SIZE; + + int iImageDataByteSize = IO.readSInt32LE(is); + if (iImageDataByteSize <= 0 || iImageDataByteSize > MAX_POSSIBLE_TIM_DATA_SIZE) + return false; + + _iTimByteSize = iImageDataByteSize; + + return true; + } + public int getImageDataByteSize() { + return _iTimByteSize - Tim.HEADER_SIZE; + } + + + private int _iTimX = -1; + public boolean timXisValid(@Nonnull InputStream is) throws EOFException, IOException { + return timXisValid(IO.readUInt16LE(is)); + } + public boolean timXisValid(int iTimX) { + if (iTimX < 0 || iTimX >= MAX_TIM_WORD_WIDTH) + return false; + + _iTimX = iTimX; + return true; + } + public int getTimX() { + return _iTimX; + } + + private int _iTimY = -1; + public boolean timYisValid(@Nonnull InputStream is) throws EOFException, IOException { + return timYisValid(IO.readUInt16LE(is)); + } + public boolean timYisValid(int iTimY) { + if (iTimY < 0 || iTimY >= MAX_TIM_HEIGHT) + return false; + + _iTimY = iTimY; + return true; + } + public int getTimY() { + return _iTimY; + } + + private int _iWordWidth = -1; + public boolean wordWidthIsValid(@Nonnull InputStream is) throws EOFException, IOException { + return wordWidthIsValid(IO.readUInt16LE(is)); + } + public boolean wordWidthIsValid(int iWordWidth) { + if (iWordWidth <= 0 || iWordWidth > MAX_TIM_WORD_WIDTH) + return false; + + _iWordWidth = iWordWidth; + return true; + } + public int getWordWidth() { + return _iWordWidth; + } + + public boolean pixelWidthIsValid(int iPixelWidth) { + final int iWordWidth; + if (_iBitsPerPixel == 16) + iWordWidth = iPixelWidth; + else if (_iBitsPerPixel == 4) { + if (iPixelWidth % 4 != 0) + return false; + iWordWidth = iPixelWidth / 2 / 2; + } else { + if (iPixelWidth % 2 != 0) + return false; + else if (_iBitsPerPixel == 8) + iWordWidth = iPixelWidth / 2; + else if (_iBitsPerPixel == 24) + iWordWidth = iPixelWidth * 3 / 2; + else + throw new IllegalStateException("Invalid bits-per-pixel " + _iBitsPerPixel); + } + return wordWidthIsValid(iWordWidth); + } + public int getPixelWidth() { + return Tim.calculatePixelWidth(_iWordWidth, _iBitsPerPixel); + } + + private int _iPixelHeight = -1; + public boolean pixelHeightIsValid(@Nonnull InputStream is) throws EOFException, IOException { + return pixelHeightIsValid(IO.readUInt16LE(is)); + } + public boolean pixelHeightIsValid(int iPixelHeight) { + if (iPixelHeight <= 0 || iPixelHeight > MAX_TIM_HEIGHT) + return false; + _iPixelHeight = iPixelHeight; + return true; + } + public int getPixelHeight() { + return _iPixelHeight; + } + + public static enum TimConsistency { + TOTALLY_CONSISTENT, + INCONSISTENT_BUT_VALID, + INCONSISTENT + } + + public @Nonnull TimConsistency timIsConsistent() { + int iExpectedTimByteSize = _iWordWidth * 2 * _iPixelHeight + Tim.HEADER_SIZE; + + TimConsistency consistency = TimConsistency.TOTALLY_CONSISTENT; + + if (_iTimByteSize != iExpectedTimByteSize) { + // Github issue #29 "TIM image not found in file" + // The image length in the header was 2 bytes longer than the calculated length. + // The rest of the data was a valid Tim image. + // Further research shows +2 bytes is not uncommon among games, + // but only +2, no other amount. So allow for +2 as well. + if (_iTimByteSize < iExpectedTimByteSize || _iTimByteSize > iExpectedTimByteSize + 2) + return TimConsistency.INCONSISTENT; + + LOG.log(Level.WARNING, "Tim data requires only {0} bytes but header says Tim is {1} bytes", + new Object[]{iExpectedTimByteSize, _iTimByteSize}); + + consistency = TimConsistency.INCONSISTENT_BUT_VALID; + } + + // Also include the trailing data in the read. + // That will allow writing an identical TIM image. + + if (_blnHasClut) { + // User CUE reported an issue with some strange TIM images from + // "Guardian's Crusade" that report 16 bits-per-pixel, but also + // have a CLUT (bug "JPSXDEC-4"). + // Turns out the image data was actually 4 or 8 bits-per-pixels. + // The CLUT width seemed to correlate with the bits-per-pixel + // (width < 256 : 4 bits/pixel, width >= 256 : 8 bits/pixel) + // No clear way to handle this case, so we'll change the code + // to at least handle these unique images the best we can. + if (_iBitsPerPixel == 16) { + if (_iClutPixelWidth < 256) + _iBitsPerPixel = 4; + else + _iBitsPerPixel = 8; + LOG.log(Level.WARNING, "TIM reports 16 bits/pixel, but it also has a CLUT. Assuming {0,number,#} bits/pixel", _iBitsPerPixel); + consistency = TimConsistency.INCONSISTENT_BUT_VALID; + } else if (_iBitsPerPixel == 24) { + LOG.log(Level.WARNING, "TIM reports 24 bits/pixel, but it also has a CLUT. Assuming 8 bits/pixel"); + _iBitsPerPixel = 8; + consistency = TimConsistency.INCONSISTENT_BUT_VALID; + } + } + + return consistency; + } + + // ========================================================================= + // CLUT + + /** + * Size of the entire CLUT structure, in bytes. + */ + private int _iClutByteSize = -1; + public boolean clutByteSizeIsValid(@Nonnull InputStream is) throws EOFException, IOException { + final int CLUT_MAX_BYTE_SIZE = MAX_TIM_WORD_WIDTH * 2 * MAX_TIM_HEIGHT + CLUT.HEADER_SIZE; + + int iClutByteSize = IO.readSInt32LE(is); + if (iClutByteSize <= 0 || iClutByteSize > CLUT_MAX_BYTE_SIZE || (iClutByteSize % 2 != 0)) + return false; + _iClutByteSize = iClutByteSize; + return true; + } + public int getClutImageDataByteSize() { + return _iClutByteSize - CLUT.HEADER_SIZE; + } + public int getClutImageDataWordSize() { + return getClutImageDataByteSize() / 2; + } + + + private int _iClutX = -1; + public boolean clutXisValid(@Nonnull InputStream is) throws EOFException, IOException { + return clutXisValid(IO.readUInt16LE(is)); + } + public boolean clutXisValid(int iClutX) { + if (iClutX < 0 || iClutX >= MAX_TIM_WORD_WIDTH) + return false; + _iClutX = iClutX; + return true; + } + public int getClutX() { + return _iClutX; + } + + + private int _iClutY = -1; + public boolean clutYisValid(@Nonnull InputStream is) throws EOFException, IOException { + return clutYisValid(IO.readUInt16LE(is)); + } + public boolean clutYisValid(int iClutY) { + if (iClutY < 0 || iClutY >= MAX_TIM_HEIGHT) + return false; + + _iClutY = iClutY; + return true; + } + public int getClutY() { + return _iClutY; + } + + + private int _iClutPixelWidth = -1; + public boolean clutPixelWidthIsValid(@Nonnull InputStream is) throws EOFException, IOException { + return clutPixelWidthIsValid(IO.readUInt16LE(is)); + } + public boolean clutPixelWidthIsValid(int iClutWidth) { + if (iClutWidth <= 0 || iClutWidth > MAX_TIM_WORD_WIDTH) + return false; + + _iClutPixelWidth = iClutWidth; + return true; + } + public int getClutPixelWidth() { + return _iClutPixelWidth; + } + + + private int _iClutPixelHeight = -1; + public boolean clutPixelHeightIsValid(@Nonnull InputStream is) throws EOFException, IOException { + return clutPixelHeightIsValid(IO.readUInt16LE(is)); + } + public boolean clutPixelHeightIsValid(int iClutHeight) { + if (iClutHeight <= 0 || iClutHeight > MAX_TIM_HEIGHT) + return false; + _iClutPixelHeight = iClutHeight; + return true; + } + public int getClutPixelHeight() { + return _iClutPixelHeight; + } + + + public boolean clutIsConsistent() { + int iExpectedClutByteSize = _iClutPixelWidth * 2 * _iClutPixelHeight + CLUT.HEADER_SIZE; + + // We've give the Tim size some flexibility after the bug report, + // but for now we'll keep the CLUT size rigid. + if (iExpectedClutByteSize != _iClutByteSize) + return false; + + // In theory 4bb CLUT width should always be a multiple of 16 + // and 8bpp CLUT should always be a multiple of 256 + // however, that is not always the case, so we'll allow for any + // CLUT dimensions + + return true; + } + +} diff --git a/jpsxdec/src/jpsxdec/util/ArgParser.java b/jpsxdec/src/jpsxdec/util/ArgParser.java index 4162f14..29a5013 100644 --- a/jpsxdec/src/jpsxdec/util/ArgParser.java +++ b/jpsxdec/src/jpsxdec/util/ArgParser.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/AudioOutputFileWriter.java b/jpsxdec/src/jpsxdec/util/AudioOutputFileWriter.java index 22264fd..9e6e870 100644 --- a/jpsxdec/src/jpsxdec/util/AudioOutputFileWriter.java +++ b/jpsxdec/src/jpsxdec/util/AudioOutputFileWriter.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/BinaryDataNotRecognized.java b/jpsxdec/src/jpsxdec/util/BinaryDataNotRecognized.java index 7b3e0ed..60d8bab 100644 --- a/jpsxdec/src/jpsxdec/util/BinaryDataNotRecognized.java +++ b/jpsxdec/src/jpsxdec/util/BinaryDataNotRecognized.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/BufferedIOIterator.java b/jpsxdec/src/jpsxdec/util/BufferedIOIterator.java index 0310fbe..9870b6e 100644 --- a/jpsxdec/src/jpsxdec/util/BufferedIOIterator.java +++ b/jpsxdec/src/jpsxdec/util/BufferedIOIterator.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/BufferedPushIterator.java b/jpsxdec/src/jpsxdec/util/BufferedPushIterator.java index a29a038..6a00493 100644 --- a/jpsxdec/src/jpsxdec/util/BufferedPushIterator.java +++ b/jpsxdec/src/jpsxdec/util/BufferedPushIterator.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/ByteArrayFPIS.java b/jpsxdec/src/jpsxdec/util/ByteArrayFPIS.java index ee07832..96574f3 100644 --- a/jpsxdec/src/jpsxdec/util/ByteArrayFPIS.java +++ b/jpsxdec/src/jpsxdec/util/ByteArrayFPIS.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/DemuxPullInputStream.java b/jpsxdec/src/jpsxdec/util/DemuxPullInputStream.java index 4b02b29..6a32052 100644 --- a/jpsxdec/src/jpsxdec/util/DemuxPullInputStream.java +++ b/jpsxdec/src/jpsxdec/util/DemuxPullInputStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/DemuxPushInputStream.java b/jpsxdec/src/jpsxdec/util/DemuxPushInputStream.java index 8a5aff1..ed684cd 100644 --- a/jpsxdec/src/jpsxdec/util/DemuxPushInputStream.java +++ b/jpsxdec/src/jpsxdec/util/DemuxPushInputStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -385,30 +385,29 @@ public boolean isEof() { public int read() { if (isEof()) return -1; - while (_currentPieceStream.isEof() && _pieceIterator.hasNext()) { - _currentPieceStream = new PieceInputStream(_pieceIterator.next()); - } + skipEofStreams(); if (isEof()) return -1; _iAvailable--; return _currentPieceStream.read(); } + private void skipEofStreams() { + while (_currentPieceStream.isEof() && _pieceIterator.hasNext()) { + _currentPieceStream = new PieceInputStream(_pieceIterator.next()); + } + } + @Override public long skip(long lngBytesToSkip) { if (isEof()) return -1; long lngTotalBytesSkipped = 0; - while (_currentPieceStream.isEof() && _pieceIterator.hasNext()) { - _currentPieceStream = new PieceInputStream(_pieceIterator.next()); - } while (lngTotalBytesSkipped < lngBytesToSkip && !isEof()) { + skipEofStreams(); long lngBytesSkipped = _currentPieceStream.skip(lngBytesToSkip - lngTotalBytesSkipped); if (lngBytesSkipped > 0) lngTotalBytesSkipped += lngBytesSkipped; - while (_currentPieceStream.isEof() && _pieceIterator.hasNext()) { - _currentPieceStream = new PieceInputStream(_pieceIterator.next()); - } } _iAvailable -= lngTotalBytesSkipped; return lngTotalBytesSkipped == 0 ? -1 : lngTotalBytesSkipped; diff --git a/jpsxdec/src/jpsxdec/util/DemuxedData.java b/jpsxdec/src/jpsxdec/util/DemuxedData.java index 7056d9f..f1ab5d4 100644 --- a/jpsxdec/src/jpsxdec/util/DemuxedData.java +++ b/jpsxdec/src/jpsxdec/util/DemuxedData.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/ExposedBAOS.java b/jpsxdec/src/jpsxdec/util/ExposedBAOS.java index 277b252..178c983 100644 --- a/jpsxdec/src/jpsxdec/util/ExposedBAOS.java +++ b/jpsxdec/src/jpsxdec/util/ExposedBAOS.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/Fraction.java b/jpsxdec/src/jpsxdec/util/Fraction.java index 79ccf36..5feff01 100644 --- a/jpsxdec/src/jpsxdec/util/Fraction.java +++ b/jpsxdec/src/jpsxdec/util/Fraction.java @@ -21,7 +21,7 @@ * An immutable class representing fractions as pairs of longs. * Fractions are always maintained in reduced form. **/ -public class Fraction implements Cloneable, Comparable, java.io.Serializable { +public class Fraction implements Cloneable, Comparable { public static final Fraction ZERO = new Fraction(0, 1); protected final long numerator_; @@ -210,12 +210,11 @@ public float multiply(float f) { * reflecting whether this Fraction is less, equal or greater than * the value of Fraction other. **/ - public int compareTo(Object other) { - Fraction b = (Fraction)(other); + public int compareTo(Fraction other) { long an = getNumerator(); long ad = getDenominator(); - long bn = b.getNumerator(); - long bd = b.getDenominator(); + long bn = other.getNumerator(); + long bd = other.getDenominator(); long l = an*bd; long r = bn*ad; return (l < r)? -1 : ((l == r)? 0: 1); diff --git a/jpsxdec/src/jpsxdec/util/IO.java b/jpsxdec/src/jpsxdec/util/IO.java index 529ef8e..a109353 100644 --- a/jpsxdec/src/jpsxdec/util/IO.java +++ b/jpsxdec/src/jpsxdec/util/IO.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/IOIterator.java b/jpsxdec/src/jpsxdec/util/IOIterator.java index 7ab7836..26c6c2d 100644 --- a/jpsxdec/src/jpsxdec/util/IOIterator.java +++ b/jpsxdec/src/jpsxdec/util/IOIterator.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/Imaging.java b/jpsxdec/src/jpsxdec/util/Imaging.java index fdcba9e..b01e774 100644 --- a/jpsxdec/src/jpsxdec/util/Imaging.java +++ b/jpsxdec/src/jpsxdec/util/Imaging.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/IncompatibleException.java b/jpsxdec/src/jpsxdec/util/IncompatibleException.java index 1684fcd..4936be1 100644 --- a/jpsxdec/src/jpsxdec/util/IncompatibleException.java +++ b/jpsxdec/src/jpsxdec/util/IncompatibleException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/Maths.java b/jpsxdec/src/jpsxdec/util/Maths.java index b3b8952..d2b05a1 100644 --- a/jpsxdec/src/jpsxdec/util/Maths.java +++ b/jpsxdec/src/jpsxdec/util/Maths.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/Misc.java b/jpsxdec/src/jpsxdec/util/Misc.java index 13a9554..8341330 100644 --- a/jpsxdec/src/jpsxdec/util/Misc.java +++ b/jpsxdec/src/jpsxdec/util/Misc.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -40,7 +40,6 @@ import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; -import java.io.UnsupportedEncodingException; import java.net.URI; import java.nio.charset.Charset; import java.util.ArrayList; @@ -63,22 +62,14 @@ public final class Misc { * @see Charset */ public static @Nonnull byte[] stringToAscii(@Nonnull String string) { - try { - return string.getBytes("US-ASCII"); - } catch (UnsupportedEncodingException ex) { - throw new RuntimeException(ex); - } + return string.getBytes(Charset.forName("US-ASCII")); } public static @Nonnull String asciiToString(@Nonnull byte[] ascii) { return asciiToString(ascii, 0, ascii.length); } public static @Nonnull String asciiToString(@Nonnull byte[] ascii, int iOffset, int iLength) { - try { - return new String(ascii, iOffset, iLength, "US-ASCII"); - } catch (UnsupportedEncodingException ex) { - throw new RuntimeException(ex); - } + return new String(ascii, iOffset, iLength, Charset.forName("US-ASCII")); } /** Makes a date X number of seconds past the year 0. */ @@ -194,7 +185,7 @@ public static boolean objectEquals(@CheckForNull Object o1, @CheckForNull Object return CURRENT_URI.relativize(f.toURI()).toString(); } - public static @Nonnull String join(@Nonnull Iterable ao, @Nonnull String sBetween) { + public static @Nonnull String join(@Nonnull Iterable ao, @Nonnull String sBetween) { StringBuilder sb = new StringBuilder(); boolean blnFirst = true; for (Object o : ao) { diff --git a/jpsxdec/src/jpsxdec/util/PushAvailableInputStream.java b/jpsxdec/src/jpsxdec/util/PushAvailableInputStream.java index a5432cf..726bb85 100644 --- a/jpsxdec/src/jpsxdec/util/PushAvailableInputStream.java +++ b/jpsxdec/src/jpsxdec/util/PushAvailableInputStream.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/TaskCanceledException.java b/jpsxdec/src/jpsxdec/util/TaskCanceledException.java index cb933fe..6888f01 100644 --- a/jpsxdec/src/jpsxdec/util/TaskCanceledException.java +++ b/jpsxdec/src/jpsxdec/util/TaskCanceledException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2012-2019 Michael Sabin + * Copyright (C) 2012-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/aviwriter/AVIMAINHEADER.java b/jpsxdec/src/jpsxdec/util/aviwriter/AVIMAINHEADER.java index 23ebccf..1b2261d 100644 --- a/jpsxdec/src/jpsxdec/util/aviwriter/AVIMAINHEADER.java +++ b/jpsxdec/src/jpsxdec/util/aviwriter/AVIMAINHEADER.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/aviwriter/AVIOLDINDEX.java b/jpsxdec/src/jpsxdec/util/aviwriter/AVIOLDINDEX.java index 2de74c7..a812baf 100644 --- a/jpsxdec/src/jpsxdec/util/aviwriter/AVIOLDINDEX.java +++ b/jpsxdec/src/jpsxdec/util/aviwriter/AVIOLDINDEX.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/aviwriter/AVISTREAMHEADER.java b/jpsxdec/src/jpsxdec/util/aviwriter/AVISTREAMHEADER.java index 18af2b8..b96bce3 100644 --- a/jpsxdec/src/jpsxdec/util/aviwriter/AVISTREAMHEADER.java +++ b/jpsxdec/src/jpsxdec/util/aviwriter/AVISTREAMHEADER.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/aviwriter/AVIstruct.java b/jpsxdec/src/jpsxdec/util/aviwriter/AVIstruct.java index 8e68e0c..248a0c0 100644 --- a/jpsxdec/src/jpsxdec/util/aviwriter/AVIstruct.java +++ b/jpsxdec/src/jpsxdec/util/aviwriter/AVIstruct.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/aviwriter/AviIsClosedException.java b/jpsxdec/src/jpsxdec/util/aviwriter/AviIsClosedException.java index d035884..32e5e5d 100644 --- a/jpsxdec/src/jpsxdec/util/aviwriter/AviIsClosedException.java +++ b/jpsxdec/src/jpsxdec/util/aviwriter/AviIsClosedException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2018-2019 Michael Sabin + * Copyright (C) 2018-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/aviwriter/AviWriter.java b/jpsxdec/src/jpsxdec/util/aviwriter/AviWriter.java index aa4582c..4af335d 100644 --- a/jpsxdec/src/jpsxdec/util/aviwriter/AviWriter.java +++ b/jpsxdec/src/jpsxdec/util/aviwriter/AviWriter.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterDIB.java b/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterDIB.java index a41d6b1..54af685 100644 --- a/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterDIB.java +++ b/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterDIB.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterMJPG.java b/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterMJPG.java index 601fd4b..149326c 100644 --- a/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterMJPG.java +++ b/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterMJPG.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterYV12.java b/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterYV12.java index 94e1448..a046b65 100644 --- a/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterYV12.java +++ b/jpsxdec/src/jpsxdec/util/aviwriter/AviWriterYV12.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/aviwriter/BITMAPINFOHEADER.java b/jpsxdec/src/jpsxdec/util/aviwriter/BITMAPINFOHEADER.java index f3b2caa..28c11c8 100644 --- a/jpsxdec/src/jpsxdec/util/aviwriter/BITMAPINFOHEADER.java +++ b/jpsxdec/src/jpsxdec/util/aviwriter/BITMAPINFOHEADER.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/aviwriter/WAVEFORMATEX.java b/jpsxdec/src/jpsxdec/util/aviwriter/WAVEFORMATEX.java index f9db002..d663c82 100644 --- a/jpsxdec/src/jpsxdec/util/aviwriter/WAVEFORMATEX.java +++ b/jpsxdec/src/jpsxdec/util/aviwriter/WAVEFORMATEX.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/AudioPlayer.java b/jpsxdec/src/jpsxdec/util/player/AudioPlayer.java index 0ca0548..233f947 100644 --- a/jpsxdec/src/jpsxdec/util/player/AudioPlayer.java +++ b/jpsxdec/src/jpsxdec/util/player/AudioPlayer.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -97,6 +97,8 @@ class AudioPlayer extends VideoTimer implements Runnable, LineListener { private SourceDataLine _dataLine; + private boolean _blnWasStarted = false; + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Experiment with using the system clock and intermittently sync with the audio time private boolean _blnUseAudioAndSystemClockTogether = false; @@ -234,6 +236,18 @@ public void run() { } } } + + // Check before we exit this block... + // Dataline javadoc: "The drain() method blocks until this internal buffer becomes empty" + // Lies! .drain() will return immediately if the audio data is small and has not been played. + // So wait until some audio was played before exiting (or until notified to stop). + synchronized (this) { + while (!_blnWasStarted) { + System.out.println("Out of audio data, but player has not been started"); + this.wait(); + } + } + } catch (IOException ex) { // this hopefully only happens because the reader was forcefully closed System.out.println("Audio player IOException stop: " + ex.getMessage()); @@ -249,6 +263,7 @@ public void run() { _dataLine.drain(); _dataLine.close(); super.terminate(); + System.out.println("AudioPlayer ending"); } @@ -265,6 +280,7 @@ public synchronized void go() { _lngLastSync = lngNow; _lngStartTime = lngNow - (long)(_dataLine.getLongFramePosition() * _dblSamplesPerNano); _dataLine.start(); + _blnWasStarted = true; } super.go(); } @@ -280,6 +296,7 @@ public synchronized void pause() { } public void finish() { + if (DEBUG) System.out.println("AudioPlayer.finish()"); // it looks like it's thread-safe to close the stream IO.closeSilently(_pipedOutputStream, LOG); } diff --git a/jpsxdec/src/jpsxdec/util/player/ClosableBoundedBlockingQueue.java b/jpsxdec/src/jpsxdec/util/player/ClosableBoundedBlockingQueue.java index 2a2c04f..6422df7 100644 --- a/jpsxdec/src/jpsxdec/util/player/ClosableBoundedBlockingQueue.java +++ b/jpsxdec/src/jpsxdec/util/player/ClosableBoundedBlockingQueue.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/DecodableFrame.java b/jpsxdec/src/jpsxdec/util/player/DecodableFrame.java index 21cce39..8e866d7 100644 --- a/jpsxdec/src/jpsxdec/util/player/DecodableFrame.java +++ b/jpsxdec/src/jpsxdec/util/player/DecodableFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/DecodedVideoFrame.java b/jpsxdec/src/jpsxdec/util/player/DecodedVideoFrame.java index acfb622..a4ad1cf 100644 --- a/jpsxdec/src/jpsxdec/util/player/DecodedVideoFrame.java +++ b/jpsxdec/src/jpsxdec/util/player/DecodedVideoFrame.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/IFrameProcessor.java b/jpsxdec/src/jpsxdec/util/player/IFrameProcessor.java index eb6ce5b..256e8be 100644 --- a/jpsxdec/src/jpsxdec/util/player/IFrameProcessor.java +++ b/jpsxdec/src/jpsxdec/util/player/IFrameProcessor.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/IMediaDataReader.java b/jpsxdec/src/jpsxdec/util/player/IMediaDataReader.java index 1a67d8d..81e9add 100644 --- a/jpsxdec/src/jpsxdec/util/player/IMediaDataReader.java +++ b/jpsxdec/src/jpsxdec/util/player/IMediaDataReader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/IPreprocessedFrameWriter.java b/jpsxdec/src/jpsxdec/util/player/IPreprocessedFrameWriter.java index 88d4158..a8dee10 100644 --- a/jpsxdec/src/jpsxdec/util/player/IPreprocessedFrameWriter.java +++ b/jpsxdec/src/jpsxdec/util/player/IPreprocessedFrameWriter.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/PlayController.java b/jpsxdec/src/jpsxdec/util/player/PlayController.java index ede6805..2d1e069 100644 --- a/jpsxdec/src/jpsxdec/util/player/PlayController.java +++ b/jpsxdec/src/jpsxdec/util/player/PlayController.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -110,7 +110,7 @@ public void setReader(@Nonnull IMediaDataReader reader) { _readerThread.setReader(reader); } - public void setVidProcressor(@Nonnull IFrameProcessor processor) { + public void setVidProcressor(@Nonnull IFrameProcessor processor) { if (_videoProcessorThread == null) throw new IllegalArgumentException(); _videoProcessorThread.setProcessor(processor); diff --git a/jpsxdec/src/jpsxdec/util/player/PlayerException.java b/jpsxdec/src/jpsxdec/util/player/PlayerException.java index 5546171..ebaa1e8 100644 --- a/jpsxdec/src/jpsxdec/util/player/PlayerException.java +++ b/jpsxdec/src/jpsxdec/util/player/PlayerException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/ReaderThread.java b/jpsxdec/src/jpsxdec/util/player/ReaderThread.java index 2262799..fb60a0f 100644 --- a/jpsxdec/src/jpsxdec/util/player/ReaderThread.java +++ b/jpsxdec/src/jpsxdec/util/player/ReaderThread.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/StopPlayingException.java b/jpsxdec/src/jpsxdec/util/player/StopPlayingException.java index 91ee61e..2e08406 100644 --- a/jpsxdec/src/jpsxdec/util/player/StopPlayingException.java +++ b/jpsxdec/src/jpsxdec/util/player/StopPlayingException.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/ThreadSafeEventListeners.java b/jpsxdec/src/jpsxdec/util/player/ThreadSafeEventListeners.java index 026a8c8..ea9087c 100644 --- a/jpsxdec/src/jpsxdec/util/player/ThreadSafeEventListeners.java +++ b/jpsxdec/src/jpsxdec/util/player/ThreadSafeEventListeners.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/VideoClock.java b/jpsxdec/src/jpsxdec/util/player/VideoClock.java index bab7b83..60be662 100644 --- a/jpsxdec/src/jpsxdec/util/player/VideoClock.java +++ b/jpsxdec/src/jpsxdec/util/player/VideoClock.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/VideoPlayer.java b/jpsxdec/src/jpsxdec/util/player/VideoPlayer.java index 268a0fe..3b20a35 100644 --- a/jpsxdec/src/jpsxdec/util/player/VideoPlayer.java +++ b/jpsxdec/src/jpsxdec/util/player/VideoPlayer.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/VideoProcessor.java b/jpsxdec/src/jpsxdec/util/player/VideoProcessor.java index df7e268..7b0a95e 100644 --- a/jpsxdec/src/jpsxdec/util/player/VideoProcessor.java +++ b/jpsxdec/src/jpsxdec/util/player/VideoProcessor.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -49,8 +49,8 @@ class VideoProcessor implements Runnable, IPreprocessedFrameWriter { private static final int CAPACITY = 50; - private final ClosableBoundedBlockingQueue _framesProcessingQueue = - new ClosableBoundedBlockingQueue(CAPACITY); + private final ClosableBoundedBlockingQueue> _framesProcessingQueue = + new ClosableBoundedBlockingQueue>(CAPACITY); @Nonnull private final VideoTimer _vidTimer; @@ -67,7 +67,7 @@ class VideoProcessor implements Runnable, IPreprocessedFrameWriter { _thread = new Thread(this, getClass().getName()); } - public void setProcessor(@Nonnull IFrameProcessor processor) { + public void setProcessor(@Nonnull IFrameProcessor processor) { _processor = processor; } @@ -79,7 +79,7 @@ public void start() { @SuppressWarnings("unchecked") public void run() { - DecodableFrame decodeFrame; + DecodableFrame decodeFrame; int[] aiImage = new int[_vidPlayer.getWidth() * _vidPlayer.getHeight()]; try { while ((decodeFrame = _framesProcessingQueue.take()) != null) { @@ -115,7 +115,7 @@ public void run() { public void writeFrame(@Nonnull Object frame, long lngPresentationNanos) throws StopPlayingException { if (DEBUG) System.out.println("Frame submitted for processing, present at " + lngPresentationNanos); try { - if (!_framesProcessingQueue.add(new DecodableFrame(frame, lngPresentationNanos))) + if (!_framesProcessingQueue.add(new DecodableFrame(frame, lngPresentationNanos))) throw new StopPlayingException(); } catch (InterruptedException ex) { throw new StopPlayingException(ex); diff --git a/jpsxdec/src/jpsxdec/util/player/VideoScreen.java b/jpsxdec/src/jpsxdec/util/player/VideoScreen.java index 05e7dc0..3680520 100644 --- a/jpsxdec/src/jpsxdec/util/player/VideoScreen.java +++ b/jpsxdec/src/jpsxdec/util/player/VideoScreen.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/VideoTimer.java b/jpsxdec/src/jpsxdec/util/player/VideoTimer.java index 03b8c61..7812e34 100644 --- a/jpsxdec/src/jpsxdec/util/player/VideoTimer.java +++ b/jpsxdec/src/jpsxdec/util/player/VideoTimer.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/jpsxdec/util/player/package-info.java b/jpsxdec/src/jpsxdec/util/player/package-info.java index ea81322..4a07ec4 100644 --- a/jpsxdec/src/jpsxdec/util/player/package-info.java +++ b/jpsxdec/src/jpsxdec/util/player/package-info.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter n Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/src/org/openide/util/ImageUtilities.java b/jpsxdec/src/org/openide/util/ImageUtilities.java index 7d0b719..0fbc8ab 100644 --- a/jpsxdec/src/org/openide/util/ImageUtilities.java +++ b/jpsxdec/src/org/openide/util/ImageUtilities.java @@ -521,8 +521,8 @@ public int filterRGB(int x, int y, int rgb) { // override the superclass behaviour to not pollute // the heap with useless properties strings. Saves tens of KBs @Override - public void setProperties(Hashtable props) { - props = (Hashtable) props.clone(); + public void setProperties(Hashtable props) { + props = (Hashtable) props.clone(); consumer.setProperties(props); } } diff --git a/jpsxdec/test/AllTestsSuite.java b/jpsxdec/test/AllTestsSuite.java index 832344a..54054bc 100644 --- a/jpsxdec/test/AllTestsSuite.java +++ b/jpsxdec/test/AllTestsSuite.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -53,6 +53,7 @@ jpsxdec.indexing.DiscIndexerXaAudioTest.class, jpsxdec.modules.crusader.DiscIndexerCrusaderTest.class, jpsxdec.modules.video.sectorbased.fps.Fps.class, + jpsxdec.modules.xa.DiscItemXaAudioStreamTest.class, jpsxdec.psxvideo.PsxYCbCr_intTest.class, jpsxdec.psxvideo.bitstreams.BitReader.class, jpsxdec.psxvideo.bitstreams.Iki.class, diff --git a/jpsxdec/test/jpsxdec/TestLog.java b/jpsxdec/test/jpsxdec/TestLog.java index f8aec93..1de9833 100644 --- a/jpsxdec/test/jpsxdec/TestLog.java +++ b/jpsxdec/test/jpsxdec/TestLog.java @@ -1,8 +1,6 @@ -package jpsxdec; - /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2018-2019 Michael Sabin + * Copyright (C) 2018-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -37,6 +35,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +package jpsxdec; + import java.io.IOException; import jpsxdec.Main; import jpsxdec.i18n.log.DebugFormatter; diff --git a/jpsxdec/test/jpsxdec/adpcm/SpuDecodeCorruption.java b/jpsxdec/test/jpsxdec/adpcm/SpuDecodeCorruption.java index b6347a6..8d49e40 100644 --- a/jpsxdec/test/jpsxdec/adpcm/SpuDecodeCorruption.java +++ b/jpsxdec/test/jpsxdec/adpcm/SpuDecodeCorruption.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/adpcm/XaDecodeCorruption.java b/jpsxdec/test/jpsxdec/adpcm/XaDecodeCorruption.java index aa378d0..b0b47f9 100644 --- a/jpsxdec/test/jpsxdec/adpcm/XaDecodeCorruption.java +++ b/jpsxdec/test/jpsxdec/adpcm/XaDecodeCorruption.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/cmdline/Command_StaticTest.java b/jpsxdec/test/jpsxdec/cmdline/Command_StaticTest.java index fdf527a..a7cb473 100644 --- a/jpsxdec/test/jpsxdec/cmdline/Command_StaticTest.java +++ b/jpsxdec/test/jpsxdec/cmdline/Command_StaticTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/discitems/DiscItemTest.java b/jpsxdec/test/jpsxdec/discitems/DiscItemTest.java index 741c6c0..7e8a3e7 100644 --- a/jpsxdec/test/jpsxdec/discitems/DiscItemTest.java +++ b/jpsxdec/test/jpsxdec/discitems/DiscItemTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are @@ -105,7 +105,7 @@ public void testOverlap() throws Exception { raf.writeByte(0); raf.close(); - CdFileSectorReader cd = new CdFileSectorReader(cdFile, 2048); + CdFileSectorReader cd = CdFileSectorReader.openWithSectorSize(cdFile, 2048); DI d1 = new DI(cd, 10, 20); diff --git a/jpsxdec/test/jpsxdec/discitems/SerializedDiscItemTest.java b/jpsxdec/test/jpsxdec/discitems/SerializedDiscItemTest.java index 9a4bb69..a94968a 100644 --- a/jpsxdec/test/jpsxdec/discitems/SerializedDiscItemTest.java +++ b/jpsxdec/test/jpsxdec/discitems/SerializedDiscItemTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2015-2019 Michael Sabin + * Copyright (C) 2015-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/indexing/DiscIndexerXaAudioTest.java b/jpsxdec/test/jpsxdec/indexing/DiscIndexerXaAudioTest.java index 131f789..0c43ff3 100644 --- a/jpsxdec/test/jpsxdec/indexing/DiscIndexerXaAudioTest.java +++ b/jpsxdec/test/jpsxdec/indexing/DiscIndexerXaAudioTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/modules/crusader/DiscIndexerCrusaderTest.java b/jpsxdec/test/jpsxdec/modules/crusader/DiscIndexerCrusaderTest.java index cbbc40d..290081e 100644 --- a/jpsxdec/test/jpsxdec/modules/crusader/DiscIndexerCrusaderTest.java +++ b/jpsxdec/test/jpsxdec/modules/crusader/DiscIndexerCrusaderTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/modules/video/sectorbased/fps/Fps.java b/jpsxdec/test/jpsxdec/modules/video/sectorbased/fps/Fps.java index 6aa8e22..fc3d856 100644 --- a/jpsxdec/test/jpsxdec/modules/video/sectorbased/fps/Fps.java +++ b/jpsxdec/test/jpsxdec/modules/video/sectorbased/fps/Fps.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/modules/xa/DiscItemXaAudioStreamTest.java b/jpsxdec/test/jpsxdec/modules/xa/DiscItemXaAudioStreamTest.java new file mode 100644 index 0000000..7a2f6c1 --- /dev/null +++ b/jpsxdec/test/jpsxdec/modules/xa/DiscItemXaAudioStreamTest.java @@ -0,0 +1,105 @@ +/* + * LainTools: PSX Serial Experiments Lain Hacking and Translation Tools + * Copyright (C) 2020 Michael Sabin + * + * Redistribution and use of the LainTools code or any derivative works are + * permitted provided that the following conditions are met: + * + * * Redistributions may not be sold, nor may they be used in commercial + * or revenue-generating business activities. + * + * * Redistributions that are modified from the original source must + * include the complete source code, including the source code for all + * components used by a binary built from the modified sources. However, as + * a special exception, the source code distributed need not include + * anything that is normally distributed (in either source or binary form) + * with the major components (compiler, kernel, and so on) of the operating + * system on which the executable runs, unless that component itself + * accompanies the executable. + * + * * Redistributions must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package jpsxdec.modules.xa; + +import java.util.BitSet; +import jpsxdec.cdreaders.CdFileSectorReader; +import org.junit.*; +import static org.junit.Assert.*; + +public class DiscItemXaAudioStreamTest { + + private static class MockSectorReader extends CdFileSectorReader { + public MockSectorReader(int iSectorLen) { + super(null, null, iSectorLen); + } + } + + + @Test + public void testSilentSectors() { + MockSectorReader cd = new MockSectorReader(100); + + // Disc is 100 sectors long + // 5 XA sectors, 8 sectors apart: 10, 18, 26, 34, 42, 50 + XaAudioFormat format = new XaAudioFormat(1, 0, 18900, 8, true); + + DiscItemXaAudioStream xa = new DiscItemXaAudioStream(cd, 10, 50, format, 8, null); + assertFalse(xa.isConfirmedToBeSilent()); + + BitSet sectorsWithAudio = new BitSet(); + xa = new DiscItemXaAudioStream(cd, 10, 50, format, 8, sectorsWithAudio); + assertTrue(xa.isConfirmedToBeSilent()); + + sectorsWithAudio = new BitSet(); + sectorsWithAudio.set(0); + xa = new DiscItemXaAudioStream(cd, 10, 50, format, 8, sectorsWithAudio); + assertFalse(xa.isConfirmedToBeSilent()); + + sectorsWithAudio = new BitSet(); + sectorsWithAudio.set(0, 5); + xa = new DiscItemXaAudioStream(cd, 10, 50, format, 8, sectorsWithAudio); + assertFalse(xa.isConfirmedToBeSilent()); + + DiscItemXaAudioStream[] split = xa.split(25); + assertEquals(10, split[0].getStartSector()); + assertEquals(18, split[0].getEndSector()); + assertFalse(split[0].isConfirmedToBeSilent()); + + assertEquals(26, split[1].getStartSector()); + assertEquals(50, split[1].getEndSector()); + assertFalse(split[1].isConfirmedToBeSilent()); + + + sectorsWithAudio = new BitSet(); + sectorsWithAudio.set(0); + xa = new DiscItemXaAudioStream(cd, 10, 50, format, 8, sectorsWithAudio); + assertFalse(xa.isConfirmedToBeSilent()); + split = xa.split(25); + assertFalse(split[0].isConfirmedToBeSilent()); + assertTrue(split[1].isConfirmedToBeSilent()); + + sectorsWithAudio = new BitSet(); + sectorsWithAudio.set(4); + xa = new DiscItemXaAudioStream(cd, 10, 50, format, 8, sectorsWithAudio); + assertFalse(xa.isConfirmedToBeSilent()); + split = xa.split(25); + assertTrue(split[0].isConfirmedToBeSilent()); + assertFalse(split[1].isConfirmedToBeSilent()); + } + +} diff --git a/jpsxdec/test/jpsxdec/psxvideo/PsxYCbCr_intTest.java b/jpsxdec/test/jpsxdec/psxvideo/PsxYCbCr_intTest.java index 6a33deb..00f7542 100644 --- a/jpsxdec/test/jpsxdec/psxvideo/PsxYCbCr_intTest.java +++ b/jpsxdec/test/jpsxdec/psxvideo/PsxYCbCr_intTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/psxvideo/bitstreams/BitReader.java b/jpsxdec/test/jpsxdec/psxvideo/bitstreams/BitReader.java index 83216c9..563f8f4 100644 --- a/jpsxdec/test/jpsxdec/psxvideo/bitstreams/BitReader.java +++ b/jpsxdec/test/jpsxdec/psxvideo/bitstreams/BitReader.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/psxvideo/bitstreams/Iki.java b/jpsxdec/test/jpsxdec/psxvideo/bitstreams/Iki.java index 4590b47..e226f42 100644 --- a/jpsxdec/test/jpsxdec/psxvideo/bitstreams/Iki.java +++ b/jpsxdec/test/jpsxdec/psxvideo/bitstreams/Iki.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/psxvideo/bitstreams/STRv2.java b/jpsxdec/test/jpsxdec/psxvideo/bitstreams/STRv2.java index 5bbddd6..370070a 100644 --- a/jpsxdec/test/jpsxdec/psxvideo/bitstreams/STRv2.java +++ b/jpsxdec/test/jpsxdec/psxvideo/bitstreams/STRv2.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/psxvideo/bitstreams/STRv3.java b/jpsxdec/test/jpsxdec/psxvideo/bitstreams/STRv3.java index d0ea696..73bc5d9 100644 --- a/jpsxdec/test/jpsxdec/psxvideo/bitstreams/STRv3.java +++ b/jpsxdec/test/jpsxdec/psxvideo/bitstreams/STRv3.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/psxvideo/mdec/tojpeg/Mdec2JpegTest.java b/jpsxdec/test/jpsxdec/psxvideo/mdec/tojpeg/Mdec2JpegTest.java index 8d22c65..f211be4 100644 --- a/jpsxdec/test/jpsxdec/psxvideo/mdec/tojpeg/Mdec2JpegTest.java +++ b/jpsxdec/test/jpsxdec/psxvideo/mdec/tojpeg/Mdec2JpegTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2013-2019 Michael Sabin + * Copyright (C) 2013-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/util/ArgParserTest.java b/jpsxdec/test/jpsxdec/util/ArgParserTest.java index aa54969..d8ca874 100644 --- a/jpsxdec/test/jpsxdec/util/ArgParserTest.java +++ b/jpsxdec/test/jpsxdec/util/ArgParserTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/util/DemuxPushInputStreamTest.java b/jpsxdec/test/jpsxdec/util/DemuxPushInputStreamTest.java index 6ae0e2f..edd6f3f 100644 --- a/jpsxdec/test/jpsxdec/util/DemuxPushInputStreamTest.java +++ b/jpsxdec/test/jpsxdec/util/DemuxPushInputStreamTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/util/DemuxedDataTest.java b/jpsxdec/test/jpsxdec/util/DemuxedDataTest.java index f4b83ca..9ead1b4 100644 --- a/jpsxdec/test/jpsxdec/util/DemuxedDataTest.java +++ b/jpsxdec/test/jpsxdec/util/DemuxedDataTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2017-2019 Michael Sabin + * Copyright (C) 2017-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/util/IOTest.java b/jpsxdec/test/jpsxdec/util/IOTest.java index 749234a..b691cca 100644 --- a/jpsxdec/test/jpsxdec/util/IOTest.java +++ b/jpsxdec/test/jpsxdec/util/IOTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/util/MiscTest.java b/jpsxdec/test/jpsxdec/util/MiscTest.java index 0fa1c7f..4115187 100644 --- a/jpsxdec/test/jpsxdec/util/MiscTest.java +++ b/jpsxdec/test/jpsxdec/util/MiscTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2016-2019 Michael Sabin + * Copyright (C) 2016-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/jpsxdec/util/player/ClosableBoundedBlockingQueueTest.java b/jpsxdec/test/jpsxdec/util/player/ClosableBoundedBlockingQueueTest.java index 92b9893..2ef0766 100644 --- a/jpsxdec/test/jpsxdec/util/player/ClosableBoundedBlockingQueueTest.java +++ b/jpsxdec/test/jpsxdec/util/player/ClosableBoundedBlockingQueueTest.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2019 Michael Sabin + * Copyright (C) 2019-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/testutil/PairList.java b/jpsxdec/test/testutil/PairList.java index de0a255..b4fe66e 100644 --- a/jpsxdec/test/testutil/PairList.java +++ b/jpsxdec/test/testutil/PairList.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2014-2019 Michael Sabin + * Copyright (C) 2014-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/jpsxdec/test/testutil/Util.java b/jpsxdec/test/testutil/Util.java index 8de8cc5..22b4394 100644 --- a/jpsxdec/test/testutil/Util.java +++ b/jpsxdec/test/testutil/Util.java @@ -1,6 +1,6 @@ /* * jPSXdec: PlayStation 1 Media Decoder/Converter in Java - * Copyright (C) 2007-2019 Michael Sabin + * Copyright (C) 2007-2020 Michael Sabin * All rights reserved. * * Redistribution and use of the jPSXdec code or any derivative works are diff --git a/laintools/src/laintools/AudioImageViewer.java b/laintools/src/laintools/AudioImageViewer.java index cd8880f..f25604b 100644 --- a/laintools/src/laintools/AudioImageViewer.java +++ b/laintools/src/laintools/AudioImageViewer.java @@ -274,7 +274,7 @@ private void _guiApplySiteBActionPerformed(java.awt.event.ActionEvent evt) {//GE private void _guiDumpSiteAActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__guiDumpSiteAActionPerformed try { _guiSiteATable.dump(); - } catch (IOException ex) { + } catch (Exception ex) { Logger.getLogger(AudioImageViewer.class.getName()).log(Level.SEVERE, null, ex); } }//GEN-LAST:event__guiDumpSiteAActionPerformed @@ -282,7 +282,7 @@ private void _guiDumpSiteAActionPerformed(java.awt.event.ActionEvent evt) {//GEN private void _guiDumpSiteBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__guiDumpSiteBActionPerformed try { _guiSiteBTable.dump(); - } catch (IOException ex) { + } catch (Exception ex) { Logger.getLogger(AudioImageViewer.class.getName()).log(Level.SEVERE, null, ex); } }//GEN-LAST:event__guiDumpSiteBActionPerformed diff --git a/laintools/src/laintools/AudioImageViewerTable.java b/laintools/src/laintools/AudioImageViewerTable.java index 4f160b1..98fa195 100644 --- a/laintools/src/laintools/AudioImageViewerTable.java +++ b/laintools/src/laintools/AudioImageViewerTable.java @@ -99,7 +99,7 @@ private void updatePanels() { _sourcePlanel.setImage(item.image()); try { _renderPlanel.setImage(item.generateImage()); - } catch (IOException ex) { + } catch (Exception ex) { ex.printStackTrace(); } } @@ -160,7 +160,7 @@ public void copySettings() { } } - public void dump() throws IOException { + public void dump() throws Exception { getSiteModel().dump(getSiteModel().getSite()); } @@ -319,7 +319,7 @@ public SiteJTableItemModel getRow(int i) { return _items.get(i); } - public void dump(String sDir) throws IOException { + public void dump(String sDir) throws Exception { for (SiteJTableItemModel siteJTableItemModel : _items) { siteJTableItemModel.dump(sDir); } @@ -451,7 +451,7 @@ public String toString() { return generateFilename(); } - public BufferedImage generateImage() throws IOException { + public BufferedImage generateImage() throws Exception { if (format() == Formats.NoSave) return null; @@ -524,7 +524,7 @@ public BufferedImage generateImage() throws IOException { return bi; } - public void dump(String sDir) throws IOException { + public void dump(String sDir) throws Exception { switch (_eFormat) { case NoSave: break; case Original: @@ -558,7 +558,7 @@ private static ByteArrayOutputStream makeCompressedTim(Tim newTim) throws IOExce } - private static ByteArrayOutputStream makeCompressedTim(BufferedImage bi, int iBitsPerPix) throws IOException { + private static ByteArrayOutputStream makeCompressedTim(BufferedImage bi, int iBitsPerPix) throws Exception { // convert to tim Tim newTim = Tim.create(bi, iBitsPerPix); ByteArrayOutputStream baos = new ByteArrayOutputStream(); diff --git a/laintools/src/laintools/PatchLainImage.java b/laintools/src/laintools/PatchLainImage.java index 73dd1b8..569bf22 100644 --- a/laintools/src/laintools/PatchLainImage.java +++ b/laintools/src/laintools/PatchLainImage.java @@ -88,7 +88,7 @@ private static void replaceFile(DiscItemISO9660File isoFile, String sReplaceFile System.out.println("Replacing " + sReplaceFile); File replaceFile = new File(sReplaceFile); - CdFileSectorReader replaceDisc = new CdFileSectorReader(replaceFile, 2048); + CdFileSectorReader replaceDisc = CdFileSectorReader.openWithSectorSize(replaceFile, 2048); if (replaceDisc.getSectorCount() > isoFile.getSectorLength()) throw new RuntimeException(sReplaceFile + " too big to fit " + isoFile); CdFileSectorReader destDisc = isoFile.getSourceCd(); diff --git a/laintools/src/laintools/ReplaceAudioImages.java b/laintools/src/laintools/ReplaceAudioImages.java index 4e2a8f8..4dffc8b 100644 --- a/laintools/src/laintools/ReplaceAudioImages.java +++ b/laintools/src/laintools/ReplaceAudioImages.java @@ -48,7 +48,7 @@ public class ReplaceAudioImages { - public static void main(String[] args) throws IOException { + public static void main(String[] args) throws Exception { if (args.length < 5) { System.out.println("Requires 5 arguments"); @@ -182,14 +182,14 @@ public String name() { } } - private static final byte[] image2pkTim(File png) throws IOException { + private static final byte[] image2pkTim(File png) throws Exception { if (!png.exists()) throw new FileNotFoundException(png.toString()); BufferedImage bi = ImageIO.read(png); return image2pkTim(bi); } - private static final byte[] image2pkTim(BufferedImage bi) throws IOException { + private static final byte[] image2pkTim(BufferedImage bi) throws Exception { // convert to tim Tim newTim = Tim.create(bi, 8); ByteArrayOutputStream temp = new ByteArrayOutputStream(); @@ -266,7 +266,7 @@ public void setSiteTableIndex(int iSiteTableIndex) { _iIndex = iSiteTableIndex; } - abstract public byte[] readData() throws IOException; + abstract public byte[] readData() throws Exception; public int getIndex() { return _iIndex; @@ -314,7 +314,7 @@ private SiteImageFromFile(char cSite, File source) { _source = source; } - public byte[] readData() throws IOException{ + public byte[] readData() throws Exception { if (_source.getName().endsWith(".png")) { return image2pkTim(_source); } else { @@ -370,7 +370,7 @@ private static class SiteImageProvider { private final SiteImageFromSITE[] _aoSiteTable; - public SiteImageProvider(char cSite, File imgageDir, File siteFile) throws IOException { + public SiteImageProvider(char cSite, File imgageDir, File siteFile) throws Exception { _cSite = cSite; _dir = imgageDir; _aoFiles = imgageDir.listFiles(); @@ -449,7 +449,7 @@ public SiteImageFromSITE getSiteImage(int iSiteTableIndex) { return _aoSiteTable[iSiteTableIndex]; } - public void write(RandomAccessFile slps, OutputStream os, boolean blnReal) throws IOException { + public void write(RandomAccessFile slps, OutputStream os, boolean blnReal) throws Exception { int iOutOffset = 0, iDummyOffset = -1; System.out.println("Site" + _cSite +": Seeking to offset of site table in slps " + _iOffsetInSlps); diff --git a/laintools/src/laintools/ReplaceLoF.java b/laintools/src/laintools/ReplaceLoF.java index aec1d5a..4cfdb69 100644 --- a/laintools/src/laintools/ReplaceLoF.java +++ b/laintools/src/laintools/ReplaceLoF.java @@ -46,6 +46,7 @@ import jpsxdec.tim.Tim; import jpsxdec.util.IO; import jpsxdec.util.BinaryDataNotRecognized; +import jpsxdec.util.IncompatibleException; public class ReplaceLoF { @@ -101,7 +102,7 @@ private static Tim extractTim(RandomAccessFile bin, int iSectorOffset, String sB } - private static void patchLoFTim(Tim lofTim) throws IOException, BinaryDataNotRecognized { + private static void patchLoFTim(Tim lofTim) throws IOException, BinaryDataNotRecognized, IncompatibleException { // palette 3 is the one that looks best for LoF // but any palette is fine BufferedImage image = lofTim.toBufferedImage(3); @@ -119,9 +120,10 @@ private static void patchLoFTim(Tim lofTim) throws IOException, BinaryDataNotRec dupTest.replaceImageData(image, clut); baos.reset(); dupTest.write(baos); - + + // Sanity check that Tim logic is working if (!Arrays.equals(abOriginal, baos.toByteArray())) { - throw new RuntimeException("Failed trying to recreate the Tim exactly"); + throw new RuntimeException("Something went wrong trying to recreate the Tim exactly"); } blankRectangle(image, 0, 48, 192, 24); @@ -149,7 +151,7 @@ private static void blankRectangle(BufferedImage bi, int iX, int iY, int iW, int } } - private static void patchVersionTim(Tim version, String sVersion) throws IOException { + private static void patchVersionTim(Tim version, String sVersion) throws IOException, IncompatibleException { final Color TEXT_COLOR = new Color(0xff, 0xff, 0xff); BufferedImage img = version.toBufferedImage(1);