jencode.c

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

C
663
字号
//===========================================================================
//	JENCODE.C
//	This file contains JPEG functions implemented for the JPEG library to 
//	implement JPEG encoding via Epson JPEG Codec.
//---------------------------------------------------------------------------
//  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 "JPEG.h"
#include "jpegcomm.h"

//---------------------------------------------------------------------------
// Local Function Prototypes
//---------------------------------------------------------------------------
static Boolean	prvAcquireJpegInfo( JPEGINFO* pJpegInfo, UInt32 frameCount );
static Boolean	prvAdd2Buffer( JPEGINFO* pJpegInfo, UInt32 size, UInt32* pTotalSize );
static void		prvAssessStatusError( prvJpegFlag jpegStatus );
static Boolean	prvInitEncodeResizer( JPEGINFO* pJpegInfo );
static Boolean	prvInitAnyEncode( JPEGINFO* pJpegInfo );
static void		prvInitEachEncode( JPEGINFO* pJpegInfo );
static void 	prvInitCamera(JPEGINFO* pJpegInfo);

//---------------------------------------------------------------------------
// Local Data
//---------------------------------------------------------------------------

void ROCDebug( prvJpegFlag jpegStatus )
{
	// Can't read REG[1004] as it will influence its state. [Roc]
	static prvJpegFlag	prevStatus = 0xFFFF;

	jpegStatus &= 0x7F7F;
	if ( jpegStatus != prevStatus )
	{
		////printf( "ROC:  REG[0802]=%02X  REG[0804]=%02X\n", jpegStatus&0xFF, (jpegStatus>>8)&0xFF );
		prevStatus = jpegStatus;
	}
}

