diff --git a/spec/images/uhdr.jpg b/spec/images/uhdr.jpg new file mode 100644 index 0000000..2e9a7cc Binary files /dev/null and b/spec/images/uhdr.jpg differ diff --git a/spec/meta_spec.lua b/spec/meta_spec.lua index 9010188..a9e1f0a 100644 --- a/spec/meta_spec.lua +++ b/spec/meta_spec.lua @@ -1,6 +1,7 @@ local vips = require "vips" local ffi = require "ffi" +local UHDR_FILE = "./spec/images/uhdr.jpg" -- test metadata read/write describe("metadata", function() local array, im @@ -59,4 +60,28 @@ describe("metadata", function() assert.are.same(im2:format(), "double") end) + + it("can set gainmap", function() + if vips.version.at_least(8, 18) and vips.has("uhdrload") then + local function crop_gainmap(image) + local gainmap = image:get_gainmap() + + if gainmap then + local new_gainmap = gainmap:crop(0, 0, 10, 10) + image = image:copy() + image:set_type(vips.gvalue.image_type, "gainmap", new_gainmap) + end + + return image + end + + local image = vips.Image.new_from_file(UHDR_FILE) + image = crop_gainmap(image) + local buf = image:write_to_buffer(".jpg") + local new_image = vips.Image.new_from_buffer(buf, "") + local new_gainmap = new_image:get_gainmap() + + assert.are.same(new_gainmap:width(), 10) + end + end) end) diff --git a/src/vips.lua b/src/vips.lua index ace8231..e6f5d42 100644 --- a/src/vips.lua +++ b/src/vips.lua @@ -64,6 +64,13 @@ function vips.concurrency_get() return vips_lib.vips_concurrency_get() end +function vips.type_find(basename, nickname) + return vips_lib.vips_type_find(basename, nickname) +end + +function vips.has(name) + return vips.type_find("VipsOperation", name) ~= 0 +end -- for compat with 1.1-6, when these were misnamed vips.set_max = vips.cache_set_max vips.get_max = vips.cache_get_max diff --git a/src/vips/Image_methods.lua b/src/vips/Image_methods.lua index 3145c6c..c9a1ef8 100644 --- a/src/vips/Image_methods.lua +++ b/src/vips/Image_methods.lua @@ -497,6 +497,16 @@ function Image_method:remove(name) return vips_lib.vips_image_remove(self.vimage, name) ~= 0 end +function Image_method:get_gainmap() + collectgarbage("stop") + local vimage = vips_lib.vips_image_get_gainmap(self.vimage) + if vimage == ffi.NULL then + return nil + end + + collectgarbage("restart") + return Image.new(vimage) +end -- standard header fields function Image_method:width() diff --git a/src/vips/cdefs.lua b/src/vips/cdefs.lua index 30d5bd1..0e87f6b 100644 --- a/src/vips/cdefs.lua +++ b/src/vips/cdefs.lua @@ -35,6 +35,8 @@ ffi.cdef [[ GType vips_blend_mode_get_type (void); GType vips_band_format_get_type (void); + GType vips_type_find (const char *basename, const char *nickname); + int vips_enum_from_nick (const char *domain, GType gtype, const char *str); const char *vips_enum_nick (GType gtype, int value); @@ -166,6 +168,8 @@ ffi.cdef [[ // opaque } VipsImage; + VipsImage *vips_image_get_gainmap(VipsImage *image); + typedef struct _VipsConnection { VipsObject parent_instance;