waifu2x
Version:
2x upscaling of images with waifu2x
871 lines • 84.6 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var util_1 = __importDefault(require("util"));
var fs_1 = __importDefault(require("fs"));
var image_size_1 = require("image-size");
var fluent_ffmpeg_1 = __importDefault(require("fluent-ffmpeg"));
var path_1 = __importDefault(require("path"));
var child_process_1 = __importDefault(require("child_process"));
var gif_encoder_1 = __importDefault(require("gif-encoder"));
var get_pixels_1 = __importDefault(require("get-pixels"));
var gif_frames_1 = __importDefault(require("gif-frames"));
var pdfkit_1 = __importDefault(require("@react-pdf/pdfkit"));
var pdf_images_1 = require("./pdf-images");
var rife_fps_1 = __importDefault(require("rife-fps"));
var exec = util_1.default.promisify(child_process_1.default.exec);
var Waifu2x = /** @class */ (function () {
function Waifu2x() {
}
var _a;
_a = Waifu2x;
Waifu2x.processes = [];
Waifu2x.addProcess = function (process) {
_a.processes.push(process);
};
Waifu2x.removeProcess = function (process) {
_a.processes = _a.processes.filter(function (p) { return p.pid !== process.pid; });
};
Waifu2x.chmod777 = function (waifu2xPath, webpPath, esrganPath, cuganPath, anime4kPath, rifePath) {
if (process.platform === "win32")
return;
var waifu2x = waifu2xPath ? path_1.default.normalize(waifu2xPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../waifu2x");
var esrgan = esrganPath ? path_1.default.normalize(esrganPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../real-esrgan");
var cugan = cuganPath ? path_1.default.normalize(cuganPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../real-cugan");
var anime4k = anime4kPath ? path_1.default.normalize(anime4kPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../anime4k");
var webp = webpPath ? path_1.default.normalize(webpPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../webp");
fs_1.default.chmodSync("".concat(waifu2x, "/waifu2x-ncnn-vulkan.app"), "777");
fs_1.default.chmodSync("".concat(esrgan, "/realesrgan-ncnn-vulkan.app"), "777");
fs_1.default.chmodSync("".concat(cugan, "/realcugan-ncnn-vulkan.app"), "777");
fs_1.default.chmodSync("".concat(anime4k, "/Anime4KCPP_CLI.app"), "777");
fs_1.default.chmodSync("".concat(webp, "/anim_dump.app"), "777");
fs_1.default.chmodSync("".concat(webp, "/cwebp.app"), "777");
fs_1.default.chmodSync("".concat(webp, "/dwebp.app"), "777");
fs_1.default.chmodSync("".concat(webp, "/img2webp.app"), "777");
fs_1.default.chmodSync("".concat(webp, "/webpmux.app"), "777");
rife_fps_1.default.chmod777(rifePath);
};
Waifu2x.parseFilename = function (source, dest, rename) {
var _b = ["", ""], image = _b[0], folder = _b[1];
if (!dest) {
image = null;
folder = null;
}
else if (path_1.default.basename(dest).includes(".")) {
image = path_1.default.basename(dest);
folder = dest.replace(image, "");
}
else {
image = null;
folder = dest;
}
if (!folder)
folder = "./";
if (folder.endsWith("/"))
folder = folder.slice(0, -1);
if (!image) {
image = "".concat(path_1.default.basename(source, path_1.default.extname(source))).concat(rename).concat(path_1.default.extname(source));
}
return { folder: folder, image: image };
};
Waifu2x.recursiveRename = function (folder, fileNames, rename) {
var _b;
if (folder.endsWith("/"))
folder = folder.slice(0, -1);
for (var i = 0; i < fileNames.length; i++) {
var fullPath = "".concat(folder, "/").concat(fileNames[i]);
var check = fs_1.default.statSync(fullPath);
if (check.isDirectory()) {
var subFiles = fs_1.default.readdirSync(fullPath);
_a.recursiveRename(fullPath, subFiles, rename);
}
else {
var pathSplit = fileNames[i].split(".");
var newName = ((_b = pathSplit === null || pathSplit === void 0 ? void 0 : pathSplit[0].split("_")) === null || _b === void 0 ? void 0 : _b[0]) + rename;
var newPath = "".concat(folder, "/").concat(newName, ".").concat(pathSplit.pop());
fs_1.default.renameSync(fullPath, newPath);
}
}
};
Waifu2x.parseDest = function (source, dest, options) {
options = __assign({}, options);
if (!dest)
dest = "./";
if (options.rename === undefined)
options.rename = "2x";
var _b = _a.parseFilename(source, dest, options.rename), folder = _b.folder, image = _b.image;
if (!path_1.default.isAbsolute(source) && !path_1.default.isAbsolute(dest)) {
var local = __dirname.includes("node_modules") ? path_1.default.join(__dirname, "../../../") : path_1.default.join(__dirname, "..");
folder = path_1.default.join(local, folder);
}
return path_1.default.normalize("".concat(folder, "/").concat(image)).replace(/\\/g, "/");
};
Waifu2x.timeout = function (ms) { return __awaiter(void 0, void 0, void 0, function () {
return __generator(_a, function (_b) {
return [2 /*return*/, new Promise(function (resolve) { return setTimeout(resolve, ms); })];
});
}); };
Waifu2x.convertToWebp = function (source, dest, webpPath, quality) { return __awaiter(void 0, void 0, void 0, function () {
var absolute, program, command, child;
return __generator(_a, function (_b) {
switch (_b.label) {
case 0:
if (!quality)
quality = 75;
absolute = webpPath ? path_1.default.normalize(webpPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../webp");
program = "cd \"".concat(absolute, "\" && ./cwebp.exe");
if (process.platform === "darwin")
program = "cd \"".concat(absolute, "\" && ./cwebp.app");
if (process.platform === "linux")
program = "cd \"".concat(absolute, "\" && ./cwebp");
command = "".concat(program, " -q ").concat(quality, " \"").concat(source, "\" -o \"").concat(dest, "\"");
child = child_process_1.default.exec(command);
_a.addProcess(child);
return [4 /*yield*/, new Promise(function (resolve, reject) {
child.on("close", function () {
_a.removeProcess(child);
resolve();
});
})];
case 1:
_b.sent();
return [2 /*return*/, dest];
}
});
}); };
Waifu2x.convertFromWebp = function (source, dest, webpPath) { return __awaiter(void 0, void 0, void 0, function () {
var absolute, program, command, child, error;
return __generator(_a, function (_b) {
switch (_b.label) {
case 0:
absolute = webpPath ? path_1.default.normalize(webpPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../webp");
program = "cd \"".concat(absolute, "\" && ./dwebp.exe");
if (process.platform === "darwin")
program = "cd \"".concat(absolute, "\" && ./dwebp.app");
if (process.platform === "linux")
program = "cd \"".concat(absolute, "\" && ./dwebp");
command = "".concat(program, " \"").concat(source, "\" -o \"").concat(dest, "\"");
child = child_process_1.default.exec(command);
_a.addProcess(child);
error = "";
return [4 /*yield*/, new Promise(function (resolve, reject) {
child.stderr.on("data", function (chunk) { return error += chunk; });
child.on("close", function () {
_a.removeProcess(child);
resolve();
});
})];
case 1:
_b.sent();
if (error.includes("animated WebP"))
return [2 /*return*/, Promise.reject(error)];
return [2 /*return*/, dest];
}
});
}); };
Waifu2x.upscaleImage = function (source, dest, options, progress) { return __awaiter(void 0, void 0, void 0, function () {
var sourcePath, _b, folder, image, local, destPath, absolute, buffer, dimensions, error_1, command, program, ext, program, ext, program, ext, program, python, program, child, stopped, poll, error;
return __generator(_a, function (_c) {
switch (_c.label) {
case 0:
options = __assign({}, options);
if (!dest)
dest = "./";
if (!options.upscaler)
options.upscaler = "waifu2x";
sourcePath = source;
if (options.rename === undefined)
options.rename = "2x";
_b = _a.parseFilename(source, dest, options.rename), folder = _b.folder, image = _b.image;
if (!fs_1.default.existsSync(folder))
fs_1.default.mkdirSync(folder, { recursive: true });
local = __dirname.includes("node_modules") ? path_1.default.join(__dirname, "../../../") : path_1.default.join(__dirname, "..");
if (!path_1.default.isAbsolute(source) && !path_1.default.isAbsolute(dest)) {
sourcePath = path_1.default.join(local, source);
folder = path_1.default.join(local, folder);
}
destPath = path_1.default.join(folder, image).replace(/\\/g, "/");
absolute = "";
if (options.upscaler === "waifu2x") {
absolute = options.waifu2xPath ? path_1.default.normalize(options.waifu2xPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../waifu2x");
}
else if (options.upscaler === "real-esrgan") {
absolute = options.esrganPath ? path_1.default.normalize(options.esrganPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../real-esrgan");
}
else if (options.upscaler === "real-cugan") {
absolute = options.cuganPath ? path_1.default.normalize(options.cuganPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../real-cugan");
}
else if (options.upscaler === "anime4k") {
absolute = options.anime4kPath ? path_1.default.normalize(options.anime4kPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../anime4k");
}
else {
absolute = options.scriptsPath ? path_1.default.normalize(options.scriptsPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../scripts");
}
buffer = fs_1.default.readFileSync(sourcePath);
dimensions = (0, image_size_1.imageSize)(buffer);
if (!(dimensions.type === "webp")) return [3 /*break*/, 4];
_c.label = 1;
case 1:
_c.trys.push([1, 3, , 4]);
return [4 /*yield*/, _a.convertFromWebp(sourcePath, destPath, options.webpPath)];
case 2:
_c.sent();
sourcePath = destPath;
return [3 /*break*/, 4];
case 3:
error_1 = _c.sent();
return [2 /*return*/, Promise.reject("Animated webp: ".concat(error_1))];
case 4:
command = "";
if (options.upscaler === "waifu2x") {
program = "cd \"".concat(absolute, "\" && waifu2x-ncnn-vulkan.exe");
if (process.platform === "darwin")
program = "cd \"".concat(absolute, "\" && ./waifu2x-ncnn-vulkan.app");
if (process.platform === "linux")
program = "cd \"".concat(absolute, "\" && ./waifu2x-ncnn-vulkan");
if (process.platform === "linux" && process.arch === "arm64")
program = "cd \"".concat(absolute, "\" && ./waifu2x-ncnn-vulkan-arm");
ext = path_1.default.extname(source).replace(".", "");
command = "".concat(program, " -i \"").concat(sourcePath, "\" -o \"").concat(destPath, "\" -f ").concat(ext);
if (options.scale)
command += " -s ".concat(options.scale);
if (options.threads)
command += " -j ".concat(options.threads, ":").concat(options.threads, ":").concat(options.threads);
if (options.waifu2xModel)
command += " -m \"".concat(options.waifu2xModel, "\"");
}
else if (options.upscaler === "real-esrgan") {
program = "cd \"".concat(absolute, "\" && realesrgan-ncnn-vulkan.exe");
if (process.platform === "darwin")
program = "cd \"".concat(absolute, "\" && ./realesrgan-ncnn-vulkan.app");
if (process.platform === "linux")
program = "cd \"".concat(absolute, "\" && ./realesrgan-ncnn-vulkan");
if (process.platform === "linux" && process.arch === "arm64")
program = "cd \"".concat(absolute, "\" && ./realesrgan-ncnn-vulkan-arm");
ext = path_1.default.extname(source).replace(".", "");
command = "".concat(program, " -i \"").concat(sourcePath, "\" -o \"").concat(destPath, "\" -f ").concat(ext, " -n ").concat(options.scale === 4 ? "realesrgan-x4plus-anime" : "realesr-animevideov3");
if (options.scale)
command += " -s ".concat(options.scale);
if (options.threads)
command += " -j ".concat(options.threads, ":").concat(options.threads, ":").concat(options.threads);
}
else if (options.upscaler === "real-cugan") {
program = "cd \"".concat(absolute, "\" && realcugan-ncnn-vulkan.exe");
if (process.platform === "darwin")
program = "cd \"".concat(absolute, "\" && ./realcugan-ncnn-vulkan.app");
if (process.platform === "linux")
program = "cd \"".concat(absolute, "\" && ./realcugan-ncnn-vulkan");
if (process.platform === "linux" && process.arch === "arm64")
program = "cd \"".concat(absolute, "\" && ./realcugan-ncnn-vulkan-arm");
ext = path_1.default.extname(source).replace(".", "");
command = "".concat(program, " -i \"").concat(sourcePath, "\" -o \"").concat(destPath, "\" -f ").concat(ext);
if (options.noise) {
if (Number(options.scale) > 2) {
if (Number(options.noise) === 2)
options.noise = 3;
if (Number(options.noise) === 1)
options.noise = 0;
}
command += " -n ".concat(options.noise);
}
if (options.scale)
command += " -s ".concat(options.scale);
if (options.threads)
command += " -j ".concat(options.threads, ":").concat(options.threads, ":").concat(options.threads);
}
else if (options.upscaler === "anime4k") {
program = "cd \"".concat(absolute, "\" && Anime4KCPP_CLI.exe");
if (process.platform === "darwin")
program = "cd \"".concat(absolute, "\" && ./Anime4KCPP_CLI.app");
if (process.platform === "linux")
program = "cd \"".concat(absolute, "\" && ./Anime4KCPP_CLI");
if (process.platform === "linux" && process.arch === "arm64")
program = "cd \"".concat(absolute, "\" && ./ac_cli");
command = "".concat(program, " -i \"").concat(sourcePath, "\" -o \"").concat(destPath, "\" -A");
if (options.scale)
command += " -z ".concat(options.scale);
}
else {
python = process.platform === "darwin" ? "PYTORCH_ENABLE_MPS_FALLBACK=1 /usr/local/bin/python3" : "python3";
program = "cd \"".concat(absolute, "\" && ").concat(python, " upscale.py");
command = "".concat(program, " -i \"").concat(sourcePath, "\" -o \"").concat(destPath, "\" -m \"").concat(options.upscaler, "\"");
if (options.pythonDownscale && Number(options.pythonDownscale > 0))
command += " -d ".concat(options.pythonDownscale);
}
child = child_process_1.default.exec(command);
_a.addProcess(child);
stopped = false;
poll = function () { return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (progress()) {
stopped = true;
child.stdio.forEach(function (s) { return s.destroy(); });
child.kill("SIGINT");
}
return [4 /*yield*/, _a.timeout(1000)];
case 1:
_b.sent();
if (!stopped)
poll();
return [2 /*return*/];
}
});
}); };
if (progress)
poll();
error = "";
return [4 /*yield*/, new Promise(function (resolve, reject) {
child.stderr.on("data", function (chunk) {
if (options.upscaler === "real-esrgan") {
var percent = Number(chunk.replace("%", "").replace(",", "."));
if (!Number.isNaN(percent))
progress === null || progress === void 0 ? void 0 : progress(percent);
}
});
child.on("close", function () {
stopped = true;
_a.removeProcess(child);
resolve();
});
})];
case 5:
_c.sent();
if (error)
return [2 /*return*/, Promise.reject(error)];
if (!(path_1.default.extname(destPath) === ".webp")) return [3 /*break*/, 7];
return [4 /*yield*/, _a.convertToWebp(destPath, destPath, options.webpPath, options.jpgWebpQuality)];
case 6:
_c.sent();
_c.label = 7;
case 7: return [2 /*return*/, path_1.default.normalize(destPath).replace(/\\/g, "/")];
}
});
}); };
Waifu2x.searchFiles = function (dir, recursive) {
if (recursive === void 0) { recursive = false; }
var files = fs_1.default.readdirSync(dir);
var fileMap = files.map(function (file) { return "".concat(dir, "/").concat(file); }).filter(function (f) { return fs_1.default.lstatSync(f).isFile(); });
if (!recursive)
return fileMap;
var dirMap = files.map(function (file) { return "".concat(dir, "/").concat(file); }).filter(function (f) { return fs_1.default.lstatSync(f).isDirectory(); });
return fileMap.concat(dirMap.flatMap(function (dirEntry) { return _a.searchFiles(dirEntry, true); }));
};
Waifu2x.upscaleImages = function (sourceFolder, destFolder, options, progress) { return __awaiter(void 0, void 0, void 0, function () {
var fileMap, retArray, cancel, counter, total, queue, i;
return __generator(_a, function (_b) {
switch (_b.label) {
case 0:
options = __assign({}, options);
if (sourceFolder.endsWith("/"))
sourceFolder = sourceFolder.slice(0, -1);
fileMap = _a.searchFiles(sourceFolder, options === null || options === void 0 ? void 0 : options.recursive);
if (!options.limit)
options.limit = fileMap.length;
retArray = [];
cancel = false;
counter = 1;
total = fileMap.length;
queue = [];
if (!options.parallelFrames)
options.parallelFrames = 1;
while (fileMap.length)
queue.push(fileMap.splice(0, options.parallelFrames));
if (progress)
progress(0, total);
i = 0;
_b.label = 1;
case 1:
if (!(i < queue.length)) return [3 /*break*/, 4];
return [4 /*yield*/, Promise.all(queue[i].map(function (f) { return __awaiter(void 0, void 0, void 0, function () {
var ret, stop;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (counter >= options.limit)
cancel = true;
return [4 /*yield*/, _a.upscaleImage(f, destFolder, options)];
case 1:
ret = _b.sent();
retArray.push(ret);
stop = progress ? progress(counter++, total) : false;
if (stop)
cancel = true;
return [2 /*return*/];
}
});
}); }))];
case 2:
_b.sent();
if (cancel)
return [3 /*break*/, 4];
_b.label = 3;
case 3:
i++;
return [3 /*break*/, 1];
case 4: return [2 /*return*/, retArray];
}
});
}); };
Waifu2x.parseTransparentColor = function (color) {
return Number("0x".concat(color.replace(/^#/, "")));
};
Waifu2x.encodeGIF = function (files, delays, dest, quality, transparentColor) { return __awaiter(void 0, void 0, void 0, function () {
return __generator(_a, function (_b) {
if (!quality)
quality = 10;
return [2 /*return*/, new Promise(function (resolve) {
var dimensions = (0, image_size_1.imageSize)(files === null || files === void 0 ? void 0 : files[0]);
var gif = new gif_encoder_1.default(dimensions.width, dimensions.height, { highWaterMark: 5 * 1024 * 1024 });
var file = fs_1.default.createWriteStream(dest);
gif.pipe(file);
gif.setQuality(quality);
gif.setRepeat(0);
gif.writeHeader();
if (transparentColor)
gif.setTransparent(_a.parseTransparentColor(transparentColor));
var counter = 0;
var addToGif = function (frames) {
(0, get_pixels_1.default)(frames[counter], function (err, pixels) {
if (err)
throw err;
gif.setDelay(10 * delays[counter]);
gif.addFrame(pixels.data);
if (counter >= frames.length - 1) {
gif.finish();
}
else {
counter++;
addToGif(files);
}
});
};
addToGif(files);
gif.on("end", resolve);
})];
});
}); };
Waifu2x.awaitStream = function (writeStream) { return __awaiter(void 0, void 0, void 0, function () {
return __generator(_a, function (_b) {
return [2 /*return*/, new Promise(function (resolve, reject) {
writeStream.on("finish", resolve);
writeStream.on("error", reject);
})];
});
}); };
Waifu2x.newDest = function (dest) {
var i = 1;
var newDest = dest;
while (fs_1.default.existsSync(newDest)) {
newDest = "".concat(dest, "_").concat(i);
i++;
}
return newDest;
};
Waifu2x.findMatchingSettings = function (dest, options) {
var i = 1;
var newDest = dest;
if (fs_1.default.existsSync(newDest)) {
var settings = JSON.parse(fs_1.default.readFileSync("".concat(newDest, "/settings.json"), "utf8"));
if (JSON.stringify(settings) === JSON.stringify(options)) {
return newDest;
}
}
newDest = "".concat(dest, "_").concat(i);
while (fs_1.default.existsSync(newDest) || i < 10) {
if (fs_1.default.existsSync(newDest)) {
var settings = JSON.parse(fs_1.default.readFileSync("".concat(newDest, "/settings.json"), "utf8"));
if (JSON.stringify(settings) === JSON.stringify(options)) {
return newDest;
}
}
i++;
newDest = "".concat(dest, "_").concat(i);
}
return null;
};
Waifu2x.upscaleGIF = function (source, dest, options, progress) { return __awaiter(void 0, void 0, void 0, function () {
function downloadFrames(frames) {
return __awaiter(this, void 0, void 0, function () {
var promiseArray, i, writeStream;
return __generator(this, function (_b) {
promiseArray = [];
for (i = 0; i < frames.length; i += step) {
writeStream = fs_1.default.createWriteStream("".concat(frameDest, "/frame").concat(i, ".").concat(frameExt));
frames[i].getImage().pipe(writeStream);
frameArray.push("".concat(frameDest, "/frame").concat(i, ".").concat(frameExt));
delayArray.push(frames[i].frameInfo.delay);
promiseArray.push(_a.awaitStream(writeStream));
}
return [2 /*return*/, Promise.all(promiseArray)];
});
});
}
var frameExt, frames, _b, folder, image, local, frameDest, resume, matching, constraint, step, frameArray, delayArray, upScaleDest, scaledFrames, cancel, counter_1, total_1, queue, i, finalDest;
return __generator(_a, function (_c) {
switch (_c.label) {
case 0:
options = __assign({}, options);
if (!dest)
dest = "./";
frameExt = options.pngFrames ? "png" : "jpg";
return [4 /*yield*/, (0, gif_frames_1.default)({ url: source, frames: "all", outputType: frameExt })];
case 1:
frames = _c.sent();
_b = _a.parseFilename(source, dest, "2x"), folder = _b.folder, image = _b.image;
if (!path_1.default.isAbsolute(source) && !path_1.default.isAbsolute(dest)) {
local = __dirname.includes("node_modules") ? path_1.default.join(__dirname, "../../../") : path_1.default.join(__dirname, "..");
folder = path_1.default.join(local, folder);
}
frameDest = "".concat(folder, "/").concat(path_1.default.basename(source, path_1.default.extname(source)), "Frames");
resume = 0;
if (fs_1.default.existsSync(frameDest)) {
matching = _a.findMatchingSettings(frameDest, options);
if (matching) {
frameDest = matching;
resume = fs_1.default.readdirSync("".concat(frameDest, "/upscaled")).length;
}
else {
frameDest = _a.newDest(frameDest);
fs_1.default.mkdirSync(frameDest, { recursive: true });
fs_1.default.writeFileSync("".concat(frameDest, "/settings.json"), JSON.stringify(options));
}
}
else {
fs_1.default.mkdirSync(frameDest, { recursive: true });
fs_1.default.writeFileSync("".concat(frameDest, "/settings.json"), JSON.stringify(options));
}
constraint = options.speed > 1 ? frames.length / options.speed : frames.length;
step = Math.ceil(frames.length / constraint);
frameArray = [];
delayArray = [];
return [4 /*yield*/, downloadFrames(frames)];
case 2:
_c.sent();
if (options.speed < 1)
delayArray = delayArray.map(function (n) { return n / options.speed; });
upScaleDest = "".concat(frameDest, "/upscaled");
if (!fs_1.default.existsSync(upScaleDest))
fs_1.default.mkdirSync(upScaleDest, { recursive: true });
options.rename = "";
scaledFrames = fs_1.default.readdirSync(upScaleDest).map(function (f) { return "".concat(upScaleDest, "/").concat(path_1.default.basename(f)); });
cancel = false;
if (!(options.scale !== 1)) return [3 /*break*/, 7];
counter_1 = resume;
total_1 = frameArray.length;
queue = [];
if (!options.parallelFrames)
options.parallelFrames = 1;
frameArray = frameArray.slice(resume);
while (frameArray.length)
queue.push(frameArray.splice(0, options.parallelFrames));
if (progress)
progress(counter_1++, total_1);
i = 0;
_c.label = 3;
case 3:
if (!(i < queue.length)) return [3 /*break*/, 6];
return [4 /*yield*/, Promise.all(queue[i].map(function (f) { return __awaiter(void 0, void 0, void 0, function () {
var destPath, stop;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, _a.upscaleImage(f, "".concat(upScaleDest, "/").concat(path_1.default.basename(f)), options)];
case 1:
destPath = _b.sent();
scaledFrames.push(destPath);
stop = progress ? progress(counter_1++, total_1) : false;
if (stop)
cancel = true;
return [2 /*return*/];
}
});
}); }))];
case 4:
_c.sent();
if (cancel)
return [3 /*break*/, 6];
_c.label = 5;
case 5:
i++;
return [3 /*break*/, 3];
case 6: return [3 /*break*/, 8];
case 7:
scaledFrames = frameArray;
_c.label = 8;
case 8:
scaledFrames = scaledFrames.sort(new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }).compare);
if (options.reverse) {
scaledFrames = scaledFrames.reverse();
delayArray = delayArray.reverse();
}
finalDest = path_1.default.join(folder, image);
return [4 /*yield*/, _a.encodeGIF(scaledFrames, delayArray, finalDest, options.quality, options.transparentColor)];
case 9:
_c.sent();
if (options.noResume || !cancel)
_a.removeDirectory(frameDest);
return [2 /*return*/, path_1.default.normalize(finalDest).replace(/\\/g, "/")];
}
});
}); };
Waifu2x.upscaleGIFs = function (sourceFolder, destFolder, options, totalProgress, progress) { return __awaiter(void 0, void 0, void 0, function () {
var files, fileMap, retArray, i, ret, stop_1, err_1;
return __generator(_a, function (_b) {
switch (_b.label) {
case 0:
options = __assign({}, options);
files = fs_1.default.readdirSync(sourceFolder);
if (sourceFolder.endsWith("/"))
sourceFolder = sourceFolder.slice(0, -1);
fileMap = files.map(function (file) { return "".concat(sourceFolder, "/").concat(file); });
if (!options.limit)
options.limit = fileMap.length;
retArray = [];
if (totalProgress)
totalProgress(0, options.limit);
i = 0;
_b.label = 1;
case 1:
if (!(i < options.limit)) return [3 /*break*/, 6];
if (!fileMap[i])
return [3 /*break*/, 6];
_b.label = 2;
case 2:
_b.trys.push([2, 4, , 5]);
return [4 /*yield*/, _a.upscaleGIF(fileMap[i], destFolder, options, progress)];
case 3:
ret = _b.sent();
stop_1 = totalProgress ? totalProgress(i + 1, options.limit) : false;
retArray.push(ret);
if (stop_1)
return [3 /*break*/, 6];
return [3 /*break*/, 5];
case 4:
err_1 = _b.sent();
return [3 /*break*/, 5];
case 5:
i++;
return [3 /*break*/, 1];
case 6: return [2 /*return*/, retArray];
}
});
}); };
Waifu2x.dumpWebpFrames = function (source, frameDest, webpPath) { return __awaiter(void 0, void 0, void 0, function () {
var absolute, program, command, child;
return __generator(_a, function (_b) {
switch (_b.label) {
case 0:
absolute = webpPath ? path_1.default.normalize(webpPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../webp");
program = "cd \"".concat(absolute, "\" && ./anim_dump.exe");
if (process.platform === "darwin")
program = "cd \"".concat(absolute, "\" && ./anim_dump.app");
if (process.platform === "linux")
program = "cd \"".concat(absolute, "\" && ./anim_dump");
command = "".concat(program, " -folder \"").concat(frameDest, "\" -prefix \"frame\" \"").concat(source, "\"");
child = child_process_1.default.exec(command);
_a.addProcess(child);
return [4 /*yield*/, new Promise(function (resolve, reject) {
child.on("close", function () {
_a.removeProcess(child);
resolve();
});
})];
case 1:
_b.sent();
return [2 /*return*/, fs_1.default.readdirSync(frameDest).sort(new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }).compare)
.filter(function (s) { return s !== "settings.json"; })];
}
});
}); };
Waifu2x.parseWebpDelays = function (source, webpPath) { return __awaiter(void 0, void 0, void 0, function () {
var absolute, program, command, child, data;
return __generator(_a, function (_b) {
switch (_b.label) {
case 0:
absolute = webpPath ? path_1.default.normalize(webpPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../webp");
program = "cd \"".concat(absolute, "\" && ./webpmux.exe");
if (process.platform === "darwin")
program = "cd \"".concat(absolute, "\" && ./webpmux.app");
if (process.platform === "linux")
program = "cd \"".concat(absolute, "\" && ./webpmux");
command = "".concat(program, " -info \"").concat(source, "\"");
child = child_process_1.default.exec(command);
data = "";
_a.addProcess(child);
return [4 /*yield*/, new Promise(function (resolve, reject) {
child.stdout.on("data", function (chunk) { return data += chunk; });
child.on("close", function () {
_a.removeProcess(child);
resolve();
});
})];
case 1:
_b.sent();
return [2 /*return*/, data.split("\n").slice(5).map(function (r) { return parseInt(r.split(/ +/g)[7]); }).filter(Boolean)];
}
});
}); };
Waifu2x.encodeAnimatedWebp = function (files, delays, dest, webpPath, quality) { return __awaiter(void 0, void 0, void 0, function () {
var frames, absolute, program, command, child, error;
return __generator(_a, function (_b) {
switch (_b.label) {
case 0:
if (!quality)
quality = 75;
frames = files.map(function (f, i) { return "-d ".concat(delays[i], " \"").concat(f, "\""); }).join(" ");
absolute = webpPath ? path_1.default.normalize(webpPath).replace(/\\/g, "/") : path_1.default.join(__dirname, "../webp");
program = "cd \"".concat(absolute, "\" && ./img2webp.exe");
if (process.platform === "darwin")
program = "cd \"".concat(absolute, "\" && ./img2webp.app");
if (process.platform === "linux")
program = "cd \"".concat(absolute, "\" && ./img2webp");
command = "".concat(program, " -loop \"0\" ").concat(frames, " -o \"").concat(dest, "\"");
child = child_process_1.default.exec(command);
_a.addProcess(child);
error = "";
return [4 /*yield*/, new Promise(function (resolve, reject) {
child.stderr.on("data", function (chunk) { return error += chunk; });
child.on("close", function () {
_a.removeProcess(child);
resolve();
});
})];
case 1:
_b.sent();
return [2 /*return*/, dest];
}
});
}); };
Waifu2x.upscaleAnimatedWebp = function (source, dest, options, progress) { return __awaiter(void 0, void 0, void 0, function () {
var _b, folder, image, local, frameDest, resume, matching, frames, delays, constraint, step, frameArray, delayArray, i, upScaleDest, scaledFrames, cancel, counter_2, total_2, queue, i, finalDest;
return __generator(_a, function (_c) {
switch (_c.label) {
case 0:
options = __assign({}, options);
if (!dest)
dest = "./";
_b = _a.parseFilename(source, dest, "2x"), folder = _b.folder, image = _b.image;
if (!path_1.default.isAbsolute(source) && !path_1.default.isAbsolute(dest)) {
local = __dirname.includes("node_modules") ? path_1.default.join(__dirname, "../../../") : path_1.default.join(__dirname, "..");
folder = path_1.default.join(local, folder);
source = path_1.default.join(local, source);
}
frameDest = "".concat(folder, "/").concat(path_1.default.basename(source, path_1.default.extname(source)), "Frames");
resume = 0;
if (fs_1.default.existsSync(frameDest)) {
matching = _a.findMatchingSettings(frameDest, options);
if (matching) {
frameDest = matching;
resume = fs_1.default.readdirSync("".concat(frameDest, "/upscaled")).length;
}
else {
frameDest = _a.newDest(frameDest);
fs_1.default.mkdirSync(frameDest, { recursive: true });
fs_1.default.writeFileSync("".concat(frameDest, "/settings.json"), JSON.stringify(options));
}
}
else {
fs_1.default.mkdirSync(frameDest, { recursive: true });
fs_1.default.writeFileSync("".concat(frameDest, "/settings.json"), JSON.stringify(options));
}
return [4 /*yield*/, _a.dumpWebpFrames(source, frameDest, options.webpPath)];
case 1:
frames = _c.sent();
return [4 /*yield*/, _a.parseWebpDelays(source, options.webpPath)];
case 2:
delays = _c.sent();
constraint = options.speed > 1 ? frames.length / options.speed : frames.length;
step = Math.ceil(frames.length / constraint);
frameArray = [];
delayArray = [];
for (i = 0; i < frames.length; i += step) {
frameArray.push("".concat(frameDest, "/").concat(frames[i]));
delayArray.push(delays[i]);
}
if (options.speed < 1)
delayArray = delayArray.map(function (n) { return n / options.speed; });
upScaleDest = "".concat(frameDest, "/upscaled");
if (!fs_1.default.existsSync(upScaleDest))
fs_1.default.mkdirSync(upScaleDest, { recursive: true });
options.rename = "";
scaledFrames = fs_1.default.readdirSync(upScaleDest).map(function (f) { return "".concat(upScaleDest, "/").concat(path_1.default.basename(f)); });
cancel = false;
if (!(options.scale !== 1)) return [3 /*break*/, 7];
counter_2 = resume;
total_2 = frameArray.length;
queue = [];
if (!options.parallelFrames)
options.parallelFrames = 1;
frameArray = frameArray.slice(resume);
while (frameArray.length)
queue.push(frameArray.splice(0, options.parallelFrames));
if (progress)
progress(counter_2++, total_2);
i = 0;
_c.label = 3;
case 3:
if (!(i < queue.length)) return [3 /*break*/, 6];
return [4 /*yield*/, Promise.all(queue[i].map(function (f) { return __awaiter(void 0, void 0, void 0, function () {
var destPath, stop;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, _a.upscaleImage(f, "".c