141 lines
3.1 KiB
C++
141 lines
3.1 KiB
C++
#include "QJTVObj.h"
|
|
#include <il/il.h>
|
|
#include <compress/XZip.h>
|
|
|
|
|
|
// QJTVObj
|
|
|
|
QJTVObj::QJTVObj()
|
|
{
|
|
m_pStream = NULL;
|
|
m_pMapper = NULL;
|
|
m_nCurWidth = 0;
|
|
m_nCurHeight = 0;
|
|
m_pBits = NULL;
|
|
m_pFrameArray = NULL;
|
|
|
|
ilInit();
|
|
ilEnable( IL_ORIGIN_SET );
|
|
ilOriginFunc( IL_ORIGIN_LOWER_LEFT );
|
|
ilEnable( IL_FORMAT_SET );
|
|
ilSetInteger( IL_FORMAT_MODE, IL_BGRA );
|
|
ilEnable( IL_FILE_OVERWRITE );
|
|
}
|
|
|
|
QJTVObj::~QJTVObj()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void QJTVObj::Clear()
|
|
{
|
|
SAFE_DELETE( m_pMapper );
|
|
SAFE_DELETE( m_pStream );
|
|
m_vFrames.clear();
|
|
m_nCurWidth = 0;
|
|
m_nCurHeight = 0;
|
|
ClearBits();
|
|
}
|
|
|
|
void QJTVObj::ClearBits()
|
|
{
|
|
SAFE_DELETE( m_pBits );
|
|
}
|
|
|
|
void QJTVObj::AllocBits()
|
|
{
|
|
if( m_nCurWidth == 0 || m_nCurHeight == 0 )
|
|
return;
|
|
|
|
m_pBits = new BYTE[ m_nCurWidth * m_nCurHeight * 4 ];
|
|
}
|
|
|
|
void QJTVObj::Load( const trf::MetaData* pMeta, KStream* pStream )
|
|
{
|
|
Clear();
|
|
|
|
m_pStream = pStream;
|
|
|
|
_DetailLoad( pMeta, m_pStream );
|
|
}
|
|
|
|
void QJTVObj::Load( const trf::MetaData* pMeta, const char* szFile )
|
|
{
|
|
Clear();
|
|
|
|
m_pStream = new KFileStream( szFile );
|
|
|
|
_DetailLoad( pMeta, m_pStream );
|
|
}
|
|
|
|
void QJTVObj::_DetailLoad( const trf::MetaData* pMeta, KStream* pStream )
|
|
{
|
|
m_pMapper = new trf::Mapper( pMeta, pStream->GetMappedPtr( 0 ), ( int ) pStream->GetLength() );
|
|
|
|
trf::MDictPtr pRoot = m_pMapper->root();
|
|
for( int i = 0; i < pRoot->count(); i++ )
|
|
{
|
|
trf::MTemplatePtr pHeader = pRoot->getTemplateAt( i );
|
|
const char* szName = pHeader->className();
|
|
|
|
if( strcmp( szName, "nx3_jtv_header" ) == 0 )
|
|
{
|
|
trf::MDictPtr pData = pHeader->getDictBy( "data" );
|
|
|
|
m_pFrameArray = pData->getTemplateArrayBy( "frame_array" );
|
|
int numFrames = m_pFrameArray->count();
|
|
m_vFrames.reserve( numFrames );
|
|
for( int j = 0; j < numFrames; j++ )
|
|
{
|
|
trf::MTemplatePtr pFrame = m_pFrameArray->getTemplateAt( j );
|
|
trf::MDictPtr pFrameData = pFrame->getDictBy( "data" );
|
|
m_vFrames.push_back( pFrameData->getDWordBy( "frame" ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void QJTVObj::GetFrame( int nFrame, BYTE*& pBits, int& nWidth, int& nHeight )
|
|
{
|
|
int nFrameIndex = -1;
|
|
if( !m_vFrames.empty() )
|
|
{
|
|
nFrameIndex = std::lower_bound( m_vFrames.begin(), m_vFrames.end(), nFrame ) - m_vFrames.begin();
|
|
if( nFrameIndex == ( int ) m_vFrames.size() )
|
|
nFrameIndex--;
|
|
}
|
|
|
|
if( nFrameIndex < 0 )
|
|
return;
|
|
|
|
trf::MTemplatePtr pFrame = m_pFrameArray->getTemplateAt( nFrameIndex );
|
|
trf::MDictPtr pFrameData = pFrame->getDictBy( "data" );
|
|
int nFrameWidth = pFrameData->getDWordBy( "width" );
|
|
int nFrameHeight = pFrameData->getDWordBy( "height" );
|
|
trf::MArrayPtr pFrameBits = pFrameData->getArrayBy( "bits" );;
|
|
|
|
const BYTE* pSrcBits = pFrameBits->getByteArray();
|
|
int nSrcSize = pFrameBits->count();
|
|
int nOrgSize = XZip::GetOriginalSize( pSrcBits, nSrcSize );
|
|
if( nOrgSize != nFrameWidth * nFrameHeight * 4 )
|
|
{
|
|
assert( 0 );
|
|
return;
|
|
}
|
|
|
|
if( m_nCurWidth * m_nCurHeight < nFrameWidth * nFrameHeight )
|
|
{
|
|
m_nCurWidth = nFrameWidth;
|
|
m_nCurHeight = nFrameHeight;
|
|
ClearBits();
|
|
AllocBits();
|
|
}
|
|
|
|
if( !XZip::Uncompress( pSrcBits, nSrcSize, m_pBits, m_nCurWidth * m_nCurHeight * 4 ) )
|
|
return;
|
|
|
|
pBits = m_pBits;
|
|
nWidth = m_nCurWidth;
|
|
nHeight = m_nCurHeight;
|
|
}
|