/*
 * Copyright 2001 Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * FIXME - implements color space(depth) converter.
 */

#include <string.h>
#include <stdio.h>
#include <assert.h>

#include "winbase.h"
#include "winnls.h"
#include "mmsystem.h"
#include "winerror.h"
#include "vfw.h"
#include "wine/debug.h"
#include "avifile_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(avifile);

static HRESULT WINAPI IGetFrame_fnQueryInterface(IGetFrame* iface,REFIID refiid,LPVOID *obj);
static ULONG WINAPI IGetFrame_fnAddRef(IGetFrame* iface);
static ULONG WINAPI IGetFrame_fnRelease(IGetFrame* iface);
static LPVOID WINAPI IGetFrame_fnGetFrame(IGetFrame* iface,LONG lPos);
static HRESULT WINAPI IGetFrame_fnBegin(IGetFrame* iface,LONG lStart,LONG lEnd,LONG lRate);
static HRESULT WINAPI IGetFrame_fnEnd(IGetFrame* iface);
static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame* iface,LPBITMAPINFOHEADER lpbi,LPVOID lpBits,INT x,INT y,INT dx,INT dy);

struct ICOM_VTABLE(IGetFrame) igetfrm = {
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	IGetFrame_fnQueryInterface,
	IGetFrame_fnAddRef,
	IGetFrame_fnRelease,
	IGetFrame_fnGetFrame,
	IGetFrame_fnBegin,
	IGetFrame_fnEnd,
	IGetFrame_fnSetFormat,
};

typedef struct IGetFrameImpl
{
	ICOM_VFIELD(IGetFrame);
	/* IUnknown stuff */
	DWORD			ref;
	/* IGetFrame stuff */
	IAVIStream*		pas;
	HIC			hIC;
	LONG			lCachedFrame;
	BITMAPINFO*		pbiICIn;
	BITMAPINFO*		pbiICOut;
	LPVOID			pvICOutBits;
	LPVOID			pvICInFmtBuf;
	DWORD			dwICInDataBufSize;
	LPVOID			pvICInDataBuf;
	LPVOID			pvICOutBuf;
} IGetFrameImpl;

static HRESULT IGetFrame_Construct( IGetFrameImpl* This,
				    IAVIStream* pstr,
				    LPBITMAPINFOHEADER lpbi );
static void IGetFrame_Destruct( IGetFrameImpl* This );




static LPVOID AVIFILE_IGetFrame_DecodeFrame(IGetFrameImpl* This,LONG lPos)
{
	HRESULT	hr;
	DWORD	dwRes;
	LONG	lFrameLength;
	LONG	lSampleCount;
	ICDECOMPRESS	icd;

	if ( This->hIC == (HIC)NULL )
		return NULL;

	hr = IAVIStream_Read(This->pas,lPos,1,NULL,0,
			     &lFrameLength,&lSampleCount);
	if ( hr != S_OK || lSampleCount <= 0 )
	{
		FIXME( "IAVIStream_Read failed! res = %08lx\n", hr );
		return NULL;
	}
	TRACE( "frame length = %ld\n", lFrameLength );

	if ( This->dwICInDataBufSize < lFrameLength )
	{
		LPVOID	lpv;

		if ( This->pvICInDataBuf == NULL )
		{
			lpv = HeapAlloc(
				AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,
				lFrameLength );
		}
		else
		{
			lpv = HeapReAlloc(
				AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,
				This->pvICInDataBuf,lFrameLength );
		}
		if ( lpv == NULL )
		{
			ERR( "out of memory!\n" );
			return NULL;
		}
		This->pvICInDataBuf = lpv;
		This->dwICInDataBufSize = lFrameLength;
	}

	hr = IAVIStream_Read(This->pas,lPos,1,
			     This->pvICInDataBuf,This->dwICInDataBufSize,
			     &lFrameLength,&lSampleCount);
	if ( hr != S_OK || lSampleCount <= 0 )
	{
		FIXME( "IAVIStream_Read to buffer failed! res = %08lx\n", hr );
		return NULL;
	}

	This->pbiICIn->bmiHeader.biSizeImage = lFrameLength;

	TRACE( "call ICM_DECOMPRESS\n" );
	icd.dwFlags = 0;
	if ( IAVIStream_FindSample(This->pas,lPos,FIND_PREV|FIND_KEY) != lPos )
		icd.dwFlags = ICDECOMPRESS_NOTKEYFRAME;
	icd.lpbiInput = &This->pbiICIn->bmiHeader;
	icd.lpInput = (BYTE*)This->pvICInDataBuf;
	icd.lpbiOutput = &This->pbiICOut->bmiHeader;
	icd.lpOutput = This->pvICOutBits;
	icd.ckid = *((DWORD*)This->pvICInDataBuf);
	dwRes = ICSendMessage(This->hIC,ICM_DECOMPRESS,
			      (DWORD)(&icd),sizeof(ICDECOMPRESS) );
	TRACE( "returned from ICM_DECOMPRESS\n" );
	if ( dwRes != ICERR_OK )
	{
		ERR( "ICDecompress failed!\n" );
		return NULL;
	}

	This->lCachedFrame = lPos;

	return This->pvICOutBits;
}

