Merge pull request #149 from waldophotos/master

Add backwards compatibility code for older `libvips` versions.
This commit is contained in:
Tomás Aparicio 2017-05-24 20:48:33 +01:00 committed by GitHub
commit 2394a2d77e
4 changed files with 61 additions and 119 deletions

155
vips.h
View file

@ -456,119 +456,70 @@ vips_sharpen_bridge(VipsImage *in, VipsImage **out, int radius, double x1, doubl
int
vips_add_band(VipsImage *in, VipsImage **out, double c) {
return vips_bandjoin_const1(in, out, c, NULL);
#if (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 2))
return vips_bandjoin_const1(in, out, c, NULL);
#else
VipsImage *base = vips_image_new();
if (
vips_black(&base, in->Xsize, in->Ysize, NULL) ||
vips_linear1(base, &base, 1, c, NULL)) {
g_object_unref(base);
return 1;
}
g_object_unref(base);
return vips_bandjoin2(in, base, out, c, NULL);
#endif
}
int
vips_watermark_image(VipsImage *in, VipsImage *sub, VipsImage **out, WatermarkImageOptions *o) {
int bands = in->Bands;
double background[4] = {0.0, 0.0, 0.0, 0.0};
VipsImage *base = vips_image_new();
VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(base), 10);
VipsArrayDouble *vipsBackground = vips_array_double_new(background, 4);
// add in and sub for unreffing and later use
t[0] = in;
t[1] = sub;
VipsImage *base = vips_image_new();
VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(base), 10);
if (has_alpha_channel(in) == 0) {
vips_add_band(in, &t[0], 255.0);
// in is no longer in the array and won't be unreffed, so add it at the end
t[8] = in;
}
t[0] = in;
t[1] = sub;
if (has_alpha_channel(sub) == 0) {
vips_add_band(sub, &t[1], 255.0);
// sub is no longer in the array and won't be unreffed, so add it at the end
t[9] = sub;
}
if (vips_embed(t[1], &t[2], o->Left, o->Top, t[0]->Xsize, t[0]->Ysize, "extend", VIPS_EXTEND_BACKGROUND, "background", vipsBackground, NULL)) {
g_object_unref(base);
return 1;
}
// Place watermark image in the right place and size it to the size of the
// image that should be watermarked
if (
vips_embed(t[1], &t[2], o->Left, o->Top, t[0]->Xsize, t[0]->Ysize, NULL)) {
g_object_unref(base);
return 1;
}
//Get Sub bands without alpha
if (vips_extract_band(t[2], &t[3], 0, "n", t[2]->Bands - 1, NULL)) {
g_object_unref(base);
return 1;
}
// Create a mask image based on the alpha band from the watermark image
// and place it in the right position
if (
vips_extract_band(t[1], &t[3], t[1]->Bands - 1, "n", 1, NULL) ||
vips_linear1(t[3], &t[4], o->Opacity, 0.0, NULL) ||
vips_cast(t[4], &t[5], VIPS_FORMAT_UCHAR, NULL) ||
vips_copy(t[5], &t[6], "interpretation", t[0]->Type, NULL) ||
vips_embed(t[6], &t[7], o->Left, o->Top, t[0]->Xsize, t[0]->Ysize, NULL)) {
g_object_unref(base);
return 1;
}
//Get Sub Image alpha
if (
vips_extract_band(t[2], &t[4], t[2]->Bands - 1, "n", 1, NULL) ||
vips_linear1(t[4], &t[4], o->Opacity / 255.0, 0.0, NULL)
) {
g_object_unref(base);
return 1;
}
// Blend the mask and watermark image and write to output.
if (vips_ifthenelse(t[7], t[2], t[0], out, "blend", TRUE, NULL)) {
g_object_unref(base);
return 1;
}
//Apply alpha to other sub bands to remove unwanted pixels
if (vips_multiply(t[3], t[4], &t[3], NULL)) {
g_object_unref(base);
return 1;
}
//Get in bands without alpha
if (vips_extract_band(t[0], &t[5], 0, "n", t[0]->Bands - 1, NULL)) {
g_object_unref(base);
return 1;
}
//Get in alpha
if (
vips_extract_band(t[0], &t[6], t[0]->Bands - 1, "n", 1, NULL) ||
vips_linear1(t[6], &t[6], 1.0 / 255.0, 0.0, NULL)
) {
g_object_unref(base);
return 1;
}
// Compute normalized output alpha channel:
//
// References:
// - http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
// - https://github.com/jcupitt/ruby-vips/issues/28#issuecomment-9014826
//
// out_a = src_a + dst_a * (1 - src_a)
// ^^^^^^^^^^^
if (
vips_linear1(t[4], &t[7], -1.0, 1.0, NULL) ||
vips_multiply(t[6], t[7], &t[8], NULL)
) {
g_object_unref(base);
return 1;
}
//outAlphaNormalized in t[8]
if (vips_add(t[4], t[8], &t[8], NULL)) {
g_object_unref(base);
return 1;
}
// Compute output RGB channels:
//
// Wikipedia:
// out_rgb = (src_rgb * src_a + dst_rgb * dst_a * (1 - src_a)) / out_a
// ^^^^^^^^^^^
// t0
//
// Omit division by `out_a` since `Compose` is supposed to output a
// premultiplied RGBA image as reversal of premultiplication is handled
// externally.
if (vips_multiply(t[5], t[7], &t[9], NULL)) {
g_object_unref(base);
return 1;
}
//outRGBPremultiplied in t[9]
if (vips_add(t[3], t[9], &t[9], NULL)) {
g_object_unref(base);
return 1;
}
if (
vips_linear1(t[8], &t[8], 255.0, 0.0, NULL) ||
vips_bandjoin2(t[9], t[8], out, NULL)
) {
g_object_unref(base);
return 1;
}
g_object_unref(base);
return 0;
g_object_unref(base);
return 0;
}
int