//------------------------------------------------------------------------------
//	jpegEncode - encode JPEG data via Epson JPEG Codec.
//
//	Input:	pJpegInfo	pointer to JPEGINFO object
//
//	Output:	TRUE means success
//			FALSe means NOT success
//
//------------------------------------------------------------------------------
Boolean jpegEncode( JPEGINFO* pJpegInfo )
{
	Boolean fSuccess = jpegValidateBuf( pJpegInfo );
	if ( fSuccess )
	{
		UInt32		frameCount;
		//prvWorld	world;
		UInt32		bufSize		= pJpegInfo->m_BufSize;
		UInt8*		pStart		= pJpegInfo->m_pBuf;
		UInt32		totalSize	= 0;

		// 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 );

		// initialize the camera interface register 100h-10ah
		prvInitCamera(pJpegInfo);

		// Enable View Encode (simultaneous display)?[norman add for big image encode]
		if(pJpegInfo->m_fWrAlways)
		{
			halWriteReg8( REG0202_RESIZE, (UInt8)(halReadReg8(REG0202_RESIZE)|0x08));
		}
		else
		{
			halWriteReg8( REG0202_RESIZE, (UInt8)(halReadReg8(REG0202_RESIZE) & (~0x08)));
		}
	
		// Initialize JPEG hardware for any capture
		fSuccess = prvInitAnyEncode( pJpegInfo );

		for ( frameCount=0; fSuccess&&((frameCount<pJpegInfo->m_FrameCount)||pJpegInfo->m_fInfLoop); ++frameCount )
		{
			JPEGMULTIFRAME* pJpegMultiFrame = (JPEGMULTIFRAME*)pJpegInfo->m_pBuf;
			if ( pJpegInfo->m_fInfLoop  )
			{
				//if ( pJpegInfo->m_fVerbose )
				//{
				//	static UInt32 nEncodes = 1;
					////printf( "\rEncode cycle: %ld", nEncodes++ );
				//}
			}
			else
			{
				if ( pJpegInfo->m_FrameCount > 1 )
				{
					fSuccess = prvAdd2Buffer( pJpegInfo, sizeof( JPEGMULTIFRAME ), &totalSize );
				}

			}

			if ( fSuccess )
			{
				// Program JPEG hardware for each capture (only do this for the first frame if Motion-JPEG)
				if ( !pJpegInfo->m_fMotionJPEG || frameCount==0 )
					prvInitEachEncode( pJpegInfo );

				// Capture JPEG data
				fSuccess = prvAcquireJpegInfo( pJpegInfo, frameCount );

				if ( pJpegInfo->m_fPause )
				{
					////printf( "Pause after last byte of JPEG data read.  Press any key to continue..." );
					//getch();
					////printf( "\n" );
				}

				if ( fSuccess )
				{
					//if ( !pJpegInfo->m_fAFAP )
					if ( pJpegInfo->m_fAFAP )
						fSuccess = jpegHasImageMarkers( pJpegInfo );
					if ( fSuccess )
					{
						if ( !pJpegInfo->m_fInfLoop )
						{
							if ( pJpegInfo->m_FrameCount > 1 )
							{	
								mfInitializeMultiFrame( pJpegMultiFrame, pJpegInfo->m_EncSize );
								fSuccess = prvAdd2Buffer( pJpegInfo, pJpegMultiFrame->PaddedSize, &totalSize );
								pJpegMultiFrame->FrameNumber = frameCount + 1;
							}
						}
					}
					else
					{
						jpegSetLastError( JPEG_ERR_NO_ENDOFIMAGE );
						break;//REG0800_JPEGCONTROL REG0810_JPEGSTARTSTOP
					}
				}
			}
			if ( pJpegInfo->m_FrameCount > 1 )
			{
				halDelayUS(pJpegInfo->m_Delay);
			}			
		}

		if ( pJpegInfo->m_FrameCount > 1 )
		{
			// Restore buffer size and start
			pJpegInfo->m_BufSize	= bufSize;
			pJpegInfo->m_pBuf		= pStart;

			// Save accumulated encoded size
			pJpegInfo->m_EncSize = totalSize;
		}

		// Perform exit sequence regardless of success
		fSuccess = prvExitSequence( fSuccess, FALSE );

		// Enable Encode Scaled Overlay
		if ( pJpegInfo->m_fSOE )
			halWriteReg8( REG004E_SCALEUP, (UInt8)(halReadReg8(REG004E_SCALEUP)&0x7F) );

		// If encoding from Memory Encode or Scaled Overlay Encode, disable RYC
		if ( pJpegInfo->m_MemEnc || pJpegInfo->m_fSOE )
			halWriteReg8( REG0210_RESIZEOP, (UInt8)(halReadReg8(REG0210_RESIZEOP)&0xEF) );

		if ( pJpegInfo->m_fMotionJPEG )
			halWriteReg8( REG0250_MJPEG, 0);	// Clear reg[250h]

//		if ( fSuccess )
//		{
//			// Restore registers regardless of success
//			fSuccess = prvRestoreWorld( pJpegInfo, &world );
//		}
	}
	return ( fSuccess );
}

