Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef __LP64__
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <iostream></iostream>
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 "timageinfo.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "tmachine.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "movsettings.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tiio_movM.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/* QuickDraw は 10.7 以降なくなった */
Toshihiro Shimizu 890ddd
//#define HAS_QUICKDRAW
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const string firstFrameKey = "frst";
Toshihiro Shimizu 890ddd
const int firstFrameKeySize = 4 * sizeof(char);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class QuickTimeCleanUp;
Toshihiro Shimizu 890ddd
class QuickTimeStuff
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	static QuickTimeStuff *instance()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_singleton)
Toshihiro Shimizu 890ddd
			m_singleton = new QuickTimeStuff();
Toshihiro Shimizu 890ddd
		return m_singleton;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	OSErr getStatus() { return m_status; }
Toshihiro Shimizu 890ddd
	~QuickTimeStuff()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	QuickTimeStuff() : m_status(noErr)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_status = noErr;
Toshihiro Shimizu 890ddd
		EnterMovies();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	static QuickTimeStuff *m_singleton;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	OSErr m_status;
Toshihiro Shimizu 890ddd
	friend class QuickTimeCleanUp; //questa DEVE essere friend, cosi' posso controllare direttamente
Toshihiro Shimizu 890ddd
								   //lo stato del singleton.
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class QuickTimeCleanUp
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	QuickTimeCleanUp() {}
Toshihiro Shimizu 890ddd
	~QuickTimeCleanUp()
