jcamencode.c

来自「是一个手机功能的模拟程序」· C语言 代码 · 共 1,071 行 · 第 1/3 页

C
1,071
字号
//===========================================================================
//	JCAMENCODE.C
//	This file contains JPEG functions implemented for the JPEG library to 
//	implement JPEG encoding via Agilent camera.
//---------------------------------------------------------------------------
//  Copyright (c) 2003 Epson Research and Development, Inc.
//  All Rights Reserved.
//===========================================================================

//---------------------------------------------------------------------------
// Include Files
//---------------------------------------------------------------------------
#include <stdio.h>

#include "multiframe.h"
#include "hal.h"
#include "chiplib.h"
#include "jpegcomm.h"
#include "JpegTable.h"

//---------------------------------------------------------------------------
// Local Data
//---------------------------------------------------------------------------
static UInt16 gCamEncodeRegIndex[] =
{
	REG0102_CMSIGNAL	,
	REG0108_CMCONTROL	,
	REG003C_LCDXFER	,
	REG0224_YUVWRSTART0,
};

//---------------------------------------------------------------------------
// Local Type Definitions
//---------------------------------------------------------------------------
#define CAMENC_REG_SIZE	(sizeof(gCamEncodeRegIndex) / sizeof( UInt16))

typedef struct tagStartAddr
{
	UInt32 m_Cur;
	UInt32 m_First;
	UInt32 m_Prev;
} prvStartAddr;

typedef struct tagCamEncodeState
{
	UInt8			m_AutoFrameXfer;
	UInt32			m_BufSize;
	Boolean			m_fCamClk;
	UInt8			m_CamControl;
	UInt8			m_CamSignal;
	UInt32			m_Count;
	Boolean			m_fYUV;
	JPEGMULTIFRAME*	m_pMulFrm;
	Boolean			m_fNoTimeOut;
	UInt8*			m_pStart;
	prvStartAddr	m_StartAddr;
	UInt32			m_TotalSize;
	UInt8			m_aSaveReg[ CAMENC_REG_SIZE ];
	Boolean			m_fUnWind;
} prvCamEncodeState;

//---------------------------------------------------------------------------
// Local Function Prototypes
//---------------------------------------------------------------------------
static Boolean	prvAccessAgilent( JPEGINFO* pJpegInfo, prvCamEncodeState* pCamEncState );
static Boolean	prvInitCapture( JPEGINFO* pJpegInfo, prvCamEncodeState* pCamEncState );
static Boolean	prvAppendHeader( JPEGINFO* pJpegInfo );
static Boolean	prvIsCaptureComplete( void );
static Boolean	prvStartCapture( JPEGINFO* pJpegInfo, prvCamEncodeState* pCamEncState, Boolean* pComplete );
static UInt8	prvStopCapture( void );
static Boolean	prvWaitForCapture( JPEGINFO* pJpegInfo, prvCamEncodeState* pCamEncState );
static Boolean	prvCopy2Jpeg( UInt8** ppDest, const void* pSource, UInt32 size, UInt8* pEnd );
static Boolean	prvAcquireRawJpeg( JPEGINFO* pJpegInfo, UInt32 startAddr );
static Boolean	prvHasDataCapInt( void );
static Boolean	prvSetJpegMode( JPEGINFO *pJpegInfo, prvCamEncodeState* pCamEncState );
static Boolean	prvInitNextCapture( JPEGINFO* pJpegInfo, prvCamEncodeState* pCamEncState );
static Boolean	prvInitAnyCapture( JPEGINFO* pJpegInfo, prvCamEncodeState* pCamEncState );
static void		prvRestoreReg( UInt8* pSaveReg );
static void		prvRestoreState( JPEGINFO* pJpegInfo, prvCamEncodeState* pCamEncState, Boolean fSuccess );
static void		prvSaveReg( UInt8* pSaveReg );
static Boolean	prvSelectQTable( JPEGINFO* pJpegInfo );
static void		prvAdvanceStartAddr( JPEGINFO* pJpegInfo, prvStartAddr* pStartAddr );
static void		prvSetStartAddrImg( UInt32 address );
static void		prvInitStartAddr( JPEGINFO* pJpegInfo, prvStartAddr* pStartAddr );
static Boolean	prvValidateParam( JPEGINFO* pJpegInfo );
static void		prvUnWind( JPEGINFO* pJpegInfo, prvCamEncodeState* pCamEncState );

