AVIRAW - An AVI reader/writer library for Euphoria 2.1+ 
Platorm independent version. 
Fourth release, 20021008
/Mic, 2002
stabmaster_@hotmail.com | http://www.cyd.liu.se/~micol972/site/


Files:
------
* aviraw.e			AVI reading/writing functions
* crunch.e			'Crunch' codec
* lcrunch.e			'Lossy Crunch' codec 
* readavi.ex			Demo program showing how to read AVI files
* writeavi.ex			Demo program showing how to write AVI files
* readme.txt			You're reading it..
* codec\crunchyuv.dll		VFW-compatible 'Crunch'/'LCrunch' codec
* codec\crunchyuv.inf		Installation file for the codec
* codec\src\*.*			Source code for crunchyuv.dll


For Windows users:
To install the CrunchYUV codec, right-click on crunchyuv.inf and select "install". You only need to do this
if you want to be able to open the compressed AVIs written by aviraw.e with other applications such as
Mediaplayer, Virtualdub, Premiere and whatnot.


Updates:
--------
20021008
	* Added another codec, Lossy CrunchYUV, or lcrunch for short. It subsamples the chrominance values to two
	  per 2x2 block of pixels, which cuts the bitrate in half (while slightly degrading the picture quality).
	  It then applies the Crunch algorithm on the result. The VFW codec (crunchyuv.dll) is capable of
	  decompressing both the lossless and the lossy versions of CrunchYUV. It can also compress 24-bit RGB
	  data into lossless CrunchYUV.

	* Fixed a bug in the CrunchYUV codec which caused the compressor to crash in some cases.

	* Did some fixes in AVI_Load and AVI_GetNextFrame. They should now be able to handle uncompressed AVIs
	  created by Virtualdub. Also changed AVI_AddFrame so that frame chunks start with '00dc' instead of
	  '00db' when compression is used (not that it really matters).

	* Fixed AVI_Load so that it handles the case where no input buffer size is given in the AVI header.

	* Added a function, AVI_GetLastErrorMessage which returns info about the last error that occured (if any).

	* Added AVI_IsInputCompressed and AVI_GetDecompressorName.
	  
	* Included the source code for crunchyuv.dll.
	  
	  
20021001
	* Rewrote the CrunchYUV compressor in assembly. I don't have any exact figures on how much faster it is than
	  the old version, but i'm guessing the speed-up factor is about 3-5. On a crappy P2-450 with 100MHz SDRAM i
	  get a throughput of about 9.5 MB/s (not including disk i/o). Added a decompressor (in the .e-file) while
	  i was at it.

	* Added two functions, AVI_GetLastCompressionTime and AVI_GetLastFrameSize for retrieving information about
	  the compression (see below).

	* Added some functions, AVI_Load, AVI_GetNextFrame, AVI_Seek and AVI_Unload for reading AVI files, including
	  those compressed with the CrunchYUV compressor. See readavi.ex for an example.


20020930
	* AVIRAW now supports compression. This does not mean that you can use your VFW codecs, like DivX. Any compressor
	  must be "baked in to" the aviraw library. At the moment, there's only one compressor available; namely CrunchYUV
	  (a twist on RLE. I modified it to work with the YUV colorspace. You can see compression ratios between 1.2-20.0).
	  I've hacked together a VFW codec (actually only a decompressor) for CrunchYUV so that you can read the compressed
	  AVIs with other applications (this only applies to Windows users). If you're only writing uncompressed AVIs then
	  there's no need to install the CrunchYUV codec.
	
	* Added a procedure, AVI_SetCompressor that lets you choose a compressor (see below).



Usage:
------

Writing AVIs:
-------------

procedure AVI_SetFileName(sequence filename)
	Set the name of the AVI file to create. 


procedure AVI_SetFrameRate(integer rate)

	Set the desired frame rate.

procedure AVI_SetFrameFormat(integer width, integer height, integer bitsperpixel)
	Set the output format. You'd better use bitsperpixel=24, as I don't handle any other cases
	in my code.


