jdecode.c

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

C
911
字号
//===========================================================================
//	JDECODE.C
//	This file contains JPEG functions implemented for the JPEG library to 
//	implement JPEG prvoding via Epson JPEG Codec.
//---------------------------------------------------------------------------
//  Copyright (c) 2003 Epson Research and Development, Inc.
//  All Rights Reserved.
//===========================================================================

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

#include "chiplib.h"
#include "hal.h"
#include "hal_regs.h"
#include "jpeg.h"
#include "jpegcomm.h"
#include "multiframe.h"

//extern unsigned long tmpjpg[12*1024*100/4];

//------------------------------------------------------------------------------
// Local Type Defintions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Local Function Prototypes
//------------------------------------------------------------------------------
static Boolean		prvCalcScaleHeight( JPEGINFO* pJpegInfo, int displayHeight );
static Boolean		prvCalcScaleWidth( JPEGINFO* pJpegInfo, int displayWidth );
static Boolean		prvIsFifoFull( void );
static Boolean		prvLoadJpeg( JPEGINFO* pJpegInfo );
static Boolean 	prvLoadMJpeg( JPEGINFO* pJpegInfo ,UInt8 * pHeader,Int32 HeaderSize);
static Boolean		prvLoadYUV( JPEGINFO* pJpegInfo );
static Boolean		prvReadMarker( JPEGINFO* pJpegInfo, prvJpegFlag jpegStatus );
static Boolean		prvInitDecodeCodec( JPEGINFO* pJpegInfo );
static Boolean		prvInitDecodeResizer( JPEGINFO* pJpegInfo );
static Boolean		prvInitNextDecode( JPEGINFO* pJpegInfo, Boolean fSuccess );

//------------------------------------------------------------------------------
//	jpegDecode - Decodes existing JPEG image from memory into hardware to be
//					displayed
//
//	Input:	pJpegInfo		pointer to JPEGINFO object
//
//	Output:	TRUE means success
//			FALSE means NOT success
//
//------------------------------------------------------------------------------
Boolean jpegDecode( JPEGINFO *pJpegInfo )
{
	Boolean fMulit;
	Boolean fMjpeg;
	UInt8 * pBuf;
	Boolean fSuccess = pJpegInfo->m_MemEnc || jpegValidateBuf(pJpegInfo);
	if ( fSuccess )
	{
		// 13.3 Resizer Restricts
		// The dimensions specified by the resizer X/Y Start/End Positions registers 
		// must be a multiple of two.
		fSuccess = (pJpegInfo->m_XStart & 1) ? FALSE : TRUE;
		if ( !fSuccess )
		{
			jpegSetLastError( JPEG_ERR_DIM_RESTRICT );
		}
		else
		{
			fSuccess = (pJpegInfo->m_YStart & 1) ? FALSE : TRUE;
			if ( !fSuccess )
			{
				jpegSetLastError( JPEG_ERR_DIM_RESTRICT );
			}
			else
			{
//				prvWorld	world;

// SAVE/RESTORE is a good idea, but the problem right now is that the save is done here after registers have already been changed by program!
// So, I'm removing SAVE/RESTORE for now until we figure out a better way of doing this. [Roc]
//				prvSaveWorld( &world );
				fMulit=mfValidateMultiFrame((JPEGMULTIFRAME *)pJpegInfo->m_pBuf);
				if(fMulit)
				{
					JPEGMULTIFRAME* pJpegMultiFrame;
					pBuf=pJpegInfo->m_pBuf+pJpegInfo->m_EncSize;
					while(pJpegInfo->m_pBuf<pBuf)
					{
						fMulit=mfValidateMultiFrame((JPEGMULTIFRAME *)pJpegInfo->m_pBuf);
						if(!fMulit)
							break;
						pJpegMultiFrame = (JPEGMULTIFRAME*)(pJpegInfo->m_pBuf);
						pJpegInfo->m_pBuf=pJpegInfo->m_pBuf+sizeof(JPEGMULTIFRAME);
						pJpegInfo->m_EncSize=pJpegMultiFrame->ResultSize;
						fSuccess = prvInitDecodeCodec( pJpegInfo );
						if ( fSuccess )
						{
							if ( pJpegInfo->m_IsYUVfile )
								fSuccess = prvLoadYUV( pJpegInfo );
							else
								fSuccess = prvLoadJpeg( pJpegInfo );
							fSuccess = prvInitNextDecode( pJpegInfo, fSuccess );
						}
						pJpegInfo->m_pBuf=pJpegInfo->m_pBuf+pJpegMultiFrame->PaddedSize;
						
					}	
				}
				else
				{
					fSuccess = prvInitDecodeCodec( pJpegInfo );
					if ( fSuccess )
					{
						if ( pJpegInfo->m_IsYUVfile )
							fSuccess = prvLoadYUV( pJpegInfo );
						else
							fSuccess = prvLoadJpeg( pJpegInfo );
						fSuccess = prvInitNextDecode( pJpegInfo, fSuccess );
					}
				}

//				fSuccess = prvRestoreWorld(pJpegInfo,&world) && fSuccess;
			}
		}
	}
	return ( fSuccess );
}

