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