/*
 * Project Name JPEG DRIVER IN WINCE
 * Copyright  2007 Samsung Electronics Co, Ltd. All Rights Reserved.
 *
 * This software is the confidential and proprietary information
 * of Samsung Electronics  ("Confidential Information").
 * you shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with Samsung Electronics
 *
 * This file implements JPEG driver.
 *
 * @name JPEG DRIVER MODULE Module (JPGDriver.c)
 * @author Jiyoung Shin (idon.shin@samsung.com)
 * @date 28-05-07
 */

#include <windows.h>
#include <oal_intr.h>
#include <devload.h>
#include <pm.h>
#include <pmplatform.h>

#include <bsp.h>
#include "JPGDriver.h"
#include "JPGMem.h"
#include "JPGMisc.h"
#include "JPGOpr.h"
#include "JPGPower.h"
#include "JPGIntr.h"

int			instanceNo = 0;
BOOL		PowerChange = FALSE;


/*----------------------------------------------------------------------------
*Function: JPG_Init

*Parameters: 		dwContext		:
*Return Value:		True/False
*Implementation Notes: Initialize JPEG Hardware
-----------------------------------------------------------------------------*/
DWORD
JPG_Init(
    DWORD dwContext
    )
{
	DWORD			ret;

    DBGMSG(JPG_FUNC,(_T("[JPGDRV] %s++\r\n"), _T(__FUNCTION__)));
    if (JPGPowerInit() == FALSE){
        ERRMSG((_T("[JPGDRV] %s :: Power Init Failed\r\n"), _T(__FUNCTION__)));
        return FALSE;
    }

    // Mutex initialization
	JPGMutexCreate();

	// Enter criticalsection
	JPGMutexLock();

    
    if( !JPGSfrMemMapping() )
    {
        RETAILMSG(1, (TEXT("DD::JPGSfrMemMapping Initialize error : %d \r\n"),GetLastError()));
        ERRMSG((_T("[JPGDRV] %s :: IOCTL_JPG_ENCODE failed\r\n"), _T(__FUNCTION__)));
        JPGMutexRelease();
        return FALSE;
    }

    if(CreateJPGIntrResource() != JPG_SUCCESS)
    {
        ERRMSG((_T("[JPGDRV] %s :: CreateJPGIntrResource Initialize error : %d \r\n"), _T(__FUNCTION__),GetLastError()));
        JPGMutexRelease();
        return FALSE;
    }
    
    instanceNo = 0;

    ret = JPGMutexRelease();

    DBGMSG(JPG_FUNC,(_T("[JPGAPI] %s--\r\n"), _T(__FUNCTION__)));
    
    return TRUE;
}


/*----------------------------------------------------------------------------
*Function: JPG_DeInit

*Parameters: 		InitHandle		:
*Return Value:		True/False
*Implementation Notes: Deinitialize JPEG Hardware
-----------------------------------------------------------------------------*/
BOOL
JPG_Deinit(
    DWORD InitHandle
    )
{

    DBGMSG(JPG_FUNC,(_T("[JPGDRV] %s++\r\n"), _T(__FUNCTION__)));
    DeleteJPGIntrResource();
    JPGMutexDelete();
    DBGMSG(JPG_FUNC,(_T("[JPGAPI] %s--\r\n"), _T(__FUNCTION__)));
    return TRUE;
}


/*----------------------------------------------------------------------------
*Function: JPG_Open

*Parameters: 		InitHandle		:Handle to JPEG  context
					dwAccess		:
					dwShareMode		:File share mode of JPEG
*Return Value:		This function returns a handle that identifies the
					open context of JPEG  to the calling application.
*Implementation Notes: Opens JPEG CODEC device for reading, writing, or both
-----------------------------------------------------------------------------*/
DWORD
JPG_Open(
    DWORD InitHandle,
    DWORD dwAccess,
    DWORD dwShareMode
    )
{
    JPG_CTX *JPGRegCtx;

    DBGMSG(JPG_FUNC,(_T("[JPGDRV] %s++\r\n"), _T(__FUNCTION__)));

    JPGPowerOnOff(JPG_POWER_ON);


	// Enter criticalsection
	JPGMutexLock();

    // check the number of instance
    if(instanceNo >= MAX_INSTANCE_NUM)
    {
        ERRMSG((_T("[JPGDRV] %s :: Instance Number error-JPEG is running\r\n"), _T(__FUNCTION__)));
        JPGMutexRelease();
        return FALSE;
    }
    
    // Register/Memory initialization
    JPGRegCtx = (JPG_CTX *)malloc(sizeof(JPG_CTX));
    if (!JPGRegCtx)
    {
        ERRMSG((_T("[JPGDRV] %s :: JPG Memory Context Allocation Fail\r\n"), _T(__FUNCTION__)));
        JPGMutexRelease();
        return FALSE;
    }
    memset(JPGRegCtx, 0x00, sizeof(JPG_CTX));


    instanceNo++;
    DBGMSG(JPG_DBG,(_T("[JPGDRV] instanceNo : %d\r\n"), instanceNo));
    
    PowerChange = FALSE;

    JPGMutexRelease();

    DBGMSG(JPG_FUNC,(_T("[JPGAPI] %s--\r\n"), _T(__FUNCTION__)));
    
    return (DWORD)JPGRegCtx;
}


