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