//------------------------------------------------------------------------------
//	prvAcquireJpegInfo - obtain JPEG data from hardware
//
//	Input:	pJpegInfo	pointer to JPEGINFO structure
//			frameCount	zero-based
//
//	Return:	TRUE means successful encoding of JPEG image
//			FALSE means NOT successul encoding of JPEG image
//
//------------------------------------------------------------------------------
Boolean prvAcquireJpegInfo( JPEGINFO* pJpegInfo, UInt32 frameCount )
{
	Boolean fSuccess = TRUE;
	Boolean fWork;
	UInt32 offset, leftover;

#ifndef MV850E
	//jpegFindTimeOut( pJpegInfo );
#endif

	do
	{
		// 8. Wait for JPEG Coded Interrupt.  Ensure that the encode has completed.
		prvJpegFlag jpegStatus = prvGetJpegStatus();
		//FEDBCA9876543210b
		//|||||||||||||||+--Reserved JPEG Line Buffer Interrupt Flag
		//||||||||||||||+---JPEG Code Interrupt Flag
		//|||||||||||||+----Line Buffer Overflow Flag
		//||||||||||||+-----Reserved Size Mismatch Flag
		//|||||||||||+------Decode Marker Read Flag
		//||||||||||+-------JPEG Decode Complete Flag
		//|||||||||+--------n/a
		//||||||||+---------Reserved
		//|||||||+----------JPEG Encode Overflow Flag
		//|||||++-----------n/a
		//||||+-------------Encode Size Limit Violation Flag
		//||++--------------n/a
		//|+----------------JPEG Codec File Out Status
		//+-----------------Reserved

//ROCDebug( jpegStatus );
		fSuccess = (jpegStatus & (LnBufOverflow|EncSizeLimit)) ? FALSE : TRUE;
		if ( !fSuccess )
		{
			prvAssessStatusError( jpegStatus );
		}
		else
		{
			fWork = (jpegStatus & JpegCodec) ? FALSE : TRUE;
			if ( !fWork )
			{
				fWork = prvGetOpWork();
			}
#ifndef MV850E
			else
			{
				//fSuccess = jpegNoTimeOut( pJpegInfo );
			}
#endif
		}
	}
	while ( fWork && fSuccess );

	//Norman debug add.Stop the camera preview
	//prvSetResize(FALSE, NULL);

	// Disable Marker Interrupt
	prvHalReadReg16( REG0806_JPEGRAWSTATUS0, REG0808_JPEGRAWSTATUS1 );
				
	// Check Codec Status to reset Codec Interrupt
	prvGetOpWork();

	// Disable all interrupts
	prvSetIrqControl( IrqDisable );

	// Reset all status flags
	prvSetJpegStatus( AllStatusClear );

	if ( fSuccess )
	{
		// 9. Read the Enocde Size Result to determine the bytes in the JPEG file.
		pJpegInfo->m_EncSize	= prvHalReadReg24( REG081C_ENCODERESULT0 );
		fSuccess				= (pJpegInfo->m_BufSize >= pJpegInfo->m_EncSize) ? TRUE : FALSE;
		if ( !fSuccess )
		{
			jpegSetLastError( JPEG_ERR_JPEG_FULL );
		}
		else
		{
			fSuccess = (pJpegInfo->m_EncSize > 0) ? TRUE : FALSE;
			if ( !fSuccess )
			{
				jpegSetLastError( JPEG_ERR_NO_JPEG_DATA );
			}
			else
			{
				// For Motion JPEG: start the next capture into other buffer before reading from the current buffer (increases encoding speed)
				if ( pJpegInfo->m_fMotionJPEG && (frameCount<pJpegInfo->m_FrameCount-1) )
				{
					if (!frameCount)
						halWriteReg8( REG0250_MJPEG, 1 );	// Disable JPEG file header from the 2nd frame
					prvSetJpeg( TRUE, TRUE );				// Perform a JPEG Software Reset
					prvInitEachEncode( pJpegInfo );
				}

				// 10. Read the approprimate number of bytes from memory
				// If Motion-JPEG, alternate between BUF1 (address 0) & BUF2 (REG[0252h-0254h])
				if (pJpegInfo->m_fMotionJPEG && (frameCount&1) )
				{
					offset = halReadReg8( REG0254_BUF2ADDR2 );
					offset <<= 8;
					offset += halReadReg8( REG0253_BUF2ADDR1 );
					offset <<= 8;
					offset += halReadReg8( REG0252_BUF2ADDR0 );
				}
				else
					offset = 0;
				halReadData( 4, offset, pJpegInfo->m_pBuf, pJpegInfo->m_EncSize );
				//halReadData( sizeof(UInt16), offset, pJpegInfo->m_pBuf, pJpegInfo->m_EncSize );
				for ( leftover=pJpegInfo->m_EncSize%4; leftover>0; leftover-- )
					*(pJpegInfo->m_pBuf + pJpegInfo->m_EncSize - leftover) = halReadDisplay8( offset + pJpegInfo->m_EncSize - leftover );
			}
		}
	}

	return ( fSuccess );
}

//-----------------------------------------------------------------------------
//	prvAdd2Buffer - performs pointer & size calculation and error control
//
//	Input:	pJpegInfo		pointer to JPEGINFO object
//			size			size to add
//			pTotalSize		pointer to total size accumulator
//
//	Return:	TRUE means successful
//			FALSE means NOT successul
//
//-----------------------------------------------------------------------------
Boolean prvAdd2Buffer( JPEGINFO* pJpegInfo, UInt32 size, UInt32* pTotalSize )
{
	Boolean	fSuccess = (Boolean)(pJpegInfo->m_BufSize >= size);
	if ( !fSuccess )
	{
		jpegSetLastError( JPEG_ERR_JPEG_FULL );

⌨️ 快捷键说明

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