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 + -
显示快捷键?