mirror of
https://github.com/lovell/sharp.git
synced 2026-02-04 13:46:19 +01:00
Switch from libvips' C to C++ binding
Requires upgrade to libvips 8.2.1
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#include <cmath>
|
||||
#include <node.h>
|
||||
#include <vips/vips.h>
|
||||
#include <vips/vips8>
|
||||
#include <vips/vector.h>
|
||||
|
||||
#include "nan.h"
|
||||
@@ -196,103 +196,60 @@ NAN_METHOD(format) {
|
||||
between two images of the same dimensions and number of channels.
|
||||
*/
|
||||
NAN_METHOD(_maxColourDistance) {
|
||||
using vips::VImage;
|
||||
using vips::VError;
|
||||
using sharp::DetermineImageType;
|
||||
using sharp::ImageType;
|
||||
using sharp::InitImage;
|
||||
using sharp::HasAlpha;
|
||||
|
||||
HandleScope();
|
||||
|
||||
// Create "hook" VipsObject to hang image references from
|
||||
VipsObject *hook = reinterpret_cast<VipsObject*>(vips_image_new());
|
||||
|
||||
// Open input files
|
||||
VipsImage *image1 = nullptr;
|
||||
VImage image1;
|
||||
ImageType imageType1 = DetermineImageType(*Utf8String(info[0]));
|
||||
if (imageType1 != ImageType::UNKNOWN) {
|
||||
image1 = InitImage(*Utf8String(info[0]), VIPS_ACCESS_SEQUENTIAL);
|
||||
if (image1 == nullptr) {
|
||||
g_object_unref(hook);
|
||||
try {
|
||||
image1 = VImage::new_from_file(*Utf8String(info[0]));
|
||||
} catch (...) {
|
||||
return ThrowError("Input file 1 has corrupt header");
|
||||
} else {
|
||||
vips_object_local(hook, image1);
|
||||
}
|
||||
} else {
|
||||
g_object_unref(hook);
|
||||
return ThrowError("Input file 1 is of an unsupported image format");
|
||||
}
|
||||
VipsImage *image2 = nullptr;
|
||||
VImage image2;
|
||||
ImageType imageType2 = DetermineImageType(*Utf8String(info[1]));
|
||||
if (imageType2 != ImageType::UNKNOWN) {
|
||||
image2 = InitImage(*Utf8String(info[1]), VIPS_ACCESS_SEQUENTIAL);
|
||||
if (image2 == nullptr) {
|
||||
g_object_unref(hook);
|
||||
try {
|
||||
image2 = VImage::new_from_file(*Utf8String(info[1]));
|
||||
} catch (...) {
|
||||
return ThrowError("Input file 2 has corrupt header");
|
||||
} else {
|
||||
vips_object_local(hook, image2);
|
||||
}
|
||||
} else {
|
||||
g_object_unref(hook);
|
||||
return ThrowError("Input file 2 is of an unsupported image format");
|
||||
}
|
||||
|
||||
// Ensure same number of channels
|
||||
if (image1->Bands != image2->Bands) {
|
||||
g_object_unref(hook);
|
||||
if (image1.bands() != image2.bands()) {
|
||||
return ThrowError("mismatchedBands");
|
||||
}
|
||||
// Ensure same dimensions
|
||||
if (image1->Xsize != image2->Xsize || image1->Ysize != image2->Ysize) {
|
||||
g_object_unref(hook);
|
||||
if (image1.width() != image2.width() || image1.height() != image2.height()) {
|
||||
return ThrowError("mismatchedDimensions");
|
||||
}
|
||||
|
||||
// Premultiply and remove alpha
|
||||
if (HasAlpha(image1)) {
|
||||
VipsImage *imagePremultiplied1;
|
||||
if (vips_premultiply(image1, &imagePremultiplied1, nullptr)) {
|
||||
g_object_unref(hook);
|
||||
return ThrowError(vips_error_buffer());
|
||||
}
|
||||
vips_object_local(hook, imagePremultiplied1);
|
||||
VipsImage *imagePremultipliedNoAlpha1;
|
||||
if (vips_extract_band(image1, &imagePremultipliedNoAlpha1, 1, "n", image1->Bands - 1, nullptr)) {
|
||||
g_object_unref(hook);
|
||||
return ThrowError(vips_error_buffer());
|
||||
}
|
||||
vips_object_local(hook, imagePremultipliedNoAlpha1);
|
||||
image1 = imagePremultipliedNoAlpha1;
|
||||
}
|
||||
if (HasAlpha(image2)) {
|
||||
VipsImage *imagePremultiplied2;
|
||||
if (vips_premultiply(image2, &imagePremultiplied2, nullptr)) {
|
||||
g_object_unref(hook);
|
||||
return ThrowError(vips_error_buffer());
|
||||
}
|
||||
vips_object_local(hook, imagePremultiplied2);
|
||||
VipsImage *imagePremultipliedNoAlpha2;
|
||||
if (vips_extract_band(image2, &imagePremultipliedNoAlpha2, 1, "n", image2->Bands - 1, nullptr)) {
|
||||
g_object_unref(hook);
|
||||
return ThrowError(vips_error_buffer());
|
||||
}
|
||||
vips_object_local(hook, imagePremultipliedNoAlpha2);
|
||||
image2 = imagePremultipliedNoAlpha2;
|
||||
}
|
||||
|
||||
// Calculate colour distance
|
||||
VipsImage *difference;
|
||||
if (vips_dE00(image1, image2, &difference, nullptr)) {
|
||||
g_object_unref(hook);
|
||||
return ThrowError(vips_error_buffer());
|
||||
}
|
||||
vips_object_local(hook, difference);
|
||||
// Extract maximum distance
|
||||
double maxColourDistance;
|
||||
if (vips_max(difference, &maxColourDistance, nullptr)) {
|
||||
g_object_unref(hook);
|
||||
return ThrowError(vips_error_buffer());
|
||||
try {
|
||||
// Premultiply and remove alpha
|
||||
if (HasAlpha(image1)) {
|
||||
image1 = image1.premultiply().extract_band(1, VImage::option()->set("n", image1.bands() - 1));
|
||||
}
|
||||
if (HasAlpha(image2)) {
|
||||
image2 = image2.premultiply().extract_band(1, VImage::option()->set("n", image2.bands() - 1));
|
||||
}
|
||||
// Calculate colour distance
|
||||
maxColourDistance = image1.dE00(image2).max();
|
||||
} catch (VError err) {
|
||||
return ThrowError(err.what());
|
||||
}
|
||||
g_object_unref(hook);
|
||||
|
||||
// Clean up libvips' per-request data and threads
|
||||
vips_error_clear();
|
||||
|
||||
Reference in New Issue
Block a user