//------------------------------------------------------------------------------
//	jpegCamEncode - fSuccesss camera image into valid JPEG image
//
//	Input:	pJpegInfo		pointer to JPEGINFO object
//
//	Return:	TRUE successful
//			FALSE if error.
//
//------------------------------------------------------------------------------
Boolean jpegCamEncode( JPEGINFO* pJpegInfo )
{
	Boolean fSuccess = jpegValidateBuf( pJpegInfo );
	if ( fSuccess )
	{
		prvCamEncodeState camEncodeState;
		fSuccess = prvInitCapture( pJpegInfo, &camEncodeState );

		// Capture for each image specified
		for 
		( 
			camEncodeState.m_Count = 1; 
			fSuccess && (camEncodeState.m_Count <= pJpegInfo->m_FrameCount); 
			++camEncodeState.m_Count 
		)
		{
#ifndef MV850E
			jpegFindTimeOut( pJpegInfo );
#endif
			camEncodeState.m_pMulFrm = (JPEGMULTIFRAME*)pJpegInfo->m_pBuf;
			if ( pJpegInfo->m_FrameCount > 1 )
			{
				pJpegInfo->m_pBuf		+= sizeof( JPEGMULTIFRAME );
				pJpegInfo->m_BufSize	-= sizeof( JPEGMULTIFRAME );
			}

			if ( pJpegInfo->m_fVerbose )
			{	
				UInt32 resizeXEnd;
				UInt32 resizeYEnd;
				UInt32 resizeXStart;
				UInt32 resizeYStart;
				UInt32 XStart;
				UInt32 YStart;
				UInt32 width;
				UInt32 height;

				GetResizerSize( &resizeXStart, &resizeYStart, &resizeXEnd, &resizeYEnd );
				AgilentDimensionGet( &XStart, &YStart, &width, &height );

				//printf( "       AGILENT   RESIZE\n" );
				//printf( "XStart  %03u      %03u\n", XStart, resizeXStart );
				//printf( "YStart  %03u      %03u\n", YStart, resizeXStart );
				//printf( "XEnd    %03u      %03u\n", width - 1, resizeXEnd );
				//printf( "YEnd    %03u      %03u\n", height - 1, resizeYEnd );
			}


			// Allow capture until notified that it is complete
			fSuccess = prvWaitForCapture( pJpegInfo, &camEncodeState );
			if ( fSuccess )
			{
				// Retrieve JPEG data from memory
				fSuccess = prvAcquireRawJpeg( pJpegInfo, camEncodeState.m_StartAddr.m_Cur );
				if ( fSuccess )
				{
					// Append headers from list of tables
					fSuccess = prvAppendHeader( pJpegInfo );
					if ( fSuccess )
					{
						// Prepare for next image to capture
						fSuccess = prvInitNextCapture( pJpegInfo, &camEncodeState );
					}
				}
			}
		}

		prvRestoreState( pJpegInfo, &camEncodeState, fSuccess );
	}
	return ( fSuccess );
}

//------------------------------------------------------------------------------
//	prvAcquireRawJpeg - retrieves JPEG data from vide memory
//
//	Input:	pJpegInfo		pointer to JPEGINFO object
//			startAddr		start address of data
//
//	Return:	TRUE means valid image
//			FALSE means NOT valid image
//
//------------------------------------------------------------------------------
Boolean prvAcquireRawJpeg( JPEGINFO* pJpegInfo, UInt32 startAddr )
{
	Boolean fSuccess	= TRUE;
	Boolean fEndOfImage = FALSE;
	UInt8	prevData	= 0;

	if ( pJpegInfo->m_fVerbose )
	{
		//printf( "ImageAddress=%XL\n", startAddr );
	}

	for 
	( 
		pJpegInfo->m_EncSize = 0; 
		(pJpegInfo->m_EncSize < pJpegInfo->m_BufSize) && (!fEndOfImage) && fSuccess; 
		++pJpegInfo->m_EncSize 
	)
	{
		UInt8 data									= halReadDisplay8( startAddr + pJpegInfo->m_EncSize );
		pJpegInfo->m_pBuf[ pJpegInfo->m_EncSize ]	= data;
		if ( prevData == 0xFF )
		{
			if ( data == 0xD9 )
			{
				++pJpegInfo->m_EncSize;
				fSuccess = (pJpegInfo->m_EncSize > 4 + 2) ? TRUE : FALSE;
				if ( !fSuccess )
				{
					jpegSetLastError( JPEG_ERR_INVALID_JPEG_DATA );
				}
				else
				{
					fEndOfImage = TRUE;
				}
			}
		}

		prevData = data;
	}

	if ( fSuccess && (!fEndOfImage) )
	{
		static aCode[] = {0xFF, 0xDA, 0x00, 63};
		fSuccess = (memcmp( aCode, pJpegInfo->m_pBuf, sizeof( aCode ) ) == 0) ? TRUE : FALSE;
		if ( !fSuccess )
		{
			jpegSetLastError( JPEG_ERR_ENCSIZELIMIT );
		}
		else
		{
			jpegSetLastError( JPEG_ERR_INVALID_JPEG_DATA );
			fSuccess = FALSE;
		}
	}

	return ( fSuccess );
}

