tahoma2d/toonz/sources/image/mov/tiio_movX.cpp
2016-06-15 15:43:10 +09:00

327 lines
9.6 KiB
C++

#include "tiio_movX.h"
#include "traster.h"
#include "trasterimage.h"
#include "tsound.h"
#ifdef NOTE
Supportato solo RGBM32, sotto NT sarebbe possibile supportare anche 1bpp,
ma mancano i TRaster opportuni...
viene supportata
solo(LA PRIMA) traccia video !!!!
#endif
// namespace {
enum QTLibError {
QTNoError = 0x0000,
QTCantCreateParams = 0x0101,
QTCantSetParams = 0x0102,
QTPixelTypeError = 0x0103,
QTCheckLibError = 0x0104
};
string buildQTErrorString(int ec) {
switch (ec) {
case QTCantCreateParams:
return "Unable to create default params";
case QTCantSetParams:
return "Unable to set default params";
case QTPixelTypeError:
return "Unsupported pixel type";
case QTCheckLibError:
return mvGetErrorStr(mvGetErrno());
default:
return "Unknown error";
}
}
//}
//-----------------------------------------------------------
// TImageWriterMov
//-----------------------------------------------------------
class TImageWriterMov : public TImageWriter {
public:
TImageWriterMov(const TFilePath &, int frameIndex, TLevelWriterMov *);
~TImageWriterMov() {}
bool is64bitOutputSupported() { return false; }
private:
// not implemented
TImageWriterMov(const TImageWriterMov &);
TImageWriterMov &operator=(const TImageWriterMov &src);
public:
void save(const TImageP &);
int m_frameIndex;
private:
TLevelWriterMov *m_lwm;
};
//-----------------------------------------------------------
// TImageReaderMov
//-----------------------------------------------------------
class TImageReaderMov : public TImageReader {
public:
TImageReaderMov(const TFilePath &, int frameIndex, TLevelReaderMov *);
~TImageReaderMov() {}
private:
// not implemented
TImageReaderMov(const TImageReaderMov &);
TImageReaderMov &operator=(const TImageReaderMov &src);
public:
TImageP load();
int m_frameIndex;
TDimension getSize() const { return TDimension(m_lrm->m_lx, m_lrm->m_ly); }
TRect getBBox() const {
return TRect(0, 0, m_lrm->m_lx - 1, m_lrm->m_ly - 1);
}
private:
TLevelReaderMov *m_lrm;
};
//-----------------------------------------------------------
//-----------------------------------------------------------
// TImageWriterMov
//-----------------------------------------------------------
TImageWriterMov::TImageWriterMov(const TFilePath &path, int frameIndex,
TLevelWriterMov *lwm)
: TImageWriter(path), m_lwm(lwm), m_frameIndex(frameIndex) {}
//-----------------------------------------------------------
void TImageWriterMov::save(const TImageP &img) {
TRasterImageP image(img);
int lx = image->getRaster()->getLx();
int ly = image->getRaster()->getLy();
void *buffer = image->getRaster()->getRawData();
int pixSize = image->getRaster()->getPixelSize();
if (pixSize != 4)
throw TImageException(m_lwm->getFilePath(), "Unsupported pixel type");
if (!m_lwm->m_initDone) {
DMparams *imageTrackParams;
if (dmParamsCreate(&imageTrackParams) != DM_SUCCESS)
throw TImageException(m_lwm->getFilePath(),
"Unable to create image track params");
if (dmSetImageDefaults(imageTrackParams, lx, ly, DM_IMAGE_PACKING_XRGB) !=
DM_SUCCESS) {
dmParamsDestroy(imageTrackParams);
throw TImageException(m_lwm->getFilePath(),
"Unable to set image defaults");
}
if (dmParamsSetFloat(imageTrackParams, DM_IMAGE_RATE,
(double)m_lwm->m_rate) != DM_SUCCESS) {
dmParamsDestroy(imageTrackParams);
throw TImageException(m_lwm->getFilePath(), "Unable to set frame rate");
}
if (dmParamsSetEnum(imageTrackParams, DM_IMAGE_ORIENTATION,
DM_TOP_TO_BOTTOM) != DM_SUCCESS) {
dmParamsDestroy(imageTrackParams);
throw TImageException(m_lwm->getFilePath(), "Unable to set frame rate");
}
if (dmParamsSetFloat(imageTrackParams, DM_IMAGE_QUALITY_SPATIAL,
m_lwm->quality) != DM_SUCCESS) {
dmParamsDestroy(imageTrackParams);
throw TImageException(m_lwm->getFilePath(), "Unable to set quality");
}
if (dmParamsSetString(imageTrackParams, DM_IMAGE_COMPRESSION,
m_lwm->compression) != DM_SUCCESS) {
dmParamsDestroy(imageTrackParams);
throw TImageException(m_lwm->getFilePath(), "Unable to set compression");
}
if (mvAddTrack(m_lwm->id, DM_IMAGE, imageTrackParams, NULL,
&(m_lwm->imageTrack)) == DM_FAILURE) {
dmParamsDestroy(imageTrackParams);
throw TImageException(m_lwm->getFilePath(),
"Unable to add image track to movie");
}
dmParamsDestroy(imageTrackParams);
m_lwm->m_initDone = true;
}
if (mvInsertFrames(m_lwm->imageTrack, m_frameIndex, 1, lx * ly * pixSize,
buffer) != DM_SUCCESS) {
throw TImageException(m_lwm->getFilePath(),
"Unable to write image to movie");
}
}
//-----------------------------------------------------------
// TLevelWriterMov
//-----------------------------------------------------------
class TWriterInfoMov : public TWriterInfo {
public:
TWriterInfoMov() : TWriterInfo() { assert(!"Not implemented"); }
~TWriterInfoMov() {}
private:
};
//-----------------------------------------------------------
TLevelWriterMov::TLevelWriterMov(const TFilePath &path)
: TLevelWriter(path)
, m_initDone(false)
, m_rate(25)
, m_IOError(QTNoError)
, quality(DM_IMAGE_QUALITY_NORMAL)
, compression(DM_IMAGE_QT_ANIM)
, m_writerInfo(new TWriterInfoMov()) {
DMparams *movieParams;
if (dmParamsCreate(&movieParams) != DM_SUCCESS) {
m_IOError = QTCantCreateParams;
return;
}
if (mvSetMovieDefaults(movieParams, MV_FORMAT_QT) != DM_SUCCESS) {
dmParamsDestroy(movieParams);
m_IOError = QTCantCreateParams;
return;
}
if (mvCreateFile(path.getFullPath().c_str(), movieParams, NULL, &id) ==
DM_FAILURE) {
static char m[1024];
dmParamsDestroy(movieParams);
m_IOError = QTCheckLibError;
return;
}
dmParamsDestroy(movieParams);
}
//-----------------------------------------------------------
void TLevelWriterMov::saveSoundTrack(TSoundTrack *) {
throw TImageException(m_path,
"TLevelWriterMov::saveSoundTrack not Implemented");
}
//-----------------------------------------------------------
TWriterInfo *TLevelWriterMov::getWriterInfo() const { return m_writerInfo; }
//-----------------------------------------------------------
TLevelWriterMov::~TLevelWriterMov() {
bool rc = (mvClose(id) == DM_SUCCESS);
// if (!rc)
// throw TImageException(getFilePath(), "Error closing mov file");
}
//-----------------------------------------------------------
TImageWriterP TLevelWriterMov::getFrameWriter(TFrameId fid) {
if (m_IOError) throw TImageException(m_path, buildQTErrorString(m_IOError));
if (fid.getLetter() != 0) return TImageWriterP(0);
int index = fid.getNumber() - 1;
TImageWriterMov *iwm = new TImageWriterMov(m_path, index, this);
return TImageWriterP(iwm);
}
//-----------------------------------------------------------
TLevelReaderMov::TLevelReaderMov(const TFilePath &path)
: TLevelReader(path)
, IOError(QTNoError)
{
m_status = mvOpenFile(path.getFullPath().c_str(), O_RDONLY, &movie);
if (m_status != DM_SUCCESS) {
IOError = QTCheckLibError;
return;
}
track = 0;
m_status = mvFindTrackByMedium(movie, DM_IMAGE, &track);
if (m_status != DM_SUCCESS) {
IOError = QTCheckLibError;
return;
}
m_lx = mvGetImageWidth(track);
m_ly = mvGetImageHeight(track);
DMpacking packing = mvGetImagePacking(track);
if (packing != DM_IMAGE_PACKING_XRGB) {
IOError = QTPixelTypeError;
return;
}
}
//------------------------------------------------
//------------------------------------------------
// TImageReaderMov
//------------------------------------------------
TImageReaderMov::TImageReaderMov(const TFilePath &path, int frameIndex,
TLevelReaderMov *lrm)
: TImageReader(path), m_lrm(lrm), m_frameIndex(frameIndex) {}
//------------------------------------------------
TLevelReaderMov::~TLevelReaderMov() { mvClose(movie); }
//------------------------------------------------
TLevelP TLevelReaderMov::loadInfo() {
TLevelP level;
if (IOError != QTNoError)
throw TImageException(m_path, buildQTErrorString(IOError));
if (!track)
throw TImageException(getFilePath().getFullPath().c_str(),
" error reading info");
MVframe nFrames = mvGetTrackLength(track);
if (nFrames == -1) return level;
for (int i = 1; i <= nFrames; i++) level->setFrame(TFrameId(i), TImageP());
return level;
}
//------------------------------------------------
TImageP TImageReaderMov::load() {
TRaster32P ret(m_lrm->m_lx, m_lrm->m_ly);
DMstatus status =
mvReadFrames(m_lrm->track, m_frameIndex, 1, m_lrm->m_lx * m_lrm->m_ly * 4,
ret->getRawData());
if (status != DM_SUCCESS) {
throw TImageException(getFilePath().getFullPath().c_str(),
mvGetErrorStr(mvGetErrno()));
}
// getImage()->setRaster(ret);
return TRasterImageP(ret);
}
//------------------------------------------------
TImageReaderP TLevelReaderMov::getFrameReader(TFrameId fid) {
if (IOError != QTNoError)
throw TImageException(m_path, buildQTErrorString(IOError));
if (fid.getLetter() != 0) return TImageReaderP(0);
int index = fid.getNumber() - 1;
TImageReaderMov *irm = new TImageReaderMov(m_path, index, this);
return TImageReaderP(irm);
}