Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/menubarcommand.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/viewcommandids.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/imageutils.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/dvdialog.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/gutil.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "toonz/namebuilder.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/tproject.h"
Toshihiro Shimizu 890ddd
#include "toonz/Naa2TlvConverter.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
#include "avicodecrestrictions.h"
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tfilepath_io.h"
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
#include "tlevel.h"
Toshihiro Shimizu 890ddd
#include "tlevel_io.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "tvectorrenderdata.h"
Toshihiro Shimizu 890ddd
#include "tofflinegl.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "timageinfo.h"
Toshihiro Shimizu 890ddd
#include "tfiletype.h"
Toshihiro Shimizu 890ddd
#include "tfilepath.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include <qapplication></qapplication>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// boost includes
Toshihiro Shimizu 890ddd
#include <boost iterator="" transform_iterator.hpp=""></boost>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**********************************************************************************
Toshihiro Shimizu 890ddd
//    Local namespace  stuff
Toshihiro Shimizu 890ddd
//**********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void addOverlappedRegions(TRegion *reg, vector<tfilledregioninf> ®Inf)</tfilledregioninf>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	regInf.push_back(TFilledRegionInf(reg->getId(), reg->getStyle()));
Toshihiro Shimizu 890ddd
	UINT regNum = reg->getSubregionCount();
Toshihiro Shimizu 890ddd
	for (UINT i = 0; i < regNum; i++)
Toshihiro Shimizu 890ddd
		addOverlappedRegions(reg->getSubregion(i), regInf);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void addRegionsInArea(TRegion *reg, vector<tfilledregioninf> ®s, const TRectD &area)</tfilledregioninf>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (area.contains(reg->getBBox()))