//------------------------------------------------------------------------------
//	jpegMDecode - Decodes existing MJPEG image from memory into hardware to be
//					displayed
//
//	Input:	pJpegInfo		pointer to JPEGINFO object
//
//	Output:	TRUE means success
//			FALSE means NOT success
//
//------------------------------------------------------------------------------

Boolean jpegMDecode( JPEGINFO *pJpegInfo )
{
	Boolean fMulit;
	Boolean fMjpeg;
	UInt8 * pBuf;
	Boolean fSuccess = pJpegInfo->m_MemEnc || jpegValidateBuf(pJpegInfo);

	pJpegInfo->m_FrameCount=0;
	
	if ( fSuccess )
	{
		// 13.3 Resizer Restricts
		// The dimensions specified by the resizer X/Y Start/End Positions registers 
		// must be a multiple of two.
		fSuccess = (pJpegInfo->m_XStart & 1) ? FALSE : TRUE;
		if ( !fSuccess )
		{
			jpegSetLastError( JPEG_ERR_DIM_RESTRICT );
		}
		else
		{
			fSuccess = (pJpegInfo->m_YStart & 1) ? FALSE : TRUE;
			if ( !fSuccess )
			{
				jpegSetLastError( JPEG_ERR_DIM_RESTRICT );
			}
			else
			{
				UInt8 * pHeader;
				JPEGMULTIFRAME* pJpegMultiFrame;
				
				pHeader=pJpegInfo->m_pBuf+sizeof(JPEGMULTIFRAME);
				pBuf=pJpegInfo->m_pBuf+pJpegInfo->m_EncSize;
				
//				prvSaveWorld( &world );

				fMulit=mfValidateMultiFrame((JPEGMULTIFRAME *)pJpegInfo->m_pBuf);
				if(!fMulit)
					return;
				pJpegMultiFrame = (JPEGMULTIFRAME*)(pJpegInfo->m_pBuf);
				pJpegInfo->m_pBuf=pJpegInfo->m_pBuf+sizeof(JPEGMULTIFRAME);
				pJpegInfo->m_EncSize=pJpegMultiFrame->ResultSize;
				fSuccess = prvInitDecodeCodec( pJpegInfo );
				if ( fSuccess )
				{
					fSuccess = prvLoadJpeg(pJpegInfo);
					fSuccess = prvInitNextDecode( pJpegInfo, fSuccess );
				}
				if ( fSuccess )
				{
					pJpegInfo->m_pBuf=pJpegInfo->m_pBuf+pJpegMultiFrame->PaddedSize;
					pJpegInfo->m_FrameCount++;
				}
				else
				{
					return FALSE;
				}

				halDelayUS(pJpegInfo->m_Delay);
				
				while(pJpegInfo->m_pBuf<pBuf)
				{
					#define HEADERSIZE 595
					fMulit=mfValidateMultiFrame((JPEGMULTIFRAME *)pJpegInfo->m_pBuf);
					if(!fMulit)
						break;
					pJpegMultiFrame = (JPEGMULTIFRAME*)(pJpegInfo->m_pBuf);
					pJpegInfo->m_pBuf=pJpegInfo->m_pBuf+sizeof(JPEGMULTIFRAME);
					pJpegInfo->m_EncSize=pJpegMultiFrame->ResultSize-2+HEADERSIZE;
					fSuccess = prvInitDecodeCodec( pJpegInfo );
					if ( fSuccess )
					{
						fSuccess = prvLoadMJpeg(pJpegInfo, pHeader, HEADERSIZE);
					}
					else
					{
						prvInitNextDecode( pJpegInfo, fSuccess );
						return FALSE;
					}
					if ( fSuccess )
					{
						fSuccess = prvInitNextDecode( pJpegInfo, fSuccess );
					}
					else
					{
						return FALSE;
					}
					if ( fSuccess )
					{
						pJpegInfo->m_pBuf=pJpegInfo->m_pBuf+pJpegMultiFrame->PaddedSize;
						pJpegInfo->m_FrameCount++;
					}
					else
					{
						return FALSE;
					}					
					//pJpegInfo->m_pBuf=pJpegInfo->m_pBuf+pJpegMultiFrame->PaddedSize;
					halDelayUS(pJpegInfo->m_Delay);	

				}

//				fSuccess = prvRestoreWorld(pJpegInfo,&world) && fSuccess;
			}
		}
	}
	return ( fSuccess );
}


