XeNote/.yarn/unplugged/sharp-npm-0.26.2-a42331601c/node_modules/sharp/src/utilities.cc
canburaks b23e3ff508 ...
2021-05-17 04:16:19 +03:00

228 lines
7.4 KiB
C++

// Copyright 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Lovell Fuller and contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cmath>
#include <string>
#include <napi.h>
#include <vips/vips8>
#include <vips/vector.h>
#include "common.h"
#include "operations.h"
#include "utilities.h"
/*
Get and set cache limits
*/
Napi::Value cache(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
// Set memory limit
if (info[0].IsNumber()) {
vips_cache_set_max_mem(info[0].As<Napi::Number>().Int32Value() * 1048576);
}
// Set file limit
if (info[1].IsNumber()) {
vips_cache_set_max_files(info[1].As<Napi::Number>().Int32Value());
}
// Set items limit
if (info[2].IsNumber()) {
vips_cache_set_max(info[2].As<Napi::Number>().Int32Value());
}
// Get memory stats
Napi::Object memory = Napi::Object::New(env);
memory.Set("current", round(vips_tracked_get_mem() / 1048576));
memory.Set("high", round(vips_tracked_get_mem_highwater() / 1048576));
memory.Set("max", round(vips_cache_get_max_mem() / 1048576));
// Get file stats
Napi::Object files = Napi::Object::New(env);
files.Set("current", vips_tracked_get_files());
files.Set("max", vips_cache_get_max_files());
// Get item stats
Napi::Object items = Napi::Object::New(env);
items.Set("current", vips_cache_get_size());
items.Set("max", vips_cache_get_max());
Napi::Object cache = Napi::Object::New(env);
cache.Set("memory", memory);
cache.Set("files", files);
cache.Set("items", items);
return cache;
}
/*
Get and set size of thread pool
*/
Napi::Value concurrency(const Napi::CallbackInfo& info) {
// Set concurrency
if (info[0].IsNumber()) {
vips_concurrency_set(info[0].As<Napi::Number>().Int32Value());
}
// Get concurrency
return Napi::Number::New(info.Env(), vips_concurrency_get());
}
/*
Get internal counters (queued tasks, processing tasks)
*/
Napi::Value counters(const Napi::CallbackInfo& info) {
Napi::Object counters = Napi::Object::New(info.Env());
counters.Set("queue", sharp::counterQueue);
counters.Set("process", sharp::counterProcess);
return counters;
}
/*
Get and set use of SIMD vector unit instructions
*/
Napi::Value simd(const Napi::CallbackInfo& info) {
// Set state
if (info[0].IsBoolean()) {
vips_vector_set_enabled(info[0].As<Napi::Boolean>().Value());
}
// Get state
return Napi::Boolean::New(info.Env(), vips_vector_isenabled());
}
/*
Get libvips version
*/
Napi::Value libvipsVersion(const Napi::CallbackInfo& info) {
char version[9];
g_snprintf(version, sizeof(version), "%d.%d.%d", vips_version(0), vips_version(1), vips_version(2));
return Napi::String::New(info.Env(), version);
}
/*
Get available input/output file/buffer/stream formats
*/
Napi::Value format(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::Object format = Napi::Object::New(env);
for (std::string const f : {
"jpeg", "png", "webp", "tiff", "magick", "openslide", "dz",
"ppm", "fits", "gif", "svg", "heif", "pdf", "vips"
}) {
// Input
Napi::Boolean hasInputFile =
Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "load").c_str()));
Napi::Boolean hasInputBuffer =
Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "load_buffer").c_str()));
Napi::Object input = Napi::Object::New(env);
input.Set("file", hasInputFile);
input.Set("buffer", hasInputBuffer);
input.Set("stream", hasInputBuffer);
// Output
Napi::Boolean hasOutputFile =
Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "save").c_str()));
Napi::Boolean hasOutputBuffer =
Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "save_buffer").c_str()));
Napi::Object output = Napi::Object::New(env);
output.Set("file", hasOutputFile);
output.Set("buffer", hasOutputBuffer);
output.Set("stream", hasOutputBuffer);
// Other attributes
Napi::Object container = Napi::Object::New(env);
container.Set("id", f);
container.Set("input", input);
container.Set("output", output);
// Add to set of formats
format.Set(f, container);
}
// Raw, uncompressed data
Napi::Boolean supported = Napi::Boolean::New(env, true);
Napi::Boolean unsupported = Napi::Boolean::New(env, false);
Napi::Object rawInput = Napi::Object::New(env);
rawInput.Set("file", unsupported);
rawInput.Set("buffer", supported);
rawInput.Set("stream", supported);
Napi::Object rawOutput = Napi::Object::New(env);
rawOutput.Set("file", unsupported);
rawOutput.Set("buffer", supported);
rawOutput.Set("stream", supported);
Napi::Object raw = Napi::Object::New(env);
raw.Set("id", "raw");
raw.Set("input", rawInput);
raw.Set("output", rawOutput);
format.Set("raw", raw);
return format;
}
/*
Synchronous, internal-only method used by some of the functional tests.
Calculates the maximum colour distance using the DE2000 algorithm
between two images of the same dimensions and number of channels.
*/
Napi::Value _maxColourDistance(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
// Open input files
VImage image1;
sharp::ImageType imageType1 = sharp::DetermineImageType(info[0].As<Napi::String>().Utf8Value().data());
if (imageType1 != sharp::ImageType::UNKNOWN) {
try {
image1 = VImage::new_from_file(info[0].As<Napi::String>().Utf8Value().c_str());
} catch (...) {
throw Napi::Error::New(env, "Input file 1 has corrupt header");
}
} else {
throw Napi::Error::New(env, "Input file 1 is of an unsupported image format");
}
VImage image2;
sharp::ImageType imageType2 = sharp::DetermineImageType(info[1].As<Napi::String>().Utf8Value().data());
if (imageType2 != sharp::ImageType::UNKNOWN) {
try {
image2 = VImage::new_from_file(info[1].As<Napi::String>().Utf8Value().c_str());
} catch (...) {
throw Napi::Error::New(env, "Input file 2 has corrupt header");
}
} else {
throw Napi::Error::New(env, "Input file 2 is of an unsupported image format");
}
// Ensure same number of channels
if (image1.bands() != image2.bands()) {
throw Napi::Error::New(env, "mismatchedBands");
}
// Ensure same dimensions
if (image1.width() != image2.width() || image1.height() != image2.height()) {
throw Napi::Error::New(env, "mismatchedDimensions");
}
double maxColourDistance;
try {
// Premultiply and remove alpha
if (sharp::HasAlpha(image1)) {
image1 = image1.premultiply().extract_band(1, VImage::option()->set("n", image1.bands() - 1));
}
if (sharp::HasAlpha(image2)) {
image2 = image2.premultiply().extract_band(1, VImage::option()->set("n", image2.bands() - 1));
}
// Calculate colour distance
maxColourDistance = image1.dE00(image2).max();
} catch (vips::VError const &err) {
throw Napi::Error::New(env, err.what());
}
// Clean up libvips' per-request data and threads
vips_error_clear();
vips_thread_shutdown();
return Napi::Number::New(env, maxColourDistance);
}