mirror of
https://github.com/lovell/sharp.git
synced 2025-12-19 07:15:08 +01:00
Combine new tile* API methods
Use v7.40.0+ libvips loader methods Separate Openslide as input vs Deep Zoom as output Split tile-based tests into new file Added assertions for generated tile size
This commit is contained in:
@@ -37,96 +37,61 @@ namespace sharp {
|
||||
*/
|
||||
ImageType DetermineImageType(void *buffer, size_t const length) {
|
||||
ImageType imageType = ImageType::UNKNOWN;
|
||||
#if (VIPS_MAJOR_VERSION >= 8)
|
||||
if (vips_foreign_is_a_buffer("jpegload_buffer", buffer, length)) {
|
||||
imageType = ImageType::JPEG;
|
||||
} else if (vips_foreign_is_a_buffer("pngload_buffer", buffer, length)) {
|
||||
imageType = ImageType::PNG;
|
||||
} else if (vips_foreign_is_a_buffer("webpload_buffer", buffer, length)) {
|
||||
imageType = ImageType::WEBP;
|
||||
} else if (vips_foreign_is_a_buffer("tiffload_buffer", buffer, length)) {
|
||||
imageType = ImageType::TIFF;
|
||||
} else if(vips_foreign_is_a_buffer("magickload_buffer", buffer, length)) {
|
||||
imageType = ImageType::MAGICK;
|
||||
}
|
||||
#else
|
||||
const char* loader = vips_foreign_find_load_buffer(buffer, length);
|
||||
|
||||
if (loader != NULL) {
|
||||
if (!strcmp(loader, "VipsForeignLoadJpegBuffer")) {
|
||||
char const *load = vips_foreign_find_load_buffer(buffer, length);
|
||||
if (load != NULL) {
|
||||
std::string loader = load;
|
||||
if (EndsWith(loader, "JpegBuffer")) {
|
||||
imageType = ImageType::JPEG;
|
||||
} else if (!strcmp(loader, "VipsForeignLoadPngBuffer")) {
|
||||
} else if (EndsWith(loader, "PngBuffer")) {
|
||||
imageType = ImageType::PNG;
|
||||
} else if (!strcmp(loader, "VipsForeignLoadWebpBuffer")) {
|
||||
} else if (EndsWith(loader, "WebpBuffer")) {
|
||||
imageType = ImageType::WEBP;
|
||||
} else if (!strcmp(loader, "VipsForeignLoadTiffBuffer")) {
|
||||
} else if (EndsWith(loader, "TiffBuffer")) {
|
||||
imageType = ImageType::TIFF;
|
||||
} else if (!strcmp(loader, "VipsForeignLoadMagickBuffer")) {
|
||||
} else if (EndsWith(loader, "MagickBuffer")) {
|
||||
imageType = ImageType::MAGICK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return imageType;
|
||||
}
|
||||
|
||||
/*
|
||||
Initialise and return a VipsImage from a buffer. Supports JPEG, PNG, WebP and TIFF.
|
||||
*/
|
||||
VipsImage* InitImage(ImageType imageType, void *buffer, size_t const length, VipsAccess const access) {
|
||||
VipsImage *image = NULL;
|
||||
if (imageType == ImageType::JPEG) {
|
||||
vips_jpegload_buffer(buffer, length, &image, "access", access, NULL);
|
||||
} else if (imageType == ImageType::PNG) {
|
||||
vips_pngload_buffer(buffer, length, &image, "access", access, NULL);
|
||||
} else if (imageType == ImageType::WEBP) {
|
||||
vips_webpload_buffer(buffer, length, &image, "access", access, NULL);
|
||||
} else if (imageType == ImageType::TIFF) {
|
||||
vips_tiffload_buffer(buffer, length, &image, "access", access, NULL);
|
||||
#if (VIPS_MAJOR_VERSION >= 8)
|
||||
} else if (imageType == ImageType::MAGICK) {
|
||||
vips_magickload_buffer(buffer, length, &image, "access", access, NULL);
|
||||
#endif
|
||||
}
|
||||
return image;
|
||||
VipsImage* InitImage(void *buffer, size_t const length, VipsAccess const access) {
|
||||
return vips_image_new_from_buffer(buffer, length, NULL, "access", access, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
Inpect the first 2-4 bytes of a file to determine image format
|
||||
Determine image format, reads the first few bytes of the file
|
||||
*/
|
||||
ImageType DetermineImageType(char const *file) {
|
||||
ImageType imageType = ImageType::UNKNOWN;
|
||||
if (vips_foreign_is_a("jpegload", file)) {
|
||||
imageType = ImageType::JPEG;
|
||||
} else if (vips_foreign_is_a("pngload", file)) {
|
||||
imageType = ImageType::PNG;
|
||||
} else if (vips_foreign_is_a("webpload", file)) {
|
||||
imageType = ImageType::WEBP;
|
||||
} else if (vips_foreign_is_a("tiffload", file)) {
|
||||
imageType = ImageType::TIFF;
|
||||
} else if(vips_foreign_is_a("magickload", file)) {
|
||||
imageType = ImageType::MAGICK;
|
||||
char const *load = vips_foreign_find_load(file);
|
||||
if (load != NULL) {
|
||||
std::string loader = load;
|
||||
if (EndsWith(loader, "JpegFile")) {
|
||||
imageType = ImageType::JPEG;
|
||||
} else if (EndsWith(loader, "Png")) {
|
||||
imageType = ImageType::PNG;
|
||||
} else if (EndsWith(loader, "WebpFile")) {
|
||||
imageType = ImageType::WEBP;
|
||||
} else if (EndsWith(loader, "Openslide")) {
|
||||
imageType = ImageType::OPENSLIDE;
|
||||
} else if (EndsWith(loader, "TiffFile")) {
|
||||
imageType = ImageType::TIFF;
|
||||
} else if (EndsWith(loader, "MagickFile")) {
|
||||
imageType = ImageType::MAGICK;
|
||||
}
|
||||
}
|
||||
|
||||
return imageType;
|
||||
}
|
||||
|
||||
/*
|
||||
Initialise and return a VipsImage from a file.
|
||||
*/
|
||||
VipsImage* InitImage(ImageType imageType, char const *file, VipsAccess const access) {
|
||||
VipsImage *image = NULL;
|
||||
if (imageType == ImageType::JPEG) {
|
||||
vips_jpegload(file, &image, "access", access, NULL);
|
||||
} else if (imageType == ImageType::PNG) {
|
||||
vips_pngload(file, &image, "access", access, NULL);
|
||||
} else if (imageType == ImageType::WEBP) {
|
||||
vips_webpload(file, &image, "access", access, NULL);
|
||||
} else if (imageType == ImageType::TIFF) {
|
||||
vips_tiffload(file, &image, "access", access, NULL);
|
||||
} else if (imageType == ImageType::MAGICK) {
|
||||
vips_magickload(file, &image, "access", access, NULL);
|
||||
}
|
||||
return image;
|
||||
VipsImage* InitImage(char const *file, VipsAccess const access) {
|
||||
return vips_image_new_from_file(file, "access", access, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace sharp {
|
||||
WEBP,
|
||||
TIFF,
|
||||
MAGICK,
|
||||
DZ
|
||||
OPENSLIDE
|
||||
};
|
||||
|
||||
// How many tasks are in the queue?
|
||||
@@ -39,12 +39,12 @@ namespace sharp {
|
||||
/*
|
||||
Initialise and return a VipsImage from a buffer. Supports JPEG, PNG, WebP and TIFF.
|
||||
*/
|
||||
VipsImage* InitImage(ImageType imageType, void *buffer, size_t const length, VipsAccess const access);
|
||||
VipsImage* InitImage(void *buffer, size_t const length, VipsAccess const access);
|
||||
|
||||
/*
|
||||
Initialise and return a VipsImage from a file.
|
||||
*/
|
||||
VipsImage* InitImage(ImageType imageType, char const *file, VipsAccess const access);
|
||||
VipsImage* InitImage(char const *file, VipsAccess const access);
|
||||
|
||||
/*
|
||||
Does this image have an embedded profile?
|
||||
|
||||
@@ -61,7 +61,7 @@ class MetadataWorker : public NanAsyncWorker {
|
||||
// From buffer
|
||||
imageType = DetermineImageType(baton->bufferIn, baton->bufferInLength);
|
||||
if (imageType != ImageType::UNKNOWN) {
|
||||
image = InitImage(imageType, baton->bufferIn, baton->bufferInLength, VIPS_ACCESS_RANDOM);
|
||||
image = InitImage(baton->bufferIn, baton->bufferInLength, VIPS_ACCESS_RANDOM);
|
||||
if (image == NULL) {
|
||||
(baton->err).append("Input buffer has corrupt header");
|
||||
imageType = ImageType::UNKNOWN;
|
||||
@@ -73,7 +73,7 @@ class MetadataWorker : public NanAsyncWorker {
|
||||
// From file
|
||||
imageType = DetermineImageType(baton->fileIn.c_str());
|
||||
if (imageType != ImageType::UNKNOWN) {
|
||||
image = InitImage(imageType, baton->fileIn.c_str(), VIPS_ACCESS_RANDOM);
|
||||
image = InitImage(baton->fileIn.c_str(), VIPS_ACCESS_RANDOM);
|
||||
if (image == NULL) {
|
||||
(baton->err).append("Input file has corrupt header");
|
||||
imageType = ImageType::UNKNOWN;
|
||||
@@ -90,7 +90,7 @@ class MetadataWorker : public NanAsyncWorker {
|
||||
case ImageType::WEBP: baton->format = "webp"; break;
|
||||
case ImageType::TIFF: baton->format = "tiff"; break;
|
||||
case ImageType::MAGICK: baton->format = "magick"; break;
|
||||
case ImageType::DZ: baton->format = "dzi"; break;
|
||||
case ImageType::OPENSLIDE: baton->format = "openslide"; break;
|
||||
case ImageType::UNKNOWN: break;
|
||||
}
|
||||
// VipsImage attributes
|
||||
|
||||
@@ -172,7 +172,7 @@ class ResizeWorker : public NanAsyncWorker {
|
||||
// From buffer
|
||||
inputImageType = DetermineImageType(baton->bufferIn, baton->bufferInLength);
|
||||
if (inputImageType != ImageType::UNKNOWN) {
|
||||
image = InitImage(inputImageType, baton->bufferIn, baton->bufferInLength, baton->accessMethod);
|
||||
image = InitImage(baton->bufferIn, baton->bufferInLength, baton->accessMethod);
|
||||
if (image != NULL) {
|
||||
// Listen for "postclose" signal to delete input buffer
|
||||
g_signal_connect(image, "postclose", G_CALLBACK(DeleteBuffer), baton->bufferIn);
|
||||
@@ -190,7 +190,7 @@ class ResizeWorker : public NanAsyncWorker {
|
||||
// From file
|
||||
inputImageType = DetermineImageType(baton->fileIn.c_str());
|
||||
if (inputImageType != ImageType::UNKNOWN) {
|
||||
image = InitImage(inputImageType, baton->fileIn.c_str(), baton->accessMethod);
|
||||
image = InitImage(baton->fileIn.c_str(), baton->accessMethod);
|
||||
if (image == NULL) {
|
||||
(baton->err).append("Input file has corrupt header");
|
||||
inputImageType = ImageType::UNKNOWN;
|
||||
@@ -801,7 +801,7 @@ class ResizeWorker : public NanAsyncWorker {
|
||||
return Error(baton, hook);
|
||||
}
|
||||
baton->outputFormat = "tiff";
|
||||
} else if (outputDz || matchInput) {
|
||||
} else if (outputDz) {
|
||||
// Write DZ to file
|
||||
std::string filename_no_extension = baton->output.substr(0, baton->output.length() - 4);
|
||||
if (vips_dzsave(image, filename_no_extension.c_str(), "strip", !baton->withMetadata,
|
||||
@@ -845,11 +845,6 @@ class ResizeWorker : public NanAsyncWorker {
|
||||
info->Set(NanNew<String>("width"), NanNew<Uint32>(static_cast<uint32_t>(width)));
|
||||
info->Set(NanNew<String>("height"), NanNew<Uint32>(static_cast<uint32_t>(height)));
|
||||
|
||||
if (baton->outputFormat == "dz" ) {
|
||||
info->Set(NanNew<String>("tileSize"), NanNew<Uint32>(static_cast<uint32_t>(baton->tileSize)));
|
||||
info->Set(NanNew<String>("tileOverlap"), NanNew<Uint32>(static_cast<uint32_t>(baton->tileOverlap)));
|
||||
}
|
||||
|
||||
if (baton->bufferOutLength > 0) {
|
||||
// Copy data to new Buffer
|
||||
argv[1] = NanNewBufferHandle(static_cast<char*>(baton->bufferOut), baton->bufferOutLength);
|
||||
|
||||
Reference in New Issue
Block a user