/****************************************************************************/

HRESULT AVIFILE_CreateIGetFrame(void** ppobj,
				IAVIStream* pstr,LPBITMAPINFOHEADER lpbi)
{
	IGetFrameImpl	*This;
	HRESULT		hr;

	*ppobj = NULL;
	This = (IGetFrameImpl*)HeapAlloc(AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,
					  sizeof(IGetFrameImpl));
	This->ref = 1;
	ICOM_VTBL(This) = &igetfrm;
	hr = IGetFrame_Construct( This, pstr, lpbi );
	if ( hr != S_OK )
	{
		IGetFrame_Destruct( This );
		return hr;
	}

	*ppobj = (LPVOID)This;

	return S_OK;
}

/****************************************************************************
 * IUnknown interface
 */

static HRESULT WINAPI IGetFrame_fnQueryInterface(IGetFrame* iface,REFIID refiid,LPVOID *obj)
{
	ICOM_THIS(IGetFrameImpl,iface);

	TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
	if ( IsEqualGUID(&IID_IUnknown,refiid) ||
	     IsEqualGUID(&IID_IGetFrame,refiid) )
	{
		IGetFrame_AddRef(iface);
		*obj = iface;
		return S_OK;
	}

	return OLE_E_ENUM_NOMORE;
}

static ULONG WINAPI IGetFrame_fnAddRef(IGetFrame* iface)
{
	ICOM_THIS(IGetFrameImpl,iface);

	TRACE("(%p)->AddRef()\n",iface);
	return ++(This->ref);
}

static ULONG WINAPI IGetFrame_fnRelease(IGetFrame* iface)
{
	ICOM_THIS(IGetFrameImpl,iface);

	TRACE("(%p)->Release()\n",iface);
	if ((--(This->ref)) > 0 )
		return This->ref;
	IGetFrame_Destruct(This);
	if ( This->pas != NULL )
		IAVIStream_Release( This->pas );

	HeapFree(AVIFILE_data.hHeap,0,iface);
	return 0;
}

/****************************************************************************
 * IGetFrrame interface
 */

static LPVOID WINAPI IGetFrame_fnGetFrame(IGetFrame* iface,LONG lPos)
{
	ICOM_THIS(IGetFrameImpl,iface);
	LPVOID	lpv;
	LONG	lKeyFrame;

	TRACE( "(%p)->(%ld)\n", This, lPos );

	if ( lPos < 0 )
		return NULL;

	if ( This->lCachedFrame == lPos )
		return This->pvICOutBits;
	if ( (This->lCachedFrame+1) != lPos )
	{
		lKeyFrame = IAVIStream_FindSample( This->pas, lPos,
						   FIND_KEY | FIND_PREV );
		if ( lKeyFrame < 0 || lKeyFrame > lPos )
			return NULL;
		while ( ++lKeyFrame < lPos )
		{
			lpv = AVIFILE_IGetFrame_DecodeFrame(This, lKeyFrame);
			if ( lpv == NULL )
				return NULL;
		}
	}

	lpv = AVIFILE_IGetFrame_DecodeFrame(This, lPos);
	TRACE( "lpv = %p\n",lpv );
	if ( lpv == NULL )
		return NULL;

	return lpv;
}

static HRESULT WINAPI IGetFrame_fnBegin(IGetFrame* iface,LONG lStart,LONG lEnd,LONG lRate)
{
	ICOM_THIS(IGetFrameImpl,iface);

	TRACE( "(%p)->(%ld,%ld,%ld)\n", This, lStart, lEnd, lRate );

	if ( This->hIC == (HIC)NULL )
		return E_UNEXPECTED;

	if ( ICDecompressBegin( This->hIC,
				This->pbiICIn,
				This->pbiICOut ) != ICERR_OK )
		return E_FAIL;

	return S_OK;
}

static HRESULT WINAPI IGetFrame_fnEnd(IGetFrame* iface)
{
	ICOM_THIS(IGetFrameImpl,iface);

	TRACE( "(%p)->()\n", This );

	if ( This->hIC == (HIC)NULL )
		return E_UNEXPECTED;

	if ( ICDecompressEnd( This->hIC ) != ICERR_OK )
		return E_FAIL;

	return S_OK;
}

