waifu2x
Version:
2x upscaling of images with waifu2x
233 lines (227 loc) • 11.9 kB
JavaScript
;
/*
Copyright (c) 2020 Ollie Thwaites
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
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 (_) 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 };
}
};
exports.__esModule = true;
var isURL = require('is-url');
var pdfjs = require('pdfjs-dist/legacy/build/pdf.js');
var Canvas = require("canvas");
var assert = require("assert").strict;
var fs = require("fs");
var util = require('util');
var readFile = util.promisify(fs.readFile);
function NodeCanvasFactory() { }
NodeCanvasFactory.prototype = {
create: function NodeCanvasFactory_create(width, height) {
assert(width > 0 && height > 0, "Invalid canvas size");
var canvas = Canvas.createCanvas(width, height);
var context = canvas.getContext("2d");
return {
canvas: canvas,
context: context
};
},
reset: function NodeCanvasFactory_reset(canvasAndContext, width, height) {
assert(canvasAndContext.canvas, "Canvas is not specified");
assert(width > 0 && height > 0, "Invalid canvas size");
canvasAndContext.canvas.width = width;
canvasAndContext.canvas.height = height;
},
destroy: function NodeCanvasFactory_destroy(canvasAndContext) {
assert(canvasAndContext.canvas, "Canvas is not specified");
// Zeroing the width and height cause Firefox to release graphics
// resources immediately, which can greatly reduce memory consumption.
canvasAndContext.canvas.width = 0;
canvasAndContext.canvas.height = 0;
canvasAndContext.canvas = null;
canvasAndContext.context = null;
}
};
function convert(pdf, conversion_config) {
if (conversion_config === void 0) { conversion_config = {}; }
return __awaiter(this, void 0, void 0, function () {
var pdfData, resp, _a, _b, outputPages, loadingTask, pdfDocument, canvasFactory, i, currentPage, i, currentPage;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
pdfData = pdf;
if (!(typeof pdf === 'string')) return [3 /*break*/, 7];
if (!(isURL(pdf) || pdf.startsWith('moz-extension://') || pdf.startsWith('chrome-extension://') || pdf.startsWith('file://'))) return [3 /*break*/, 3];
return [4 /*yield*/, fetch(pdf)];
case 1:
resp = _c.sent();
_a = Uint8Array.bind;
return [4 /*yield*/, resp.arrayBuffer()];
case 2:
pdfData = new (_a.apply(Uint8Array, [void 0, _c.sent()]))();
return [3 /*break*/, 6];
case 3:
if (!/pdfData:pdf\/([a-zA-Z]*);base64,([^"]*)/.test(pdf)) return [3 /*break*/, 4];
pdfData = new Uint8Array(Buffer.from(pdf.split(',')[1], 'base64'));
return [3 /*break*/, 6];
case 4:
_b = Uint8Array.bind;
return [4 /*yield*/, readFile(pdf)];
case 5:
pdfData = new (_b.apply(Uint8Array, [void 0, _c.sent()]))();
_c.label = 6;
case 6: return [3 /*break*/, 8];
case 7:
if (Buffer.isBuffer(pdf)) {
pdfData = new Uint8Array(pdf);
}
// Support for Uint8Array input
// @ts-ignore
else if (!pdf instanceof Uint8Array) {
//@ts-ignore
return [2 /*return*/, pdf];
}
_c.label = 8;
case 8:
outputPages = [];
loadingTask = pdfjs.getDocument({ data: pdfData, disableFontFace: true, verbosity: 0 });
return [4 /*yield*/, loadingTask.promise];
case 9:
pdfDocument = _c.sent();
canvasFactory = new NodeCanvasFactory();
if (conversion_config.height <= 0 || conversion_config.width <= 0)
console.error("Negative viewport dimension given. Defaulting to 100% scale.");
if (!conversion_config.page_numbers) return [3 /*break*/, 14];
i = 0;
_c.label = 10;
case 10:
if (!(i < conversion_config.page_numbers.length)) return [3 /*break*/, 13];
return [4 /*yield*/, doc_render(pdfDocument, conversion_config.page_numbers[i], canvasFactory, conversion_config)];
case 11:
currentPage = _c.sent();
if (currentPage != null) {
// This allows for base64 conversion of output images
if (conversion_config.base64)
outputPages.push(currentPage.toString('base64'));
else
outputPages.push(new Uint8Array(currentPage));
}
_c.label = 12;
case 12:
i++;
return [3 /*break*/, 10];
case 13: return [3 /*break*/, 18];
case 14:
i = 1;
_c.label = 15;
case 15:
if (!(i <= pdfDocument.numPages)) return [3 /*break*/, 18];
return [4 /*yield*/, doc_render(pdfDocument, i, canvasFactory, conversion_config)];
case 16:
currentPage = _c.sent();
if (currentPage != null) {
// This allows for base64 conversion of output images
if (conversion_config.base64)
outputPages.push(currentPage.toString('base64'));
else
outputPages.push(new Uint8Array(currentPage));
}
_c.label = 17;
case 17:
i++;
return [3 /*break*/, 15];
case 18: return [2 /*return*/, outputPages];
}
});
});
} // convert method
exports["default"] = convert;
function doc_render(pdfDocument, pageNo, canvasFactory, conversion_config) {
return __awaiter(this, void 0, void 0, function () {
var page, outputScale, viewport, canvasAndContext, renderContext, renderTask, image;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
// Page number sanity check
if (pageNo < 1 || pageNo > pdfDocument.numPages) {
console.error("Invalid page number " + pageNo);
return [2 /*return*/];
}
if (conversion_config && conversion_config.scale && conversion_config.scale <= 0) {
console.error("Invalid scale " + conversion_config.scale);
return [2 /*return*/];
}
return [4 /*yield*/, pdfDocument.getPage(pageNo)];
case 1:
page = _a.sent();
outputScale = conversion_config.scale || 1.0;
viewport = page.getViewport({ scale: outputScale });
// Scale it up / down dependent on the sizes given in the config (if there
// are any)
if (conversion_config.width)
outputScale = conversion_config.width / viewport.width;
else if (conversion_config.height)
outputScale = conversion_config.height / viewport.height;
if (outputScale != 1 && outputScale > 0)
viewport = page.getViewport({ scale: outputScale });
canvasAndContext = canvasFactory.create(viewport.width, viewport.height);
renderContext = {
canvasContext: canvasAndContext.context,
viewport: viewport,
canvasFactory: canvasFactory
};
return [4 /*yield*/, page.render(renderContext).promise];
case 2:
renderTask = _a.sent();
image = canvasAndContext.canvas.toBuffer();
return [2 /*return*/, image];
}
});
});
} // doc_render