|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef __LP64__
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <math.h></math.h>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "texception.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsound.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tconvert.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpropertytype.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trop.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "timageinfo.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trasterimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmachine.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "../mov/tiio_movM.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tiio_3gpM.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
int CompressionNoneId = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class QuickTimeCleanUp;
|
|
Shinya Kitaoka |
120a6e |
class QuickTimeStuff {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
static QuickTimeStuff *instance() {
|
|
Shinya Kitaoka |
120a6e |
if (!m_singleton) m_singleton = new QuickTimeStuff();
|
|
Shinya Kitaoka |
120a6e |
return m_singleton;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
OSErr getStatus() { return m_status; }
|
|
Shinya Kitaoka |
120a6e |
~QuickTimeStuff() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
QuickTimeStuff() : m_status(noErr) {
|
|
Shinya Kitaoka |
120a6e |
m_status = noErr;
|
|
Shinya Kitaoka |
120a6e |
EnterMovies();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
static QuickTimeStuff *m_singleton;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
OSErr m_status;
|
|
Shinya Kitaoka |
120a6e |
friend class QuickTimeCleanUp; // questa DEVE essere friend, cosi' posso
|
|
Shinya Kitaoka |
120a6e |
// controllare direttamente
|
|
Shinya Kitaoka |
120a6e |
// lo stato del singleton.
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class QuickTimeCleanUp {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
QuickTimeCleanUp() {}
|
|
Shinya Kitaoka |
120a6e |
~QuickTimeCleanUp() { /*
|
|
Shinya Kitaoka |
120a6e |
Nel caso si arrivasse qui senza il
|
|
Shinya Kitaoka |
120a6e |
singleton instanziato, e si facesse direttamente
|
|
Shinya Kitaoka |
120a6e |
'delete QuickTimeStuff::instance();'
|
|
Shinya Kitaoka |
120a6e |
Quicktime non farebbe in tempo a terminare le
|
|
Shinya Kitaoka |
120a6e |
sue routine di inizializzazione (che sono
|
|
Shinya Kitaoka |
120a6e |
ANCHE su altri thread) e la chiamata a
|
|
Shinya Kitaoka |
120a6e |
TerminateQTML() causerebbe un crash
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
if (QuickTimeStuff::m_singleton) delete QuickTimeStuff::m_singleton;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QuickTimeCleanUp cleanUp;
|
|
Toshihiro Shimizu |
890ddd |
QuickTimeStuff *QuickTimeStuff::m_singleton = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
enum QTLibError {
|
|
Shinya Kitaoka |
120a6e |
QTNoError = 0x0000,
|
|
Shinya Kitaoka |
120a6e |
QTNotInstalled,
|
|
Shinya Kitaoka |
120a6e |
QTUnknownError,
|
|
Shinya Kitaoka |
120a6e |
QTUnableToOpenFile,
|
|
Shinya Kitaoka |
120a6e |
QTCantCreateFile,
|
|
Shinya Kitaoka |
120a6e |
QTUnableToGetCompressorNames,
|
|
Shinya Kitaoka |
120a6e |
QTUnableToCreateResource,
|
|
Shinya Kitaoka |
120a6e |
QTUnableToUpdateMovie,
|
|
Shinya Kitaoka |
120a6e |
QTBadTimeValue,
|
|
Shinya Kitaoka |
120a6e |
QTUnableToDoMovieTask,
|
|
Shinya Kitaoka |
120a6e |
QTUnableToSetTimeValue,
|
|
Shinya Kitaoka |
120a6e |
QTUnableToSetMovieGWorld,
|
|
Shinya Kitaoka |
120a6e |
QTUnableToSetMovieBox,
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
string buildQTErrorString(int ec) {
|
|
Shinya Kitaoka |
120a6e |
switch (ec) {
|
|
Shinya Kitaoka |
120a6e |
case QTNotInstalled:
|
|
Shinya Kitaoka |
120a6e |
return "Can't create; ensure that quicktime is correctly installed on your "
|
|
Shinya Kitaoka |
120a6e |
"machine";
|
|
Shinya Kitaoka |
120a6e |
case QTUnknownError:
|
|
Shinya Kitaoka |
120a6e |
return "Unknown error";
|
|
Shinya Kitaoka |
120a6e |
case QTUnableToOpenFile:
|
|
Shinya Kitaoka |
120a6e |
return "can't open file";
|
|
Shinya Kitaoka |
120a6e |
case QTCantCreateFile:
|
|
Shinya Kitaoka |
120a6e |
return "can't create movie";
|
|
Shinya Kitaoka |
120a6e |
case QTUnableToGetCompressorNames:
|
|
Shinya Kitaoka |
120a6e |
return "unable to get compressor name";
|
|
Shinya Kitaoka |
120a6e |
case QTUnableToCreateResource:
|
|
Shinya Kitaoka |
120a6e |
return "can't create resource";
|
|
Shinya Kitaoka |
120a6e |
case QTUnableToUpdateMovie:
|
|
Shinya Kitaoka |
120a6e |
return "unable to update movie";
|
|
Shinya Kitaoka |
120a6e |
case QTBadTimeValue:
|
|
Shinya Kitaoka |
120a6e |
return "bad frame number";
|
|
Shinya Kitaoka |
120a6e |
case QTUnableToDoMovieTask:
|
|
Shinya Kitaoka |
120a6e |
return "unable to do movie task";
|
|
Shinya Kitaoka |
120a6e |
case QTUnableToSetTimeValue:
|
|
Shinya Kitaoka |
120a6e |
return "unable to set time value";
|
|
Shinya Kitaoka |
120a6e |
case QTUnableToSetMovieGWorld:
|
|
Shinya Kitaoka |
120a6e |
return "unable to set movie graphic world";
|
|
Shinya Kitaoka |
120a6e |
case QTUnableToSetMovieBox:
|
|
Shinya Kitaoka |
120a6e |
return "unable to set movie box";
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
default: { return "unknown error ('" + std::to_string(ec) + "')"; }
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN2
|
|
Shinya Kitaoka |
120a6e |
inline LPSTR AtlW2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars, UINT acp) {
|
|
Shinya Kitaoka |
120a6e |
assert(lpw != NULL);
|
|
Shinya Kitaoka |
120a6e |
assert(lpa != NULL);
|
|
Shinya Kitaoka |
120a6e |
// verify that no illegal character present
|
|
Shinya Kitaoka |
120a6e |
// since lpa was allocated based on the size of lpw
|
|
Shinya Kitaoka |
120a6e |
// don't worry about the number of chars
|
|
Shinya Kitaoka |
120a6e |
lpa[0] = '\0';
|
|
Shinya Kitaoka |
120a6e |
WideCharToMultiByte(acp, 0, lpw, -1, lpa, nChars, NULL, NULL);
|
|
Shinya Kitaoka |
120a6e |
return lpa;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
string long2fourchar(TINT32 fcc) {
|
|
Shinya Kitaoka |
120a6e |
string s;
|
|
Shinya Kitaoka |
120a6e |
s += (char((fcc & 0xff000000) >> 24));
|
|
Shinya Kitaoka |
120a6e |
s += (char((fcc & 0x00ff0000) >> 16));
|
|
Shinya Kitaoka |
120a6e |
s += (char((fcc & 0x0000ff00) >> 8));
|
|
Shinya Kitaoka |
120a6e |
s += (char((fcc & 0x000000ff) >> 0));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return s;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const string CodecNamesId = "PU_CodecName";
|
|
Toshihiro Shimizu |
890ddd |
const string CodecQualityId = "PU_CodecQuality";
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// TImageWriter3gp
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class TImageWriter3gp : public TImageWriter {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TImageWriter3gp(const TFilePath &, int frameIndex, TLevelWriter3gp *);
|
|
Shinya Kitaoka |
120a6e |
~TImageWriter3gp() { m_lwm->release(); }
|
|
Shinya Kitaoka |
120a6e |
bool is64bitOutputSupported() { return false; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
// not implemented
|
|
Shinya Kitaoka |
120a6e |
TImageWriter3gp(const TImageWriter3gp &);
|
|
Shinya Kitaoka |
120a6e |
TImageWriter3gp &operator=(const TImageWriter3gp &src);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
void save(const TImageP &);
|
|
Shinya Kitaoka |
120a6e |
int m_frameIndex;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
TLevelWriter3gp *m_lwm;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// TImageReader3gp
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
class TImageReader3gp : public TImageReader {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TImageReader3gp(const TFilePath &, int frameIndex, TLevelReader3gp *);
|
|
Shinya Kitaoka |
120a6e |
~TImageReader3gp() { m_lrm->release(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
// not implemented
|
|
Shinya Kitaoka |
120a6e |
TImageReader3gp(const TImageReader3gp &);
|
|
Shinya Kitaoka |
120a6e |
TImageReader3gp &operator=(const TImageReader3gp &src);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TImageP load();
|
|
Shinya Kitaoka |
120a6e |
void load(const TRasterP &rasP, const TPoint &pos = TPoint(0, 0),
|
|
Shinya Kitaoka |
120a6e |
int shrinkX = 1, int shrinkY = 1);
|
|
Shinya Kitaoka |
120a6e |
int m_frameIndex;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDimension getSize() const { return m_lrm->getSize(); }
|
|
Shinya Kitaoka |
120a6e |
TRect getBBox() const { return m_lrm->getBBox(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
TLevelReader3gp *m_lrm;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// TImageWriter3gp
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageWriter3gp::TImageWriter3gp(const TFilePath &path, int frameIndex,
|
|
Shinya Kitaoka |
120a6e |
TLevelWriter3gp *lwm)
|
|
Shinya Kitaoka |
120a6e |
: TImageWriter(path), m_lwm(lwm), m_frameIndex(frameIndex) {
|
|
Shinya Kitaoka |
120a6e |
m_lwm->addRef();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void copy(TRasterP rin, PixelXRGB *bufout, int lx, int ly,
|
|
Shinya Kitaoka |
120a6e |
unsigned short rowbytes = 0) {
|
|
Shinya Kitaoka |
120a6e |
rin->lock();
|
|
Shinya Kitaoka |
120a6e |
TRaster32P rin32 = rin;
|
|
Shinya Kitaoka |
120a6e |
assert(rin32);
|
|
Shinya Kitaoka |
120a6e |
int lineOffset =
|
|
Shinya Kitaoka |
120a6e |
(rowbytes == 0)
|
|
Shinya Kitaoka |
120a6e |
? lx
|
|
Shinya Kitaoka |
120a6e |
: rowbytes / sizeof(PixelXRGB); // in pixelsize, cioe 4 bytes
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
PixelXRGB *rowout = &(bufout[(ly - 1) * lineOffset]) /*-startOffset*/;
|
|
Shinya Kitaoka |
120a6e |
for (int y = 0; y < rin32->getLy(); y++) {
|
|
Shinya Kitaoka |
120a6e |
PixelXRGB *pixout = rowout;
|
|
Shinya Kitaoka |
120a6e |
TPixelRGBM32 *pixin = rin32->pixels(y);
|
|
Shinya Kitaoka |
120a6e |
TPixelRGBM32 *pixinEnd = pixin + rin32->getLx();
|
|
Shinya Kitaoka |
120a6e |
while (pixin < pixinEnd) {
|
|
Shinya Kitaoka |
120a6e |
pixout->x = pixin->m;
|
|
Shinya Kitaoka |
120a6e |
pixout->r = pixin->r;
|
|
Shinya Kitaoka |
120a6e |
pixout->g = pixin->g;
|
|
Shinya Kitaoka |
120a6e |
pixout->b = pixin->b;
|
|
Shinya Kitaoka |
120a6e |
pixout++;
|
|
Shinya Kitaoka |
120a6e |
pixin++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
rowout -= lineOffset;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
rin->unlock();
|
|
Shinya Kitaoka |
120a6e |
} // end function
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
TWriterInfo *TWriterInfo3gp::create(const string &)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return new TWriterInfo3gp();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TWriterInfo3gp::TWriterInfo3gp(const TWriterInfo3gp&src)
|
|
Toshihiro Shimizu |
890ddd |
:TWriterInfo(src)
|
|
Toshihiro Shimizu |
890ddd |
,m_codecTable(src.m_codecTable)
|
|
Toshihiro Shimizu |
890ddd |
,m_qualityTable(src.m_qualityTable)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TWriterInfo *TWriterInfo3gp::clone() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return new TWriterInfo3gp(*this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TWriterInfo3gp::TWriterInfo3gp()
|
|
Toshihiro Shimizu |
890ddd |
:TWriterInfo()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (QuickTimeStuff::instance()->getStatus()!=noErr)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
CodecNameSpecListPtr codecList;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (GetCodecNameList(&codecList, 0) !=noErr)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TIntEnumeration codecNames;
|
|
Toshihiro Shimizu |
890ddd |
for (short i = 0; i < codecList->count; ++i)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
CodecNameSpec *codecNameSpec = &(codecList->List[i]);
|
|
Toshihiro Shimizu |
890ddd |
UCHAR len = codecNameSpec->typeName[0];
|
|
Toshihiro Shimizu |
890ddd |
string name((char*)&codecNameSpec->typeName[1], len);
|
|
Toshihiro Shimizu |
890ddd |
if (name=="None")
|
|
Shinya Kitaoka |
120a6e |
CompressionNoneId = i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
codecNames.addItem(name, i);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_codecTable.insert(CodecTable::value_type(i, codecNameSpec->cType));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DisposeCodecNameList(codecList);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
addProperty(CodecNamesId, codecNames, 0);
|
|
Toshihiro Shimizu |
890ddd |
int q = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TIntEnumeration codecQuality;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
codecQuality.addItem("min quality",q);
|
|
Toshihiro Shimizu |
890ddd |
m_qualityTable.insert(QualityTable::value_type(q++, codecMinQuality));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
codecQuality.addItem("low quality",q);
|
|
Toshihiro Shimizu |
890ddd |
m_qualityTable.insert(QualityTable::value_type(q++, codecLowQuality));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
codecQuality.addItem("max quality",q);
|
|
Toshihiro Shimizu |
890ddd |
m_qualityTable.insert(QualityTable::value_type(q++, codecMaxQuality));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
codecQuality.addItem("normal quality",q);
|
|
Toshihiro Shimizu |
890ddd |
m_qualityTable.insert(QualityTable::value_type(q++, codecNormalQuality));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
codecQuality.addItem("high quality",q);
|
|
Toshihiro Shimizu |
890ddd |
m_qualityTable.insert(QualityTable::value_type(q++, codecHighQuality));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
codecQuality.addItem("lossless quality",q);
|
|
Toshihiro Shimizu |
890ddd |
m_qualityTable.insert(QualityTable::value_type(q++, codecLosslessQuality));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
addProperty(CodecQualityId, codecQuality,0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TWriterInfo3gp::~TWriterInfo3gp()
|
|
Toshihiro Shimizu |
890ddd |
{}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
void TImageWriter3gp::save(const TImageP &img) {
|
|
Shinya Kitaoka |
120a6e |
m_lwm->save(img, m_frameIndex);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
void getFSRefFromPosixPath(const char *filepath, FSRef *fileRef, bool writing) {
|
|
Shinya Kitaoka |
120a6e |
const UInt8 *filename = (const UInt8 *)filepath;
|
|
Shinya Kitaoka |
120a6e |
if (writing) {
|
|
Shinya Kitaoka |
120a6e |
FILE *fp = fopen(filepath, "wb");
|
|
Shinya Kitaoka |
120a6e |
assert(fp);
|
|
Shinya Kitaoka |
120a6e |
fclose(fp);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
OSErr err = FSPathMakeRef(filename, fileRef, 0);
|
|
Shinya Kitaoka |
120a6e |
// assert(err==noErr);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void getFSSpecFromPosixPath(const char *filepath, FSSpec *fileSpec,
|
|
Shinya Kitaoka |
120a6e |
bool writing) {
|
|
Shinya Kitaoka |
120a6e |
FSRef fileRef;
|
|
Shinya Kitaoka |
120a6e |
getFSRefFromPosixPath(filepath, &fileRef, writing);
|
|
Shinya Kitaoka |
120a6e |
OSErr err = FSGetCatalogInfo(&fileRef, kFSCatInfoNone, 0, 0, fileSpec, 0);
|
|
Shinya Kitaoka |
120a6e |
assert(err == noErr);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TLevelWriter3gp::save(const TImageP &img, int frameIndex) {
|
|
Shinya Kitaoka |
120a6e |
if (m_cancelled) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterImageP image(img);
|
|
Shinya Kitaoka |
120a6e |
int lx = image->getRaster()->getLx();
|
|
Shinya Kitaoka |
120a6e |
int ly = image->getRaster()->getLy();
|
|
Shinya Kitaoka |
120a6e |
// void *buffer = image->getRaster()->getRawData();
|
|
Shinya Kitaoka |
120a6e |
int pixSize = image->getRaster()->getPixelSize();
|
|
Shinya Kitaoka |
120a6e |
if (pixSize != 4)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "Unsupported pixel type");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker sl(&m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!m_properties) m_properties = new Tiio::MovWriterProperties();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Tiio::MovWriterProperties *prop = (Tiio::MovWriterProperties *)(m_properties);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// CodecType compression = StandardCompressionType; prop->getCurrentCodec();
|
|
Shinya Kitaoka |
120a6e |
// CodecQ quality = StandardQualityType; prop->getCurrentQuality();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!m_initDone) {
|
|
Shinya Kitaoka |
120a6e |
// FSSpec fspec;
|
|
Shinya Kitaoka |
120a6e |
Rect frame;
|
|
Shinya Kitaoka |
120a6e |
long max_compressed_size;
|
|
Shinya Kitaoka |
120a6e |
QDErr err;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_videoTrack = NewMovieTrack(m_movie, FixRatio((short)lx, 1),
|
|
Shinya Kitaoka |
120a6e |
FixRatio((short)ly, 1), kNoVolume);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if ((err = GetMoviesError() != noErr))
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "can't create video track");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_dataRef = nil;
|
|
Shinya Kitaoka |
120a6e |
m_hMovieData = NewHandle(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Construct the Handle data reference
|
|
Shinya Kitaoka |
120a6e |
err = PtrToHand(&m_hMovieData, &m_dataRef, sizeof(Handle));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if ((err = GetMoviesError() != noErr))
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "can't create Data Ref");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_videoMedia =
|
|
Shinya Kitaoka |
120a6e |
NewTrackMedia(m_videoTrack, VideoMediaType, (TINT32)m_frameRate,
|
|
Shinya Kitaoka |
120a6e |
m_dataRef, HandleDataHandlerSubType);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
OpenADefaultComponent(MovieExportType, '3gpp', &m_myExporter);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// err = (short)MovieExportDoUserDialog(m_myExporter, m_movie, 0, 0, 0,
|
|
Shinya Kitaoka |
120a6e |
// &m_cancelled);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// if (m_cancelled)
|
|
Shinya Kitaoka |
120a6e |
// throw TImageException(getFilePath(), "User abort of 3GP render");
|
|
Shinya Kitaoka |
120a6e |
if ((err = GetMoviesError() != noErr))
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "can't create video media");
|
|
Shinya Kitaoka |
120a6e |
if ((err = BeginMediaEdits(m_videoMedia)) != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "can't begin edit video media");
|
|
Shinya Kitaoka |
120a6e |
frame.left = 0;
|
|
Shinya Kitaoka |
120a6e |
frame.top = 0;
|
|
Shinya Kitaoka |
120a6e |
frame.right = lx;
|
|
Shinya Kitaoka |
120a6e |
frame.bottom = ly;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
if ((err = NewGWorld(&(m_gworld), pixSize * 8, &frame, 0, 0, 0))!=noErr)
|
|
Toshihiro Shimizu |
890ddd |
#else /* Mac OSX 10.7 later */
|
|
Shinya Kitaoka |
120a6e |
if ((err = QTNewGWorld(&(m_gworld), pixSize * 8, &frame, 0, 0, 0)) != noErr)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "can't create movie buffer");
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Shinya Kitaoka |
120a6e |
LockPixels(m_gworld->portPixMap);
|
|
Shinya Kitaoka |
120a6e |
if ((err = GetMaxCompressionSize(m_gworld->portPixMap, &frame, 0, quality,
|
|
Shinya Kitaoka |
120a6e |
compression, anyCodec,
|
|
Shinya Kitaoka |
120a6e |
&max_compressed_size)) != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "can't get max compression size");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
PixMapHandle pixmapH = GetPortPixMap (m_gworld);
|
|
Toshihiro Shimizu |
890ddd |
LockPixels(pixmapH);
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
PixMapHandle pixmapH = NULL;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
max_compressed_size = lx * ly * 4 * 20;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*if ((err = GetMaxCompressionSize(pixmapH, &frame, 0,
|
|
Shinya Kitaoka |
120a6e |
quality, compression,anyCodec,
|
|
Shinya Kitaoka |
120a6e |
&max_compressed_size))!=noErr)
|
|
Toshihiro Shimizu |
890ddd |
throw TImageException(getFilePath(), "can't get max compression size");*/
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_compressedData = NewHandle(max_compressed_size);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if ((err = MemError()) != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(),
|
|
Shinya Kitaoka |
120a6e |
"can't allocate compressed data for movie");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
MoveHHi(m_compressedData);
|
|
Shinya Kitaoka |
120a6e |
HLock(m_compressedData);
|
|
Shinya Kitaoka |
120a6e |
if ((err = MemError()) != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "can't allocate img handle");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
m_pixmap = GetGWorldPixMap(m_gworld);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!LockPixels(m_pixmap))
|
|
Toshihiro Shimizu |
890ddd |
throw TImageException(getFilePath(), "can't lock pixels");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
buf = (PixelXRGB*) GetPixBaseAddr(m_pixmap);
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
m_pixmap = NULL;
|
|
Shinya Kitaoka |
120a6e |
buf = NULL;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
buf_lx = lx;
|
|
Shinya Kitaoka |
120a6e |
buf_ly = ly;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_initDone = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
unsigned short rowBytes =
|
|
Shinya Kitaoka |
120a6e |
(unsigned short)(((short)(*(m_pixmap))->rowBytes & ~(3 << 14)));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Rect frame;
|
|
Shinya Kitaoka |
120a6e |
ImageDescriptionHandle img_descr;
|
|
Shinya Kitaoka |
120a6e |
Ptr compressed_data_ptr;
|
|
Shinya Kitaoka |
120a6e |
QDErr err;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
frame.left = 0;
|
|
Shinya Kitaoka |
120a6e |
frame.top = 0;
|
|
Shinya Kitaoka |
120a6e |
frame.right = lx;
|
|
Shinya Kitaoka |
120a6e |
frame.bottom = ly;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterP ras = image->getRaster();
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Shinya Kitaoka |
120a6e |
compressed_data_ptr = StripAddress(*(m_compressedData));
|
|
Shinya Kitaoka |
120a6e |
copy(ras, buf, buf_lx, buf_ly);
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
compressed_data_ptr = *m_compressedData;
|
|
Shinya Kitaoka |
120a6e |
copy(ras, buf, buf_lx, buf_ly, rowBytes);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
img_descr = (ImageDescriptionHandle)NewHandle(4);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Shinya Kitaoka |
120a6e |
if ((err = CompressImage(m_gworld->portPixMap, &frame, quality, compression,
|
|
Shinya Kitaoka |
120a6e |
img_descr, compressed_data_ptr)) != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "can't compress image");
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
PixMapHandle pixmapH = GetPortPixMap (m_gworld);
|
|
Toshihiro Shimizu |
890ddd |
if ((err = CompressImage(pixmapH,
|
|
Toshihiro Shimizu |
890ddd |
&frame,
|
|
Toshihiro Shimizu |
890ddd |
codecNormalQuality, kJPEGCodecType,
|
|
Toshihiro Shimizu |
890ddd |
img_descr, compressed_data_ptr))!=noErr)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
throw TImageException(getFilePath(), "can't compress image");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if ((err = AddMediaSample(
|
|
Shinya Kitaoka |
120a6e |
m_videoMedia, m_compressedData, 0, (*img_descr)->dataSize, 1,
|
|
Shinya Kitaoka |
120a6e |
(SampleDescriptionHandle)img_descr, 1, 0, 0)) != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "can't add image to movie media");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DisposeHandle((Handle)img_descr);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// TLevelWriterMov
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TLevelWriter3gp::TLevelWriter3gp(const TFilePath &path, TPropertyGroup *winfo)
|
|
Shinya Kitaoka |
120a6e |
: TLevelWriter(path, winfo)
|
|
Shinya Kitaoka |
120a6e |
, m_initDone(false)
|
|
Shinya Kitaoka |
120a6e |
, m_IOError(QTNoError)
|
|
Shinya Kitaoka |
120a6e |
, m_pixmap(0)
|
|
Shinya Kitaoka |
120a6e |
, m_compressedData(0)
|
|
Shinya Kitaoka |
120a6e |
, m_gworld(0)
|
|
Shinya Kitaoka |
120a6e |
, m_videoMedia(0)
|
|
Shinya Kitaoka |
120a6e |
, m_videoTrack(0)
|
|
Shinya Kitaoka |
120a6e |
, m_movie(0)
|
|
Shinya Kitaoka |
120a6e |
, m_cancelled(false)
|
|
Shinya Kitaoka |
120a6e |
, m_soundDataRef(0)
|
|
Shinya Kitaoka |
120a6e |
, m_hSoundMovieData(0)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
m_frameRate = 12.;
|
|
Shinya Kitaoka |
120a6e |
QDErr err;
|
|
Shinya Kitaoka |
120a6e |
// FSSpec fspec;
|
|
Shinya Kitaoka |
120a6e |
if (QuickTimeStuff::instance()->getStatus() != noErr) {
|
|
Shinya Kitaoka |
120a6e |
m_IOError = QTNotInstalled;
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, buildQTErrorString(m_IOError));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_movie = NewMovie(0);
|
|
Shinya Kitaoka |
120a6e |
if ((err = GetMoviesError() != noErr))
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "can't create movie");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
#define FailIf(cond, handler) \
|
|
Shinya Kitaoka |
120a6e |
if (cond) { \
|
|
Shinya Kitaoka |
120a6e |
DebugStr((ConstStr255Param) #cond " goto " #handler); \
|
|
Shinya Kitaoka |
120a6e |
goto handler; \
|
|
Shinya Kitaoka |
120a6e |
} else \
|
|
Shinya Kitaoka |
120a6e |
0
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
#define FailIf(cond, handler) \
|
|
Shinya Kitaoka |
120a6e |
if (cond) { \
|
|
Shinya Kitaoka |
120a6e |
goto handler; \
|
|
Shinya Kitaoka |
120a6e |
} else \
|
|
Shinya Kitaoka |
120a6e |
0
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
#define FailWithAction(cond, action, handler) \
|
|
Shinya Kitaoka |
120a6e |
if (cond) { \
|
|
Shinya Kitaoka |
120a6e |
DebugStr((ConstStr255Param) #cond " goto " #handler); \
|
|
Shinya Kitaoka |
120a6e |
{ action; } \
|
|
Shinya Kitaoka |
120a6e |
goto handler; \
|
|
Shinya Kitaoka |
120a6e |
} else \
|
|
Shinya Kitaoka |
120a6e |
0
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
#define FailWithAction(cond, action, handler) \
|
|
Shinya Kitaoka |
120a6e |
if (cond) { \
|
|
Shinya Kitaoka |
120a6e |
{ action; } \
|
|
Shinya Kitaoka |
120a6e |
goto handler; \
|
|
Shinya Kitaoka |
120a6e |
} else \
|
|
Shinya Kitaoka |
120a6e |
0
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TLevelWriter3gp::saveSoundTrack(TSoundTrack *st) {
|
|
Shinya Kitaoka |
120a6e |
Track theTrack;
|
|
Shinya Kitaoka |
120a6e |
OSErr myErr = noErr;
|
|
Shinya Kitaoka |
120a6e |
SoundDescriptionV1Handle mySampleDesc;
|
|
Shinya Kitaoka |
120a6e |
Media myMedia;
|
|
Shinya Kitaoka |
120a6e |
Handle myDestHandle;
|
|
Shinya Kitaoka |
120a6e |
SoundComponentData sourceInfo;
|
|
Shinya Kitaoka |
120a6e |
SoundComponentData destInfo;
|
|
Shinya Kitaoka |
120a6e |
SoundConverter converter;
|
|
Shinya Kitaoka |
120a6e |
CompressionInfo compressionInfo;
|
|
Shinya Kitaoka |
120a6e |
int err;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!st) throw TException("null reference to soundtrack");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (st->getBitPerSample() != 16) {
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, "Only 16 bits per sample is supported");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
theTrack = NewMovieTrack(m_movie, 0, 0, kFullVolume);
|
|
Shinya Kitaoka |
120a6e |
myErr = GetMoviesError();
|
|
Shinya Kitaoka |
120a6e |
if (myErr != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, "error creating audio track");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FailIf(myErr != noErr, CompressErr);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myDestHandle = NewHandle(0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FailWithAction(myDestHandle == NULL, myErr = MemError(), NoDest);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
*myDestHandle = (char *)st->getRawData();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//////////
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
// create a media for the track passed in
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
//////////
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// set new track to be a sound track
|
|
Shinya Kitaoka |
120a6e |
m_soundDataRef = nil;
|
|
Shinya Kitaoka |
120a6e |
m_hSoundMovieData = NewHandle(0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Construct the Handle data reference
|
|
Shinya Kitaoka |
120a6e |
err = PtrToHand(&m_hSoundMovieData, &m_soundDataRef, sizeof(Handle));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((err = GetMoviesError() != noErr))
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "can't create Data Ref");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myMedia = NewTrackMedia(theTrack, SoundMediaType, st->getSampleRate(),
|
|
Shinya Kitaoka |
120a6e |
m_soundDataRef,
|
|
Shinya Kitaoka |
120a6e |
HandleDataHandlerSubType); // track->rate >> 16
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myErr = GetMoviesError();
|
|
Shinya Kitaoka |
120a6e |
if (myErr != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, "error setting audio track");
|
|
Shinya Kitaoka |
120a6e |
FailIf(myErr != noErr, Exit);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// start a media editing session
|
|
Shinya Kitaoka |
120a6e |
myErr = BeginMediaEdits(myMedia);
|
|
Shinya Kitaoka |
120a6e |
if (myErr != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, "error beginning edit audio track");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FailIf(myErr != noErr, Exit);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
sourceInfo.flags = 0x0;
|
|
Shinya Kitaoka |
120a6e |
sourceInfo.format = kSoundNotCompressed;
|
|
Shinya Kitaoka |
120a6e |
sourceInfo.numChannels = st->getChannelCount();
|
|
Shinya Kitaoka |
120a6e |
sourceInfo.sampleSize = st->getBitPerSample();
|
|
Shinya Kitaoka |
120a6e |
sourceInfo.sampleRate = st->getSampleRate();
|
|
Shinya Kitaoka |
120a6e |
sourceInfo.sampleCount = st->getSampleCount();
|
|
Shinya Kitaoka |
120a6e |
sourceInfo.buffer = (unsigned char *)st->getRawData();
|
|
Shinya Kitaoka |
120a6e |
sourceInfo.reserved = 0x0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
destInfo.flags = kNoSampleRateConversion | kNoSampleSizeConversion |
|
|
Shinya Kitaoka |
120a6e |
kNoSampleFormatConversion | kNoChannelConversion |
|
|
Shinya Kitaoka |
120a6e |
kNoDecompression | kNoVolumeConversion |
|
|
Shinya Kitaoka |
120a6e |
kNoRealtimeProcessing;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
destInfo.format = k16BitNativeEndianFormat;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
destInfo.numChannels = st->getChannelCount();
|
|
Shinya Kitaoka |
120a6e |
destInfo.sampleSize = st->getBitPerSample();
|
|
Shinya Kitaoka |
120a6e |
destInfo.sampleRate = st->getSampleRate();
|
|
Shinya Kitaoka |
120a6e |
destInfo.sampleCount = st->getSampleCount();
|
|
Shinya Kitaoka |
120a6e |
destInfo.buffer = (unsigned char *)st->getRawData();
|
|
Shinya Kitaoka |
120a6e |
destInfo.reserved = 0x0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
SoundConverterOpen(&sourceInfo, &destInfo, &converter);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myErr =
|
|
Shinya Kitaoka |
120a6e |
SoundConverterGetInfo(converter, siCompressionFactor, &compressionInfo);
|
|
Shinya Kitaoka |
120a6e |
if (myErr != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, "error getting audio converter info");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myErr = GetCompressionInfo(fixedCompression, sourceInfo.format,
|
|
Shinya Kitaoka |
120a6e |
sourceInfo.numChannels, sourceInfo.sampleSize,
|
|
Shinya Kitaoka |
120a6e |
&compressionInfo);
|
|
Shinya Kitaoka |
120a6e |
if (myErr != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, "error getting audio compression info");
|
|
Shinya Kitaoka |
120a6e |
FailIf(myErr != noErr, ConverterErr);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
compressionInfo.bytesPerFrame =
|
|
Shinya Kitaoka |
120a6e |
compressionInfo.bytesPerPacket * destInfo.numChannels;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//////////
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
// create a sound sample description
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
//////////
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// use the SoundDescription format 1 because it adds fields for data size
|
|
Shinya Kitaoka |
120a6e |
// information
|
|
Shinya Kitaoka |
120a6e |
// and is required by AddSoundDescriptionExtension if an extension is required
|
|
Shinya Kitaoka |
120a6e |
// for the compression format
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
mySampleDesc =
|
|
Shinya Kitaoka |
120a6e |
(SoundDescriptionV1Handle)NewHandleClear(sizeof(SoundDescriptionV1));
|
|
Shinya Kitaoka |
120a6e |
FailWithAction(myErr != noErr, myErr = MemError(), Exit);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.descSize = sizeof(SoundDescriptionV1);
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.dataFormat = destInfo.format;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.resvd1 = 0;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.resvd2 = 0;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.dataRefIndex = 1;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.version = 1;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.revlevel = 0;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.vendor = 0;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.numChannels = destInfo.numChannels;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.sampleSize = destInfo.sampleSize;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.compressionID = 0;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.packetSize = 0;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).desc.sampleRate = st->getSampleRate() << 16;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).samplesPerPacket = compressionInfo.samplesPerPacket;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).bytesPerPacket = compressionInfo.bytesPerPacket;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).bytesPerFrame = compressionInfo.bytesPerFrame;
|
|
Shinya Kitaoka |
120a6e |
(**mySampleDesc).bytesPerSample = compressionInfo.bytesPerSample;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//////////
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
// add samples to the media
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
//////////
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myErr = AddMediaSample(
|
|
Shinya Kitaoka |
120a6e |
myMedia, myDestHandle, 0,
|
|
Shinya Kitaoka |
120a6e |
destInfo.sampleCount * compressionInfo.bytesPerFrame, 1,
|
|
Shinya Kitaoka |
120a6e |
(SampleDescriptionHandle)mySampleDesc,
|
|
Shinya Kitaoka |
120a6e |
destInfo.sampleCount * compressionInfo.samplesPerPacket, 0, NULL);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (myErr != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, "error adding audio samples");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FailIf(myErr != noErr, MediaErr);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myErr = EndMediaEdits(myMedia);
|
|
Shinya Kitaoka |
120a6e |
if (myErr != noErr) throw TImageException(m_path, "error ending audio edit");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FailIf(myErr != noErr, MediaErr);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//////////
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
// insert the media into the track
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
//////////
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myErr =
|
|
Shinya Kitaoka |
120a6e |
InsertMediaIntoTrack(theTrack, 0, 0, GetMediaDuration(myMedia), fixed1);
|
|
Shinya Kitaoka |
120a6e |
if (myErr != noErr)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, "error inserting audio track");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FailIf(myErr != noErr, MediaErr);
|
|
Shinya Kitaoka |
120a6e |
goto Done;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ConverterErr:
|
|
Toshihiro Shimizu |
890ddd |
NoDest:
|
|
Toshihiro Shimizu |
890ddd |
CompressErr:
|
|
Toshihiro Shimizu |
890ddd |
Exit:
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Done:
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
MediaErr:
|
|
Shinya Kitaoka |
120a6e |
if (mySampleDesc != NULL) DisposeHandle((Handle)mySampleDesc);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (converter) SoundConverterClose(converter);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (myErr != noErr) throw TImageException(m_path, "error saving audio track");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TLevelWriter3gp::~TLevelWriter3gp() {
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
if (m_pixmap)
|
|
Toshihiro Shimizu |
890ddd |
UnlockPixels(m_pixmap);
|
|
Toshihiro Shimizu |
890ddd |
if (m_compressedData)
|
|
Toshihiro Shimizu |
890ddd |
DisposeHandle(m_compressedData);
|
|
Toshihiro Shimizu |
890ddd |
if (m_gworld)
|
|
Toshihiro Shimizu |
890ddd |
DisposeGWorld(m_gworld);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QDErr err;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_videoMedia)
|
|
Shinya Kitaoka |
120a6e |
if ((err = EndMediaEdits(m_videoMedia)) != noErr) {
|
|
Shinya Kitaoka |
120a6e |
} // throw TImageException(getFilePath(), "can't end edit media");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_videoTrack)
|
|
Shinya Kitaoka |
120a6e |
if ((err = InsertMediaIntoTrack(m_videoTrack, 0, 0,
|
|
Shinya Kitaoka |
120a6e |
GetMediaDuration(m_videoMedia), fixed1))) {
|
|
Shinya Kitaoka |
120a6e |
} // throw TImageException(getFilePath(), "can't insert media into track");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
short resId = movieInDataForkResID;
|
|
Shinya Kitaoka |
120a6e |
if (m_movie) {
|
|
Shinya Kitaoka |
120a6e |
FSSpec fspec;
|
|
Shinya Kitaoka |
120a6e |
long myFlags = 0L;
|
|
Shinya Kitaoka |
120a6e |
OSErr myErr = noErr;
|
|
Shinya Kitaoka |
120a6e |
// UCHAR myCancelled = FALSE;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
getFSSpecFromPosixPath(::to_string(m_path).c_str(), &fspec, true);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myFlags = createMovieFileDeleteCurFile; // |
|
|
Shinya Kitaoka |
120a6e |
// movieFileSpecValid | movieToFileOnlyExport;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myErr =
|
|
Shinya Kitaoka |
120a6e |
ConvertMovieToFile(m_movie, // the movie to convert
|
|
Shinya Kitaoka |
120a6e |
NULL, // all tracks in the movie
|
|
Shinya Kitaoka |
120a6e |
&fspec, // the output file
|
|
Shinya Kitaoka |
120a6e |
'3gpp', // the output file type
|
|
Shinya Kitaoka |
120a6e |
FOUR_CHAR_CODE('TVOD'), // the output file creator
|
|
Shinya Kitaoka |
120a6e |
smSystemScript, // the script
|
|
Shinya Kitaoka |
120a6e |
&resId, // no resource ID to be returned
|
|
Shinya Kitaoka |
120a6e |
myFlags, // export flags
|
|
Shinya Kitaoka |
120a6e |
m_myExporter); // no specific exp
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
DisposeHandle(m_hMovieData);
|
|
Shinya Kitaoka |
120a6e |
DisposeHandle(m_dataRef);
|
|
Shinya Kitaoka |
120a6e |
if (m_hSoundMovieData) DisposeHandle(m_hSoundMovieData);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_refNum) CloseMovieFile(m_refNum);
|
|
Shinya Kitaoka |
120a6e |
DisposeMovie(m_movie);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageWriterP TLevelWriter3gp::getFrameWriter(TFrameId fid) {
|
|
Shinya Kitaoka |
120a6e |
if (m_cancelled) return 0;
|
|
Shinya Kitaoka |
120a6e |
if (m_IOError) throw TImageException(m_path, buildQTErrorString(m_IOError));
|
|
Shinya Kitaoka |
120a6e |
if (fid.getLetter() != 0) return TImageWriterP(0);
|
|
Shinya Kitaoka |
120a6e |
int index = fid.getNumber() - 1;
|
|
Shinya Kitaoka |
120a6e |
TImageWriter3gp *iwm = new TImageWriter3gp(m_path, index, this);
|
|
Shinya Kitaoka |
120a6e |
return TImageWriterP(iwm);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TLevelReader3gp::TLevelReader3gp(const TFilePath &path)
|
|
Shinya Kitaoka |
120a6e |
: TLevelReader(path)
|
|
Shinya Kitaoka |
120a6e |
, m_IOError(QTNoError)
|
|
Shinya Kitaoka |
120a6e |
, m_track(0)
|
|
Shinya Kitaoka |
120a6e |
, m_movie(0)
|
|
Shinya Kitaoka |
120a6e |
, m_depth(0)
|
|
Toshihiro Shimizu |
890ddd |
// ,m_timeScale(0)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
FSSpec fspec;
|
|
Shinya Kitaoka |
120a6e |
QDErr err;
|
|
Shinya Kitaoka |
120a6e |
Boolean dataRefWasChanged;
|
|
Shinya Kitaoka |
120a6e |
if (QuickTimeStuff::instance()->getStatus() != noErr) {
|
|
Shinya Kitaoka |
120a6e |
m_IOError = QTNotInstalled;
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::string const str_path = ::to_string(m_path).c_str();
|
|
Shinya Kitaoka |
120a6e |
FSMakeFSSpec(0, 0, reinterpret_cast<unsigned *="" char="" const="">(str_path.c_str()),</unsigned>
|
|
Shinya Kitaoka |
120a6e |
&fspec);
|
|
Shinya Kitaoka |
120a6e |
getFSSpecFromPosixPath(str_path.c_str(), &fspec, false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((err = OpenMovieFile(&fspec, &m_refNum, fsRdPerm))) {
|
|
Shinya Kitaoka |
120a6e |
m_IOError = QTUnableToOpenFile;
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_resId = 0;
|
|
Shinya Kitaoka |
120a6e |
Str255 name;
|
|
Shinya Kitaoka |
120a6e |
err = NewMovieFromFile(&m_movie, m_refNum, &m_resId, name, fsRdPerm,
|
|
Shinya Kitaoka |
120a6e |
&dataRefWasChanged);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int numTracks = GetMovieTrackCount(m_movie);
|
|
Shinya Kitaoka |
120a6e |
assert(numTracks == 1 || numTracks == 2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_track =
|
|
Shinya Kitaoka |
120a6e |
GetMovieIndTrackType(m_movie, 1, VideoMediaType, movieTrackMediaType);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// m_track=GetMovieTrack(m_movie,numTracks);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ImageDescriptionHandle imageH;
|
|
Shinya Kitaoka |
120a6e |
imageH = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription));
|
|
Shinya Kitaoka |
120a6e |
TINT32 index = 1;
|
|
Shinya Kitaoka |
120a6e |
Media theMedia = GetTrackMedia(m_track);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
GetMediaSampleDescription(theMedia, index, (SampleDescriptionHandle)imageH);
|
|
Shinya Kitaoka |
120a6e |
ImageDescriptionPtr imagePtr = *imageH;
|
|
Shinya Kitaoka |
120a6e |
m_lx = imagePtr->width;
|
|
Shinya Kitaoka |
120a6e |
m_ly = imagePtr->height;
|
|
Shinya Kitaoka |
120a6e |
m_depth = imagePtr->depth;
|
|
Shinya Kitaoka |
120a6e |
m_info = new TImageInfo();
|
|
Shinya Kitaoka |
120a6e |
m_info->m_lx = m_lx;
|
|
Shinya Kitaoka |
120a6e |
m_info->m_ly = m_ly;
|
|
Shinya Kitaoka |
120a6e |
Tiio::MovWriterProperties *prop = new Tiio::MovWriterProperties();
|
|
Shinya Kitaoka |
120a6e |
m_info->m_properties = prop;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
DisposeHandle((Handle)imageH);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_info->m_frameRate = GetMediaTimeScale(theMedia);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// TImageReader3gp
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageReader3gp::TImageReader3gp(const TFilePath &path, int frameIndex,
|
|
Shinya Kitaoka |
120a6e |
TLevelReader3gp *lrm)
|
|
Shinya Kitaoka |
120a6e |
: TImageReader(path), m_lrm(lrm), m_frameIndex(frameIndex) {
|
|
Shinya Kitaoka |
120a6e |
m_lrm->addRef();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TLevelReader3gp::~TLevelReader3gp() {
|
|
Shinya Kitaoka |
120a6e |
StopMovie(m_movie);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_refNum) CloseMovieFile(m_refNum);
|
|
Shinya Kitaoka |
120a6e |
if (m_movie) DisposeMovie(m_movie);
|
|
Shinya Kitaoka |
120a6e |
// ExitMovies();
|
|
Shinya Kitaoka |
120a6e |
// TerminateQTML();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TLevelP TLevelReader3gp::loadInfo() {
|
|
Shinya Kitaoka |
120a6e |
TLevelP level;
|
|
Shinya Kitaoka |
120a6e |
if (m_IOError != QTNoError)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, buildQTErrorString(m_IOError));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
OSType mediaType = VisualMediaCharacteristic;
|
|
Shinya Kitaoka |
120a6e |
TimeValue nextTime, currentTime;
|
|
Shinya Kitaoka |
120a6e |
currentTime = 0;
|
|
Shinya Kitaoka |
120a6e |
nextTime = 0;
|
|
Shinya Kitaoka |
120a6e |
// per il primo
|
|
Shinya Kitaoka |
120a6e |
int f = 1;
|
|
Shinya Kitaoka |
120a6e |
// io vorrei fare '|', ma sul manuale c'e' scritto '+'
|
|
Shinya Kitaoka |
120a6e |
GetMovieNextInterestingTime(m_movie, nextTimeMediaSample + nextTimeEdgeOK, 1,
|
|
Shinya Kitaoka |
120a6e |
&mediaType, currentTime, 0, &nextTime, 0);
|
|
Shinya Kitaoka |
120a6e |
if (nextTime != -1) {
|
|
Shinya Kitaoka |
120a6e |
TFrameId frame(f);
|
|
Shinya Kitaoka |
120a6e |
level->setFrame(frame, TImageP());
|
|
Shinya Kitaoka |
120a6e |
currentTimes.push_back(nextTime);
|
|
Shinya Kitaoka |
120a6e |
f++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
currentTime = nextTime;
|
|
Shinya Kitaoka |
120a6e |
while (nextTime != -1) {
|
|
Shinya Kitaoka |
120a6e |
GetMovieNextInterestingTime(m_movie, nextTimeMediaSample, 1, &mediaType,
|
|
Shinya Kitaoka |
120a6e |
currentTime, 0, &nextTime, 0);
|
|
Shinya Kitaoka |
120a6e |
if (nextTime != -1) {
|
|
Shinya Kitaoka |
120a6e |
TFrameId frame(f);
|
|
Shinya Kitaoka |
120a6e |
level->setFrame(frame, TImageP());
|
|
Shinya Kitaoka |
120a6e |
currentTimes.push_back(nextTime);
|
|
Shinya Kitaoka |
120a6e |
f++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
currentTime = nextTime;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return level;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageP TImageReader3gp::load() {
|
|
Shinya Kitaoka |
120a6e |
TRasterPT<tpixelrgbm32> ret(m_lrm->getSize());</tpixelrgbm32>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_lrm->load(ret, m_frameIndex, TPointI(), 1, 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return TRasterImageP(ret);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TImageReader3gp::load(const TRasterP &rasP, const TPoint &pos, int shrinkX,
|
|
Shinya Kitaoka |
120a6e |
int shrinkY) {
|
|
Shinya Kitaoka |
120a6e |
if ((shrinkX != 1) || (shrinkY != 1) || (pos != TPoint(0, 0))) {
|
|
Shinya Kitaoka |
120a6e |
TImageReader::load(rasP, pos, shrinkX, shrinkY);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
m_lrm->load(rasP, m_frameIndex, pos, shrinkX, shrinkY);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
inline void setMatteAndYMirror(const TRaster32P &ras) {
|
|
Shinya Kitaoka |
120a6e |
ras->lock();
|
|
Shinya Kitaoka |
38fd86 |
TPixel32 *upRow = ras->pixels();
|
|
Shinya Kitaoka |
38fd86 |
TPixel32 *dwRow = ras->pixels(ras->getLy() - 1);
|
|
Shinya Kitaoka |
38fd86 |
int hLy = (int)(ras->getLy() / 2. + 0.5); // piccola pessimizzazione...
|
|
Shinya Kitaoka |
38fd86 |
int wrap = ras->getWrap();
|
|
Shinya Kitaoka |
38fd86 |
int lx = ras->getLx();
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *upPix = 0;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *lastPix = ras->pixels(hLy);
|
|
Shinya Kitaoka |
120a6e |
while (upPix < lastPix) {
|
|
Shinya Kitaoka |
120a6e |
upPix = upRow;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *dwPix = dwRow;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *endPix = upPix + lx;
|
|
Shinya Kitaoka |
120a6e |
while (upPix < endPix) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 tmpPix(upPix->r, upPix->g, upPix->b, 0xff);
|
|
Shinya Kitaoka |
120a6e |
*upPix = *dwPix;
|
|
Shinya Kitaoka |
120a6e |
upPix->m = 0xff;
|
|
Shinya Kitaoka |
120a6e |
*dwPix = tmpPix;
|
|
Shinya Kitaoka |
120a6e |
++upPix;
|
|
Shinya Kitaoka |
120a6e |
++dwPix;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
upRow += wrap;
|
|
Shinya Kitaoka |
120a6e |
dwRow -= wrap;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TLevelReader3gp::load(const TRasterP &rasP, int frameIndex,
|
|
Shinya Kitaoka |
120a6e |
const TPoint &pos, int shrinkX, int shrinkY) {
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ras = rasP;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker sl(&m_mutex);
|
|
Shinya Kitaoka |
120a6e |
ras->lock();
|
|
Shinya Kitaoka |
120a6e |
if (m_IOError != QTNoError) goto error;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Rect rect;
|
|
Shinya Kitaoka |
120a6e |
rect.right = pos.x + ras->getLx();
|
|
Shinya Kitaoka |
120a6e |
rect.left = pos.x;
|
|
Shinya Kitaoka |
120a6e |
rect.bottom = pos.y + ras->getLy();
|
|
Shinya Kitaoka |
120a6e |
rect.top = pos.y;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
GWorldPtr offscreenGWorld;
|
|
Shinya Kitaoka |
120a6e |
OSErr err;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined TNZ_MACHINE_CHANNEL_ORDER_BGRM
|
|
Shinya Kitaoka |
120a6e |
OSType pixelFormat = k32BGRAPixelFormat;
|
|
Toshihiro Shimizu |
890ddd |
#elif defined TNZ_MACHINE_CHANNEL_ORDER_MRGB
|
|
Shinya Kitaoka |
120a6e |
OSType pixelFormat = k32ARGBPixelFormat;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
err = QTNewGWorldFromPtr(&offscreenGWorld, pixelFormat, &rect, 0, 0, 0,
|
|
Shinya Kitaoka |
120a6e |
ras->getRawData(), ras->getWrap() * 4);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (err != noErr) {
|
|
Shinya Kitaoka |
120a6e |
m_IOError = QTUnableToCreateResource;
|
|
Shinya Kitaoka |
120a6e |
goto error;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
SetMovieBox(m_movie, &rect);
|
|
Shinya Kitaoka |
120a6e |
err = GetMoviesError();
|
|
Shinya Kitaoka |
120a6e |
if (err != noErr) {
|
|
Shinya Kitaoka |
120a6e |
m_IOError = QTUnableToSetMovieBox;
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
DisposeGWorld(offscreenGWorld);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
goto error;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
SetMovieGWorld(m_movie, offscreenGWorld, GetGWorldDevice(offscreenGWorld));
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
err = GetMoviesError();
|
|
Shinya Kitaoka |
120a6e |
if (err != noErr) {
|
|
Shinya Kitaoka |
120a6e |
m_IOError = QTUnableToSetMovieGWorld;
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
DisposeGWorld(offscreenGWorld);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
goto error;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TimeValue currentTime = currentTimes[frameIndex];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
SetMovieTimeValue(m_movie, currentTime);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
err = GetMoviesError();
|
|
Shinya Kitaoka |
120a6e |
if (err != noErr) {
|
|
Shinya Kitaoka |
120a6e |
m_IOError = QTUnableToSetTimeValue;
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
DisposeGWorld(offscreenGWorld);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
goto error;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
err = UpdateMovie(m_movie);
|
|
Shinya Kitaoka |
120a6e |
if (err != noErr) {
|
|
Shinya Kitaoka |
120a6e |
m_IOError = QTUnableToUpdateMovie;
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
DisposeGWorld(offscreenGWorld);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
goto error;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
MoviesTask(m_movie, 0);
|
|
Shinya Kitaoka |
120a6e |
err = GetMoviesError();
|
|
Shinya Kitaoka |
120a6e |
if (err != noErr) {
|
|
Shinya Kitaoka |
120a6e |
m_IOError = QTUnableToDoMovieTask;
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
DisposeGWorld(offscreenGWorld);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
goto error;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
SetMovieGWorld(m_movie, 0, 0);
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
DisposeGWorld(offscreenGWorld);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_depth != 32) {
|
|
Shinya Kitaoka |
120a6e |
setMatteAndYMirror(rasP);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
rasP->yMirror();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
error:
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, buildQTErrorString(m_IOError));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageReaderP TLevelReader3gp::getFrameReader(TFrameId fid) {
|
|
Shinya Kitaoka |
120a6e |
if (m_IOError != QTNoError)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, buildQTErrorString(m_IOError));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (fid.getLetter() != 0) return TImageReaderP(0);
|
|
Shinya Kitaoka |
120a6e |
int index = fid.getNumber() - 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageReader3gp *irm = new TImageReader3gp(m_path, index, this);
|
|
Shinya Kitaoka |
120a6e |
return TImageReaderP(irm);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
#endif //__LP64__
|