#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); }