Toshihiro Shimizu 890ddd
	{ /*
Toshihiro Shimizu 890ddd
                        Nel caso si arrivasse qui senza il singleton instanziato, e si facesse direttamente
Toshihiro Shimizu 890ddd
                        'delete QuickTimeStuff::instance();' Quicktime non farebbe in tempo a terminare le
Toshihiro Shimizu 890ddd
                        sue routine di inizializzazione (che sono ANCHE su altri thread) e la chiamata a
Toshihiro Shimizu 890ddd
                        TerminateQTML() causerebbe un crash
Toshihiro Shimizu 890ddd
                        */
Toshihiro Shimizu 890ddd
		//std::cout << "destroing variable... Thread = " << GetCurrentThreadId() << std::endl;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//              std::cout <<"~QTCleanup"<< std::endl;
Toshihiro Shimizu 890ddd
		if (QuickTimeStuff::m_singleton)
Toshihiro Shimizu 890ddd
			delete QuickTimeStuff::m_singleton;
Toshihiro Shimizu 890ddd
	}
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 {
Toshihiro Shimizu 890ddd
	QTNoError = 0x0000,
Toshihiro Shimizu 890ddd
	QTNotInstalled,
Toshihiro Shimizu 890ddd
	QTUnknownError,
Toshihiro Shimizu 890ddd
	QTUnableToOpenFile,
Toshihiro Shimizu 890ddd
	QTCantCreateFile,
Toshihiro Shimizu 890ddd
	QTUnableToGetCompressorNames,
Toshihiro Shimizu 890ddd
	QTUnableToCreateResource,
Toshihiro Shimizu 890ddd
	QTUnableToUpdateMovie,
Toshihiro Shimizu 890ddd
	QTBadTimeValue,
Toshihiro Shimizu 890ddd
	QTUnableToDoMovieTask,
Toshihiro Shimizu 890ddd
	QTUnableToSetTimeValue,
Toshihiro Shimizu 890ddd
	QTUnableToSetMovieGWorld,
Toshihiro Shimizu 890ddd
	QTUnableToSetMovieBox,
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
////-----------------------------------------------------------
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//CodecType Tiio::MovWriterProperties::getCurrentCodec()const
Toshihiro Shimizu 890ddd
//{
Toshihiro Shimizu 890ddd
//std::map<wstring, codectype="">::const_iterator it;</wstring,>
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//it = m_codecMap.find(m_codec.getValue());
Toshihiro Shimizu 890ddd
//assert(it!=m_codecMap.end());
Toshihiro Shimizu 890ddd
//return it->second;
Toshihiro Shimizu 890ddd
//}
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
////-----------------------------------------------------------
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//wstring Tiio::MovWriterProperties::getCurrentNameFromCodec(CodecType &cCodec)const
Toshihiro Shimizu 890ddd
//{
Toshihiro Shimizu 890ddd
//std::map<wstring, codectype="">::const_iterator it;</wstring,>
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//for(it=m_codecMap.begin();it!=m_codecMap.end();++it)
Toshihiro Shimizu 890ddd
//{
Toshihiro Shimizu 890ddd
////  CodecType tmp=it->second;
Toshihiro Shimizu 890ddd
//  if(it->second==cCodec) break;
Toshihiro Shimizu 890ddd
//}
Toshihiro Shimizu 890ddd
//assert(it!=m_codecMap.end());
Toshihiro Shimizu 890ddd
//return it->first;
Toshihiro Shimizu 890ddd
//}
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
////-----------------------------------------------------------
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//wstring Tiio::MovWriterProperties::getCurrentQualityFromCodeQ(CodecQ &cCodecQ)const
Toshihiro Shimizu 890ddd
//{
Toshihiro Shimizu 890ddd
//std::map<wstring, codecq="">::const_iterator it;</wstring,>
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//for(it=m_qualityMap.begin();it!=m_qualityMap.end();++it)
Toshihiro Shimizu 890ddd
//{
Toshihiro Shimizu 890ddd
////  CodecQ tmp=it->second;
Toshihiro Shimizu 890ddd
//  if(it->second==cCodecQ) break;
Toshihiro Shimizu 890ddd
//}
Toshihiro Shimizu 890ddd
//assert(it!=m_qualityMap.end());
Toshihiro Shimizu 890ddd
//return it->first;
Toshihiro Shimizu 890ddd
//}
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
////-----------------------------------------------------------
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//CodecQ Tiio::MovWriterProperties::getCurrentQuality() const
Toshihiro Shimizu 890ddd
//{
Toshihiro Shimizu 890ddd
//std::map<wstring, codecq="">::const_iterator it;</wstring,>
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//it = m_qualityMap.find(m_quality.getValue());
Toshihiro Shimizu 890ddd
//assert(it!=m_qualityMap.end());
Toshihiro Shimizu 890ddd
//return it->second;
Toshihiro Shimizu 890ddd
//}
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
////-----------------------------------------------------------
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//TPropertyGroup* Tiio::MovWriterProperties::clone() const
Toshihiro Shimizu 890ddd
//{
Toshihiro Shimizu 890ddd
//  MovWriterProperties*g = new MovWriterProperties();
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//	g->m_codec.setValue(m_codec.getValue());
Toshihiro Shimizu 890ddd
//	g->m_quality.setValue(m_quality.getValue());
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//return (TPropertyGroup*)g;
Toshihiro Shimizu 890ddd
//}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Tiio::MovWriterProperties::MovWriterProperties()
Toshihiro Shimizu 890ddd
//: m_codec("Codec")
Toshihiro Shimizu 890ddd
//, m_quality("Quality")
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (QuickTimeStuff::instance()->getStatus() != noErr) {
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//if (InitializeQTML(0)!=noErr)
Toshihiro Shimizu 890ddd
	//    return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ComponentInstance ci = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
Toshihiro Shimizu 890ddd
	QTAtomContainer settings;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (SCGetSettingsAsAtomContainer(ci, &settings) != noErr)
Toshihiro Shimizu 890ddd
		assert(false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	fromAtomsToProperties(settings, *this);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
CodecNameSpecListPtr codecList;
Toshihiro Shimizu 890ddd
if (GetCodecNameList(&codecList, 0) !=noErr) return;
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
  // codecNameSpec->typeName contains the name of the codec in Pascal String Format
Toshihiro Shimizu 890ddd
  // byte 0 = Len
Toshihiro Shimizu 890ddd
  // byte [1..Len] data
Toshihiro Shimizu 890ddd
  UCHAR len = codecNameSpec->typeName[0];
Toshihiro Shimizu 890ddd
  string name((char*)&codecNameSpec->typeName[1], len);
Toshihiro Shimizu 890ddd
	m_codec.addValue(toWideString(name));
Toshihiro Shimizu 890ddd
	if (i==0) m_codec.setValue(toWideString(name));
Toshihiro Shimizu 890ddd
	m_codecMap[toWideString(name)] = codecNameSpec->cType;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DisposeCodecNameList(codecList);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TIntEnumeration  codecQuality;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
m_quality.addValue(L"min quality"); 
Toshihiro Shimizu 890ddd
      m_qualityMap[L"min quality"] = codecMinQuality;
Toshihiro Shimizu 890ddd
m_quality.addValue(L"low quality");
Toshihiro Shimizu 890ddd
      m_qualityMap[L"low quality"] = codecLowQuality;
Toshihiro Shimizu 890ddd
m_quality.addValue(L"normal quality");
Toshihiro Shimizu 890ddd
      m_qualityMap[L"normal quality"] = codecNormalQuality;
Toshihiro Shimizu 890ddd
m_quality.addValue(L"high quality");
Toshihiro Shimizu 890ddd
      m_qualityMap[L"high quality"] = codecHighQuality;
Toshihiro Shimizu 890ddd
m_quality.addValue(L"max quality");
Toshihiro Shimizu 890ddd
      m_qualityMap[L"max quality"] = codecMaxQuality;
Toshihiro Shimizu 890ddd
m_quality.addValue(L"lossless quality");
Toshihiro Shimizu 890ddd
      m_qualityMap[L"lossless quality"] = codecLosslessQuality;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
m_quality.setValue(L"normal quality");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bind(m_codec);
Toshihiro Shimizu 890ddd
bind(m_quality);
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
m_qualityTable.insert(QualityTable::value_type(q++, codecMinQuality));
Toshihiro Shimizu 890ddd
m_qualityTable.insert(QualityTable::value_type(q++, codecLowQuality));
Toshihiro Shimizu 890ddd
m_qualityTable.insert(QualityTable::value_type(q++, codecMaxQuality));
Toshihiro Shimizu 890ddd
m_qualityTable.insert(QualityTable::value_type(q++, codecNormalQuality));
Toshihiro Shimizu 890ddd
m_qualityTable.insert(QualityTable::value_type(q++, codecHighQuality));
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
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
string buildQTErrorString(int ec)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	switch (ec) {
Toshihiro Shimizu 890ddd
	case QTNotInstalled:
Toshihiro Shimizu 890ddd
		return "Can't create; ensure that quicktime is correctly installed on your machine";
Toshihiro Shimizu 890ddd
	case QTUnknownError:
Toshihiro Shimizu 890ddd
		return "Unknown error";
Toshihiro Shimizu 890ddd
	case QTUnableToOpenFile:
Toshihiro Shimizu 890ddd
		return "can't open file";
Toshihiro Shimizu 890ddd
	case QTCantCreateFile:
Toshihiro Shimizu 890ddd
		return "can't create movie";
Toshihiro Shimizu 890ddd
	case QTUnableToGetCompressorNames:
Toshihiro Shimizu 890ddd
		return "unable to get compressor name";
Toshihiro Shimizu 890ddd
	case QTUnableToCreateResource:
Toshihiro Shimizu 890ddd
		return "can't create resource";
Toshihiro Shimizu 890ddd
	case QTUnableToUpdateMovie:
Toshihiro Shimizu 890ddd
		return "unable to update movie";
Toshihiro Shimizu 890ddd
	case QTBadTimeValue:
Toshihiro Shimizu 890ddd
		return "bad frame number";
Toshihiro Shimizu 890ddd
	case QTUnableToDoMovieTask:
Toshihiro Shimizu 890ddd
		return "unable to do movie task";
Toshihiro Shimizu 890ddd
	case QTUnableToSetTimeValue:
Toshihiro Shimizu 890ddd
		return "unable to set time value";
Toshihiro Shimizu 890ddd
	case QTUnableToSetMovieGWorld:
Toshihiro Shimizu 890ddd
		return "unable to set movie graphic world";
Toshihiro Shimizu 890ddd
	case QTUnableToSetMovieBox:
Toshihiro Shimizu 890ddd
		return "unable to set movie box";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	default: {
Toshihiro Shimizu 890ddd
		return "unknown error ('" + toString(ec) + "')";
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
#ifdef WIN2
Toshihiro Shimizu 890ddd
inline LPSTR AtlW2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars, UINT acp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(lpw != NULL);
Toshihiro Shimizu 890ddd
	assert(lpa != NULL);
Toshihiro Shimizu 890ddd
	// verify that no illegal character present
Toshihiro Shimizu 890ddd
	// since lpa was allocated based on the size of lpw
Toshihiro Shimizu 890ddd
	// don't worry about the number of chars
Toshihiro Shimizu 890ddd
	lpa[0] = '\0';
Toshihiro Shimizu 890ddd
	WideCharToMultiByte(acp, 0, lpw, -1, lpa, nChars, NULL, NULL);
Toshihiro Shimizu 890ddd
	return lpa;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
string long2fourchar(TINT32 fcc)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	string s;
Toshihiro Shimizu 890ddd
	s += (char((fcc & 0xff000000) >> 24));
Toshihiro Shimizu 890ddd
	s += (char((fcc & 0x00ff0000) >> 16));
Toshihiro Shimizu 890ddd
	s += (char((fcc & 0x0000ff00) >> 8));
Toshihiro Shimizu 890ddd
	s += (char((fcc & 0x000000ff) >> 0));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return s;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TimeScale frameRateToTimeScale(double frameRate)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return tround(frameRate * 100.0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const string CodecNamesId = "PU_CodecName";
Toshihiro Shimizu 890ddd
const string CodecQualityId = "PU_CodecQuality";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool IsQuickTimeInstalled()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return QuickTimeStuff::instance()->getStatus() == noErr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//  TImageWriterMov
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class TImageWriterMov : public TImageWriter
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TImageWriterMov(const TFilePath &, int frameIndex, TLevelWriterMov *);
Toshihiro Shimizu 890ddd
	~TImageWriterMov() { m_lwm->release(); }
Toshihiro Shimizu 890ddd
	bool is64bitOutputSupported() { return false; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	//not implemented
Toshihiro Shimizu 890ddd
	TImageWriterMov(const TImageWriterMov &);
Toshihiro Shimizu 890ddd
	TImageWriterMov &operator=(const TImageWriterMov &src);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	void save(const TImageP &);
Toshihiro Shimizu 890ddd
	int m_frameIndex;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	TLevelWriterMov *m_lwm;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
//  TImageReaderMov
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
class TImageReaderMov : public TImageReader
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TImageReaderMov(const TFilePath &, int frameIndex, TLevelReaderMov *);
Toshihiro Shimizu 890ddd
	~TImageReaderMov() { m_lrm->release(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	//not implemented
Toshihiro Shimizu 890ddd
	TImageReaderMov(const TImageReaderMov &);
Toshihiro Shimizu 890ddd
	TImageReaderMov &operator=(const TImageReaderMov &src);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TImageP load();
Toshihiro Shimizu 890ddd
	void load(const TRasterP &rasP, const TPoint &pos = TPoint(0, 0), int shrinkX = 1, int shrinkY = 1);
Toshihiro Shimizu 890ddd
	int m_frameIndex;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TDimension getSize() const { return m_lrm->getSize(); }
Toshihiro Shimizu 890ddd
	TRect getBBox() const { return m_lrm->getBBox(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	TLevelReaderMov *m_lrm;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
//        TImageWriterMov
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TImageWriterMov::TImageWriterMov(const TFilePath &path, int frameIndex, TLevelWriterMov *lwm)
Toshihiro Shimizu 890ddd
	: TImageWriter(path), m_lwm(lwm), m_frameIndex(frameIndex)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_lwm->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void copy(TRasterP rin, PixelXRGB *bufout, int lx, int ly, unsigned short rowbytes = 0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	rin->lock();
Toshihiro Shimizu 890ddd
	TRaster32P rin32 = rin;
Toshihiro Shimizu 890ddd
	assert(rin32);
Toshihiro Shimizu 890ddd
	int lineOffset = (rowbytes == 0) ? lx : rowbytes / sizeof(PixelXRGB); //in pixelsize, cioe 4 bytes
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PixelXRGB *rowout = &(bufout[(ly - 1) * lineOffset]) /*-startOffset*/;
Toshihiro Shimizu 890ddd
	for (int y = 0; y < rin32->getLy(); y++) {
Toshihiro Shimizu 890ddd
		PixelXRGB *pixout = rowout;
Toshihiro Shimizu 890ddd
		TPixelRGBM32 *pixin = rin32->pixels(y);
Toshihiro Shimizu 890ddd
		TPixelRGBM32 *pixinEnd = pixin + rin32->getLx();
Toshihiro Shimizu 890ddd
		while (pixin < pixinEnd) {
Toshihiro Shimizu 890ddd
			pixout->x = pixin->m;
Toshihiro Shimizu 890ddd
			pixout->r = pixin->r;
Toshihiro Shimizu 890ddd
			pixout->g = pixin->g;
Toshihiro Shimizu 890ddd
			pixout->b = pixin->b;
Toshihiro Shimizu 890ddd
			pixout++;
Toshihiro Shimizu 890ddd
			pixin++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		rowout -= lineOffset;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	rin->unlock();
Toshihiro Shimizu 890ddd
} //end function
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
TWriterInfo *TWriterInfoMov::create(const string &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
return new TWriterInfoMov();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TWriterInfoMov::TWriterInfoMov(const TWriterInfoMov&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 *TWriterInfoMov::clone() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
return new TWriterInfoMov(*this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TWriterInfoMov::TWriterInfoMov() 
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
  // codecNameSpec->typeName contains the name of the codec in Pascal String Format
Toshihiro Shimizu 890ddd
  // byte 0 = Len
Toshihiro Shimizu 890ddd
  // byte [1..Len] data
Toshihiro Shimizu 890ddd
  UCHAR len = codecNameSpec->typeName[0];
Toshihiro Shimizu 890ddd
  string name((char*)&codecNameSpec->typeName[1], len);
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
Toshihiro Shimizu 890ddd
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
TWriterInfoMov::~TWriterInfoMov()
Toshihiro Shimizu 890ddd
{}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TImageWriterMov::save(const TImageP &img)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_lwm->save(img, m_frameIndex);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
bool getFSRefFromPosixPath(const char *filepath, FSRef *fileRef, bool writing)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const UInt8 *filename = (const UInt8 *)filepath;
Toshihiro Shimizu 890ddd
	if (writing) {
Toshihiro Shimizu 890ddd
		FILE *fp = fopen(filepath, "wb");
Toshihiro Shimizu 890ddd
		if (!fp)
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
		fclose(fp);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	OSErr err = FSPathMakeRef(filename, fileRef, 0);
Toshihiro Shimizu 890ddd
	return err == noErr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool getFSSpecFromPosixPath(const char *filepath, FSSpec *fileSpec, bool writing)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FSRef fileRef;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!getFSRefFromPosixPath(filepath, &fileRef, writing))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	OSErr err = FSGetCatalogInfo(&fileRef, kFSCatInfoNone, 0, 0, fileSpec, 0);
Toshihiro Shimizu 890ddd
	return err == noErr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TLevelWriterMov::save(const TImageP &img, int frameIndex)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_firstFrame = tmin(frameIndex, m_firstFrame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterImageP image(img);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		throw TImageException(getFilePath(), "Unsupported image type");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int lx = image->getRaster()->getLx();
Toshihiro Shimizu 890ddd
	int ly = image->getRaster()->getLy();
Toshihiro Shimizu 890ddd
	//void *buffer = image->getRaster()->getRawData();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int pixSize = image->getRaster()->getPixelSize();
Toshihiro Shimizu 890ddd
	if (pixSize != 4)
Toshihiro Shimizu 890ddd
		throw TImageException(getFilePath(), "Unsupported pixel type");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMutexLocker sl(&m_mutex);
Toshihiro Shimizu 890ddd
	if (!m_properties)
Toshihiro Shimizu 890ddd
		m_properties = new Tiio::MovWriterProperties();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Tiio::MovWriterProperties *prop = (Tiio::MovWriterProperties *)(m_properties);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
const char* codec = toString(prop->m_codec.getValue()).c_str();
Toshihiro Shimizu 890ddd
const char* qual = toString(prop->m_quality.getValue()).c_str();
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//CodecType codecType;
Toshihiro Shimizu 890ddd
	//try {
Toshihiro Shimizu 890ddd
	//codecType = prop->getCurrentCodec();
Toshihiro Shimizu 890ddd
	//  } catch (...)//boost::bad_any_cast&)
Toshihiro Shimizu 890ddd
	//    {
Toshihiro Shimizu 890ddd
	//    throw TImageException(m_path, "bad codec name");
Toshihiro Shimizu 890ddd
	//    }
Toshihiro Shimizu 890ddd
	//
Toshihiro Shimizu 890ddd
	//CodecQ quality = prop->getCurrentQuality();
Toshihiro Shimizu 890ddd
	QDErr err;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_videoTrack == 0) {
Toshihiro Shimizu 890ddd
		QTAtomContainer atoms;
Toshihiro Shimizu 890ddd
		QTNewAtomContainer(&atoms);
Toshihiro Shimizu 890ddd
		fromPropertiesToAtoms(*prop, atoms);
Toshihiro Shimizu 890ddd
		m_ci = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
Toshihiro Shimizu 890ddd
		if (SCSetSettingsFromAtomContainer(m_ci, atoms) != noErr) {
Toshihiro Shimizu 890ddd
			CloseComponent(m_ci);
Toshihiro Shimizu 890ddd
			assert(!"cannot use that quickTime codec, use default");
Toshihiro Shimizu 890ddd
			m_ci = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		QTDisposeAtomContainer(atoms);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//FSSpec fspec;
Toshihiro Shimizu 890ddd
		Rect frame;
Toshihiro Shimizu 890ddd
		long max_compressed_size;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (QuickTimeStuff::instance()->getStatus() != noErr) {
Toshihiro Shimizu 890ddd
			m_IOError = QTNotInstalled;
Toshihiro Shimizu 890ddd
			throw TImageException(m_path, buildQTErrorString(m_IOError));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// First, set the movie's time scale to match a suitable multiple of m_frameRate.
Toshihiro Shimizu 890ddd
		// The timeScale will be used for both the movie and media.
Toshihiro Shimizu 890ddd
		TimeScale timeScale = ::frameRateToTimeScale(m_frameRate);
Toshihiro Shimizu 890ddd
		SetMovieTimeScale(m_movie, timeScale);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_videoTrack = NewMovieTrack(m_movie, FixRatio((short)lx, 1), FixRatio((short)ly, 1), kNoVolume);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if ((err = GetMoviesError() != noErr))
Toshihiro Shimizu 890ddd
			throw TImageException(getFilePath(), "can't create video track");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_videoMedia = NewTrackMedia(m_videoTrack, VideoMediaType, timeScale, 0, 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if ((err = GetMoviesError() != noErr))
Toshihiro Shimizu 890ddd
			throw TImageException(getFilePath(), "can't create video media");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		frame.left = 0;
Toshihiro Shimizu 890ddd
		frame.top = 0;
Toshihiro Shimizu 890ddd
		frame.right = lx;
Toshihiro Shimizu 890ddd
		frame.bottom = ly;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Toshihiro Shimizu 890ddd
		if ((err = QTNewGWorld(&(m_gworld), pixSize * 8, &frame, 0, 0, 0)) != noErr)
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		if ((err = NewGWorld(&(m_gworld), pixSize * 8, &frame, 0, 0, 0)) != noErr)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
			throw TImageException(getFilePath(), "can't create movie buffer");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//#ifdef WIN32
Toshihiro Shimizu 890ddd
		//  LockPixels(m_gworld->portPixMap);
Toshihiro Shimizu 890ddd
		//  if ((err = GetMaxCompressionSize(m_gworld->portPixMap, &frame, 0,
Toshihiro Shimizu 890ddd
		//                                quality,  compression,anyCodec,
Toshihiro Shimizu 890ddd
		//                         	 &max_compressed_size))!=noErr)
Toshihiro Shimizu 890ddd
		//    throw TImageException(getFilePath(), "can't get max compression size");
Toshihiro Shimizu 890ddd
		//
Toshihiro Shimizu 890ddd
		//#else
Toshihiro Shimizu 890ddd
		//  PixMapHandle pixmapH = GetPortPixMap (m_gworld);
Toshihiro Shimizu 890ddd
		//
Toshihiro Shimizu 890ddd
		//  LockPixels(pixmapH);
Toshihiro Shimizu 890ddd
		//  if ((err = GetMaxCompressionSize(pixmapH, &frame, 0,
Toshihiro Shimizu 890ddd
		//                                quality,  codecType,anyCodec,
Toshihiro Shimizu 890ddd
		//				 &max_compressed_size))!=noErr)
Toshihiro Shimizu 890ddd
		//    throw TImageException(getFilePath(), "can't get max compression size");
Toshihiro Shimizu 890ddd
		//
Toshihiro Shimizu 890ddd
		//#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//m_compressedData = NewHandle(max_compressed_size);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if ((err = MemError()) != noErr)
Toshihiro Shimizu 890ddd
			throw TImageException(getFilePath(), "can't allocate compressed data for movie");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//MoveHHi(m_compressedData);
Toshihiro Shimizu 890ddd
		//HLock(m_compressedData);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if ((err = MemError()) != noErr)
Toshihiro Shimizu 890ddd
			throw TImageException(getFilePath(), "can't allocate img handle");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/* FIXME: QuickDraw とともに無くなったようだ */
Toshihiro Shimizu 890ddd
#if defined(HAS_QUICKDRAW)
Toshihiro Shimizu 890ddd
		m_pixmap = GetGWorldPixMap(m_gworld);
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
#endif
Toshihiro Shimizu 890ddd
		buf_lx = lx;
Toshihiro Shimizu 890ddd
		buf_ly = ly;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((err = BeginMediaEdits(m_videoMedia)) != noErr)
Toshihiro Shimizu 890ddd
		throw TImageException(getFilePath(), "can't begin edit video media");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	unsigned short rowBytes = (unsigned short)(((short)(*(m_pixmap))->rowBytes & ~(3 << 14)));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Rect frame;
Toshihiro Shimizu 890ddd
	ImageDescriptionHandle img_descr = 0;
Toshihiro Shimizu 890ddd
	Handle compressedData = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	frame.left = 0;
Toshihiro Shimizu 890ddd
	frame.top = 0;
Toshihiro Shimizu 890ddd
	frame.right = lx;
Toshihiro Shimizu 890ddd
	frame.bottom = ly;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterP ras = image->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
	compressed_data_ptr = StripAddress(*(m_compressedData));
Toshihiro Shimizu 890ddd
	copy(ras, buf, buf_lx, buf_ly);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	//compressed_data_ptr  = *m_compressedData;
Toshihiro Shimizu 890ddd
	copy(ras, buf, buf_lx, buf_ly, rowBytes);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//img_descr = (ImageDescriptionHandle)NewHandle(4);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
	if ((err = CompressImage(m_gworld->portPixMap,
Toshihiro Shimizu 890ddd
							 &frame,
Toshihiro Shimizu 890ddd
							 quality, compression,
Toshihiro Shimizu 890ddd
							 img_descr, compressed_data_ptr)) != noErr)
Toshihiro Shimizu 890ddd
		throw TImageException(getFilePath(), "can't compress image");
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined(HAS_QUICKDRAW)
Toshihiro Shimizu 890ddd
	PixMapHandle pixmapH = GetPortPixMap(m_gworld);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((err = SCCompressImage(
Toshihiro Shimizu 890ddd
			 m_ci,
Toshihiro Shimizu 890ddd
			 pixmapH,
Toshihiro Shimizu 890ddd
			 &frame,
Toshihiro Shimizu 890ddd
			 &img_descr,
Toshihiro Shimizu 890ddd
			 &compressedData)) != noErr)
Toshihiro Shimizu 890ddd
		throw TImageException(getFilePath(), "can't compress image");
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// if ((err = CompressImage(pixmapH,
Toshihiro Shimizu 890ddd
//	                 &frame,
Toshihiro Shimizu 890ddd
//  			 quality, codecType,
Toshihiro Shimizu 890ddd
//			 img_descr, compressed_data_ptr))!=noErr)
Toshihiro Shimizu 890ddd
//  throw TImageException(getFilePath(), "can't compress image");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TimeValue sampleTime;
Toshihiro Shimizu 890ddd
	if ((err = AddMediaSample(m_videoMedia, compressedData, 0,
Toshihiro Shimizu 890ddd
							  (*img_descr)->dataSize, 100,
Toshihiro Shimizu 890ddd
							  (SampleDescriptionHandle)img_descr,
Toshihiro Shimizu 890ddd
							  1, 0, &sampleTime)) != noErr)
Toshihiro Shimizu 890ddd
		throw TImageException(getFilePath(), "can't add image to movie media");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((err = EndMediaEdits(m_videoMedia)) != noErr)
Toshihiro Shimizu 890ddd
		throw TImageException(getFilePath(), "can't end edit media");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	DisposeHandle(compressedData);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	DisposeHandle((Handle)img_descr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_savedFrames.push_back(std::pair<int, timevalue="">(frameIndex, sampleTime));</int,>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
//        TLevelWriterMov
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TLevelWriterMov::TLevelWriterMov(const TFilePath &path, TPropertyGroup *winfo)
Toshihiro Shimizu 890ddd
	: TLevelWriter(path, winfo), m_IOError(QTNoError), m_pixmap(0)
Toshihiro Shimizu 890ddd
	  //,m_compressedData(0)
Toshihiro Shimizu 890ddd
	  ,
Toshihiro Shimizu 890ddd
	  m_gworld(0), m_videoMedia(0), m_videoTrack(0), m_soundMedia(0), m_soundTrack(0), m_movie(0), m_firstFrame((std::numeric_limits<int>::max)())</int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_frameRate = 12.;
Toshihiro Shimizu 890ddd
	QDErr err;
Toshihiro Shimizu 890ddd
	FSSpec fspec;
Toshihiro Shimizu 890ddd
	if (QuickTimeStuff::instance()->getStatus() != noErr) {
Toshihiro Shimizu 890ddd
		m_IOError = QTNotInstalled;
Toshihiro Shimizu 890ddd
		throw TImageException(m_path, buildQTErrorString(m_IOError));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//  const char *pStr = toString(m_path.getWideString()).c_str();
Toshihiro Shimizu 890ddd
	QString qStr = QString::fromStdWString(m_path.getWideString());
Toshihiro Shimizu 890ddd
	const char *pStr = qStr.toUtf8().data();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//   std::cout << "TLevelWriterMov costruttore FP: " << toString(m_path.getWideString()) << std::endl;
Toshihiro Shimizu 890ddd
	//   std::cout << "TLevelWriterMov costruttore char: " << pStr << std::endl;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!getFSSpecFromPosixPath(pStr, &fspec, true)) {
Toshihiro Shimizu 890ddd
		m_IOError = QTUnableToOpenFile;
Toshihiro Shimizu 890ddd
		throw TImageException(m_path, buildQTErrorString(m_IOError));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Fix: in alcuni rari casi non veniva il mov preesistente
Toshihiro Shimizu 890ddd
	if (TSystem::doesExistFileOrLevel(m_path))
Toshihiro Shimizu 890ddd
		TSystem::deleteFile(m_path);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((err = CreateMovieFile(&fspec, 'TVOD', smCurrentScript,
Toshihiro Shimizu 890ddd
							   createMovieFileDeleteCurFile | createMovieFileDontCreateResFile,
Toshihiro Shimizu 890ddd
							   &(m_refNum), &(m_movie)) != noErr)) {
Toshihiro Shimizu 890ddd
		m_IOError = QTCantCreateFile;
Toshihiro Shimizu 890ddd
		throw TImageException(m_path, buildQTErrorString(m_IOError));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Toshihiro Shimizu 890ddd
#define FailIf(cond, handler)                                      \
Toshihiro Shimizu 890ddd
	if (cond) {                                                    \
Toshihiro Shimizu 890ddd
		/*		DebugStr((ConstStr255Param)#cond " goto " #handler);*/ \
Toshihiro Shimizu 890ddd
		goto handler;                                              \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define FailIf(cond, handler) \
Toshihiro Shimizu 890ddd
	if (cond) {               \
Toshihiro Shimizu 890ddd
		goto handler;         \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Toshihiro Shimizu 890ddd
#define C(cond, action, handler)                                   \
Toshihiro Shimizu 890ddd
	if (cond) {                                                    \
Toshihiro Shimizu 890ddd
		/*		DebugStr((ConstStr255Param)#cond " goto " #handler);*/ \
Toshihiro Shimizu 890ddd
		{                                                          \
Toshihiro Shimizu 890ddd
			action;                                                \
Toshihiro Shimizu 890ddd
		}                                                          \
Toshihiro Shimizu 890ddd
		goto handler;                                              \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define FailWithAction(cond, action, handler) \
Toshihiro Shimizu 890ddd
	if (cond) {                               \
Toshihiro Shimizu 890ddd
		{                                     \
Toshihiro Shimizu 890ddd
			action;                           \
Toshihiro Shimizu 890ddd
		}                                     \
Toshihiro Shimizu 890ddd
		goto handler;                         \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TLevelWriterMov::saveSoundTrack(TSoundTrack *st)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	OSErr myErr = noErr;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//int err;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!st)
Toshihiro Shimizu 890ddd
		throw TException("null reference to soundtrack");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (st->getBitPerSample() != 16) {
Toshihiro Shimizu 890ddd
		throw TImageException(m_path, "Only 16 bits per sample is supported");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_soundTrack == 0) {
Toshihiro Shimizu 890ddd
		m_soundTrack = NewMovieTrack(m_movie, 0, 0, kFullVolume);
Toshihiro Shimizu 890ddd
		myErr = GetMoviesError();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		FailIf(myErr != noErr, CompressErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_soundMedia = NewTrackMedia(m_soundTrack, SoundMediaType, st->getSampleRate(), NULL, 0); //track->rate >> 16
Toshihiro Shimizu 890ddd
		myErr = GetMoviesError();
Toshihiro Shimizu 890ddd
		FailIf(myErr != noErr, Exit);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SoundDescriptionV1Handle mySampleDesc;
Toshihiro Shimizu 890ddd
	Handle myDestHandle;
Toshihiro Shimizu 890ddd
	SoundComponentData sourceInfo;
Toshihiro Shimizu 890ddd
	SoundComponentData destInfo;
Toshihiro Shimizu 890ddd
	SoundConverter converter;
Toshihiro Shimizu 890ddd
	CompressionInfo compressionInfo;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	myDestHandle = NewHandle(0);
Toshihiro Shimizu 890ddd
	FailWithAction(myDestHandle == NULL, myErr = MemError(), NoDest);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	*myDestHandle = (char *)st->getRawData();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// start a media editing session
Toshihiro Shimizu 890ddd
	myErr = BeginMediaEdits(m_soundMedia);
Toshihiro Shimizu 890ddd
	FailIf(myErr != noErr, Exit);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	sourceInfo.flags = 0x0;
Toshihiro Shimizu 890ddd
	sourceInfo.format = kSoundNotCompressed;
Toshihiro Shimizu 890ddd
	sourceInfo.numChannels = st->getChannelCount();
Toshihiro Shimizu 890ddd
	sourceInfo.sampleSize = st->getBitPerSample();
Toshihiro Shimizu 890ddd
	sourceInfo.sampleRate = st->getSampleRate();
Toshihiro Shimizu 890ddd
	sourceInfo.sampleCount = st->getSampleCount();
Toshihiro Shimizu 890ddd
	sourceInfo.buffer = (unsigned char *)st->getRawData();
Toshihiro Shimizu 890ddd
	sourceInfo.reserved = 0x0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	destInfo.flags = kNoSampleRateConversion | kNoSampleSizeConversion |
Toshihiro Shimizu 890ddd
					 kNoSampleFormatConversion | kNoChannelConversion |
Toshihiro Shimizu 890ddd
					 kNoDecompression | kNoVolumeConversion |
Toshihiro Shimizu 890ddd
					 kNoRealtimeProcessing;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	destInfo.format = k16BitNativeEndianFormat;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	destInfo.numChannels = st->getChannelCount();
Toshihiro Shimizu 890ddd
	destInfo.sampleSize = st->getBitPerSample();
Toshihiro Shimizu 890ddd
	destInfo.sampleRate = st->getSampleRate();
Toshihiro Shimizu 890ddd
	destInfo.sampleCount = st->getSampleCount();
Toshihiro Shimizu 890ddd
	destInfo.buffer = (unsigned char *)st->getRawData();
Toshihiro Shimizu 890ddd
	destInfo.reserved = 0x0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SoundConverterOpen(&sourceInfo, &destInfo, &converter);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	myErr = SoundConverterGetInfo(converter, siCompressionFactor, &compressionInfo);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	myErr = SoundConverterGetInfo(converter, siCompressionFactor, &compressionInfo);
Toshihiro Shimizu 890ddd
	myErr = GetCompressionInfo(fixedCompression, sourceInfo.format, sourceInfo.numChannels, sourceInfo.sampleSize, &compressionInfo);
Toshihiro Shimizu 890ddd
	FailIf(myErr != noErr, ConverterErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	compressionInfo.bytesPerFrame = compressionInfo.bytesPerPacket * destInfo.numChannels;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//////////
Toshihiro Shimizu 890ddd
	//
Toshihiro Shimizu 890ddd
	// create a sound sample description
Toshihiro Shimizu 890ddd
	//
Toshihiro Shimizu 890ddd
	//////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// use the SoundDescription format 1 because it adds fields for data size information
Toshihiro Shimizu 890ddd
	// and is required by AddSoundDescriptionExtension if an extension is required for the compression format
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	mySampleDesc = (SoundDescriptionV1Handle)NewHandleClear(sizeof(SoundDescriptionV1));
Toshihiro Shimizu 890ddd
	FailWithAction(myErr != noErr, myErr = MemError(), Exit);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.descSize = sizeof(SoundDescriptionV1);
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.dataFormat = destInfo.format;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.resvd1 = 0;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.resvd2 = 0;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.dataRefIndex = 1;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.version = 1;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.revlevel = 0;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.vendor = 0;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.numChannels = destInfo.numChannels;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.sampleSize = destInfo.sampleSize;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.compressionID = 0;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.packetSize = 0;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).desc.sampleRate = st->getSampleRate() << 16;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).samplesPerPacket = compressionInfo.samplesPerPacket;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).bytesPerPacket = compressionInfo.bytesPerPacket;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).bytesPerFrame = compressionInfo.bytesPerFrame;
Toshihiro Shimizu 890ddd
	(**mySampleDesc).bytesPerSample = compressionInfo.bytesPerSample;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//////////
Toshihiro Shimizu 890ddd
	//
Toshihiro Shimizu 890ddd
	// add samples to the media
Toshihiro Shimizu 890ddd
	//
Toshihiro Shimizu 890ddd
	//////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*if ((err = AddMediaSample(m_videoMedia, compressedData,  0, 
Toshihiro Shimizu 890ddd
	                        (*img_descr)->dataSize, 1, 
Toshihiro Shimizu 890ddd
												  (SampleDescriptionHandle)img_descr, 
Toshihiro Shimizu 890ddd
													1, 0, 0))!=noErr)
Toshihiro Shimizu 890ddd
  throw TImageException(getFilePath(), "can't add image to movie media");*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	myErr = AddMediaSample(m_soundMedia, myDestHandle,
Toshihiro Shimizu 890ddd
						   0,
Toshihiro Shimizu 890ddd
						   destInfo.sampleCount * compressionInfo.bytesPerFrame,
Toshihiro Shimizu 890ddd
						   1,
Toshihiro Shimizu 890ddd
						   (SampleDescriptionHandle)mySampleDesc,
Toshihiro Shimizu 890ddd
						   destInfo.sampleCount * compressionInfo.samplesPerPacket,
Toshihiro Shimizu 890ddd
						   0,
Toshihiro Shimizu 890ddd
						   NULL);
Toshihiro Shimizu 890ddd
	FailIf(myErr != noErr, MediaErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	myErr = EndMediaEdits(m_soundMedia);
Toshihiro Shimizu 890ddd
	FailIf(myErr != noErr, MediaErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//////////
Toshihiro Shimizu 890ddd
	//
Toshihiro Shimizu 890ddd
	// insert the media into the track
Toshihiro Shimizu 890ddd
	//
Toshihiro Shimizu 890ddd
	//////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	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:
Toshihiro Shimizu 890ddd
	if (mySampleDesc != NULL)
Toshihiro Shimizu 890ddd
		DisposeHandle((Handle)mySampleDesc);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (converter)
Toshihiro Shimizu 890ddd
		SoundConverterClose(converter);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (myErr != noErr)
Toshihiro Shimizu 890ddd
		throw TImageException(m_path, "error saving audio track");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TLevelWriterMov::~TLevelWriterMov()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
/* FIXME: */
Toshihiro Shimizu 890ddd
#if defined(HAS_QUICKDRAW)
Toshihiro Shimizu 890ddd
	if (m_pixmap)
Toshihiro Shimizu 890ddd
		UnlockPixels(m_pixmap);
Toshihiro Shimizu 890ddd
	if (m_gworld)
Toshihiro Shimizu 890ddd
		DisposeGWorld(m_gworld);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	if (m_ci)
Toshihiro Shimizu 890ddd
		CloseComponent(m_ci);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QDErr err;
Toshihiro Shimizu 890ddd
	OSStatus mderr;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_videoTrack) {
Toshihiro Shimizu 890ddd
		//Insert the saved Frames into the track. Holes in the frames sequence will be intended as still
Toshihiro Shimizu 890ddd
		//frames.
Toshihiro Shimizu 890ddd
		TimeValue movieTimeScale = GetMovieTimeScale(m_movie);
Toshihiro Shimizu 890ddd
		int savedFramesSize = (int)m_savedFrames.size() - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int i;
Toshihiro Shimizu 890ddd
		for (i = 0; i < savedFramesSize; ++i) {
Toshihiro Shimizu 890ddd
			TimeValue mediaPosition = m_savedFrames[i].second;
Toshihiro Shimizu 890ddd
			TimeValue trackPosition = ((m_savedFrames[i].first - m_firstFrame) * movieTimeScale) / m_frameRate;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TimeValue duration = m_savedFrames[i + 1].first - m_savedFrames[i].first;
Toshihiro Shimizu 890ddd
			Fixed ratio = tround(fixed1 / (double)duration);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if ((err =
Toshihiro Shimizu 890ddd
					 InsertMediaIntoTrack(m_videoTrack, trackPosition, mediaPosition, 100, ratio)) != noErr)
Toshihiro Shimizu 890ddd
				throw TImageException(getFilePath(), "can't insert media into track");
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (savedFramesSize >= 0) {
Toshihiro Shimizu 890ddd
			TimeValue mediaPosition = m_savedFrames[i].second;
Toshihiro Shimizu 890ddd
			TimeValue trackPosition = ((m_savedFrames[i].first - m_firstFrame) * movieTimeScale) / m_frameRate;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			// The last frame has duration 1 (frame):
Toshihiro Shimizu 890ddd
			//   duration = 1  =>  ratio = fixed1
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if ((err =
Toshihiro Shimizu 890ddd
					 InsertMediaIntoTrack(m_videoTrack, trackPosition, mediaPosition, 100, fixed1)) != noErr)
Toshihiro Shimizu 890ddd
				throw TImageException(getFilePath(), "can't insert media into track");
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		QTMetaDataRef metaDataRef;
Toshihiro Shimizu 890ddd
		if ((mderr = QTCopyMovieMetaData(m_movie, &metaDataRef)) != noErr)
Toshihiro Shimizu 890ddd
			throw TImageException(getFilePath(), "can't access metadata informations");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if ((mderr =
Toshihiro Shimizu 890ddd
				 QTMetaDataAddItem(
Toshihiro Shimizu 890ddd
					 metaDataRef,
Toshihiro Shimizu 890ddd
					 kQTMetaDataStorageFormatUserData,
Toshihiro Shimizu 890ddd
					 kQTMetaDataKeyFormatUserData,
Toshihiro Shimizu 890ddd
					 (const UInt8 *)firstFrameKey.c_str(),
Toshihiro Shimizu 890ddd
					 firstFrameKeySize,
Toshihiro Shimizu 890ddd
					 (const UInt8 *)(&m_firstFrame),
Toshihiro Shimizu 890ddd
					 sizeof(int),
Toshihiro Shimizu 890ddd
					 kQTMetaDataTypeUnsignedIntegerBE,
Toshihiro Shimizu 890ddd
					 0)) != noErr)
Toshihiro Shimizu 890ddd
			throw TImageException(getFilePath(), "can't insert metadata informations");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		QTMetaDataRelease(metaDataRef);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_soundTrack) {
Toshihiro Shimizu 890ddd
		if (0 != (err = InsertMediaIntoTrack(m_soundTrack, 0, 0, GetMediaDuration(m_soundMedia), fixed1)))
Toshihiro Shimizu 890ddd
			throw TImageException(getFilePath(), "can't insert sound into track");
Toshihiro Shimizu 890ddd
		//FailIf(err != noErr, MediaErr);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	short resId = movieInDataForkResID;
Toshihiro Shimizu 890ddd
	if (m_movie)
Toshihiro Shimizu 890ddd
		if ((err = AddMovieResource(m_movie, m_refNum, &resId, 0)) != noErr) {
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/**************************************************************************************/
Toshihiro Shimizu 890ddd
#ifdef PROVA3GP
Toshihiro Shimizu 890ddd
	//  char *inputFileName = toString(m_path.getWideString()).c_str();
Toshihiro Shimizu 890ddd
	QString qStr = QString::fromStdWString(m_path.getWideString());
Toshihiro Shimizu 890ddd
	char *inputFileName = qStr.toUtf8().data();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	OSType movieType = FOUR_CHAR_CODE('3gpp');
Toshihiro Shimizu 890ddd
	OSType creator = 'TVOD';
Toshihiro Shimizu 890ddd
	Movie movie;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// get the file
Toshihiro Shimizu 890ddd
	FSSpec inFsSpec;
Toshihiro Shimizu 890ddd
	//NativePathNameToFSSpec(inputFileName, &inFsSpec, 0);
Toshihiro Shimizu 890ddd
	FSMakeFSSpec(0, 0, inputFileName, &inFsSpec);
Toshihiro Shimizu 890ddd
	getFSSpecFromPosixPath(pStr, &inFsSpec, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Initialize Quicktime Movie Toolbox
Toshihiro Shimizu 890ddd
	//EnterMovies ();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// open the movie
Toshihiro Shimizu 890ddd
	short sResRefNum;
Toshihiro Shimizu 890ddd
	OpenMovieFile(&inFsSpec, &sResRefNum, fsRdPerm);
Toshihiro Shimizu 890ddd
	NewMovieFromFile(&movie, sResRefNum, nil, nil, 0, nil);
Toshihiro Shimizu 890ddd
	CloseMovieFile(sResRefNum);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UCHAR myCancelled = FALSE;
Toshihiro Shimizu 890ddd
	MovieExportComponent m_myExporter;
Toshihiro Shimizu 890ddd
	OpenADefaultComponent(MovieExportType, '3gpp', &m_myExporter);
Toshihiro Shimizu 890ddd
	err = (short)MovieExportDoUserDialog(m_myExporter, movie, 0, 0, 0, &myCancelled);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((err != noErr))
Toshihiro Shimizu 890ddd
		throw TImageException(getFilePath(), "can't export 3gp");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FSSpec fspec;
Toshihiro Shimizu 890ddd
	FSMakeFSSpec(0, 0, "C:\\temp\\out.3gp", &fspec);
Toshihiro Shimizu 890ddd
	getFSSpecFromPosixPath(pStr, &fspec, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//NativePathNameToFSSpec	("C:\\temp\\out.3gp", &fspec, kFullNativePath);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	long myFlags = 0L;
Toshihiro Shimizu 890ddd
	myFlags = createMovieFileDeleteCurFile; // |
Toshihiro Shimizu 890ddd
											//movieFileSpecValid | movieToFileOnlyExport;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	err = ConvertMovieToFile(
Toshihiro Shimizu 890ddd
		movie,					// the movie to convert
Toshihiro Shimizu 890ddd
		0,						// all tracks in the movie
Toshihiro Shimizu 890ddd
		&fspec,					// the output file
Toshihiro Shimizu 890ddd
		FOUR_CHAR_CODE('3gpp'), // the output file type
Toshihiro Shimizu 890ddd
		FOUR_CHAR_CODE('TVOD'), // the output file creator
Toshihiro Shimizu 890ddd
		smSystemScript,			// the script
Toshihiro Shimizu 890ddd
		0,						// no resource ID to be returned
Toshihiro Shimizu 890ddd
		myFlags,				// export flags
Toshihiro Shimizu 890ddd
		m_myExporter);			// no specific exp
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
if (sResRefNum)
Toshihiro Shimizu 890ddd
	CloseMovieFile(sResRefNum);
Toshihiro Shimizu 890ddd
DisposeMovie(movie);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
if (m_refNum)
Toshihiro Shimizu 890ddd
	CloseMovieFile(m_refNum);
Toshihiro Shimizu 890ddd
DisposeMovie(m_movie);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TImageWriterP TLevelWriterMov::getFrameWriter(TFrameId fid)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_IOError)
Toshihiro Shimizu 890ddd
		throw TImageException(m_path, buildQTErrorString(m_IOError));
Toshihiro Shimizu 890ddd
	if (fid.getLetter() != 0)
Toshihiro Shimizu 890ddd
		return TImageWriterP(0);
Toshihiro Shimizu 890ddd
	int index = fid.getNumber() - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TImageWriterMov *iwm = new TImageWriterMov(m_path, index, this);
Toshihiro Shimizu 890ddd
	return TImageWriterP(iwm);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TLevelReaderMov::TLevelReaderMov(const TFilePath &path)
Toshihiro Shimizu 890ddd
	: TLevelReader(path), m_IOError(QTNoError), m_track(0), m_movie(0), m_depth(0), m_readAsToonzOutput(false)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//std::cout << "MOVIE PATH : " << toString(path) << std::endl;
Toshihiro Shimizu 890ddd
	FSSpec fspec;
Toshihiro Shimizu 890ddd
	QDErr err;
Toshihiro Shimizu 890ddd
	Boolean dataRefWasChanged;
Toshihiro Shimizu 890ddd
	if (QuickTimeStuff::instance()->getStatus() != noErr) {
Toshihiro Shimizu 890ddd
		m_IOError = QTNotInstalled;
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//	const char *pStr = toString(m_path.getWideString()).c_str();
Toshihiro Shimizu 890ddd
	QString qStr = QString::fromStdWString(m_path.getWideString());
Toshihiro Shimizu 890ddd
	char *pStr = qStr.toUtf8().data();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//FSMakeFSSpec(0, 0,(const unsigned char*)pStr , &fspec);
Toshihiro Shimizu 890ddd
	getFSSpecFromPosixPath(pStr, &fspec, false);
Toshihiro Shimizu 890ddd
	pStr = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((err = OpenMovieFile(&fspec, &m_refNum, fsRdPerm))) {
Toshihiro Shimizu 890ddd
		m_IOError = QTUnableToOpenFile;
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_resId = 0;
Toshihiro Shimizu 890ddd
	Str255 name;
Toshihiro Shimizu 890ddd
	err = NewMovieFromFile(&m_movie, m_refNum, &m_resId,
Toshihiro Shimizu 890ddd
						   name, fsRdPerm, &dataRefWasChanged);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int numTracks = GetMovieTrackCount(m_movie);
Toshihiro Shimizu 890ddd
	//assert(numTracks==1 || numTracks ==2);
Toshihiro Shimizu 890ddd
	m_track = GetMovieIndTrackType(m_movie, 1, VideoMediaType, movieTrackMediaType);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//m_track=GetMovieTrack(m_movie,numTracks);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ImageDescriptionHandle imageH;
Toshihiro Shimizu 890ddd
	imageH = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription));
Toshihiro Shimizu 890ddd
	TINT32 index = 1;
Toshihiro Shimizu 890ddd
	Media theMedia = GetTrackMedia(m_track);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	GetMediaSampleDescription(theMedia, index, (SampleDescriptionHandle)imageH);
Toshihiro Shimizu 890ddd
	ImageDescriptionPtr imagePtr = *imageH;
Toshihiro Shimizu 890ddd
	m_lx = imagePtr->width;
Toshihiro Shimizu 890ddd
	m_ly = imagePtr->height;
Toshihiro Shimizu 890ddd
	m_depth = imagePtr->depth;
Toshihiro Shimizu 890ddd
	m_info = new TImageInfo();
Toshihiro Shimizu 890ddd
	m_info->m_lx = m_lx;
Toshihiro Shimizu 890ddd
	m_info->m_ly = m_ly;
Toshihiro Shimizu 890ddd
	Tiio::MovWriterProperties *prop = new Tiio::MovWriterProperties();
Toshihiro Shimizu 890ddd
	m_info->m_properties = prop;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	DisposeHandle((Handle)imageH);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_info->m_frameRate = GetMediaTimeScale(theMedia) / 100.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
// TImageReaderMov
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TImageReaderMov::TImageReaderMov(const TFilePath &path, int frameIndex, TLevelReaderMov *lrm)
Toshihiro Shimizu 890ddd
	: TImageReader(path), m_lrm(lrm), m_frameIndex(frameIndex)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_lrm->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TLevelReaderMov::~TLevelReaderMov()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	StopMovie(m_movie);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_refNum)
Toshihiro Shimizu 890ddd
		CloseMovieFile(m_refNum);
Toshihiro Shimizu 890ddd
	if (m_movie)
Toshihiro Shimizu 890ddd
		DisposeMovie(m_movie);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TLevelP TLevelReaderMov::loadInfo()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_readAsToonzOutput)
Toshihiro Shimizu 890ddd
		return loadToonzOutputFormatInfo();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TLevelP level;
Toshihiro Shimizu 890ddd
	if (m_IOError != QTNoError)
Toshihiro Shimizu 890ddd
		throw TImageException(m_path, buildQTErrorString(m_IOError));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	OSType mediaType = VisualMediaCharacteristic;
Toshihiro Shimizu 890ddd
	TimeValue nextTime, currentTime;
Toshihiro Shimizu 890ddd
	currentTime = 0;
Toshihiro Shimizu 890ddd
	nextTime = 0;
Toshihiro Shimizu 890ddd
	//per il primo
Toshihiro Shimizu 890ddd
	int f = 0;
Toshihiro Shimizu 890ddd
	// io vorrei fare '|', ma sul manuale c'e' scritto '+'
Toshihiro Shimizu 890ddd
	GetMovieNextInterestingTime(m_movie, nextTimeMediaSample + nextTimeEdgeOK, 1, &mediaType, currentTime, 0, &nextTime, 0);
Toshihiro Shimizu 890ddd
	if (nextTime != -1) {
Toshihiro Shimizu 890ddd
		TFrameId frame(f + 1);
Toshihiro Shimizu 890ddd
		level->setFrame(frame, TImageP());
Toshihiro Shimizu 890ddd
		currentTimes[f] = nextTime;
Toshihiro Shimizu 890ddd
		f++;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	currentTime = nextTime;
Toshihiro Shimizu 890ddd
	while (nextTime != -1) {
Toshihiro Shimizu 890ddd
		GetMovieNextInterestingTime(m_movie, nextTimeMediaSample, 1, &mediaType, currentTime, 0, &nextTime, 0);
Toshihiro Shimizu 890ddd
		if (nextTime != -1) {
Toshihiro Shimizu 890ddd
			TFrameId frame(f + 1);
Toshihiro Shimizu 890ddd
			level->setFrame(frame, TImageP());
Toshihiro Shimizu 890ddd
			currentTimes[f] = nextTime;
Toshihiro Shimizu 890ddd
			f++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		currentTime = nextTime;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return level;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TLevelP TLevelReaderMov::loadToonzOutputFormatInfo()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TLevelP level;
Toshihiro Shimizu 890ddd
	if (m_IOError != QTNoError)
Toshihiro Shimizu 890ddd
		throw TImageException(m_path, buildQTErrorString(m_IOError));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	OSStatus mderr;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Retrieve the first frame of movie. This info has been put in a metadata atom.
Toshihiro Shimizu 890ddd
	QTMetaDataRef metaDataRef;
Toshihiro Shimizu 890ddd
	if ((mderr = QTCopyMovieMetaData(m_movie, &metaDataRef)) != noErr)
Toshihiro Shimizu 890ddd
		throw TImageException(m_path, "can't access metadata informations");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QTMetaDataItem firstFrameItem;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Find the metadata atom
Toshihiro Shimizu 890ddd
	mderr = QTMetaDataGetNextItem(
Toshihiro Shimizu 890ddd
		metaDataRef,
Toshihiro Shimizu 890ddd
		kQTMetaDataStorageFormatUserData,
Toshihiro Shimizu 890ddd
		kQTMetaDataItemUninitialized,
Toshihiro Shimizu 890ddd
		kQTMetaDataKeyFormatUserData,
Toshihiro Shimizu 890ddd
		(const UInt8 *)firstFrameKey.c_str(),
Toshihiro Shimizu 890ddd
		firstFrameKeySize,
Toshihiro Shimizu 890ddd
		&firstFrameItem);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Try to read the value. If the atom was not found, just assume firstFrame = 0.
Toshihiro Shimizu 890ddd
	int firstFrame = 0;
Toshihiro Shimizu 890ddd
	if (mderr == noErr) {
Toshihiro Shimizu 890ddd
		//The atom was found. Then, retrieve the value
Toshihiro Shimizu 890ddd
		if ((mderr =
Toshihiro Shimizu 890ddd
				 QTMetaDataGetItemValue(
Toshihiro Shimizu 890ddd
					 metaDataRef,
Toshihiro Shimizu 890ddd
					 firstFrameItem,
Toshihiro Shimizu 890ddd
					 (UInt8 *)(&firstFrame),
Toshihiro Shimizu 890ddd
					 sizeof(int),
Toshihiro Shimizu 890ddd
					 0) != noErr))
Toshihiro Shimizu 890ddd
			throw TImageException(m_path, "can't read metadata informations");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	mderr = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QTMetaDataRelease(metaDataRef);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	OSType mediaType = VisualMediaCharacteristic;
Toshihiro Shimizu 890ddd
	TimeValue nextTime, currentTime;
Toshihiro Shimizu 890ddd
	currentTime = 0;
Toshihiro Shimizu 890ddd
	nextTime = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TimeValue movieDuration = GetMovieDuration(m_movie);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<timevalue> interestingTimeValues;</timevalue>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// io vorrei fare '|', ma sul manuale c'e' scritto '+'
Toshihiro Shimizu 890ddd
	GetMovieNextInterestingTime(m_movie, nextTimeMediaSample + nextTimeEdgeOK, 1, &mediaType, currentTime, 0, &nextTime, 0);
Toshihiro Shimizu 890ddd
	if (nextTime != -1) {
Toshihiro Shimizu 890ddd
		interestingTimeValues.push_back(nextTime);
Toshihiro Shimizu 890ddd
		currentTime = nextTime;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	while (nextTime != -1) {
Toshihiro Shimizu 890ddd
		GetMovieNextInterestingTime(m_movie, nextTimeMediaSample, 1, &mediaType, currentTime, 0, &nextTime, 0);
Toshihiro Shimizu 890ddd
		if (nextTime != -1) {
Toshihiro Shimizu 890ddd
			interestingTimeValues.push_back(nextTime);
Toshihiro Shimizu 890ddd
			currentTime = nextTime;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (currentTime != -1) {
Toshihiro Shimizu 890ddd
		double frameRate = m_info->m_frameRate;
Toshihiro Shimizu 890ddd
		TimeScale movieTimeScale = GetMovieTimeScale(m_movie);
Toshihiro Shimizu 890ddd
		int firstFrameTimeValue = movieTimeScale * firstFrame;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		std::vector<timevalue>::iterator it;</timevalue>
Toshihiro Shimizu 890ddd
		for (it = interestingTimeValues.begin(); it != interestingTimeValues.end(); ++it) {
Toshihiro Shimizu 890ddd
			int frame = firstFrame + tround((*it * frameRate) / (double)movieTimeScale);
Toshihiro Shimizu 890ddd
			TFrameId frameId(frame + 1);
Toshihiro Shimizu 890ddd
			level->setFrame(frameId, TImageP());
Toshihiro Shimizu 890ddd
			currentTimes[frame] = *it;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return level;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TImageP TImageReaderMov::load()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterPT<tpixelrgbm32> ret(m_lrm->getSize());</tpixelrgbm32>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_lrm->load(ret, m_frameIndex, TPointI(), 1, 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TRasterImageP(ret);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TImageReaderMov::load(const TRasterP &rasP, const TPoint &pos, int shrinkX, int shrinkY)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if ((shrinkX != 1) || (shrinkY != 1) || (pos != TPoint(0, 0))) {
Toshihiro Shimizu 890ddd
		TImageReader::load(rasP, pos, shrinkX, shrinkY);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		m_lrm->load(rasP, m_frameIndex, pos, shrinkX, shrinkY);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
inline void setMatteAndYMirror(const TRaster32P &ras)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ras->lock();
Toshihiro Shimizu 890ddd
	TPixel32 *upRow = ras->pixels();
Toshihiro Shimizu 890ddd
	TPixel32 *dwRow = ras->pixels(ras->getLy() - 1);
Toshihiro Shimizu 890ddd
	int hLy = (int)(ras->getLy() / 2. + 0.5); //piccola pessimizzazione...
Toshihiro Shimizu 890ddd
	int wrap = ras->getWrap();
Toshihiro Shimizu 890ddd
	int lx = ras->getLx();
Toshihiro Shimizu 890ddd
	TPixel32 *upPix = 0;
Toshihiro Shimizu 890ddd
	TPixel32 *lastPix = ras->pixels(hLy);
Toshihiro Shimizu 890ddd
	while (upPix < lastPix) {
Toshihiro Shimizu 890ddd
		upPix = upRow;
Toshihiro Shimizu 890ddd
		TPixel32 *dwPix = dwRow;
Toshihiro Shimizu 890ddd
		TPixel32 *endPix = upPix + lx;
Toshihiro Shimizu 890ddd
		while (upPix < endPix) {
Toshihiro Shimizu 890ddd
			TPixel32 tmpPix(upPix->r, upPix->g, upPix->b, 0xff);
Toshihiro Shimizu 890ddd
			*upPix = *dwPix;
Toshihiro Shimizu 890ddd
			upPix->m = 0xff;
Toshihiro Shimizu 890ddd
			*dwPix = tmpPix;
Toshihiro Shimizu 890ddd
			++upPix;
Toshihiro Shimizu 890ddd
			++dwPix;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		upRow += wrap;
Toshihiro Shimizu 890ddd
		dwRow -= wrap;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	ras->lock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TLevelReaderMov::load(const TRasterP &rasP, int frameIndex, const TPoint &pos, int shrinkX, int shrinkY)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	GWorldPtr offscreenGWorld = 0;
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QMutexLocker sl(&m_mutex);
Toshihiro Shimizu 890ddd
		if (m_IOError != QTNoError)
Toshihiro Shimizu 890ddd
			throw TImageException(m_path, buildQTErrorString(m_IOError));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRaster32P ras = rasP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		Rect rect;
Toshihiro Shimizu 890ddd
		rect.right = pos.x + ras->getLx();
Toshihiro Shimizu 890ddd
		rect.left = pos.x;
Toshihiro Shimizu 890ddd
		rect.bottom = pos.y + ras->getLy();
Toshihiro Shimizu 890ddd
		rect.top = pos.y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		OSErr err;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined TNZ_MACHINE_CHANNEL_ORDER_BGRM
Toshihiro Shimizu 890ddd
		OSType pixelFormat = k32BGRAPixelFormat;
Toshihiro Shimizu 890ddd
#elif defined TNZ_MACHINE_CHANNEL_ORDER_MRGB
Toshihiro Shimizu 890ddd
		OSType pixelFormat = k32ARGBPixelFormat;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		//ras->lock();
Toshihiro Shimizu 890ddd
		err = QTNewGWorldFromPtr(
Toshihiro Shimizu 890ddd
			&offscreenGWorld, pixelFormat,
Toshihiro Shimizu 890ddd
			&rect, 0, 0, 0, ras->getRawData(), ras->getWrap() * 4);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (err != noErr) {
Toshihiro Shimizu 890ddd
			m_IOError = QTUnableToCreateResource;
Toshihiro Shimizu 890ddd
			goto error;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		SetMovieBox(m_movie, &rect);
Toshihiro Shimizu 890ddd
		err = GetMoviesError();
Toshihiro Shimizu 890ddd
		if (err != noErr) {
Toshihiro Shimizu 890ddd
			m_IOError = QTUnableToSetMovieBox;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			goto error;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined(HAS_QUICKDRAW)
Toshihiro Shimizu 890ddd
		SetMovieGWorld(m_movie, offscreenGWorld, GetGWorldDevice(offscreenGWorld));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		err = GetMoviesError();
Toshihiro Shimizu 890ddd
		if (err != noErr) {
Toshihiro Shimizu 890ddd
			m_IOError = QTUnableToSetMovieGWorld;
Toshihiro Shimizu 890ddd
			goto error;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (currentTimes.empty())
Toshihiro Shimizu 890ddd
			loadInfo();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		std::map<int, timevalue="">::iterator it = currentTimes.find(frameIndex);</int,>
Toshihiro Shimizu 890ddd
		if (it == currentTimes.end())
Toshihiro Shimizu 890ddd
			goto error;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TimeValue currentTime = it->second;
Toshihiro Shimizu 890ddd
		SetMovieTimeValue(m_movie, currentTime);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		err = GetMoviesError();
Toshihiro Shimizu 890ddd
		if (err != noErr) {
Toshihiro Shimizu 890ddd
			m_IOError = QTUnableToSetTimeValue;
Toshihiro Shimizu 890ddd
			goto error;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		err = UpdateMovie(m_movie);
Toshihiro Shimizu 890ddd
		if (err != noErr) {
Toshihiro Shimizu 890ddd
			m_IOError = QTUnableToUpdateMovie;
Toshihiro Shimizu 890ddd
			goto error;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		MoviesTask(m_movie, 0);
Toshihiro Shimizu 890ddd
		err = GetMoviesError();
Toshihiro Shimizu 890ddd
		if (err != noErr) {
Toshihiro Shimizu 890ddd
			m_IOError = QTUnableToDoMovieTask;
Toshihiro Shimizu 890ddd
			goto error;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		SetMovieGWorld(m_movie, 0, 0);
Toshihiro Shimizu 890ddd
#if defined(HAS_QUICKDRAW)
Toshihiro Shimizu 890ddd
		DisposeGWorld(offscreenGWorld);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		// ras->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_depth != 32) {
Toshihiro Shimizu 890ddd
		setMatteAndYMirror(rasP);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		rasP->yMirror();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
error:
Toshihiro Shimizu 890ddd
//rasP->unlock();
Toshihiro Shimizu 890ddd
#if defined(HAS_QUICKDRAW)
Toshihiro Shimizu 890ddd
	if (offscreenGWorld)
Toshihiro Shimizu 890ddd
		DisposeGWorld(offscreenGWorld);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	throw TImageException(m_path, buildQTErrorString(m_IOError));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TImageReaderP TLevelReaderMov::getFrameReader(TFrameId fid)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_IOError != QTNoError)
Toshihiro Shimizu 890ddd
		throw TImageException(m_path, buildQTErrorString(m_IOError));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (fid.getLetter() != 0)
Toshihiro Shimizu 890ddd
		return TImageReaderP(0);
Toshihiro Shimizu 890ddd
	int index = fid.getNumber() - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TImageReaderMov *irm = new TImageReaderMov(m_path, index, this);
Toshihiro Shimizu 890ddd
	return TImageReaderP(irm);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif //!__LP64__