/* * DataList.java * * Created on den 29 december 2004, 23:33 */ package krut.KRUT_Recording; /** * * @author jonte */ import java.awt.image.*; import java.io.*; import javax.imageio.*; /** DataList is a class used to reload the images * from the file they are saved in by the ScreenGrabber, * and then supply them to the JpegImagesToMovieMod class. * In other words, this is a class for communication between * the ScreenGrabber class and the JpegImagesToMovieMod class. * It opens the file containing the images from the grabber, and * then supplies the JpegImagesToMovieMod with the images one by * one, through the readNode method. * * This class does not take any arguments to it's constructor, * but nevertheless, the following things need to be done before * the DataList class can be used: * * The input file containing the data of the images making up * every frame must be set using the setInFile(File) method. * * A user must also provide an integer array containting the size * in bytes for every image in the File inFile. * * Additionally, an integer array containing the numbers of images * marked as "missed" must be provided. * * Finally, a user must provide an integer value of the total * number of frames. * * See the parameter comments for more details. */ public class DataList { /** This flag is set to true by the program when all the * frames have been delivered. It should be checked by the user * of this class. This is the only way of telling if all * the frames are processed or not. * * When a user presses "cancel" in an EndodingProgressBar, * that class will set this flag to true (in it's cancelAction() * method), and fake that the frames have run out. */ public boolean finished = false; /** This is an integer containing the total number of frames * in the picSizes array. That means that the totalPics plus * the total number of missed frames will equal the total * number of frames in the final film. totalPics is the * total number of unique frames. * * The reason why a parameter of this kind is needed is * because the picSizes array will typically be much * larger than the number of actual frames. Look at the * comments in the ScreenGrabber.init() method for more info. * * (There is some redundancy, as the length of the picSizes * array must be the same as totalPics) */ public int totalPics = 0; /** A simple counter of how many unique frames we have sent. * Unique as in not doubles sent to compensate for a missing * frame. */ public int donePics = 0; /** How many frames have been sent in total, including * doublets. */ public int sentPics = 0; /** The stream wrapping inFile. */ public FileInputStream inStream; /** The input file for the frames. */ public File inFile; /** The parameter picSizes should, before encoding is started, * contain an array of the size in bytes of every single * image in the image file inFile. This parameter * must be directly set by the user before encoding begins. * It should contain an amount of integers equal to the * amount of images in the file inFile. So if a film of * 200 unique frames is to be encoded, this parameter * should be an array of more than 200 integers. */ public int[] picSizes; /** The parameter missedFrames should, before encoding is started, * contain an array of the frame number of every frame that is * missing from the image file inFile. This parameter * must be directly set by the user before encoding begins. * If there are no missing frames in the image file inFile, * this parameter must still contain at least one integer. * * Examples: * * If there are no missing frames, the array missedFrames * can contain only zero's, EXCEPT for in the first position. * The first position should in this case contain something * that could not possibly be a valid frame number in the film, * such as picSizes.length + 1; * * If the frames 10 and 12 are missing, the array should start with * {10, 12}, and after that continue with any number lower than the * current frame number. The easiest way to avoid stupid mistakes * is to have the rest of the array stay the way it is: filled with * zero's. */ public int[] missedFrames; /** An internal counter of how many missed frames we have * sent doubles for so far. */ private int cntMissed; /** The carrier of the data. Data is read into nodeData from * the data file, and is returned from nodeData from the readNode() * method. */ private byte[] nodeData; public DataList() { cntMissed = 0; } /** Sets the file containing the frames. * * @param input A file containg the frames for the movie. * * @return true if a FileInputStream wrapping input could * be opened, false if not. */ public boolean setInFile(File input) { try { inFile = input; inStream = new FileInputStream(inFile); return true; } catch (FileNotFoundException e) { System.err.println(e); return false; } } /** Read the next frame * * @return a byte array containing the frame data. */ public synchronized byte[] readNode() { try { if (donePics < totalPics) { /** Check that the upcoming frame is not a missed one. */ if (missedFrames[cntMissed] != donePics) { /** Make a byte array of the exact size of the next frame. */ nodeData = new byte[picSizes[donePics]]; inStream.read(nodeData, 0, picSizes[donePics]); donePics++; } else { /** If this frame is a missed one we just keep all the data * in memory, and send the last frame once more (there * is always an empty frame at the start of the film, not * to worry). */ cntMissed++; } /** When we are done we just set finished = true, * and expect users to behave and never call again. * The cntMissed check is nothing but a bugcheck, * it will never happend. */ if ((donePics == totalPics) || (cntMissed == missedFrames.length)) finished = true; sentPics++; /** Return the frame. */ return nodeData; } else { System.err.println("Error, too many frames"); return null; } } catch (IOException e) { System.err.println("File error " + e); return null; } } }