procedure AVI_SetCompressor(integer compressor)
	Set the AVI compressor. Possible values are:
		AVI_NO_COMPRESSION:	Speaks for itself
		AVI_CRUNCH:		Lossless CrunchYUV (best-case compression ratio = 85:1)
		AVI_LCRUNCH:		Lossy CrunchYUV (will give a compression ratio of *at least* 2:1)

	
function AVI_Begin()	(integer)
	Initialize the AVI output engine. By this time you should have called at least AVI_SetFrameFormat.
	Returns	non-zero on success. 

	
procedure AVI_End()
	Release the AVI output engine. 


function AVI_AddFrame(atom framePointer)	
	Add another frame to the AVI stream. The framePointer is a pointer to an array of pixels, whose
	format should of course comply to the format you defined with AVI_SetFrameFormat.
	!!! Note that these frames are interpreted as Windows DIBs, i.e. they're assumed to be stored bottom-up !!!
	Returns non-zero on success.


function AVI_GetLastCompressionTime()
	Get the time spent on compressing the last(/latest) frame. If the compression type is AVI_NO_COMPRESSION
	then the return value will always be zero, otherwise it will be an atom representing a number of seconds.


function AVI_GetLastFrameSize()
	Get the size of the last frame that was added to the stream. The return value is of type integer.


AVI_SetFileName, AVI_SetFrameRate and AVI_SetCompressor are optional. The default filename, framerate and compressor
are "untitled.avi", 30 and AVI_NO_COMPRESSION, respectively. 


Reading AVIs:
-------------

function AVI_Load(sequence filename)
	Load an AVI. Only uncompressed AVIs, or those compressed with the CrunchYUV codecs can be loaded. Also, the AVI
	may only contain one stream (i.e. it can't be loaded if you have added an audio track). You can only have one
	AVI loaded at a time; to load a new one you must call AVI_Unload first. AVI_Load returns non-zero on success.


function AVI_GetNextFrame(atom framePointer)
	Get the next frame from a loaded AVI stream. The frame will be stored in the memory pointed to by framePointer.
	Note that the frames are currently read top-down when they *should* be read bottom-up. I'll probably fix this
	later. The function returns non-zero on success.


function AVI_Seek(integer frameNumber)
	Seek to a frame in a loaded AVI stream. The frames are enumerated 0..totalFrames-1. If you try to seek outside
	the available range or if no index is present the function will return -1. Otherwise, frameNumber is returned.


procedure AVI_Unload()
	Unload a previously loaded AVI.


function AVI_GetInputFrameFormat()
	Get the format of the loaded AVI. The return value is {width, height, bitcount}. You can index this sequence with
	AVI_FRAMEFORMAT_WIDTH, AVI_FRAMEFORMAT_HEIGHT and AVI_FRAMEFORMAT_BITCOUNT.


function AVI_GetInputFrameCount()
	Get the total number of frames in the loaded AVI.


function AVI_IsInputCompressed()
	Returns true if the currently loaded AVI is compressed, false otherwise.


function AVI_GetDecompressorName()
	Get the name of the decompressor that is/will be used to decompress the currently loaded AVI.


Misc.:
------

function AVI_GetLastErrorMessage()
	If an error occurs, you can call this function to get an explanation (a text string) of what went wrong.


	

Troubleshooting:
----------------
Q: "I try to open demo.avi with <insert video player here> but it gives me an error message"

A: The demo program writes a compressed AVI so you need to install the CrunchYUV codecs. You do this by right-clicking
   the file called crunchyuv.inf in the codec directory and selecting "install" from the popup menu. If you're running
   Linux/BSD or pure DOS then you won't be able to open the compressed AVI. In this case, just remove the line in 
   writeavi.ex that says "AVI_SetCompressor(AVI_LCRUNCH)" and re-generate the AVI.

Q: "The video output from Crunch/LCrunch is messed up"

A: Oops.. I don't know of any bugs in it, but i don't rule out the possibility.