//------------------------------------------------------------------------------
//	prvIsFifoFull - determines if FIFO flag is set or not
//
//	Input:	n/a
//
//	Output:	TRUE means FIFO is full
//			FALSE means FIFO is NOT full
//
//------------------------------------------------------------------------------
Boolean prvIsFifoFull( void )
{
	UInt8 irqStatus		= halReadReg8( REG0300_IRQSTATUS0 );
	Boolean fFifoFull	= (irqStatus & 0x20) ? TRUE : FALSE;
	return ( fFifoFull );
}

//------------------------------------------------------------------------------
//	prvLoadJpeg - loads JPEG data into FIFO
//
//	Input:	pJpegInfo		pointer to JPEGINFO object
//
//	Output:	TRUE means success
//			FALSE means NOT success
//
//------------------------------------------------------------------------------
static Boolean prvLoadJpeg( JPEGINFO* pJpegInfo )
{
	Boolean fSuccess		= TRUE;
	UInt8	fifoSize		= 32;
	UInt32	jpegDataSize	= pJpegInfo->m_EncSize;
	UInt8*	pData			= pJpegInfo->m_pBuf;
	UInt8	irqEnable;
	//UInt16	prevStatus		= 0;

	// If decoding from memory, don't load anything, just wait until decoding is done.
	if ( pJpegInfo->m_MemEnc )
	{
		while ( (halReadReg8(REG0802_JPEGSTATUS0)&0x02) == 0 )
			continue;

		if ( pJpegInfo->m_fPause )
		{
			//printf( "Pause right after JPEG decode is complete.  Press any key to continue..." );
			//getch();
			//printf( "\n" );
		}
		return TRUE;
	}

#ifndef MV850E
	//jpegFindTimeOut( pJpegInfo );
#endif
	if ( !pJpegInfo->m_fFastCpu )
	{
		irqEnable = halReadReg8( REG0302_IRQENABLE0 );
		//76543210b
		//|||||||+--I2C Interrupt Enable
		//||||||+---LCD Interface Busy Interrupt Enable
		//|||||+----Camera Error Interrupt Enable
		//||||+-----JPEG Interrupt Enable
		//|||+------Camera Data Capture Interrupt Enable
		//||+-------JPEG FIFO Full Interrupt Enable
		//|+--------JPEG FIFO Empty Interrupt Enable
		//+---------JPEG FIFO Overflow Interrupt Enable

		halWriteReg8( REG0302_IRQENABLE0, (UInt8)(irqEnable | 0x20) );
	}

	while ( fSuccess && jpegDataSize )
	{
		if ( pJpegInfo->m_fFastCpu )
		{
			if ( pJpegInfo->m_fAFAP )
			{
				for ( ; jpegDataSize; --jpegDataSize, ++pData )
					halWriteReg8( REG081A_JPEGFIFOWRITE, *pData );
			}
			else
			{
				for ( ; fifoSize && jpegDataSize; --fifoSize, --jpegDataSize, ++pData )
					halWriteReg8( REG081A_JPEGFIFOWRITE, *pData );
				fifoSize = 32 - (halReadReg8(REG0808_JPEGRAWSTATUS1)&0x3F);
			}
		}
		else
		{
			Boolean fFifoFull;

			do
			{
				fFifoFull = prvIsFifoFull();
#ifndef MV850E
				if ( !fFifoFull )
				{
					//fSuccess = jpegNoTimeOut( pJpegInfo );
				}
#endif
			}
			while ( fSuccess && (!fFifoFull) );

			if ( fSuccess )
			{
				for ( ; (!fFifoFull) && jpegDataSize; ++pData, --jpegDataSize )
				{
					halWriteReg8( REG081A_JPEGFIFOWRITE, *pData );
					fFifoFull = prvIsFifoFull();
				}
			}
		}

		if ( fSuccess )
		{
			prvJpegFlag jpegStatus = prvGetJpegStatus();

			/*if ( pJpegInfo->m_fVerbose )
			{
				if ( jpegStatus != prevStatus )
				{
					if ( jpegStatus & JpegCodec )
						//printf( "JpegCodec " );
					if ( jpegStatus & LnBufOverflow )
						//printf( "LnBufOverflow " );
					if ( jpegStatus & JpegDecMarkerRd )
						//printf( "DecodeMarkerRead " );
					if ( jpegStatus & JpegDecComplete )
						//printf( "JpegComplete" );
					//printf( "\n" );

					prevStatus = jpegStatus;
				}
			}*/

			// Decode Marker Read
			if ( jpegStatus & JpegDecMarkerRd )
			{
				fSuccess = prvReadMarker( pJpegInfo, jpegStatus );
			}
#ifndef MV850E
			else
			{
				//fSuccess = jpegNoTimeOut( pJpegInfo );
			}
#endif
		}
	}

	if ( pJpegInfo->m_fPause )
	{
		//printf( "Pause right after JPEG decode is complete.  Press any key to continue..." );
		//getch();
		//printf( "\n" );
	}

	if ( !pJpegInfo->m_fFastCpu )
	{
		halWriteReg8( REG0302_IRQENABLE0, irqEnable );
	}

	return ( fSuccess );
}

