package ch.werner_randelshofer.gui.image;/*Copyright (C) 1999 Werner Randelshoferwerner.randelshofer@mythen.chhttp://www.mythen.ch/w.randelshofer/    Permission to use this release of ANIMMovieTrack is herebygranted without fee provided that the complete copyrightnotice and this permission notice appear in all copiesand in supporting documentation.*/import java.util.Vector;import java.awt.image.MemoryImageSource;import java.awt.image.ColorModel;import java.awt.image.IndexColorModel;import java.awt.image.DirectColorModel;import java.awt.image.ImageProducer;/** * @author	Werner Randelshofer, Staldenmattweg 2, CH-6405 Immensee, Switzerland * @version	1999-02-14	Created. */public class ANIMMovieTrack	{	/* BMHD data. */	/** Raster width and heigth in pixels. */	private int width_,height_; 	/** Pixel position for this image. */	private int xPosition_,yPosition_; 	/** Number of source bitplanes. */	private int nbPlanes_;	private int masking_; 	protected final static int		MSK_NONE = 0,		MSK_HAS_MASK = 1,		MSK_HAS_TRANSPARENT_COLOR = 2,		MSK_LASSO = 3;			private int compression_;	public final static int		CMP_NONE = 0,		CMP_BYTE_RUN_1 = 1;	/** Index of transparent color. */	private int transparentColor_;	/** Pixel aspect ratio. */	private int xAspect_, yAspect_;	/** Page size in pixels. */	private int pageWidth_, pageHeight_;	/* CAMG data. */	/** Screenmode. */	private int screenMode_;	/** Screenmodes. */	public final static int		MODE_INDEXED_COLORS = 0,		MODE_DIRECT_COLORS = 1,		MODE_EHB = 2,		MODE_HAM6 = 3,		MODE_HAM8 = 4;		private Vector frames_ = new Vector();		private Bitmap bitmapEven_, bitmapOdd_;	private MemoryImageSource memoryImage_;	private int preparedEven_, preparedOdd_;	private int fetchedEven_, fetchedOdd_;		public void setWidth(int width) { width_ = width; }	public void setHeight(int height) { height_ = height; }	public void setXPosition(int xPosition) { xPosition_ = xPosition; }	public void setYPosition(int yPosition) { yPosition_ = yPosition; }	public void setNbPlanes(int nbPlanes) { nbPlanes_ = nbPlanes; }	public void setMasking(int masking) { masking_ = masking; }	public void setCompression(int compression) { compression_ = compression; }	public void setTransparentColor(int colorIndex) { transparentColor_ = colorIndex; }	public void setXAspect(int xAspect) { xAspect_ = xAspect; }	public void setYAspect(int yAspect) { yAspect_ = yAspect; }	public void setPageWidth(int pageWidth) { pageWidth_ = pageWidth; }	public void setPageHeight(int pageHeight) { pageHeight_ = pageHeight; }		public void setScreenMode(int screenMode) { screenMode_ = screenMode; }	public int getWidth() { return width_; }	public int getHeight() { return height_; }	public int getXPosition() { return xPosition_; }	public int getYPosition() { return yPosition_; }	public int getNbPlanes() { return nbPlanes_; }	public int getMasking() { return masking_; }	public int getCompression() { return compression_; }	public int getTransparentColor() { return transparentColor_; }	public int getXAspect() { return xAspect_; }	public int getYAspect() { return yAspect_; }	public int getPageWidth() { return pageWidth_; }	public int getPageHeight() { return pageHeight_; }		public int getScreenMode() { return screenMode_; }		public void addFrame(ANIMFrame frame)		{		frames_.addElement(frame);		if (frames_.size() == 1)			{			realize();			}		}		public int getFrameCount()		{		int size = frames_.size();		return size > 3 ? size - 2 : size;		}		public synchronized void realize()		{		ColorModel cm;		if (frames_.size() > 0)			{			ANIMFrame frame = (ANIMFrame)frames_.elementAt(0);			cm = frame.getColorModel();			}		else			{ cm = DirectColorModel.getRGBdefault(); }		bitmapEven_ = new Bitmap(width_, height_, nbPlanes_ + (masking_ == MSK_HAS_MASK ? 1 : 0), cm);		bitmapOdd_ = new Bitmap(width_, height_, nbPlanes_ + (masking_ == MSK_HAS_MASK ? 1 : 0), cm);		if (cm instanceof DirectColorModel)			{			memoryImage_ = new MemoryImageSource(width_,height_,cm, new int[width_*height_] ,0,width_);			}		else			{			memoryImage_ = new MemoryImageSource(width_,height_,cm, new byte[width_*height_] ,0,width_);			}		memoryImage_.setAnimated(true);		preparedEven_ = preparedOdd_ = Integer.MAX_VALUE;		fetchedEven_ = fetchedOdd_ = Integer.MAX_VALUE;		if (frames_.size() > 0)			{			showFrame(0);			}		notifyAll();		}		public synchronized boolean isRealized()		{		return memoryImage_ != null;		}	public synchronized void waitRealized()	throws InterruptedException		{		while (memoryImage_ == null)			{ wait(); }		}		public ImageProducer getImageProducer()		{		return memoryImage_;		}		public void fetchFrame(int index)		{		ANIMFrame frame = null;		int fetched;				Bitmap bitmap;		if ((index & 1) == 0)			{ // even?			if (fetchedEven_ == index)				{ return; }			fetched = fetchedEven_;			bitmap = bitmapEven_;			if (fetched > index)				{				frame = (ANIMFrame)frames_.elementAt(0);				frame.decode(bitmap,this);				fetched = 0;				}			fetchedEven_ = index;			}		else			{ // odd?			if (fetchedOdd_ == index)				{ return; }			fetched = fetchedOdd_;			fetchedOdd_ = index;			bitmap = bitmapOdd_;			if (fetched > index)				{				frame = (ANIMFrame)frames_.elementAt(0);				frame.decode(bitmap,this);				frame = (ANIMFrame)frames_.elementAt(1);				frame.decode(bitmap,this);				fetched = 1;				}			}		for (int i=fetched+2; i <= index; i+=2)			{			frame = (ANIMFrame)frames_.elementAt(i);			frame.decode(bitmap,this);			}		}	public void prepareFrame(int index)		{		Bitmap bitmap;		int prepared;				if ((index & 1) == 0)			{ // even?			if (preparedEven_ == index)				{ return; }			prepared = preparedEven_;			preparedEven_ = index;			bitmap = bitmapEven_;			}		else			{ // odd?			if (preparedOdd_ == index)				{ return; }			prepared = preparedOdd_;			preparedOdd_ = index;			bitmap = bitmapOdd_;			}					fetchFrame(index);				ANIMFrame frame = (ANIMFrame)frames_.elementAt(index);		ColorModel cm = frame.getColorModel();		bitmap.setColorModel(cm);		if (prepared == index - 2 &&			(! (cm instanceof HAMColorModel) || cm == ((ANIMFrame)frames_.elementAt(prepared)).getColorModel())			)			{/*			int type = bitmap.getPixelType();			if (type == Bitmap.BYTE_PIXEL)				{				byte[] p = bitmap.getBytePixels();				for (int i=p.length-1;i > -1; i--)					{ p[i] = 0; }				}			else if (type == Bitmap.INT_PIXEL)				{				int[] p = bitmap.getIntPixels();				for (int i=p.length-1;i > -1; i--)					{ p[i] = 0; }				}*/			bitmap.convertToChunky(frame.getTopBound(this),frame.getLeftBound(this),frame.getBottomBound(this),frame.getRightBound(this));			}		else			{			bitmap.convertToChunky();			}		}	public void showFrame(int index)		{		Bitmap bitmap;		int prepared;		if ((index & 1) == 0)			{ // even?			bitmap = bitmapEven_;			prepared = preparedEven_;			bitmap = bitmapEven_;			}		else			{ // odd?			bitmap = bitmapOdd_;			prepared = preparedOdd_;			bitmap = bitmapOdd_;			}		prepareFrame(index);		ANIMFrame frame = (ANIMFrame)frames_.elementAt(index);		ColorModel cm = frame.getColorModel();		if (bitmap.getPixelType() == Bitmap.INT_PIXEL)			{			memoryImage_.newPixels(bitmap.getIntPixels(),cm,0,width_);			}		else			{			memoryImage_.newPixels(bitmap.getBytePixels(),cm,0,width_);			}		}		public long getRelTime(int index)		{		return ((ANIMFrame)frames_.elementAt(index)).getRelTime();		}	}