|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/scriptbinding_image.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/scriptbinding_level.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/scriptbinding_files.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsystem.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttoonzimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfiletype.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "timage_io.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tlevel_io.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace TScriptBinding {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Image::Image() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Image::Image(const TImageP img) : m_img(img) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Image::Image(TImage *img) : m_img(img) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Image::~Image() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QScriptValue Image::ctor(QScriptContext *context, QScriptEngine *engine) {
|
|
Shinya Kitaoka |
120a6e |
Image *img = new Image();
|
|
Shinya Kitaoka |
120a6e |
QScriptValue obj = create(engine, img);
|
|
Shinya Kitaoka |
120a6e |
QScriptValue err = checkArgumentCount(context, "the Image constructor", 0, 1);
|
|
Shinya Kitaoka |
120a6e |
if (err.isError()) return err;
|
|
Shinya Kitaoka |
120a6e |
if (context->argumentCount() == 1) {
|
|
Shinya Kitaoka |
120a6e |
return obj.property("load").call(obj, context->argumentsObject());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return obj;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QScriptValue Image::toString() {
|
|
Shinya Kitaoka |
120a6e |
if (m_img) {
|
|
Shinya Kitaoka |
120a6e |
TImage::Type type = m_img->getType();
|
|
Shinya Kitaoka |
120a6e |
if (type == TImage::RASTER)
|
|
Shinya Kitaoka |
120a6e |
return QString("Raster image ( %1 x %2 )")
|
|
Shinya Kitaoka |
120a6e |
.arg(getWidth())
|
|
Shinya Kitaoka |
120a6e |
.arg(getHeight());
|
|
Shinya Kitaoka |
120a6e |
else if (type == TImage::TOONZ_RASTER)
|
|
Shinya Kitaoka |
120a6e |
return QString("Toonz raster image ( %1 x %2 )")
|
|
Shinya Kitaoka |
120a6e |
.arg(getWidth())
|
|
Shinya Kitaoka |
120a6e |
.arg(getHeight());
|
|
Shinya Kitaoka |
120a6e |
else if (type == TImage::VECTOR)
|
|
Shinya Kitaoka |
120a6e |
return QString("Vector image");
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return QString("Image");
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
return "Empty image";
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int Image::getWidth() {
|
|
Shinya Kitaoka |
120a6e |
return !!m_img && !!m_img->raster() ? m_img->raster()->getSize().lx : 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int Image::getHeight() {
|
|
Shinya Kitaoka |
120a6e |
return !!m_img && !!m_img->raster() ? m_img->raster()->getSize().ly : 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double Image::getDpi() {
|
|
Shinya Kitaoka |
120a6e |
if (TRasterImageP ri = m_img) {
|
|
Shinya Kitaoka |
120a6e |
double dpix = 0, dpiy = 0;
|
|
Shinya Kitaoka |
120a6e |
ri->getDpi(dpix, dpiy);
|
|
Shinya Kitaoka |
120a6e |
return dpix;
|
|
Shinya Kitaoka |
120a6e |
} else if (TToonzImageP ti = m_img) {
|
|
Shinya Kitaoka |
120a6e |
double dpix = 0, dpiy = 0;
|
|
Shinya Kitaoka |
120a6e |
ti->getDpi(dpix, dpiy);
|
|
Shinya Kitaoka |
120a6e |
return dpix;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QString Image::getType() const {
|
|
Shinya Kitaoka |
120a6e |
if (m_img) {
|
|
Shinya Kitaoka |
120a6e |
TImage::Type type = m_img->getType();
|
|
Shinya Kitaoka |
120a6e |
if (type == TImage::RASTER)
|
|
Shinya Kitaoka |
120a6e |
return "Raster";
|
|
Shinya Kitaoka |
120a6e |
else if (type == TImage::TOONZ_RASTER)
|
|
Shinya Kitaoka |
120a6e |
return "ToonzRaster";
|
|
Shinya Kitaoka |
120a6e |
else if (type == TImage::VECTOR)
|
|
Shinya Kitaoka |
120a6e |
return "Vector";
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return "Unknown";
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
return "Empty";
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QScriptValue Image::load(const QScriptValue &fpArg) {
|
|
Shinya Kitaoka |
120a6e |
// clear the old image (if any)
|
|
Shinya Kitaoka |
120a6e |
m_img = TImageP();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// get the path
|
|
Shinya Kitaoka |
120a6e |
TFilePath fp;
|
|
Shinya Kitaoka |
120a6e |
QScriptValue err = checkFilePath(context(), fpArg, fp);
|
|
Shinya Kitaoka |
120a6e |
if (err.isError()) return err;
|
|
Shinya Kitaoka |
120a6e |
QString fpStr = fpArg.toString();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
// check if the file/level does exist
|
|
Shinya Kitaoka |
120a6e |
if (!TSystem::doesExistFileOrLevel(fp)) {
|
|
Shinya Kitaoka |
120a6e |
return context()->throwError(tr("File %1 doesn't exist").arg(fpStr));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// the file could be a level
|
|
Shinya Kitaoka |
120a6e |
TFileType::Type fileType = TFileType::getInfo(fp);
|
|
Shinya Kitaoka |
120a6e |
if (TFileType::isLevel(fileType)) {
|
|
Shinya Kitaoka |
120a6e |
// file is a level: read first frame
|
|
Shinya Kitaoka |
120a6e |
TLevelReaderP lr(fp);
|
|
Shinya Kitaoka |
120a6e |
TLevelP level = lr->loadInfo();
|
|
Shinya Kitaoka |
120a6e |
int n = level->getFrameCount();
|
|
Shinya Kitaoka |
120a6e |
if (n > 0) {
|
|
Shinya Kitaoka |
120a6e |
// there are some frames
|
|
Shinya Kitaoka |
120a6e |
TFrameId fid = fp.getFrame();
|
|
Shinya Kitaoka |
120a6e |
if (fid == TFrameId::NO_FRAME || fid == TFrameId::EMPTY_FRAME)
|
|
Shinya Kitaoka |
120a6e |
fid = level->begin()->first;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_img = lr->getFrameReader(fid)->load();
|
|
Shinya Kitaoka |
120a6e |
if (!m_img) {
|
|
Shinya Kitaoka |
120a6e |
return context()->throwError(QString("Could not read %1").arg(fpStr));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_img->setPalette(level->getPalette());
|
|
Shinya Kitaoka |
120a6e |
if (n > 1 && (fp.getFrame() == TFrameId::EMPTY_FRAME ||
|
|
Shinya Kitaoka |
120a6e |
fp.getFrame() == TFrameId::NO_FRAME)) {
|
|
Shinya Kitaoka |
120a6e |
// warning: a multi-frame level read into an Image
|
|
Shinya Kitaoka |
120a6e |
warning(tr("Loaded first frame of %1").arg(n));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// level contains no frame (not sure it can even happen)
|
|
Shinya Kitaoka |
120a6e |
return context()->throwError(
|
|
Shinya Kitaoka |
120a6e |
QString("%1 contains no frames").arg(fpStr));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// plain image: try to read it
|
|
Shinya Kitaoka |
120a6e |
if (!TImageReader::load(fp, m_img)) {
|
|
Shinya Kitaoka |
120a6e |
return context()->throwError(
|
|
Shinya Kitaoka |
120a6e |
QString("File %1 not found or not readable").arg(fpStr));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// return a reference to the Image object
|
|
Shinya Kitaoka |
120a6e |
return context()->thisObject();
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
return context()->throwError(
|
|
Shinya Kitaoka |
120a6e |
tr("Unexpected error while reading image").arg(fpStr));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QScriptValue Image::save(const QScriptValue &fpArg) {
|
|
Shinya Kitaoka |
120a6e |
// clear the old image (if any)
|
|
Shinya Kitaoka |
120a6e |
if (!m_img) {
|
|
Shinya Kitaoka |
120a6e |
return context()->throwError("Can't save an empty image");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// get the path
|
|
Shinya Kitaoka |
120a6e |
TFilePath fp;
|
|
Shinya Kitaoka |
120a6e |
QScriptValue err = checkFilePath(context(), fpArg, fp);
|
|
Shinya Kitaoka |
120a6e |
if (err.isError()) return err;
|
|
Shinya Kitaoka |
120a6e |
QString fpStr = fpArg.toString();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// handle conversion (if it is needed and possible)
|
|
Shinya Kitaoka |
120a6e |
TFileType::Type fileType = TFileType::getInfo(fp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool isCompatible = false;
|
|
Shinya Kitaoka |
120a6e |
if (TFileType::isFullColor(fileType)) {
|
|
Shinya Kitaoka |
120a6e |
if (m_img->getType() == TImage::RASTER) isCompatible = true;
|
|
Shinya Kitaoka |
120a6e |
} else if (TFileType::isVector(fileType)) {
|
|
Shinya Kitaoka |
120a6e |
if (m_img->getType() == TImage::VECTOR) isCompatible = true;
|
|
Shinya Kitaoka |
120a6e |
} else if (fileType & TFileType::CMAPPED_IMAGE) {
|
|
Shinya Kitaoka |
120a6e |
if (m_img->getType() == TImage::TOONZ_RASTER) isCompatible = true;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
return context()->throwError(tr("Unrecognized file type :").arg(fpStr));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (!isCompatible) {
|
|
Shinya Kitaoka |
120a6e |
return context()->throwError(
|
|
Shinya Kitaoka |
120a6e |
tr("Can't save a %1 image to this file type : %2")
|
|
Shinya Kitaoka |
120a6e |
.arg(getType())
|
|
Shinya Kitaoka |
120a6e |
.arg(fpStr));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
if (TFileType::isLevel(fileType)) {
|
|
Shinya Kitaoka |
120a6e |
TLevelP level = new TLevel();
|
|
Shinya Kitaoka |
120a6e |
level->setPalette(m_img->getPalette());
|
|
Shinya Kitaoka |
120a6e |
level->setFrame(TFrameId(1), m_img);
|
|
Shinya Kitaoka |
120a6e |
TLevelWriterP lw(fp);
|
|
Shinya Kitaoka |
120a6e |
if (m_img->getPalette()) lw->setPalette(m_img->getPalette());
|
|
Shinya Kitaoka |
120a6e |
lw->save(level);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
TImageWriterP iw(fp);
|
|
Shinya Kitaoka |
120a6e |
iw->save(fp, m_img);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// return a reference to the Image object
|
|
Shinya Kitaoka |
120a6e |
return context()->thisObject();
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
return context()->throwError(
|
|
Shinya Kitaoka |
120a6e |
tr("Unexpected error while writing image").arg(fpStr));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QScriptValue checkImage(QScriptContext *context, const QScriptValue &value,
|
|
Shinya Kitaoka |
120a6e |
Image *&img) {
|
|
Shinya Kitaoka |
120a6e |
img = qscriptvalue_cast(value);
|
|
Shinya Kitaoka |
120a6e |
if (!img || !img->getImg())
|
|
Shinya Kitaoka |
120a6e |
return context->throwError(
|
|
Shinya Kitaoka |
120a6e |
QObject::tr("Bad argument (%1): should be an Image (not empty)")
|
|
Shinya Kitaoka |
120a6e |
.arg(value.toString()));
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return QScriptValue();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace TScriptBinding
|