/*----------------------------------------------------------------------------
*Function: JPG_Close

*Parameters: 		OpenHandle		:
*Return Value:		True/False
*Implementation Notes: This function closes the device context identified by
						OpenHandle
-----------------------------------------------------------------------------*/
BOOL
JPG_Close(DWORD OpenHandle)
{
    BOOL    result = TRUE;
    JPG_CTX *JPGRegCtx = NULL;

    DBGMSG(JPG_FUNC,(_T("[JPGDRV] %s++\r\n"), _T(__FUNCTION__)));
    if(PowerChange == TRUE)
    {
        ERRMSG((_T("[JPGDRV] %s :: Power state is changed after open\r\n"), _T(__FUNCTION__)));
        return FALSE;
    }

    JPGRegCtx = (JPG_CTX*)OpenHandle;
    if(!JPGRegCtx)
    {
        ERRMSG((_T("[JPGDRV] %s :: JPG Invalid Input Handle\r\n"), _T(__FUNCTION__)));
        return FALSE;
    }

	JPGMutexLock();

    free(JPGRegCtx);
    
    if((--instanceNo) < 0)
        instanceNo = 0;
        
    JPGMutexRelease();

    JPGPowerOnOff(JPG_POWER_OFF);
    DBGMSG(JPG_FUNC,(_T("[JPGAPI] %s--\r\n"), _T(__FUNCTION__)));
    return TRUE;
}