static Boolean prvLoadMJpeg( JPEGINFO* pJpegInfo ,UInt8 * pHeader,Int32 HeaderSize)
{
	Boolean fSuccess		= TRUE;
	Boolean	fLoadHeader=FALSE;
	UInt8	fifoSize		= 32;
	Int32	jpegDataSize	= pJpegInfo->m_EncSize-HeaderSize;
	UInt8*	pData			= pJpegInfo->m_pBuf;
	UInt8	irqEnable;
	//UInt16	prevStatus		= 0;

	// If decoding from memory, don't load anything, just wait until decoding is done.
	if ( pJpegInfo->m_MemEnc )
	{
		while ( (halReadReg8(REG0802_JPEGSTATUS0)&0x02) == 0 )
			continue;

		if ( pJpegInfo->m_fPause )
		{
			//printf( "Pause right after JPEG decode is complete.  Press any key to continue..." );
			//getch();
			//printf( "\n" );
		}
		return TRUE;
	}

#ifndef MV850E
	//jpegFindTimeOut( pJpegInfo );
#endif
	if ( !pJpegInfo->m_fFastCpu )
	{
		irqEnable = halReadReg8( REG0302_IRQENABLE0 );
		//76543210b
		//|||||||+--I2C Interrupt Enable
		//||||||+---LCD Interface Busy Interrupt Enable
		//|||||+----Camera Error Interrupt Enable
		//||||+-----JPEG Interrupt Enable
		//|||+------Camera Data Capture Interrupt Enable
		//||+-------JPEG FIFO Full Interrupt Enable
		//|+--------JPEG FIFO Empty Interrupt Enable
		//+---------JPEG FIFO Overflow Interrupt Enable

		halWriteReg8( REG0302_IRQENABLE0, (UInt8)(irqEnable | 0x20) );
	}
/*	
	while ( fSuccess && HeaderSize)
	{
		if ( pJpegInfo->m_fFastCpu )
		{

⌨️ 快捷键说明

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