static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame* iface,LPBITMAPINFOHEADER lpbi,LPVOID lpBits,INT x,INT y,INT dx,INT dy)
{
	ICOM_THIS(IGetFrameImpl,iface);
	HRESULT	hr;
	LONG	fmtlen;
	BITMAPINFOHEADER	biTemp;
	DWORD	dwSizeImage;

	FIXME( "(%p)->(%p,%p,%d,%d,%d,%d)\n",This,lpbi,lpBits,x,y,dx,dy );

	IGetFrame_Destruct(This);

	hr = IAVIStream_ReadFormat(This->pas,0,NULL,&fmtlen);
	if ( hr != S_OK )
		return hr;
	This->pvICInFmtBuf = HeapAlloc(
		AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,fmtlen);
	if ( This->pvICInFmtBuf == NULL )
		return AVIERR_MEMORY;
	hr = IAVIStream_ReadFormat(This->pas,0,This->pvICInFmtBuf,&fmtlen);
	if ( hr != S_OK )
		return hr;
	This->pbiICIn = (LPBITMAPINFO)This->pvICInFmtBuf;

	This->hIC = (HIC)ICOpen( ICTYPE_VIDEO,
				 This->pbiICIn->bmiHeader.biCompression,
				 ICMODE_DECOMPRESS );
	if ( This->hIC == (HIC)NULL )
	{
		ERR( "no AVI decompressor for %c%c%c%c.\n",
		     (int)(This->pbiICIn->bmiHeader.biCompression>> 0)&0xff,
		     (int)(This->pbiICIn->bmiHeader.biCompression>> 8)&0xff,
		     (int)(This->pbiICIn->bmiHeader.biCompression>>16)&0xff,
		     (int)(This->pbiICIn->bmiHeader.biCompression>>24)&0xff );
		return E_FAIL;
	}

	if ( lpbi == NULL || lpbi == ((LPBITMAPINFOHEADER)1) )
	{
		memset( &biTemp, 0, sizeof(biTemp) );
		biTemp.biSize = sizeof(BITMAPINFOHEADER);
		biTemp.biWidth = This->pbiICIn->bmiHeader.biWidth;
		biTemp.biHeight = This->pbiICIn->bmiHeader.biHeight;
		biTemp.biPlanes = 1;
		biTemp.biBitCount = 24;
		biTemp.biCompression = 0;
		lpbi = &biTemp;
	}

	if ( lpbi->biPlanes != 1 || lpbi->biCompression != 0 )
		return E_FAIL;

	dwSizeImage =
		((This->pbiICIn->bmiHeader.biWidth*lpbi->biBitCount+7)/8)*
					This->pbiICIn->bmiHeader.biHeight;
	This->pvICOutBuf = HeapAlloc(
		AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,
		(sizeof(BITMAPINFO)+sizeof(RGBQUAD)*256)*2+
		dwSizeImage );
	if ( This->pvICOutBuf == NULL )
		return AVIERR_MEMORY;

	This->pbiICOut = (BITMAPINFO*)This->pvICOutBuf;
	This->pvICOutBits = (LPVOID)( (BYTE*)This->pvICOutBuf +
				sizeof(BITMAPINFO) + sizeof(RGBQUAD)*256 );

	This->pbiICOut->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	This->pbiICOut->bmiHeader.biWidth = This->pbiICIn->bmiHeader.biWidth;
	This->pbiICOut->bmiHeader.biHeight = This->pbiICIn->bmiHeader.biHeight;
	This->pbiICOut->bmiHeader.biPlanes = 1;
	This->pbiICOut->bmiHeader.biBitCount = lpbi->biBitCount;
	This->pbiICOut->bmiHeader.biSizeImage = dwSizeImage;
	memcpy( This->pvICOutBits, This->pbiICOut, sizeof(BITMAPINFOHEADER) );

	return S_OK;
}

static HRESULT IGetFrame_Construct( IGetFrameImpl* This,
				    IAVIStream* pstr,
				    LPBITMAPINFOHEADER lpbi )
{
	HRESULT	hr;

	TRACE( "(%p)->(%p,%p)\n",This,pstr,lpbi );

	IAVIStream_AddRef( pstr );
	This->pas = pstr;
	This->hIC = (HIC)NULL;
	This->lCachedFrame = -1L;
	This->pbiICIn = NULL;
	This->pbiICOut = NULL;
	This->pvICInFmtBuf = NULL;
	This->pvICInDataBuf = NULL;
	This->dwICInDataBufSize = 0;
	This->pvICOutBuf = NULL;

	hr = IGetFrame_SetFormat((IGetFrame*)This,lpbi,NULL,0,0,0,0);
	if ( hr != S_OK )
		return hr;

	return S_OK;
}

static void IGetFrame_Destruct( IGetFrameImpl* This )
{
	if ( This->hIC != (HIC)NULL )
	{
		ICClose( This->hIC );
		This->hIC = (HIC)NULL;
	}
	if ( This->pvICInFmtBuf != NULL )
	{
		HeapFree( AVIFILE_data.hHeap, 0, This->pvICInFmtBuf );
		This->pvICInFmtBuf = NULL;
	}
	if ( This->pvICInDataBuf != NULL )
	{
		HeapFree( AVIFILE_data.hHeap, 0, This->pvICInDataBuf );
		This->pvICInDataBuf = NULL;
	}
	if ( This->pvICOutBuf != NULL )
	{
		HeapFree( AVIFILE_data.hHeap, 0, This->pvICOutBuf );
		This->pvICOutBuf = NULL;
	}

	This->lCachedFrame = -1L;
	This->pbiICIn = NULL;
	This->pbiICOut = NULL;
	This->dwICInDataBufSize = 0;
}