Toshihiro Shimizu 890ddd
		regs.push_back(TFilledRegionInf(reg->getId(), reg->getStyle()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (reg->getBBox().overlaps(area)) {
Toshihiro Shimizu 890ddd
		UINT regNum = reg->getSubregionCount();
Toshihiro Shimizu 890ddd
		for (UINT i = 0; i < regNum; i++)
Toshihiro Shimizu 890ddd
			addRegionsInArea(reg->getSubregion(i), regs, area);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void getFrameIds(TFrameId from, TFrameId to, const TLevelP &level,
Toshihiro Shimizu 890ddd
				 std::vector<tframeid> &frames)</tframeid>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
		static inline TFrameId getFrame(const TLevel::Table::value_type &pair)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			return pair.first;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}; // locals
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (from.isEmptyFrame())
Toshihiro Shimizu 890ddd
		from = TFrameId(-(std::numeric_limits<int>::max)());</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (to.isEmptyFrame())
Toshihiro Shimizu 890ddd
		to = TFrameId((std::numeric_limits<int>::max)());</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (from > to)
Toshihiro Shimizu 890ddd
		tswap(from, to);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const TLevel::Table &table = *level->getTable();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TLevel::Table::const_iterator lBegin = table.lower_bound(from),
Toshihiro Shimizu 890ddd
								  lEnd = table.upper_bound(to);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(frames.empty());
Toshihiro Shimizu 890ddd
	frames.insert(frames.end(), boost::make_transform_iterator(lBegin, locals::getFrame),
Toshihiro Shimizu 890ddd
				  boost::make_transform_iterator(lEnd, locals::getFrame));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**********************************************************************************
Toshihiro Shimizu 890ddd
//    ImageUtils namespace  stuff
Toshihiro Shimizu 890ddd
//**********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace ImageUtils
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// todo: spostare da qualche altra parte. rendere accessibile a tutti. utilizzare
Toshihiro Shimizu 890ddd
// anche nella libreria dovunque si usi direttamente "_files"
Toshihiro Shimizu 890ddd
TFilePath getResourceFolder(const TFilePath &scenePath)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return scenePath.getParentDir() + (scenePath.getName() + "_files");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void copyScene(const TFilePath &dst, const TFilePath &src)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TSystem::copyFile(dst, src);
Toshihiro Shimizu 890ddd
	if (TProjectManager::instance()->isTabModeEnabled())
Toshihiro Shimizu 890ddd
		TSystem::copyDir(getResourceFolder(dst), getResourceFolder(src));
Toshihiro Shimizu 890ddd
	TFilePath srcIcon = ToonzScene::getIconPath(src);
Toshihiro Shimizu 890ddd
	if (TFileStatus(srcIcon).doesExist()) {
Toshihiro Shimizu 890ddd
		TFilePath dstIcon = ToonzScene::getIconPath(dst);
Toshihiro Shimizu 890ddd
		TSystem::copyFile(dstIcon, srcIcon);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFilePath duplicate(const TFilePath &levelPath)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (levelPath == TFilePath())
Toshihiro Shimizu 890ddd
		return TFilePath();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!TSystem::doesExistFileOrLevel(levelPath)) {
Toshihiro Shimizu 890ddd
		MsgBox(WARNING, QObject::tr("It is not possible to find the %1 level.").arg(QString::fromStdWString(levelPath.getWideString())));
Toshihiro Shimizu 890ddd
		return TFilePath();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	NameBuilder *nameBuilder = NameBuilder::getBuilder(toWideString(levelPath.getName()));
Toshihiro Shimizu 890ddd
	wstring levelNameOut;
Toshihiro Shimizu 890ddd
	do
Toshihiro Shimizu 890ddd
		levelNameOut = nameBuilder->getNext();
Toshihiro Shimizu 890ddd
	while (TSystem::doesExistFileOrLevel(levelPath.withName(levelNameOut)));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePath levelPathOut = levelPath.withName(levelNameOut);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		if (levelPath.getType() == "tnz")
Toshihiro Shimizu 890ddd
			copyScene(levelPathOut, levelPath);
Toshihiro Shimizu 890ddd
		else {
Toshihiro Shimizu 890ddd
			TSystem::copyFileOrLevel_throw(levelPathOut, levelPath);
Toshihiro Shimizu 890ddd
			if (levelPath.getType() == "tlv") {
Toshihiro Shimizu 890ddd
				TFilePath pltPath = levelPath.withType("tpl");
Toshihiro Shimizu 890ddd
				if (TSystem::doesExistFileOrLevel(pltPath))
Toshihiro Shimizu 890ddd
					TSystem::copyFileOrLevel_throw(levelPathOut.withType("tpl"), pltPath);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} catch (...) {
Toshihiro Shimizu 890ddd
		QString msg = QObject::tr("There was an error copying %1").arg(toQString(levelPath));
Toshihiro Shimizu 890ddd
		MsgBox(CRITICAL, msg);
Toshihiro Shimizu 890ddd
		return TFilePath();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//  QString msg = QString("Copied ") +
Toshihiro Shimizu 890ddd
	//                QString::fromStdWString(levelPath.withoutParentDir().getWideString()) +
Toshihiro Shimizu 890ddd
	//                QString(" to " +
Toshihiro Shimizu 890ddd
	//                QString::fromStdWString(levelPathOut.withoutParentDir().getWideString()));
Toshihiro Shimizu 890ddd
	//  MsgBox(INFORMATION,msg);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return levelPathOut;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void premultiply(const TFilePath &levelPath)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (levelPath == TFilePath())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!TSystem::doesExistFileOrLevel(levelPath)) {
Toshihiro Shimizu 890ddd
		MsgBox(WARNING, QObject::tr("It is not possible to find the level %1").arg(QString::fromStdWString(levelPath.getWideString())));
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFileType::Type type = TFileType::getInfo(levelPath);
Toshihiro Shimizu 890ddd
	if (type == TFileType::CMAPPED_LEVEL) {
Toshihiro Shimizu 890ddd
		MsgBox(WARNING, QObject::tr("Cannot premultiply the selected file."));
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (type == TFileType::VECTOR_LEVEL || type == TFileType::VECTOR_IMAGE) {
Toshihiro Shimizu 890ddd
		MsgBox(WARNING, QObject::tr("Cannot premultiply a vector-based level."));
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (type != TFileType::RASTER_LEVEL && type != TFileType::RASTER_IMAGE) {
Toshihiro Shimizu 890ddd
		MsgBox(INFORMATION, QObject::tr("Cannot premultiply the selected file."));
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		TLevelReaderP lr = TLevelReaderP(levelPath);
Toshihiro Shimizu 890ddd
		if (!lr)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TLevelP level = lr->loadInfo();
Toshihiro Shimizu 890ddd
		if (!level || level->getFrameCount() == 0)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		bool isMovie = type == TFileType::RASTER_LEVEL;
Toshihiro Shimizu 890ddd
		/*  
Toshihiro Shimizu 890ddd
    if (!isMovie && lr->getImageInfo()->m_samplePerPixel!=4)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    QMessageBox::information(0, QString("ERROR"), QString("Only rgbm images can be premultiplied!"));
Toshihiro Shimizu 890ddd
    return;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
    */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TLevelWriterP lw;
Toshihiro Shimizu 890ddd
		if (!isMovie) {
Toshihiro Shimizu 890ddd
			lw = TLevelWriterP(levelPath);
Toshihiro Shimizu 890ddd
			if (!lw)
Toshihiro Shimizu 890ddd
				return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
Toshihiro Shimizu 890ddd
		qApp->processEvents();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int count = 0;
Toshihiro Shimizu 890ddd
		TLevel::Iterator it = level->begin();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (; it != level->end(); ++it) {
Toshihiro Shimizu 890ddd
			TImageReaderP ir = lr->getFrameReader(it->first);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRasterImageP rimg = (TRasterImageP)ir->load();
Toshihiro Shimizu 890ddd
			if (!rimg)
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRop::premultiply(rimg->getRaster());
Toshihiro Shimizu 890ddd
			ir = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (isMovie)
Toshihiro Shimizu 890ddd
				level->setFrame(it->first, rimg);
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				TImageWriterP iw = lw->getFrameWriter(it->first);
Toshihiro Shimizu 890ddd
				iw->save(levelPath.withFrame(it->first), rimg);
Toshihiro Shimizu 890ddd
				iw = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		lr = TLevelReaderP();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (isMovie) {
Toshihiro Shimizu 890ddd
			TSystem::deleteFile(levelPath);
Toshihiro Shimizu 890ddd
			lw = TLevelWriterP(levelPath);
Toshihiro Shimizu 890ddd
			if (!lw) {
Toshihiro Shimizu 890ddd
				QApplication::restoreOverrideCursor();
Toshihiro Shimizu 890ddd
				return;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			lw->save(level);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} catch (...) {
Toshihiro Shimizu 890ddd
		MsgBox(WARNING, QObject::tr("Cannot premultiply the selected file."));
Toshihiro Shimizu 890ddd
		QApplication::restoreOverrideCursor();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QApplication::restoreOverrideCursor();
Toshihiro Shimizu 890ddd
	QString msg = QObject::tr("Level %1 premultiplied.").arg(QString::fromStdString(levelPath.getLevelName()));
Toshihiro Shimizu 890ddd
	MsgBox(INFORMATION, msg);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void getFillingInformationOverlappingArea(
Toshihiro Shimizu 890ddd
	const TVectorImageP &vi,
Toshihiro Shimizu 890ddd
	vector<tfilledregioninf> ®Inf,</tfilledregioninf>
Toshihiro Shimizu 890ddd
	const TRectD &area1,
Toshihiro Shimizu 890ddd
	const TRectD &area2)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!vi->isComputedRegionAlmostOnce())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(area1 != TRectD() || area2 != TRectD());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vi->findRegions();
Toshihiro Shimizu 890ddd
	UINT regNum = vi->getRegionCount();
Toshihiro Shimizu 890ddd
	TRegion *reg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (UINT i = 0; i < regNum; i++) {
Toshihiro Shimizu 890ddd
		reg = vi->getRegion(i);
Toshihiro Shimizu 890ddd
		if (reg->getBBox().overlaps(area1) || reg->getBBox().overlaps(area2))
Toshihiro Shimizu 890ddd
			addOverlappedRegions(reg, regInf);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void getFillingInformationInArea(
Toshihiro Shimizu 890ddd
	const TVectorImageP &vi,
Toshihiro Shimizu 890ddd
	vector<tfilledregioninf> ®s,</tfilledregioninf>
Toshihiro Shimizu 890ddd
	const TRectD &area)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!vi->isComputedRegionAlmostOnce())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	vi->findRegions();
Toshihiro Shimizu 890ddd
	UINT regNum = vi->getRegionCount();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (UINT i = 0; i < regNum; i++)
Toshihiro Shimizu 890ddd
		addRegionsInArea(vi->getRegion(i), regs, area);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void assignFillingInformation(
Toshihiro Shimizu 890ddd
	TVectorImage &vi,
Toshihiro Shimizu 890ddd
	const std::vector<tfilledregioninf> ®s)</tfilledregioninf>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	vi.findRegions();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT r, rCount = UINT(regs.size());
Toshihiro Shimizu 890ddd
	for (r = 0; r != rCount; ++r) {
Toshihiro Shimizu 890ddd
		const TFilledRegionInf &rInfo = regs[r];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (TRegion *region = vi.getRegion(rInfo.m_regionId))
Toshihiro Shimizu 890ddd
			region->setStyle(rInfo.m_styleId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void getStrokeStyleInformationInArea(
Toshihiro Shimizu 890ddd
	const TVectorImageP &vi,
Toshihiro Shimizu 890ddd
	vector<pair<int, int="">> &strokesInfo,</pair<int,>
Toshihiro Shimizu 890ddd
	const TRectD &area)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!vi->isComputedRegionAlmostOnce())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	vi->findRegions();
Toshihiro Shimizu 890ddd
	UINT regNum = vi->getStrokeCount();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (UINT i = 0; i < vi->getStrokeCount(); i++) {
Toshihiro Shimizu 890ddd
		if (!vi->inCurrentGroup(i))
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		if (area.contains(vi->getStroke(i)->getBBox()))
Toshihiro Shimizu 890ddd
			strokesInfo.push_back(pair<int, int="">(i, vi->getStroke(i)->getStyle()));</int,>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
void convertFromCM(const TLevelReaderP &lr, const TPaletteP &plt, const TLevelWriterP &lw, const vector<tframeid> &frames,</tframeid>
Toshihiro Shimizu 890ddd
				   const TAffine &aff, const TRop::ResampleFilterType &resType, FrameTaskNotifier *frameNotifier, const TPixel &bgColor, bool removeDotBeforeFrameNumber = false)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)frames.size(); i++) {
Toshihiro Shimizu 890ddd
		if (frameNotifier->abortTask())
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			TImageReaderP ir = lr->getFrameReader(frames[i]);
Toshihiro Shimizu 890ddd
			TImageP img = ir->load();
Toshihiro Shimizu 890ddd
			TToonzImageP toonzImage(img);
Toshihiro Shimizu 890ddd
			double xdpi, ydpi;
Toshihiro Shimizu 890ddd
			toonzImage->getDpi(xdpi, ydpi);
Toshihiro Shimizu 890ddd
			assert(toonzImage);
Toshihiro Shimizu 890ddd
			if (toonzImage) {
Toshihiro Shimizu 890ddd
				TRasterCM32P rasCMImage = toonzImage->getRaster();
Toshihiro Shimizu 890ddd
				TRaster32P ras(convert(aff * convert(rasCMImage->getBounds())).getSize());
Toshihiro Shimizu 890ddd
				if (!aff.isIdentity())
Toshihiro Shimizu 890ddd
					TRop::resample(ras, rasCMImage, plt, aff, resType);
Toshihiro Shimizu 890ddd
				else
Toshihiro Shimizu 890ddd
					TRop::convert(ras, rasCMImage, plt);
Toshihiro Shimizu 890ddd
				if (bgColor != TPixel::Transparent)
Toshihiro Shimizu 890ddd
					TRop::addBackground(ras, bgColor);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				TRasterImageP rasImage(ras);
Toshihiro Shimizu 890ddd
				rasImage->setDpi(xdpi, ydpi);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				/*---
Toshihiro Shimizu 890ddd
					ConvertPopup での指定に合わせて、[レベル名].[フレーム番号].[拡張子]
Toshihiro Shimizu 890ddd
					のうち、[レベル名]と[フレーム番号]の間のドットを消す。
Toshihiro Shimizu 890ddd
					例:A.0001.tga → A0001.tga になる。
Toshihiro Shimizu 890ddd
				---*/
Toshihiro Shimizu 890ddd
				if (removeDotBeforeFrameNumber) {
Toshihiro Shimizu 890ddd
					TFilePath outPath = lw->getFilePath().withFrame(frames[i]);
Toshihiro Shimizu 890ddd
					/*--- フレーム番号と拡張子の文字数の合計。大抵8 ---*/
Toshihiro Shimizu 890ddd
					int index = 4 + 1 + outPath.getType().length();
Toshihiro Shimizu 890ddd
					wstring renamedStr = outPath.getWideString();
Toshihiro Shimizu 890ddd
					if (renamedStr[renamedStr.length() - index - 1] == L'.')
Toshihiro Shimizu 890ddd
						renamedStr = renamedStr.substr(0, renamedStr.length() - index - 1) + renamedStr.substr(renamedStr.length() - index, index);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					const TFilePath fp(renamedStr);
Toshihiro Shimizu 890ddd
					TImageWriterP writer(fp);
Toshihiro Shimizu 890ddd
					writer->setProperties(lw->getProperties());
Toshihiro Shimizu 890ddd
					writer->save(rasImage);
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					TImageWriterP iw = lw->getFrameWriter(frames[i]);
Toshihiro Shimizu 890ddd
					iw->save(rasImage);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} catch (...) {
Toshihiro Shimizu 890ddd
			//QString msg=QObject::tr("Frame %1 : conversion failed!").arg(QString::number(i+1));
Toshihiro Shimizu 890ddd
			//      MsgBox(INFORMATION,msg);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		/*-- これはプログレスバーを進めるものなので、動画番号ではなく、完了したフレームの枚数を投げる --*/
Toshihiro Shimizu 890ddd
		frameNotifier->notifyFrameCompleted(100 * (i + 1) / frames.size());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void convertFromVI(const TLevelReaderP &lr, const TPaletteP &plt, const TLevelWriterP &lw, const vector<tframeid> &frames,</tframeid>
Toshihiro Shimizu 890ddd
				   const TRop::ResampleFilterType &resType, int width, FrameTaskNotifier *frameNotifier)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QString msg;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	vector<tvectorimagep> images;</tvectorimagep>
Toshihiro Shimizu 890ddd
	TRectD maxBbox;
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)frames.size(); i++) { //trovo la bbox che possa contenere tutte le immagini
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			TImageReaderP ir = lr->getFrameReader(frames[i]);
Toshihiro Shimizu 890ddd
			TVectorImageP img = ir->load();
Toshihiro Shimizu 890ddd
			images.push_back(img);
Toshihiro Shimizu 890ddd
			maxBbox += img->getBBox();
Toshihiro Shimizu 890ddd
		} catch (...) {
Toshihiro Shimizu 890ddd
			msg = QObject::tr("Frame %1 : conversion failed!").arg(QString::fromStdString(frames[i].expand()));
Toshihiro Shimizu 890ddd
			MsgBox(INFORMATION, msg);
Toshihiro Shimizu 890ddd
			;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	maxBbox = maxBbox.enlarge(2);
Toshihiro Shimizu 890ddd
	TAffine aff;
Toshihiro Shimizu 890ddd
	if (width) //calcolo l'affine
Toshihiro Shimizu 890ddd
		aff = TScale((double)width / maxBbox.getLx());
Toshihiro Shimizu 890ddd
	maxBbox = aff * maxBbox;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)images.size(); i++) {
Toshihiro Shimizu 890ddd
		if (frameNotifier->abortTask())
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			TVectorImageP vectorImage = images[i];
Toshihiro Shimizu 890ddd
			assert(vectorImage);
Toshihiro Shimizu 890ddd
			if (vectorImage) {
Toshihiro Shimizu 890ddd
				//faccio il render dell'immagine
Toshihiro Shimizu 890ddd
				vectorImage->transform(aff, true);
Toshihiro Shimizu 890ddd
				const TVectorRenderData rd(TTranslation(-maxBbox.getP00()), TRect(), plt.getPointer(), 0, true, true);
Toshihiro Shimizu 890ddd
				TOfflineGL *glContext = new TOfflineGL(convert(maxBbox).getSize());
Toshihiro Shimizu 890ddd
				glContext->clear(TPixel32::Transparent);
Toshihiro Shimizu 890ddd
				glContext->draw(vectorImage, rd);
Toshihiro Shimizu 890ddd
				TRaster32P rasImage = (glContext->getRaster());
Toshihiro Shimizu 890ddd
				TImageWriterP iw = lw->getFrameWriter(TFrameId(i + 1));
Toshihiro Shimizu 890ddd
				iw->save(TRasterImageP(rasImage));
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} catch (...) {
Toshihiro Shimizu 890ddd
			msg = QObject::tr("Frame %1 : conversion failed!").arg(QString::fromStdString(frames[i].expand()));
Toshihiro Shimizu 890ddd
			MsgBox(INFORMATION, msg);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		frameNotifier->notifyFrameCompleted(100 * (i + 1) / frames.size());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void convertFromFullRaster(const TLevelReaderP &lr, const TLevelWriterP &lw, const vector<tframeid> &_frames,</tframeid>
Toshihiro Shimizu 890ddd
						   const TAffine &aff, const TRop::ResampleFilterType &resType, FrameTaskNotifier *frameNotifier,
Toshihiro Shimizu 890ddd
						   const TPixel &bgColor, bool removeDotBeforeFrameNumber = false)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	vector<tframeid> frames = _frames;</tframeid>
Toshihiro Shimizu 890ddd
	if (frames.empty() && lr->loadInfo()->getFrameCount() == 1) //e' una immagine singola, non un livello
Toshihiro Shimizu 890ddd
		frames.push_back(TFrameId());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)frames.size(); i++) {
Toshihiro Shimizu 890ddd
		if (frameNotifier->abortTask())
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			TRasterImageP img;
Toshihiro Shimizu 890ddd
			if (frames[i] == TFrameId()) //immagine singola, non livello
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				assert(frames.size() == 1);
Toshihiro Shimizu 890ddd
				TImageP _img;
Toshihiro Shimizu 890ddd
				if (!TImageReader::load(lr->getFilePath(), _img))
Toshihiro Shimizu 890ddd
					continue;
Toshihiro Shimizu 890ddd
				img = _img;
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				TImageReaderP ir = lr->getFrameReader(frames[i]);
Toshihiro Shimizu 890ddd
				img = ir->load();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			TRaster32P raster(convert(aff * img->getBBox()).getSize());
Toshihiro Shimizu 890ddd
			if (!aff.isIdentity())
Toshihiro Shimizu 890ddd
				TRop::resample(raster, img->getRaster(), aff, resType);
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				if ((TRaster32P)img->getRaster())
Toshihiro Shimizu 890ddd
					raster = img->getRaster();
Toshihiro Shimizu 890ddd
				else
Toshihiro Shimizu 890ddd
					TRop::convert(raster, img->getRaster());
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (bgColor != TPixel::Transparent)
Toshihiro Shimizu 890ddd
				TRop::addBackground(raster, bgColor);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRasterImageP newImg(raster);
Toshihiro Shimizu 890ddd
			double xDpi, yDpi;
Toshihiro Shimizu 890ddd
			img->getDpi(xDpi, yDpi);
Toshihiro Shimizu 890ddd
			if (xDpi == 0 && yDpi == 0)
Toshihiro Shimizu 890ddd
				xDpi = yDpi = Preferences::instance()->getDefLevelDpi();
Toshihiro Shimizu 890ddd
			newImg->setDpi(xDpi, yDpi);
Toshihiro Shimizu 890ddd
			if (frames[i] == TFrameId())
Toshihiro Shimizu 890ddd
				TImageWriter::save(lw->getFilePath(), newImg);
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				/*---
Toshihiro Shimizu 890ddd
			ConvertPopup での指定に合わせて、[レベル名].[フレーム番号].[拡張子]
Toshihiro Shimizu 890ddd
			のうち、[レベル名]と[フレーム番号]の間のドットを消す。
Toshihiro Shimizu 890ddd
			例:A.0001.tga → A0001.tga になる。
Toshihiro Shimizu 890ddd
			---*/
Toshihiro Shimizu 890ddd
				if (removeDotBeforeFrameNumber) {
Toshihiro Shimizu 890ddd
					TFilePath outPath = lw->getFilePath().withFrame(frames[i]);
Toshihiro Shimizu 890ddd
					/*--- フレーム番号と拡張子の文字数の合計。大抵8 ---*/
Toshihiro Shimizu 890ddd
					int index = 4 + 1 + outPath.getType().length();
Toshihiro Shimizu 890ddd
					wstring renamedStr = outPath.getWideString();
Toshihiro Shimizu 890ddd
					if (renamedStr[renamedStr.length() - index - 1] == L'.')
Toshihiro Shimizu 890ddd
						renamedStr = renamedStr.substr(0, renamedStr.length() - index - 1) + renamedStr.substr(renamedStr.length() - index, index);
Toshihiro Shimizu 890ddd
					const TFilePath fp(renamedStr);
Toshihiro Shimizu 890ddd
					TImageWriterP writer(fp);
Toshihiro Shimizu 890ddd
					writer->setProperties(lw->getProperties());
Toshihiro Shimizu 890ddd
					writer->save(newImg);
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					TImageWriterP iw = lw->getFrameWriter(frames[i]);
Toshihiro Shimizu 890ddd
					iw->save(newImg);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} catch (...) {
Toshihiro Shimizu 890ddd
			//QString msg=QObject::tr("Frame %1 : conversion failed!").arg(QString::number(i+1));
Toshihiro Shimizu 890ddd
			//MsgBox(INFORMATION,msg);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		/*-- これはプログレスバーを進めるものなので、動画番号ではなく、完了したフレームの枚数を投げる --*/
Toshihiro Shimizu 890ddd
		frameNotifier->notifyFrameCompleted(100 * (i + 1) / frames.size());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void convertFromVector(const TLevelReaderP &lr, const TLevelWriterP &lw, const vector<tframeid> &_frames,</tframeid>
Toshihiro Shimizu 890ddd
					   FrameTaskNotifier *frameNotifier)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	vector<tframeid> frames = _frames;</tframeid>
Toshihiro Shimizu 890ddd
	TLevelP lv = lr->loadInfo();
Toshihiro Shimizu 890ddd
	if (frames.empty() && lv->getFrameCount() == 1) //e' una immagine singola, non un livello
Toshihiro Shimizu 890ddd
		frames.push_back(TFrameId());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)frames.size(); i++) {
Toshihiro Shimizu 890ddd
		if (frameNotifier->abortTask())
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			TVectorImageP img;
Toshihiro Shimizu 890ddd
			if (frames[i] == TFrameId()) //immagine singola, non livello
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				assert(frames.size() == 1);
Toshihiro Shimizu 890ddd
				TImageP _img;
Toshihiro Shimizu 890ddd
				if (!TImageReader::load(lr->getFilePath(), _img))
Toshihiro Shimizu 890ddd
					continue;
Toshihiro Shimizu 890ddd
				img = _img;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				TImageReaderP ir = lr->getFrameReader(frames[i]);
Toshihiro Shimizu 890ddd
				img = ir->load();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			img->setPalette(lv->getPalette());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (frames[i] == TFrameId())
Toshihiro Shimizu 890ddd
				TImageWriter::save(lw->getFilePath(), img);
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				TImageWriterP iw = lw->getFrameWriter(frames[i]);
Toshihiro Shimizu 890ddd
				iw->save(img);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} catch (...) {
Toshihiro Shimizu 890ddd
			//QString msg=QObject::tr("Frame %1 : conversion failed!").arg(QString::number(i+1));
Toshihiro Shimizu 890ddd
			//MsgBox(INFORMATION,msg);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		frameNotifier->notifyFrameCompleted(100 * (i + 1) / frames.size());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void convert(const TFilePath &source, const TFilePath &dest,
Toshihiro Shimizu 890ddd
			 const TFrameId &from, const TFrameId &to,
Toshihiro Shimizu 890ddd
			 double framerate,
Toshihiro Shimizu 890ddd
			 TPropertyGroup *prop,
Toshihiro Shimizu 890ddd
			 FrameTaskNotifier *frameNotifier,
Toshihiro Shimizu 890ddd
			 const TPixel &bgColor,
Toshihiro Shimizu 890ddd
			 bool removeDotBeforeFrameNumber)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::string dstExt = dest.getType(),
Toshihiro Shimizu 890ddd
				srcExt = source.getType();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Load source level structure
Toshihiro Shimizu 890ddd
	TLevelReaderP lr(source);
Toshihiro Shimizu 890ddd
	TLevelP level = lr->loadInfo();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
	if (dstExt == "avi") {
Toshihiro Shimizu 890ddd
		TDimension res(0, 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		const TImageInfo *info = lr->getImageInfo(level->begin()->first);
Toshihiro Shimizu 890ddd
		res.lx = info->m_lx;
Toshihiro Shimizu 890ddd
		res.ly = info->m_ly;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		string codecName = prop->getProperty(0)->getValueAsString();
Toshihiro Shimizu 890ddd
		if (!AviCodecRestrictions::canWriteMovie(toWideString(codecName), res)) {
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
			//QString msg=QObject::tr("The image resolution does not fit the chosen output file format.");
Toshihiro Shimizu 890ddd
			//MsgBox(WARNING,msg);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Get the frames available in level inside the [from, to] range
Toshihiro Shimizu 890ddd
	std::vector<tframeid> frames;</tframeid>
Toshihiro Shimizu 890ddd
	getFrameIds(from, to, level, frames);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Write the destination level
Toshihiro Shimizu 890ddd
	TLevelWriterP lw(dest, prop);
Toshihiro Shimizu 890ddd
	lw->setFrameRate(framerate);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (srcExt == "tlv")
Toshihiro Shimizu 890ddd
		convertFromCM(lr, level->getPalette(), lw, frames, TAffine(), TRop::Triangle, frameNotifier, bgColor, removeDotBeforeFrameNumber);
Toshihiro Shimizu 890ddd
	else if (srcExt == "pli")
Toshihiro Shimizu 890ddd
		//assert(!"Conversion from pli files is currently diabled");
Toshihiro Shimizu 890ddd
		convertFromVector(lr, lw, frames, frameNotifier);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		convertFromFullRaster(lr, lw, frames, TAffine(), TRop::Triangle, frameNotifier, bgColor, removeDotBeforeFrameNumber);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void convertNaa2Tlv(
Toshihiro Shimizu 890ddd
	const TFilePath &source, const TFilePath &dest,
Toshihiro Shimizu 890ddd
	const TFrameId &from, const TFrameId &to,
Toshihiro Shimizu 890ddd
	FrameTaskNotifier *frameNotifier,
Toshihiro Shimizu 890ddd
	TPalette *palette)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::string dstExt = dest.getType(),
Toshihiro Shimizu 890ddd
				srcExt = source.getType();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Load source level structure
Toshihiro Shimizu 890ddd
	TLevelReaderP lr(source);
Toshihiro Shimizu 890ddd
	TLevelP level = lr->loadInfo();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Get the frames available in level inside the [from, to] range
Toshihiro Shimizu 890ddd
	vector<tframeid> frames;</tframeid>
Toshihiro Shimizu 890ddd
	getFrameIds(from, to, level, frames);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (frames.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Write the destination level
Toshihiro Shimizu 890ddd
	TLevelWriterP lw; // Initialized just before a sure write
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Naa2TlvConverter converter;
Toshihiro Shimizu 890ddd
	converter.setPalette(palette);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int f, fCount = int(frames.size());
Toshihiro Shimizu 890ddd
	for (f = 0; f != fCount; ++f) {
Toshihiro Shimizu 890ddd
		if (frameNotifier->abortTask())
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		try {
Toshihiro Shimizu 890ddd
			TImageReaderP ir = lr->getFrameReader(frames[f]);
Toshihiro Shimizu 890ddd
			TImageP img = ir->load();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (!img)
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRasterImageP ri = img;
Toshihiro Shimizu 890ddd
			if (!ri)
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRaster32P raster = ri->getRaster(); // Converts only 32-bit images, it seems...
Toshihiro Shimizu 890ddd
			if (!raster)						 //
Toshihiro Shimizu 890ddd
				continue;						 //
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			converter.process(raster);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (TToonzImageP dstImg = converter.makeTlv(false)) // Opaque synthetic inks
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				if (converter.getPalette() == 0)
Toshihiro Shimizu 890ddd
					converter.setPalette(dstImg->getPalette());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (!lw)					  // Initialize output file only on a sure write
Toshihiro Shimizu 890ddd
					lw = TLevelWriterP(dest); //
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				TImageWriterP iw = lw->getFrameWriter(frames[f]);
Toshihiro Shimizu 890ddd
				iw->save(dstImg);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				MsgBox(DVGui::WARNING, QObject::tr(
Toshihiro Shimizu 890ddd
										   "The source image seems not suitable for this kind of conversion"));
Toshihiro Shimizu 890ddd
				frameNotifier->notifyError();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} catch (...) {
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		frameNotifier->notifyFrameCompleted(100 * (f + 1) / frames.size());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define ZOOMLEVELS 13
Toshihiro Shimizu 890ddd
#define NOZOOMINDEX 6
Toshihiro Shimizu 890ddd
double ZoomFactors[ZOOMLEVELS] = {0.015625, 0.03125, 0.0625, 0.125, 0.25,
Toshihiro Shimizu 890ddd
								  0.5, 1, 2, 4, 8, 16, 32, 64};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double getQuantizedZoomFactor(double zf, bool forward)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (forward && (zf > ZoomFactors[ZOOMLEVELS - 1] || areAlmostEqual(zf, ZoomFactors[ZOOMLEVELS - 1], 1e-5)))
Toshihiro Shimizu 890ddd
		return zf;
Toshihiro Shimizu 890ddd
	else if (!forward && (zf < ZoomFactors[0] || areAlmostEqual(zf, ZoomFactors[0], 1e-5)))
Toshihiro Shimizu 890ddd
		return zf;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert((!forward && zf > ZoomFactors[0]) || (forward && zf < ZoomFactors[ZOOMLEVELS - 1]));
Toshihiro Shimizu 890ddd
	int i = 0;
Toshihiro Shimizu 890ddd
	for (i = 0; i <= ZOOMLEVELS - 1; i++)
Toshihiro Shimizu 890ddd
		if (areAlmostEqual(zf, ZoomFactors[i], 1e-5))
Toshihiro Shimizu 890ddd
			zf = ZoomFactors[i];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (forward && zf < ZoomFactors[0])
Toshihiro Shimizu 890ddd
		return ZoomFactors[0];
Toshihiro Shimizu 890ddd
	else if (!forward && zf > ZoomFactors[ZOOMLEVELS - 1])
Toshihiro Shimizu 890ddd
		return ZoomFactors[ZOOMLEVELS - 1];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < ZOOMLEVELS - 1; i++)
Toshihiro Shimizu 890ddd
		if (ZoomFactors[i + 1] - zf >= 0 && zf - ZoomFactors[i] >= 0) {
Toshihiro Shimizu 890ddd
			if (forward && ZoomFactors[i + 1] == zf)
Toshihiro Shimizu 890ddd
				return ZoomFactors[i + 2];
Toshihiro Shimizu 890ddd
			else if (!forward && ZoomFactors[i] == zf)
Toshihiro Shimizu 890ddd
				return ZoomFactors[i - 1];
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				return forward ? ZoomFactors[i + 1] : ZoomFactors[i];
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	return ZoomFactors[NOZOOMINDEX];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace ImageUtils
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void getViewerShortcuts(int &zoomIn, int &zoomOut, int &zoomReset, int &zoomFit, int &showHideFullScreen, int &actualPixelSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	CommandManager *cManager = CommandManager::instance();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	zoomIn = cManager->getKeyFromShortcut(cManager->getShortcutFromId(V_ZoomIn));
Toshihiro Shimizu 890ddd
	zoomOut = cManager->getKeyFromShortcut(cManager->getShortcutFromId(V_ZoomOut));
Toshihiro Shimizu 890ddd
	zoomReset = cManager->getKeyFromShortcut(cManager->getShortcutFromId(V_ZoomReset));
Toshihiro Shimizu 890ddd
	zoomFit = cManager->getKeyFromShortcut(cManager->getShortcutFromId(V_ZoomFit));
Toshihiro Shimizu 890ddd
	showHideFullScreen = cManager->getKeyFromShortcut(cManager->getShortcutFromId(V_ShowHideFullScreen));
Toshihiro Shimizu 890ddd
	actualPixelSize = cManager->getKeyFromShortcut(cManager->getShortcutFromId(V_ActualPixelSize));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace ImageUtils
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ShortcutZoomer::ShortcutZoomer(QWidget *zoomingWidget)
Toshihiro Shimizu 890ddd
	: m_widget(zoomingWidget)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool ShortcutZoomer::exec(QKeyEvent *event)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int zoomInKey, zoomOutKey, zoomResetKey, zoomFitKey, showHideFullScreenKey, actualPixelSize;
Toshihiro Shimizu 890ddd
	getViewerShortcuts(zoomInKey, zoomOutKey, zoomResetKey, zoomFitKey, showHideFullScreenKey, actualPixelSize);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int key = event->key();
Toshihiro Shimizu 890ddd
	if (key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Alt)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	key = key | event->modifiers() & (~0xf0000000); // Ignore if the key is a numpad key
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return (key == showHideFullScreenKey) ? toggleFullScreen() : (key == Qt::Key_Escape) ? toggleFullScreen(true) : (key == actualPixelSize) ? setActualPixelSize() : (key == zoomFitKey) ? fit() : (key == zoomInKey ||
Toshihiro Shimizu 890ddd
																																																	 key == zoomOutKey ||
Toshihiro Shimizu 890ddd
																																																	 key == zoomResetKey)
Toshihiro Shimizu 890ddd
																																																		? zoom(key == zoomInKey, key == zoomResetKey)
Toshihiro Shimizu 890ddd
																																																		: false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*********************************************************************************************
Toshihiro Shimizu 890ddd
//    FullScreenWidget  implementation
Toshihiro Shimizu 890ddd
//*********************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FullScreenWidget::FullScreenWidget(QWidget *parent)
Toshihiro Shimizu 890ddd
	: QWidget(parent)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QHBoxLayout *layout = new QHBoxLayout(this);
Toshihiro Shimizu 890ddd
	layout->setMargin(0);
Toshihiro Shimizu 890ddd
	layout->setSpacing(0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	setLayout(layout);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FullScreenWidget::setWidget(QWidget *widget)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QLayout *layout = this->layout();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delete layout->takeAt(0);
Toshihiro Shimizu 890ddd
	if (m_widget = widget)
Toshihiro Shimizu 890ddd
		layout->addWidget(m_widget);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool FullScreenWidget::toggleFullScreen(bool quit)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (windowState() & Qt::WindowFullScreen) {
Toshihiro Shimizu 890ddd
		hide();
Toshihiro Shimizu 890ddd
		setWindowFlags(windowFlags() & ~(Qt::Window | Qt::WindowStaysOnTopHint));
Toshihiro Shimizu 890ddd
		showNormal();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		setContentsMargins(0, 0, 0, 0); // ...
Toshihiro Shimizu 890ddd
		m_widget->setFocus();
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	} else if (!quit) {
Toshihiro Shimizu 890ddd
		setContentsMargins(0, 0, 1, 1); // QTBUG #7556
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		setWindowFlags(windowFlags() | Qt::Window | Qt::WindowStaysOnTopHint);
Toshihiro Shimizu 890ddd
		showFullScreen();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //imageutils