/* * @(#)PatchDialog.java - patching video basics * * Copyright (c) 2001-2005 by dvb.matt, All rights reserved. * * This file is part of ProjectX, a free Java based demux utility. * By the authors, ProjectX is intended for educational purposes only, * as a non-commercial test project. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package net.sourceforge.dvb.projectx.gui; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.JComboBox; import javax.swing.UIManager; import net.sourceforge.dvb.projectx.common.Resource; import net.sourceforge.dvb.projectx.common.Common; import net.sourceforge.dvb.projectx.common.Keys; import net.sourceforge.dvb.projectx.gui.UISwitchListener; import net.sourceforge.dvb.projectx.gui.CommonGui; import net.sourceforge.dvb.projectx.xinput.XInputFile; /** * Class Patch Panel. */ public class PatchDialog extends JDialog { /** patchfield */ private JTextField[] patchfield = new JTextField[3]; private JComboBox aspectbox; /** the file to be patched */ XInputFile xInputFile=null; /** the labels */ private String[] notes = { " H:"," V:"," BR:","bps " }; private long ins=0; private byte[] os = new byte[1]; /** instance of the PatchListener */ private PatchListener patchAction = new PatchListener(); /** * ActionListener for the PatchPanel. */ private class PatchListener implements ActionListener { /* (non-Javadoc) * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent e) { String actName = e.getActionCommand(); if (actName.equals("change")) change(); else if (actName.equals("cancel")) cancel(); } } /** * Constructor of the PatchPanel. * * @param f The parent Frame */ public PatchDialog(JFrame f) { super(f, Resource.getString("PatchPanel.Title"), true); JPanel container = new JPanel(); container.setLayout( new BorderLayout() ); JPanel grid = new JPanel(); grid.setLayout(new BoxLayout(grid, BoxLayout.X_AXIS)); for (int a = 0; a < patchfield.length; a++) { patchfield[a] = new JTextField(""); patchfield[a].setPreferredSize(new Dimension(65,22)); patchfield[a].setMaximumSize(new Dimension(65,22)); grid.add(Box.createRigidArea(new Dimension(5, 1))); grid.add(new JLabel(notes[a])); grid.add(patchfield[a]); } grid.add(new JLabel(notes[3])); grid.add(Box.createRigidArea(new Dimension(5, 1))); aspectbox = new JComboBox(Keys.ITEMS_ChangeAspectRatio); aspectbox.setPreferredSize(new Dimension(120,22)); aspectbox.setMaximumSize(new Dimension(120,22)); aspectbox.addActionListener(patchAction); grid.add(aspectbox); grid.add(Box.createRigidArea(new Dimension(5, 1))); JButton changebutton = new JButton(); CommonGui.localize(changebutton, "PatchPanel.Change"); changebutton.setActionCommand("change"); changebutton.addActionListener(patchAction); grid.add(changebutton); grid.add(Box.createRigidArea(new Dimension(5, 1))); JButton cancelbutton = new JButton(); CommonGui.localize(cancelbutton, "PatchPanel.Cancel"); cancelbutton.setActionCommand("cancel"); cancelbutton.addActionListener(patchAction); grid.add(cancelbutton); getRootPane().setDefaultButton(cancelbutton); container.add(grid); getContentPane().add(container); //pack(); setSize(600, 150); centerDialog(); UIManager.addPropertyChangeListener(new UISwitchListener(container)); } /** * Search the given file for video basics. * * @param file * @param os * @return */ private boolean search(XInputFile aXInputFile, byte[] os) { try { long size = aXInputFile.length(); byte[] ps = new byte[((size<650000)?(int)size:650000)]; aXInputFile.randomAccessSingleRead(ps, 0); for (int a = 0; a < ps.length - 15; a++) { if (ps[a] != 0 || ps[a + 1] != 0 || ps[a + 2] != 1 || ps[a + 3] != (byte)0xB3 || ps[a + 4] != os[4] || ps[a + 5] != os[5] || ps[a + 6] != os[6] || ps[a + 7] != os[7] ) continue; ins = a; patchfield[0].setText("" + ((255 & ps[a + 4])<<4 | (240 & ps[a + 5])>>>4)); patchfield[1].setText("" + ((15 & ps[a + 5])<<8 | (255 & ps[a + 6]))); patchfield[2].setText("" + (((255 & ps[a + 8])<<10 | (255 & ps[a + 9])<<2 | (192 & ps[a + 10])>>>6) * 400)); aspectbox.setSelectedIndex((0xFF & ps[a + 7])>>4); return true; } } catch (IOException e) { Common.setExceptionMessage(e); } return false; } /** * @param file1 * @param os */ public boolean entry(XInputFile aXInputFile) { xInputFile = aXInputFile; os = xInputFile.getStreamInfo().getVideoHeader(); if (os == null) return false; if (search(xInputFile, os)) this.show(); return true; } /** * Centers this dialog on the users screen. */ protected void centerDialog() { Dimension screenSize = this.getToolkit().getScreenSize(); Dimension size = this.getSize(); screenSize.height = screenSize.height / 2; screenSize.width = screenSize.width / 2; size.height = size.height / 2; size.width = size.width / 2; int y = screenSize.height - size.height; int x = screenSize.width - size.width; this.setLocation(x,y); } /** * Callback for the cancel event. */ private void cancel() { this.setVisible(false); } /** * Callback for the change event. */ private void change() { try { int hsize=Integer.parseInt(patchfield[0].getText()); int vsize=Integer.parseInt(patchfield[1].getText()); int brate=Integer.parseInt(patchfield[2].getText()) / 400; int aspectindex = aspectbox.getSelectedIndex(); os[4] = (byte)(0xFF & hsize>>>4); os[5] = (byte)((0xF0 & hsize<<4) | (0xF & vsize>>>8)); os[6] = (byte)(0xFF & vsize); os[8] = (byte)(0xFF & brate>>>10); os[9] = (byte)(0xFF & brate>>>2); os[10]= (byte)((0x3F & os[10]) | (0xC0 & brate<<6)); if (aspectindex >= 0) os[7] = (byte)((0xF & os[7]) | (aspectindex<<4)); dochange(); } catch (NumberFormatException e) {} catch (NullPointerException e) {} } /** * applies the actual change to the file. */ private void dochange() { try { xInputFile.randomAccessOpen("rw"); xInputFile.randomAccessSeek(ins); xInputFile.randomAccessWrite(os); xInputFile.randomAccessClose(); } catch (IOException e) { Common.setExceptionMessage(e); } this.setVisible(false); } }