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