//------------------------------------------------------------------------------
//	prvInitCapture - Saves and prepares hardware and software for encoding
//
//	Input:	pJpegInfo		pointer to JPEGINFO object
//			pCamEncState	pointer to camEncodeState object
//
//	Return:	TRUE means successfully appended JPEG tables to image
//			FALSE means NOT successfully appended JPEG tables to image
//
//------------------------------------------------------------------------------
Boolean prvInitCapture( JPEGINFO* pJpegInfo, prvCamEncodeState* pCamEncState )
{
	Boolean fSuccess;

	prvSaveReg( pCamEncState->m_aSaveReg );

#ifndef MV850E
	jpegFindTimeOut( pJpegInfo );
#endif

	// Prepare to fSuccess JPEG image
	pCamEncState->m_fUnWind = fSuccess = prvInitAnyCapture( pJpegInfo, pCamEncState );
	if ( fSuccess )
	{
		// Set Agilent Camera in JPEG mode
		fSuccess = prvSetJpegMode( pJpegInfo, pCamEncState );
		if ( fSuccess )
		{
			halDelayUS( pJpegInfo->m_Delay * 1000 );

			// CMHREF & CMVREF Active High
			halWriteReg8( REG0102_CMSIGNAL, 0x06 );
			//76543210b
			//|||||||+--Valid Input Clock Edge
			//||||||+---CMVREF Active Select 1=Active Hi 0=Active Lo
			//|||||+----CMHREF Active Select 1=Active Hi 0=Active Lo
			//|||++-----YUV Data Format Select
			//||+-------Clock Mode Select
			//|+--------Reserved
			//+---------n/a

			// Camera Data Type=YUV Camera Stop after next CMVREF Repeat Capture enabled
			halWriteReg8( REG0108_CMCONTROL, 0x1C );
			//76543210b
			//|||||||+--CMCLK Output Hold Reset
			//||||||+---Capture Frame
			//|||||+----Repeat Capture Frame
			//||||+-----Camera Capture Stop
			//|||+------Camera Data Type 1=YUV 0=JPEG
			//+++-------n/a

			// Camera Data Type=JPEG Camera Stop after next CMVREF Repeat Capture enabled
			halWriteReg8( REG0108_CMCONTROL, 0x0C );

			// Camera Data Type=JPEG Repeat Capture enabled
			halWriteReg8( REG0108_CMCONTROL, 0x04 );

			fSuccess = prvSelectQTable( pJpegInfo );
			if ( fSuccess )
			{
				// Reverse 13711 HREF/VREF polarities
				pCamEncState->m_CamSignal = halReadReg8( REG0102_CMSIGNAL );
				//76543210b
				//|||||||+--Valid Input Clock Edge
				//||||||+---CMVREF Active Select 1=Active Hi 0=Active Lo
				//|||||+----CMHREF Active Select 1=Active Hi 0=Active Lo
				//|||++-----YUV Data Format Select
				//||+-------Clock Mode Select
				//|+--------Reserved
				//+---------n/a

				// CMHREF & CMVREF Active High
				halWriteReg8( REG0102_CMSIGNAL, (UInt8)(pCamEncState->m_CamSignal | 0x06) );

				prvInitStartAddr( pJpegInfo, &pCamEncState->m_StartAddr );
			}
		}
	}

	pCamEncState->m_pStart		= pJpegInfo->m_pBuf;
	pCamEncState->m_BufSize		= pJpegInfo->m_BufSize;
	pCamEncState->m_TotalSize	= 0;
	return ( fSuccess );
}

//------------------------------------------------------------------------------
//	prvAppendHeader - reorganizes JPEG image to include appropriate JPEG headers
//
//	Input:	pJpegInfo	pointer to JPEGINFO object
//
//	Return:	TRUE means successfully appended JPEG tables to image
//			FALSE means NOT successfully appended JPEG tables to image
//
//------------------------------------------------------------------------------
Boolean prvAppendHeader( JPEGINFO* pJpegInfo )
{
#define QUANT_SIZE (3 * (sizeof( QUANTIZATIONHEADER ) + 64))
#define HEADER_SIZE (sizeof( g_JpegHeader) + QUANT_SIZE + sizeof( REMAINDERINFO ))
	UInt32	size		= HEADER_SIZE + pJpegInfo->m_EncSize - 4;
	Boolean fSuccess	= (size <= pJpegInfo->m_BufSize) ? TRUE : FALSE;
	if ( !fSuccess )
	{
		jpegSetLastError( JPEG_ERR_ENCSIZELIMIT );
	}
	else
	{
		UInt8*	pStartJpeg	= (UInt8*)malloc( size + 4 );
		fSuccess			= (pStartJpeg != NULL) ? TRUE : FALSE;
		if ( !fSuccess )
		{
			jpegSetLastError( JPEG_ERR_ENCSIZELIMIT );
		}
		else
		{
			UInt8			iQTable = *(pJpegInfo->m_pBuf + 3) - 1;
			const UInt8*	pQTable = &g_aQTable[ iQTable ][ 0 ];
			UInt8*			pDest	= pStartJpeg;
			UInt8*			pEnd	= pDest + (size + (4 - 1));

			if ( pJpegInfo->m_fVerbose )
			{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?