/*----------------------------------------------------------------------------
*Function: JPG_IOControl

*Parameters: 		OpenHandle		:
					dwIoControlCode	:
*Return Value:		True/False
*Implementation Notes: JPEG_IOControl sends commands to initiate different
*                       operations like Init,Decode and Deinit.The test
*                       application uses the DeviceIOControl function to
*                       specify an operation to perform
-----------------------------------------------------------------------------*/
BOOL
JPG_IOControl(
    DWORD OpenHandle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{
    JPG_CTX *JPGRegCtx = NULL;
    JPG_ARGS    *pArgs = NULL;
    JPG_DEC_PROC_PARAM *DecReturn = NULL;
    JPG_ENC_PROC_PARAM *EncParam = NULL;
	
    BOOL    result = FALSE;


    DBGMSG(JPG_FUNC,(_T("[JPGDRV] %s++\r\n"), _T(__FUNCTION__)));

    if(PowerChange == TRUE)
    {
        ERRMSG((_T("[JPGDRV] %s :: Power state is changed after open\r\n"), _T(__FUNCTION__)));
        return FALSE;
    }

    JPGRegCtx = (JPG_CTX*)OpenHandle;
    if(!JPGRegCtx)
    {
        ERRMSG((_T("[JPGDRV] %s :: JPG Invalid Input Handle\r\n"), _T(__FUNCTION__)));
        return FALSE;
    }

	// Enter criticalsection
	JPGMutexLock();

    JPGClockOnOff(JPG_CLK_ON);

    switch ( dwIoControlCode )
    {
        case IOCTL_JPG_DECODE:
            DBGMSG(JPG_DBG,(_T("[JPGDRV] IOCTL_JPEG_DECODE\r\n")));
            pArgs = (JPG_ARGS *)pInBuf;
            if(!pArgs)
            {
                ERRMSG((_T("[JPGDRV] %s :: JPG Invalid Input Parameter(pInBuf)r\n"), _T(__FUNCTION__)));
                break;
            }

		DecReturn = pArgs->decParam;
		
            if(!DecReturn)
            {
                ERRMSG((_T("[JPGDRV] %s :: JPG Invalid Input Parameter(DecReturn)\r\n"), _T(__FUNCTION__)));
                break;
            }

            DBGMSG(JPG_DBG,(_T("[JPGDRV] DecReturn->fileSize : %d\r\n"), DecReturn->fileSize));
            DBGMSG(JPG_DBG,(_T("[JPGDRV] pArgs->phyInBuf=0x%08x, pArgs->phyOutBuf=0x%08x\r\n"), pArgs->phyInBuf, pArgs->phyOutBuf));

		JPGRegCtx->JPGDataAddr = (unsigned int)pArgs->phyInBuf;
		JPGRegCtx->IMGDataAddr = (unsigned int)pArgs->phyOutBuf;

            result = decodeJPG(JPGRegCtx, DecReturn);
            break;

        case IOCTL_JPG_ENCODE:
            DBGMSG(JPG_DBG,(_T("[JPGDRV] IOCTL_JPEG_ENCODE\r\n")));
            pArgs = (JPG_ARGS *)pInBuf;
            if(!pArgs)
            {
                ERRMSG((_T("[JPGDRV] %s :: JPG Invalid Input Parameter(pInBuf)\r\n"), _T(__FUNCTION__)));
                break;
            }
		
		EncParam = pArgs->encParam;
		
            if(!EncParam)
            {
                ERRMSG((_T("[JPGDRV] %s :: JPG Invalid Input Parameter(pBytesReturned)\r\n"), _T(__FUNCTION__)));
                break;
            }

            DBGMSG(JPG_DBG,(_T("[JPGDRV] width : %d hegiht : %d enctype : %d quality : %d inFormat: %d mode_Y16: %d\r\n")
                                ,EncParam->width, EncParam->height, EncParam->encType, EncParam->quality, EncParam->inFormat, EncParam->mode_Y16));

            if(EncParam->encType == JPG_MAIN)
            {
                DBGMSG(JPG_DBG,(_T("[JPGDRV] pArgs->phyInBuf=0x%08x, pArgs->phyOutBuf=0x%08x\r\n"), pArgs->phyInBuf, pArgs->phyOutBuf));
			JPGRegCtx->IMGDataAddr = (unsigned int)pArgs->phyInBuf;
			JPGRegCtx->JPGDataAddr = (unsigned int)pArgs->phyOutBuf;
            }
		else
		{
                DBGMSG(JPG_DBG,(_T("[JPGDRV] pArgs->phyInBuf=0x%08x, pArgs->phyOutBuf=0x%08x\r\n"), pArgs->phyInThumbBuf, pArgs->phyOutThumbBuf));
			JPGRegCtx->IMGThumbDataAddr = (unsigned int)pArgs->phyInThumbBuf;
			JPGRegCtx->JPGThumbDataAddr = (unsigned int)pArgs->phyOutThumbBuf;
            }

            
            result = encodeJPG(JPGRegCtx, EncParam);

            DBGMSG(JPG_DBG,(_T("[JPGDRV] encoded file size : %d\r\n"), EncParam->fileSize));

            break;

        default :
            ERRMSG((_T("[JPGDRV] %s :: JPG Invalid IOControl\r\n"), _T(__FUNCTION__)));
    }

    JPGClockOnOff(JPG_CLK_OFF);
    JPGMutexRelease();
    DBGMSG(JPG_FUNC,(_T("[JPGAPI] %s--\r\n"), _T(__FUNCTION__)));

    return result;
}

/*----------------------------------------------------------------------------
*Function: JPG_Write

*Parameters: 		dwContext		:
*Return Value:		True/False
*Implementation Notes: Initialize JPEG Hardware
-----------------------------------------------------------------------------*/
DWORD
JPG_Write(
    DWORD OpenHandle,
    LPCVOID pBuffer,
    DWORD dwNumBytes
    )
{

    return TRUE;
}

BOOL JPG_PowerUp(DWORD InitHandle)
{
    return TRUE;
}

BOOL JPG_PowerDown(DWORD InitHandle)
{
    return TRUE;
}

/*----------------------------------------------------------------------------
*Function: JPEG_DllMain

*Parameters: 		DllInstance		:
					Reason			:
					Reserved		:
*Return Value:		True/False
*Implementation Notes: Entry point for JPEG.dll
-----------------------------------------------------------------------------*/
BOOL WINAPI
JPG_DllMain(
    HINSTANCE DllInstance,
    DWORD Reason,
    LPVOID Reserved
    )
{
    switch(Reason)
    {
        case DLL_PROCESS_ATTACH:
            DEBUGREGISTER(DllInstance);
            break;
    }

    return TRUE;
}
