#include "toonz/cleanupparameters.h" #include "tstream.h" #include "texception.h" #include "toonz/toonzscene.h" #include "toonz/sceneproperties.h" #include "toonz/txshleveltypes.h" #include "tsystem.h" #include "tenv.h" #include "tconvert.h" #include "cleanuppalette.h" #include "tpalette.h" #ifdef _MSC_VER #pragma warning(disable : 4996) #endif using namespace CleanupTypes; #define FDG_VERSION_FILE "VERSION_1.0" CleanupParameters CleanupParameters::GlobalParameters; CleanupParameters CleanupParameters::LastSavedParameters; //========================================================= namespace { //========================================================= class FdgManager { // singleton std::map m_infos; void loadFieldGuideInfo(); FdgManager() { loadFieldGuideInfo(); } public: static FdgManager *instance() { static FdgManager _instance; return &_instance; } const FDG_INFO *getFdg(std::string name) const { std::map::const_iterator it; it = m_infos.find(name); if (it == m_infos.end()) return 0; else return &it->second; } void getFdgNames(std::vector &names) const { std::map::const_iterator it; for (it = m_infos.begin(); it != m_infos.end(); ++it) names.push_back(it->first); } }; //--------------------------------------------------------- #define REMOVE_CR(s) \ { \ while (*(s) && *(s) != '\n' && *(s) != '\r') (s)++; \ *(s) = '\0'; \ } #define SKIP_BLANKS(s) \ { \ while (*(s) && (*(s) == ' ' || *(s) == '\t')) (s)++; \ } #define STR_EQ(s1, s2) (!strcmp((s1), (s2))) //--------------------------------------------------------- void FdgManager::loadFieldGuideInfo() { FILE *fp; char *s, buffer[256], label[100], arg[100]; int i, version = 0, cnt; try { TFilePathSet fps = TSystem::readDirectory(TEnv::getConfigDir() + "fdg", false); for (TFilePathSet::iterator it = fps.begin(); it != fps.end(); ++it) { TFilePath fname = *it; if (fname.getType() != "fdg") continue; fp = fopen(::to_string(fname.getWideString()).c_str(), "r"); if (!fp) continue; FDG_INFO fdg_info; // memset(&fdg_info,0, sizeof(FDG_INFO)); fdg_info.dots.resize(3); cnt = 0; while (fgets(buffer, 256, fp)) { s = buffer; if (*s == '#' || *s == '*') continue; REMOVE_CR(s) s = buffer; SKIP_BLANKS(s) if (!*s) continue; for (i = 0; *s && *s != ' ' && *s != '\t'; i++, s++) label[i] = *s; label[i] = '\0'; SKIP_BLANKS(s) for (i = 0; *s && *s != ' ' && *s != '\t'; i++, s++) arg[i] = *s; arg[i] = '\0'; /* suppongo ci siano sempre 3 dots */ if (STR_EQ(label, FDG_VERSION_FILE)) version = 1; else if (STR_EQ(label, "CTRX")) sscanf(arg, "%lf", &fdg_info.ctr_x), fdg_info.ctr_type = 1; else if (STR_EQ(label, "CTRY")) sscanf(arg, "%lf", &fdg_info.ctr_y), fdg_info.ctr_type = 1; else if (STR_EQ(label, "ANGLE")) sscanf(arg, "%lf", &fdg_info.ctr_angle), fdg_info.ctr_type = 1; else if (STR_EQ(label, "SKEW")) sscanf(arg, "%lf", &fdg_info.ctr_skew), fdg_info.ctr_type = 1; else if (STR_EQ(label, "HOLE")) { sscanf(arg, "%d", &cnt); if (cnt >= (int)fdg_info.dots.size()) { fdg_info.dots.push_back(CleanupTypes::DOT()); } } else if (STR_EQ(label, "X0")) sscanf(arg, "%d", &fdg_info.dots[cnt].x1); else if (STR_EQ(label, "Y0")) sscanf(arg, "%d", &fdg_info.dots[cnt].y1); else if (STR_EQ(label, "X1")) sscanf(arg, "%d", &fdg_info.dots[cnt].x2); else if (STR_EQ(label, "Y1")) sscanf(arg, "%d", &fdg_info.dots[cnt].y2); else if (STR_EQ(label, "X")) sscanf(arg, "%f", &fdg_info.dots[cnt].x); else if (STR_EQ(label, "Y")) sscanf(arg, "%f", &fdg_info.dots[cnt].y); else if (STR_EQ(label, "XSIZE")) sscanf(arg, "%d", &fdg_info.dots[cnt].lx); else if (STR_EQ(label, "YSIZE")) sscanf(arg, "%d", &fdg_info.dots[cnt].ly); else if (STR_EQ(label, "AREA")) sscanf(arg, "%d", &fdg_info.dots[cnt].area); else if (STR_EQ(label, "END")) { } else if (STR_EQ(label, "DIST_CTR_TO_CTR_HOLE")) sscanf(arg, "%lf", &fdg_info.dist_ctr_to_ctr_hole); else if (STR_EQ(label, "DIST_CTR_HOLE_TO_EDGE")) sscanf(arg, "%lf", &fdg_info.dist_ctr_hole_to_edge); } fclose(fp); if (!fdg_info.ctr_type && version != 1) { // tmsg_error("load field guide info: bad file or old version"); // return FALSE; } else { fdg_info.m_name = fname.getName(); m_infos[fdg_info.m_name] = fdg_info; } } } catch (...) { } // return TRUE; } } // namespace //========================================================= CleanupParameters::CleanupParameters() : m_autocenterType(AUTOCENTER_NONE) , m_pegSide(PEGS_BOTTOM) , m_fdgInfo() , m_rotate(0) , m_flipx(false) , m_flipy(false) , m_offx(0) , m_offy(0) //, m_scale(1) , m_lineProcessingMode(lpGrey) , m_noAntialias(false) , m_postAntialias(false) , m_despeckling(2) , m_aaValue(70) , m_closestField(999.) , m_sharpness(90.) , m_autoAdjustMode(AUTO_ADJ_NONE) , m_transparencyCheckEnabled(false) , m_colors() , m_path() , m_cleanupPalette(createStandardCleanupPalette()) , m_camera() , m_dirtyFlag(false) //, m_resName("") , m_offx_lock(false) , m_offy_lock(false) {} //--------------------------------------------------------- bool CleanupParameters::setFdgByName(std::string name) { const FDG_INFO *info = FdgManager::instance()->getFdg(name); if (info) { m_fdgInfo = *info; return true; } else { m_fdgInfo = FDG_INFO(); return false; } } //--------------------------------------------------------- void CleanupParameters::getFdgNames(std::vector &names) { FdgManager::instance()->getFdgNames(names); } //--------------------------------------------------------- TFilePath CleanupParameters::getPath(ToonzScene *scene) const { if (m_path == TFilePath()) { int levelType = (m_lineProcessingMode != lpNone) ? TZP_XSHLEVEL : OVL_XSHLEVEL; TFilePath fp = scene->getDefaultLevelPath(levelType); return fp.getParentDir(); } else return scene->decodeSavePath(m_path); } //--------------------------------------------------------- void CleanupParameters::setPath(ToonzScene *scene, TFilePath fp) { if (fp == scene->getDefaultLevelPath(TZP_XSHLEVEL).getParentDir()) m_path = TFilePath(); else m_path = scene->codeSavePath(fp); } //------------------------------------------------------------------------------ void CleanupParameters::getOutputImageInfo(TDimension &outDim, double &outDpiX, double &outDpiY) const { double lq_nozoom, lp_nozoom; double zoom_factor; // Retrieve camera infos const TDimensionD &cameraSize = m_camera.getSize(); const TDimension &cameraRes = m_camera.getRes(); // Camera resolution lp_nozoom = cameraRes.lx; lq_nozoom = cameraRes.ly; // Zoom factor due to the 'closest field' parameter if (m_closestField < cameraSize.lx) zoom_factor = cameraSize.lx / m_closestField; else zoom_factor = 1.0; // Output image resolution (considering the closest field) // apart from any rotation (eg m_parameters.m_rotate == 90 or 270) outDim.lx = troundp(zoom_factor * lp_nozoom); outDim.ly = troundp(zoom_factor * lq_nozoom); // output image dpi outDpiX = zoom_factor * cameraRes.lx / cameraSize.lx; outDpiY = zoom_factor * cameraRes.ly / cameraSize.ly; } //------------------------------------------------------------------------------------ void CleanupParameters::assign(const CleanupParameters *param, bool clonePalette) { // m_resName = param->m_resName; m_camera = param->m_camera; m_autocenterType = param->m_autocenterType; m_pegSide = param->m_pegSide; m_fdgInfo = param->m_fdgInfo; m_rotate = param->m_rotate; m_flipx = param->m_flipx; m_flipy = param->m_flipy; // m_scale = param->m_scale; m_offx = param->m_offx; m_offy = param->m_offy; m_closestField = param->m_closestField; m_autoAdjustMode = param->m_autoAdjustMode; m_sharpness = param->m_sharpness; m_path = param->m_path; m_colors = param->m_colors; m_dirtyFlag = param->m_dirtyFlag; m_transparencyCheckEnabled = param->m_transparencyCheckEnabled; m_lineProcessingMode = param->m_lineProcessingMode; m_noAntialias = param->m_noAntialias; m_postAntialias = param->m_postAntialias; m_despeckling = param->m_despeckling; m_aaValue = param->m_aaValue; // In modern Toonz scenes, there always is a cleanup palette. // In older Toonz scenes, it may be missing. In this case, leave the current // one. if (clonePalette && param->m_cleanupPalette) m_cleanupPalette = param->m_cleanupPalette->clone(); m_offx_lock = param->m_offx_lock; m_offy_lock = param->m_offy_lock; } //--------------------------------------------------------- void CleanupParameters::saveData(TOStream &os) const { CleanupParameters::LastSavedParameters.assign(this); os.openChild("cleanupCamera"); m_camera.saveData(os); os.closeChild(); os.openChild("cleanupPalette"); m_cleanupPalette->saveData(os); os.closeChild(); std::map attr; if (m_autocenterType != AUTOCENTER_NONE) { attr.clear(); attr["type"] = std::to_string(m_autocenterType); attr["pegHoles"] = std::to_string(m_pegSide); os.openCloseChild("autoCenter", attr); } if (m_flipx || m_flipy || m_rotate != 0 //|| m_scale!=1 || m_offx != 0 || m_offy != 0) { attr.clear(); std::string flip = std::string(m_flipx ? "x" : "") + std::string(m_flipy ? "y" : ""); if (flip != "") attr["flip"] = flip; if (m_rotate != 0) attr["rotate"] = std::to_string(m_rotate); if (m_offx != 0.0) attr["xoff"] = std::to_string(m_offx); if (m_offy != 0.0) attr["yoff"] = std::to_string(m_offy); os.openCloseChild("transform", attr); } if (m_lineProcessingMode != lpNone) { attr.clear(); attr["sharpness"] = std::to_string(m_sharpness); attr["autoAdjust"] = std::to_string(m_autoAdjustMode); attr["mode"] = (m_lineProcessingMode == lpGrey ? "grey" : "color"); os.openCloseChild("lineProcessing", attr); } if (m_noAntialias) { attr.clear(); os.openCloseChild("noAntialias", attr); } if (m_postAntialias) { attr.clear(); os.openCloseChild("MLAA", attr); } attr.clear(); attr["value"] = std::to_string(m_despeckling); os.openCloseChild("despeckling", attr); attr.clear(); attr["value"] = std::to_string(m_aaValue); os.openCloseChild("aaValue", attr); attr.clear(); attr["value"] = std::to_string(m_closestField); os.openCloseChild("closestField", attr); attr.clear(); attr["name"] = m_fdgInfo.m_name; os.openCloseChild("fdg", attr); attr.clear(); if (m_path != TFilePath()) os.child("path") << m_path; } //--------------------------------------------------------- void CleanupParameters::loadData(TIStream &is, bool globalParams) { if (globalParams) { CleanupParameters cp; assign(&cp); } std::string tagName; m_lineProcessingMode = lpNone; m_noAntialias = false; m_postAntialias = false; while (is.matchTag(tagName)) { if (tagName == "cleanupPalette") { m_cleanupPalette->loadData(is); m_cleanupPalette->setIsCleanupPalette(true); is.closeChild(); } else if (tagName == "cleanupCamera") { m_camera.loadData(is); is.closeChild(); } else if (tagName == "autoCenter") { m_autocenterType = AUTOCENTER_FDG; std::string s = is.getTagAttribute("type"); if (s != "" && isInt(s)) m_autocenterType = (AUTOCENTER_TYPE)std::stoi(s); s = is.getTagAttribute("pegHoles"); if (s != "" && isInt(s)) m_pegSide = (PEGS_SIDE)std::stoi(s); } else if (tagName == "transform") { std::string s = is.getTagAttribute("flip"); m_flipx = (s.find("x") != std::string::npos); m_flipy = (s.find("y") != std::string::npos); s = is.getTagAttribute("rotate"); if (s != "" && isInt(s)) m_rotate = std::stoi(s); s = is.getTagAttribute("xoff"); if (s != "" && isDouble(s)) m_offx = std::stod(s); s = is.getTagAttribute("yoff"); if (s != "" && isDouble(s)) m_offy = std::stod(s); } else if (tagName == "lineProcessing") { m_lineProcessingMode = lpGrey; std::string s = is.getTagAttribute("sharpness"); if (s != "" && isDouble(s)) m_sharpness = std::stod(s); s = is.getTagAttribute("autoAdjust"); if (s != "" && isDouble(s)) m_autoAdjustMode = (CleanupTypes::AUTO_ADJ_MODE)std::stoi(s); s = is.getTagAttribute("mode"); if (s != "" && s == "color") m_lineProcessingMode = lpColor; } else if (tagName == "despeckling") { std::string s = is.getTagAttribute("value"); if (s != "" && isInt(s)) m_despeckling = std::stoi(s); } else if (tagName == "aaValue") { std::string s = is.getTagAttribute("value"); if (s != "" && isInt(s)) m_aaValue = std::stoi(s); } else if (tagName == "noAntialias") m_noAntialias = true; else if (tagName == "MLAA") m_postAntialias = true; else if (tagName == "closestField") { std::string s = is.getTagAttribute("value"); if (s != "" && isDouble(s)) m_closestField = std::stod(s); } else if (tagName == "fdg") { std::string s = is.getTagAttribute("name"); if (s != "") setFdgByName(s); } else if (tagName == "path") { is >> m_path; is.closeChild(); } else is.skipCurrentTag(); } CleanupParameters::LastSavedParameters.assign(this); if (globalParams) CleanupParameters::GlobalParameters.assign(this); } //--------------------------------------------------------- const CleanupTypes::FDG_INFO &CleanupParameters::getFdgInfo() { if (m_fdgInfo.m_name == "") { std::vector names; FdgManager::instance()->getFdgNames(names); if (names.size() > 1) { const CleanupTypes::FDG_INFO *info = FdgManager::instance()->getFdg(names[0]); if (info) m_fdgInfo = *info; } } return m_fdgInfo; }