Added first cut at AVI RIFF Viewer tool window.
This commit is contained in:
parent
9853ff37b0
commit
41e04ece0b
|
@ -524,6 +524,7 @@ set(SRC_DRIVERS_SDL
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/sdl-throttle.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/unix-netplay.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/AviRecord.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/AviRiffViewer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/avi/avi-utils.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/avi/fileio.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/avi/gwavi.cpp
|
||||
|
|
|
@ -0,0 +1,419 @@
|
|||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 mjbudd77
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
// AviRiffViewer.cpp
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QCloseEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include "Qt/main.h"
|
||||
#include "Qt/config.h"
|
||||
#include "Qt/fceuWrapper.h"
|
||||
#include "Qt/AviRiffViewer.h"
|
||||
#include "Qt/ConsoleUtilities.h"
|
||||
|
||||
static AviRiffViewerDialog *win = NULL;
|
||||
//----------------------------------------------------------------------------
|
||||
static int riffWalkCallback( int type, long long int fpos, const char *fourcc, size_t size, void *userData )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ( win )
|
||||
{
|
||||
ret = win->riffWalkCallback( type, fpos, fourcc, size );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
//--- AVI RIFF Viewer Dialog
|
||||
//----------------------------------------------------------------------------
|
||||
AviRiffViewerDialog::AviRiffViewerDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
QMenuBar *menuBar;
|
||||
QVBoxLayout *mainLayout;
|
||||
QHBoxLayout *hbox;
|
||||
QPushButton *closeButton;
|
||||
QTreeWidgetItem *item;
|
||||
|
||||
win = this;
|
||||
avi = NULL;
|
||||
|
||||
setWindowTitle("AVI RIFF Viewer");
|
||||
|
||||
resize(512, 512);
|
||||
|
||||
menuBar = buildMenuBar();
|
||||
mainLayout = new QVBoxLayout();
|
||||
setLayout(mainLayout);
|
||||
mainLayout->setMenuBar( menuBar );
|
||||
|
||||
riffTree = new AviRiffTree();
|
||||
|
||||
riffTree->setColumnCount(4);
|
||||
riffTree->setSelectionMode( QAbstractItemView::SingleSelection );
|
||||
riffTree->setAlternatingRowColors(true);
|
||||
|
||||
item = new QTreeWidgetItem();
|
||||
item->setText(0, QString::fromStdString("Block"));
|
||||
item->setText(1, QString::fromStdString("FCC"));
|
||||
item->setText(2, QString::fromStdString("Size"));
|
||||
item->setText(3, QString::fromStdString("FilePos"));
|
||||
item->setTextAlignment(0, Qt::AlignLeft);
|
||||
item->setTextAlignment(1, Qt::AlignLeft);
|
||||
item->setTextAlignment(2, Qt::AlignLeft);
|
||||
item->setTextAlignment(3, Qt::AlignLeft);
|
||||
|
||||
riffTree->setHeaderItem(item);
|
||||
|
||||
riffTree->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
|
||||
//connect( riffTree, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(hotKeyActivated(QTreeWidgetItem*,int) ) );
|
||||
|
||||
mainLayout->addWidget(riffTree);
|
||||
|
||||
closeButton = new QPushButton( tr("Close") );
|
||||
closeButton->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton));
|
||||
connect(closeButton, SIGNAL(clicked(void)), this, SLOT(closeWindow(void)));
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
hbox->addStretch(5);
|
||||
hbox->addWidget( closeButton, 1 );
|
||||
mainLayout->addLayout( hbox );
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
AviRiffViewerDialog::~AviRiffViewerDialog(void)
|
||||
{
|
||||
printf("Destroy AVI RIFF Viewer Window\n");
|
||||
|
||||
if ( avi )
|
||||
{
|
||||
delete avi; avi = NULL;
|
||||
}
|
||||
win = NULL;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void AviRiffViewerDialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
printf("AVI RIFF Viewer Window Event\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
event->accept();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void AviRiffViewerDialog::closeWindow(void)
|
||||
{
|
||||
//printf("Close Window\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
QMenuBar *AviRiffViewerDialog::buildMenuBar(void)
|
||||
{
|
||||
QMenu *fileMenu;
|
||||
//QActionGroup *actGroup;
|
||||
QAction *act;
|
||||
int opt, useNativeMenuBar=0;
|
||||
|
||||
QMenuBar *menuBar = new QMenuBar();
|
||||
|
||||
// This is needed for menu bar to show up on MacOS
|
||||
g_config->getOption( "SDL.UseNativeMenuBar", &useNativeMenuBar );
|
||||
|
||||
menuBar->setNativeMenuBar( useNativeMenuBar ? true : false );
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Menu Start
|
||||
//-----------------------------------------------------------------------
|
||||
// File
|
||||
fileMenu = menuBar->addMenu(tr("&File"));
|
||||
|
||||
// File -> Open
|
||||
act = new QAction(tr("&Open"), this);
|
||||
act->setShortcut(QKeySequence::Open);
|
||||
act->setStatusTip(tr("Open AVI File"));
|
||||
connect(act, SIGNAL(triggered()), this, SLOT(openAviFileDialog(void)) );
|
||||
|
||||
fileMenu->addAction(act);
|
||||
|
||||
// File -> Close
|
||||
act = new QAction(tr("&Close"), this);
|
||||
act->setShortcut(QKeySequence::Close);
|
||||
act->setStatusTip(tr("Close Window"));
|
||||
connect(act, SIGNAL(triggered()), this, SLOT(closeWindow(void)) );
|
||||
|
||||
fileMenu->addAction(act);
|
||||
|
||||
return menuBar;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void AviRiffViewerDialog::openAviFileDialog(void)
|
||||
{
|
||||
std::string last;
|
||||
int ret, useNativeFileDialogVal;
|
||||
QString filename;
|
||||
std::string lastPath;
|
||||
//char dir[512];
|
||||
const char *base, *rom;
|
||||
QFileDialog dialog(this, tr("Open AVI Movie for Inspection") );
|
||||
QList<QUrl> urls;
|
||||
QDir d;
|
||||
|
||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||
|
||||
dialog.setNameFilter(tr("AVI Movies (*.avi) ;; All files (*)"));
|
||||
|
||||
dialog.setViewMode(QFileDialog::List);
|
||||
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
||||
dialog.setLabelText( QFileDialog::Accept, tr("Open") );
|
||||
|
||||
base = FCEUI_GetBaseDirectory();
|
||||
|
||||
urls << QUrl::fromLocalFile( QDir::rootPath() );
|
||||
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first());
|
||||
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first());
|
||||
|
||||
if ( base )
|
||||
{
|
||||
urls << QUrl::fromLocalFile( QDir( base ).absolutePath() );
|
||||
|
||||
d.setPath( QString(base) + "/avi");
|
||||
|
||||
if ( d.exists() )
|
||||
{
|
||||
urls << QUrl::fromLocalFile( d.absolutePath() );
|
||||
}
|
||||
|
||||
dialog.setDirectory( d.absolutePath() );
|
||||
}
|
||||
dialog.setDefaultSuffix( tr(".avi") );
|
||||
|
||||
g_config->getOption ("SDL.AviFilePath", &lastPath);
|
||||
if ( lastPath.size() > 0 )
|
||||
{
|
||||
dialog.setDirectory( QString::fromStdString(lastPath) );
|
||||
}
|
||||
|
||||
rom = getRomFile();
|
||||
|
||||
if ( rom )
|
||||
{
|
||||
char baseName[512];
|
||||
getFileBaseName( rom, baseName );
|
||||
|
||||
if ( baseName[0] != 0 )
|
||||
{
|
||||
dialog.selectFile(baseName);
|
||||
}
|
||||
}
|
||||
|
||||
// Check config option to use native file dialog or not
|
||||
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
||||
|
||||
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
||||
dialog.setSidebarUrls(urls);
|
||||
|
||||
ret = dialog.exec();
|
||||
|
||||
if ( ret )
|
||||
{
|
||||
QStringList fileList;
|
||||
fileList = dialog.selectedFiles();
|
||||
|
||||
if ( fileList.size() > 0 )
|
||||
{
|
||||
filename = fileList[0];
|
||||
}
|
||||
}
|
||||
|
||||
if ( filename.isNull() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
//qDebug() << "selected file path : " << filename.toUtf8();
|
||||
|
||||
printf( "AVI Debug movie %s\n", filename.toStdString().c_str() );
|
||||
|
||||
lastPath = QFileInfo(filename).absolutePath().toStdString();
|
||||
|
||||
if ( lastPath.size() > 0 )
|
||||
{
|
||||
g_config->setOption ("SDL.AviFilePath", lastPath);
|
||||
}
|
||||
|
||||
openFile( filename.toStdString().c_str() );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int AviRiffViewerDialog::openFile( const char *filepath )
|
||||
{
|
||||
if ( avi )
|
||||
{
|
||||
closeFile();
|
||||
}
|
||||
|
||||
avi = new gwavi_t();
|
||||
|
||||
if ( avi->openIn( filepath ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
itemStack.clear();
|
||||
|
||||
avi->setRiffWalkCallback( ::riffWalkCallback, this );
|
||||
avi->printHeaders();
|
||||
|
||||
return 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int AviRiffViewerDialog::closeFile(void)
|
||||
{
|
||||
if ( avi )
|
||||
{
|
||||
delete avi; avi = NULL;
|
||||
}
|
||||
riffTree->clear();
|
||||
itemStack.clear();
|
||||
|
||||
return 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int AviRiffViewerDialog::riffWalkCallback( int type, long long int fpos, const char *fourcc, size_t size )
|
||||
{
|
||||
AviRiffTreeItem *item, *groupItem;
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case gwavi_t::RIFF_START:
|
||||
{
|
||||
item = new AviRiffTreeItem(type, fpos, fourcc, size);
|
||||
|
||||
itemStack.push_back(item);
|
||||
|
||||
riffTree->addTopLevelItem(item);
|
||||
}
|
||||
break;
|
||||
case gwavi_t::RIFF_END:
|
||||
{
|
||||
itemStack.pop_back();
|
||||
}
|
||||
break;
|
||||
case gwavi_t::LIST_START:
|
||||
{
|
||||
item = new AviRiffTreeItem(type, fpos, fourcc, size);
|
||||
|
||||
groupItem = itemStack.back();
|
||||
|
||||
itemStack.push_back(item);
|
||||
|
||||
groupItem->addChild(item);
|
||||
}
|
||||
break;
|
||||
case gwavi_t::LIST_END:
|
||||
{
|
||||
itemStack.pop_back();
|
||||
}
|
||||
break;
|
||||
case gwavi_t::CHUNK_START:
|
||||
{
|
||||
item = new AviRiffTreeItem(type, fpos, fourcc, size);
|
||||
|
||||
groupItem = itemStack.back();
|
||||
|
||||
groupItem->addChild(item);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// UnHandled Type
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
//--- AVI RIFF Tree View
|
||||
//----------------------------------------------------------------------------
|
||||
AviRiffTree::AviRiffTree(QWidget *parent)
|
||||
: QTreeWidget(parent)
|
||||
{
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
AviRiffTree::~AviRiffTree(void)
|
||||
{
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
//--- AVI RIFF Viewer Dialog
|
||||
//----------------------------------------------------------------------------
|
||||
AviRiffTreeItem::AviRiffTreeItem(int typeIn, long long int fposIn, const char *fourccIn, size_t sizeIn, QTreeWidgetItem *parent)
|
||||
: QTreeWidgetItem(parent)
|
||||
{
|
||||
char stmp[64];
|
||||
|
||||
type = typeIn;
|
||||
fpos = fposIn;
|
||||
size = sizeIn;
|
||||
|
||||
strcpy( fourcc, fourccIn );
|
||||
|
||||
//sprintf( stmp, "0x%08llX", fposIn );
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case gwavi_t::RIFF_START:
|
||||
case gwavi_t::RIFF_END:
|
||||
setText( 0, QString("RIFF") );
|
||||
break;
|
||||
case gwavi_t::LIST_START:
|
||||
case gwavi_t::LIST_END:
|
||||
setText( 0, QString("LIST") );
|
||||
break;
|
||||
default:
|
||||
case gwavi_t::CHUNK_START:
|
||||
setText( 0, QString("CHUNK") );
|
||||
break;
|
||||
}
|
||||
|
||||
setText( 1, QString(fourcc) );
|
||||
|
||||
sprintf( stmp, "%zu", size );
|
||||
|
||||
setText( 2, QString(stmp) );
|
||||
|
||||
sprintf( stmp, "0x%08llX", fposIn );
|
||||
|
||||
setText( 3, QString(stmp) );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
AviRiffTreeItem::~AviRiffTreeItem(void)
|
||||
{
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
|
@ -0,0 +1,83 @@
|
|||
// AviRiffViewer.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QTreeView>
|
||||
#include <QTreeWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QMenuBar>
|
||||
#include <QAction>
|
||||
|
||||
#include "Qt/avi/gwavi.h"
|
||||
|
||||
class AviRiffTreeItem : public QTreeWidgetItem
|
||||
{
|
||||
//Q_OBJECT
|
||||
|
||||
public:
|
||||
AviRiffTreeItem(int type, long long int fpos, const char *fourcc, size_t size, QTreeWidgetItem *parent = nullptr);
|
||||
~AviRiffTreeItem(void);
|
||||
|
||||
private:
|
||||
int type;
|
||||
char fourcc[8];
|
||||
size_t size;
|
||||
long long int fpos;
|
||||
};
|
||||
|
||||
class AviRiffTree : public QTreeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AviRiffTree(QWidget *parent = 0);
|
||||
~AviRiffTree(void);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
class AviRiffViewerDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AviRiffViewerDialog(QWidget *parent = 0);
|
||||
~AviRiffViewerDialog(void);
|
||||
|
||||
int riffWalkCallback( int type, long long int fpos, const char *fourcc, size_t size );
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
QMenuBar *buildMenuBar(void);
|
||||
|
||||
int openFile( const char *filepath );
|
||||
int closeFile(void);
|
||||
|
||||
gwavi_t *avi;
|
||||
AviRiffTree *riffTree;
|
||||
std::list <AviRiffTreeItem*> itemStack;
|
||||
|
||||
private:
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void openAviFileDialog(void);
|
||||
//void ItemActivated(QTreeWidgetItem *item, int column);
|
||||
};
|
|
@ -72,6 +72,7 @@
|
|||
#include "Qt/HelpPages.h"
|
||||
#include "Qt/GuiConf.h"
|
||||
#include "Qt/AviRecord.h"
|
||||
#include "Qt/AviRiffViewer.h"
|
||||
#include "Qt/MoviePlay.h"
|
||||
#include "Qt/MovieRecord.h"
|
||||
#include "Qt/MovieOptions.h"
|
||||
|
@ -1595,6 +1596,14 @@ void consoleWin_t::createMainMenu(void)
|
|||
act->setStatusTip(tr("Open Palette Editor Window"));
|
||||
connect(act, SIGNAL(triggered()), this, SLOT(openPaletteEditorWin(void)) );
|
||||
|
||||
toolsMenu->addAction(act);
|
||||
|
||||
// Tools -> AVI RIFF Viewer
|
||||
act = new QAction(tr("&AVI RIFF Viewer ..."), this);
|
||||
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
||||
act->setStatusTip(tr("Open AVI RIFF Viewer Window"));
|
||||
connect(act, SIGNAL(triggered()), this, SLOT(openAviRiffViewer(void)) );
|
||||
|
||||
toolsMenu->addAction(act);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
@ -2799,6 +2808,17 @@ void consoleWin_t::openPaletteEditorWin(void)
|
|||
win->show();
|
||||
}
|
||||
|
||||
void consoleWin_t::openAviRiffViewer(void)
|
||||
{
|
||||
AviRiffViewerDialog *win;
|
||||
|
||||
//printf("Open AVI RIFF Viewer Window\n");
|
||||
|
||||
win = new AviRiffViewerDialog(this);
|
||||
|
||||
win->show();
|
||||
}
|
||||
|
||||
void consoleWin_t::openMovieOptWin(void)
|
||||
{
|
||||
MovieOptionsDialog_t *win;
|
||||
|
|
|
@ -334,6 +334,7 @@ class consoleWin_t : public QMainWindow
|
|||
void openGuiConfWin(void);
|
||||
void openTimingConfWin(void);
|
||||
void openPaletteEditorWin(void);
|
||||
void openAviRiffViewer(void);
|
||||
void openTimingStatWin(void);
|
||||
void openMovieOptWin(void);
|
||||
void openCodeDataLogger(void);
|
||||
|
|
|
@ -83,6 +83,7 @@ gwavi_t::gwavi_t(void)
|
|||
bits_per_pixel = 24;
|
||||
avi_std = 2;
|
||||
audioEnabled = false;
|
||||
riffWalkCallback = NULL;
|
||||
}
|
||||
|
||||
gwavi_t::~gwavi_t(void)
|
||||
|
@ -660,11 +661,13 @@ int gwavi_t::printHeaders(void)
|
|||
{
|
||||
char fourcc[8];
|
||||
unsigned int ret, fileSize, size;
|
||||
long long int fpos;
|
||||
|
||||
if ( in == NULL )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
fpos = ftell(in);
|
||||
|
||||
if (read_chars_bin(in, fourcc, 4) == -1)
|
||||
return -1;
|
||||
|
@ -687,6 +690,11 @@ int gwavi_t::printHeaders(void)
|
|||
fourcc[4] = 0;
|
||||
printf("FileType: '%s'\n", fourcc );
|
||||
|
||||
if ( riffWalkCallback )
|
||||
{
|
||||
riffWalkCallback( RIFF_START, fpos, fourcc, fileSize, riffWalkUserData );
|
||||
}
|
||||
|
||||
while ( size >= 4 )
|
||||
{
|
||||
if (read_chars_bin(in, fourcc, 4) == -1)
|
||||
|
@ -728,10 +736,13 @@ unsigned int gwavi_t::readList(int lvl)
|
|||
char fourcc[8], listType[8], pad[4];
|
||||
unsigned int size, listSize=0;
|
||||
char indent[256];
|
||||
long long int fpos;
|
||||
|
||||
memset( indent, ' ', lvl*3);
|
||||
indent[lvl*3] = 0;
|
||||
|
||||
fpos = ftell(in);
|
||||
|
||||
if (read_uint(in, listSize) == -1)
|
||||
{
|
||||
(void)fprintf(stderr, "readList: read_int() failed\n");
|
||||
|
@ -754,6 +765,10 @@ unsigned int gwavi_t::readList(int lvl)
|
|||
size -= 4;
|
||||
bytesRead += 4;
|
||||
|
||||
if ( riffWalkCallback )
|
||||
{
|
||||
riffWalkCallback( LIST_START, fpos-4, listType, listSize, riffWalkUserData );
|
||||
}
|
||||
printf("%sList Start: '%s' %u\n", indent, listType, listSize );
|
||||
|
||||
while ( size >= 4 )
|
||||
|
@ -805,6 +820,12 @@ unsigned int gwavi_t::readList(int lvl)
|
|||
}
|
||||
printf("%sList End: %s %u\n", indent, listType, bytesRead);
|
||||
|
||||
if ( riffWalkCallback )
|
||||
{
|
||||
fpos = ftell(in);
|
||||
|
||||
riffWalkCallback( LIST_END, fpos, listType, listSize, riffWalkUserData );
|
||||
}
|
||||
return bytesRead+4;
|
||||
}
|
||||
|
||||
|
@ -813,10 +834,13 @@ unsigned int gwavi_t::readChunk(const char *id, int lvl)
|
|||
unsigned int r, ret, size, chunkSize, bytesRead=0;
|
||||
unsigned short dataWord;
|
||||
char indent[256];
|
||||
long long int fpos;
|
||||
|
||||
memset( indent, ' ', lvl*3);
|
||||
indent[lvl*3] = 0;
|
||||
|
||||
fpos = ftell(in);
|
||||
|
||||
if (read_uint(in, chunkSize) == -1)
|
||||
{
|
||||
(void)fprintf(stderr, "readChunk: read_uint() failed\n");
|
||||
|
@ -824,9 +848,14 @@ unsigned int gwavi_t::readChunk(const char *id, int lvl)
|
|||
}
|
||||
printf("%sChunk Start: %s %u\n", indent, id, chunkSize);
|
||||
|
||||
if ( riffWalkCallback )
|
||||
{
|
||||
riffWalkCallback( CHUNK_START, fpos-4, id, chunkSize, riffWalkUserData );
|
||||
}
|
||||
|
||||
if ( chunkSize == 0 )
|
||||
{
|
||||
return 0;
|
||||
return 4;
|
||||
}
|
||||
size = chunkSize;
|
||||
|
||||
|
|
|
@ -175,6 +175,15 @@ class gwavi_t
|
|||
static const unsigned int IF_KEYFRAME = 0x00000010;
|
||||
static const unsigned int IF_NO_TIME = 0x00000100;
|
||||
|
||||
enum
|
||||
{
|
||||
RIFF_START,
|
||||
RIFF_END,
|
||||
LIST_START,
|
||||
LIST_END,
|
||||
CHUNK_START
|
||||
};
|
||||
|
||||
gwavi_t(void);
|
||||
~gwavi_t(void);
|
||||
|
||||
|
@ -198,6 +207,12 @@ class gwavi_t
|
|||
|
||||
int printHeaders(void);
|
||||
|
||||
void setRiffWalkCallback( int (*cb)( int type, long long int fpos, const char *fourcc, size_t size, void *userData ), void *userData )
|
||||
{
|
||||
riffWalkCallback = cb;
|
||||
riffWalkUserData = userData;
|
||||
};
|
||||
|
||||
private:
|
||||
FILE *in;
|
||||
FILE *out;
|
||||
|
@ -252,6 +267,9 @@ class gwavi_t
|
|||
unsigned int readAviHeader(void);
|
||||
unsigned int readStreamHeader(void);
|
||||
unsigned int readIndexBlock( unsigned int chunkSize );
|
||||
|
||||
void *riffWalkUserData;
|
||||
int (*riffWalkCallback)( int type, long long int fpos, const char *fourcc, size_t size, void *userData );
|
||||
};
|
||||
|
||||
#endif /* ndef H_GWAVI */
|
||||
|
|
Loading…
Reference in New Issue