libvips/test/test_foreign.py
John Cupitt 5916e25c31 rename python bandjoin as ibandjoin
oh argh class and instance methods are in the same namespace, so we have
to rename the instance one as ibandjoin

also, start adding a test for arrayjoin
2015-12-12 12:29:20 +00:00

462 lines
16 KiB
Python
Executable File

#!/usr/bin/python
from __future__ import division
import unittest
import math
import os
import shutil
#import logging
#logging.basicConfig(level = logging.DEBUG)
from gi.repository import Vips
Vips.leak_set(True)
# an expanding zip ... if either of the args is not a list, duplicate it down
# the other
def zip_expand(x, y):
if isinstance(x, list) and isinstance(y, list):
return list(zip(x, y))
elif isinstance(x, list):
return [[i, y] for i in x]
elif isinstance(y, list):
return [[x, j] for j in y]
else:
return [[x, y]]
class TestForeign(unittest.TestCase):
# test a pair of things which can be lists for approx. equality
def assertAlmostEqualObjects(self, a, b, places = 4, msg = ''):
#print 'assertAlmostEqualObjects %s = %s' % (a, b)
for x, y in zip_expand(a, b):
self.assertAlmostEqual(x, y, places = places, msg = msg)
def setUp(self):
self.matlab_file = "images/sample.mat"
self.jpeg_file = "images/IMG_4618.jpg"
self.png_file = "images/sample.png"
self.tiff_file = "images/sample.tif"
self.profile_file = "images/sRGB.icm"
self.analyze_file = "images/t00740_tr1_segm.hdr"
self.gif_file = "images/cramps.gif"
self.webp_file = "images/1.webp"
self.exr_file = "images/sample.exr"
self.fits_file = "images/WFPC2u5780205r_c0fx.fits"
self.openslide_file = "images/CMU-1-Small-Region.svs"
self.colour = Vips.Image.jpegload(self.jpeg_file)
self.mono = self.colour.extract_band(1)
self.rad = self.colour.float2rad()
self.cmyk = self.colour.ibandjoin(self.mono)
self.cmyk = self.cmyk.copy(interpretation = Vips.Interpretation.CMYK)
im = Vips.Image.new_from_file(self.gif_file)
# some libMagick will load this mono image as RGB, some as mono ... test
# band 0 to be safe
self.onebit = im[0] > 128
# we have test files for formats which have a clear standard
def file_loader(self, loader, test_file, validate):
im = Vips.call(loader, test_file)
validate(self, im)
im = Vips.Image.new_from_file(test_file)
validate(self, im)
def buffer_loader(self, loader, test_file, validate):
with open(test_file, 'rb') as f:
buf = f.read()
im = Vips.call(loader, buf)
validate(self, im)
im = Vips.Image.new_from_buffer(buf, "")
validate(self, im)
def save_load(self, format, im):
x = Vips.Image.new_temp_file(format)
im.write(x)
self.assertEqual(im.width, x.width)
self.assertEqual(im.height, x.height)
self.assertEqual(im.bands, x.bands)
max_diff = (im - x).abs().max()
self.assertEqual(max_diff, 0)
def save_load_file(self, filename, options, im, thresh):
# yuk!
# but we can't set format parameters for Vips.Image.new_temp_file()
im.write_to_file(filename + options)
x = Vips.Image.new_from_file(filename)
self.assertEqual(im.width, x.width)
self.assertEqual(im.height, x.height)
self.assertEqual(im.bands, x.bands)
max_diff = (im - x).abs().max()
self.assertTrue(max_diff <= thresh)
x = None
os.unlink(filename)
def save_load_buffer(self, saver, loader, im, max_diff = 0):
buf = Vips.call(saver, im)
x = Vips.call(loader, buf)
self.assertEqual(im.width, x.width)
self.assertEqual(im.height, x.height)
self.assertEqual(im.bands, x.bands)
self.assertLessEqual((im - x).abs().max(), max_diff)
def test_vips(self):
self.save_load_file("test.v", "", self.colour, 0)
# check we can save and restore metadata
self.colour.write_to_file("test.v")
x = Vips.Image.new_from_file("test.v")
before_exif = self.colour.get_value("exif-data")
after_exif = x.get_value("exif-data")
self.assertEqual(len(before_exif), len(after_exif))
for i in range(len(before_exif)):
self.assertEqual(before_exif[i], after_exif[i])
x = None
os.unlink("test.v")
def test_jpeg(self):
x = Vips.type_find("VipsForeign", "jpegload")
if not x.is_instantiatable():
print("no jpeg support in this vips, skipping test")
return
def jpeg_valid(self, im):
a = im(10, 10)
self.assertAlmostEqualObjects(a, [6, 5, 3])
profile = im.get_value("icc-profile-data")
self.assertEqual(len(profile), 1352)
self.assertEqual(im.width, 1024)
self.assertEqual(im.height, 768)
self.assertEqual(im.bands, 3)
self.file_loader("jpegload", self.jpeg_file, jpeg_valid)
self.buffer_loader("jpegload_buffer", self.jpeg_file, jpeg_valid)
self.save_load_buffer("jpegsave_buffer", "jpegload_buffer", self.colour,
60)
self.save_load("%s.jpg", self.mono)
self.save_load("%s.jpg", self.colour)
# see if we have exif parsing
have_exif = False
x = Vips.Image.new_from_file(self.jpeg_file)
try:
# our test image does have this field
y = x.get_value("exif-ifd0-Orientation")
have_exif = True
except:
pass
if have_exif:
# we need a copy of the image to set the new metadata on
# otherwise we get caching problems
x = x.copy()
x.set_value("exif-ifd0-Orientation", "2")
x.write_to_file("test.jpg")
x = Vips.Image.new_from_file("test.jpg")
y = x.get_value("exif-ifd0-Orientation")
self.assertEqual(y[0], "2")
os.unlink("test.jpg")
def test_png(self):
x = Vips.type_find("VipsForeign", "pngload")
if not x.is_instantiatable():
print("no png support in this vips, skipping test")
return
def png_valid(self, im):
a = im(10, 10)
self.assertAlmostEqualObjects(a, [38671.0, 33914.0, 26762.0])
self.assertEqual(im.width, 290)
self.assertEqual(im.height, 442)
self.assertEqual(im.bands, 3)
self.file_loader("pngload", self.png_file, png_valid)
self.buffer_loader("pngload_buffer", self.png_file, png_valid)
self.save_load_buffer("pngsave_buffer", "pngload_buffer", self.colour)
self.save_load("%s.png", self.mono)
self.save_load("%s.png", self.colour)
def test_tiff(self):
x = Vips.type_find("VipsForeign", "tiffload")
if not x.is_instantiatable():
print("no tiff support in this vips, skipping test")
return
def tiff_valid(self, im):
a = im(10, 10)
self.assertAlmostEqualObjects(a, [38671.0, 33914.0, 26762.0])
self.assertEqual(im.width, 290)
self.assertEqual(im.height, 442)
self.assertEqual(im.bands, 3)
self.file_loader("tiffload", self.tiff_file, tiff_valid)
self.buffer_loader("tiffload_buffer", self.tiff_file, tiff_valid)
self.save_load("%s.tif", self.mono)
self.save_load("%s.tif", self.colour)
self.save_load("%s.tif", self.cmyk)
self.save_load("%s.tif", self.onebit)
self.save_load("%s.tif[squash]", self.onebit)
self.save_load("%s.tif[miniswhite]", self.onebit)
self.save_load("%s.tif[squash,miniswhite]", self.onebit)
self.save_load_file("test.tif", "[tile]", self.colour, 0)
self.save_load_file("test.tif", "[tile,pyramid]", self.colour, 0)
self.save_load_file("test.tif",
"[tile,pyramid,compression=jpeg]", self.colour, 0)
self.save_load_file("test.tif", "[bigtiff]", self.colour, 0)
self.save_load_file("test.tif", "[compression=jpeg]", self.colour, 10)
self.save_load_file("test.tif",
"[tile,tile-width=256]", self.colour, 10)
def test_magickload(self):
x = Vips.type_find("VipsForeign", "magickload")
if not x.is_instantiatable():
print("no magick support in this vips, skipping test")
return
def gif_valid(self, im):
a = im(10, 10)
# some libMagick produce an RGB for this image, some a mono
if len(a) > 1:
self.assertAlmostEqual(a, [33, 33, 33])
self.assertEqual(im.bands, 3)
else:
self.assertAlmostEqual(a, [33])
self.assertEqual(im.bands, 1)
self.assertEqual(im.width, 159)
self.assertEqual(im.height, 203)
self.file_loader("magickload", self.gif_file, gif_valid)
self.buffer_loader("magickload_buffer", self.gif_file, gif_valid)
def test_webp(self):
x = Vips.type_find("VipsForeign", "webpload")
if not x.is_instantiatable():
print("no webp support in this vips, skipping test")
return
def webp_valid(self, im):
a = im(10, 10)
self.assertAlmostEqualObjects(a, [71, 166, 236])
self.assertEqual(im.width, 550)
self.assertEqual(im.height, 368)
self.assertEqual(im.bands, 3)
self.file_loader("webpload", self.webp_file, webp_valid)
self.buffer_loader("webpload_buffer", self.webp_file, webp_valid)
self.save_load_buffer("webpsave_buffer", "webpload_buffer", self.colour,
50)
self.save_load("%s.webp", self.colour)
def test_analyzeload(self):
def analyze_valid(self, im):
a = im(10, 10)
self.assertAlmostEqual(a[0], 3335)
self.assertEqual(im.width, 128)
self.assertEqual(im.height, 8064)
self.assertEqual(im.bands, 1)
self.file_loader("analyzeload", self.analyze_file, analyze_valid)
def test_matload(self):
x = Vips.type_find("VipsForeign", "matload")
if not x.is_instantiatable():
print("no matlab support in this vips, skipping test")
return
def matlab_valid(self, im):
a = im(10, 10)
self.assertAlmostEqualObjects(a, [38671.0, 33914.0, 26762.0])
self.assertEqual(im.width, 290)
self.assertEqual(im.height, 442)
self.assertEqual(im.bands, 3)
self.file_loader("matload", self.matlab_file, matlab_valid)
def test_openexrload(self):
x = Vips.type_find("VipsForeign", "openexrload")
if not x.is_instantiatable():
print("no openexr support in this vips, skipping test")
return
def exr_valid(self, im):
a = im(10, 10)
self.assertAlmostEqualObjects(a, [0.124512, 0.159668,
0.040375, 1.0],
places = 5)
self.assertEqual(im.width, 610)
self.assertEqual(im.height, 406)
self.assertEqual(im.bands, 4)
self.file_loader("openexrload", self.exr_file, exr_valid)
def test_fitsload(self):
x = Vips.type_find("VipsForeign", "fitsload")
if not x.is_instantiatable():
print("no fits support in this vips, skipping test")
return
def fits_valid(self, im):
a = im(10, 10)
self.assertAlmostEqualObjects(a, [-0.165013, -0.148553, 1.09122,
-0.942242],
places = 5)
self.assertEqual(im.width, 200)
self.assertEqual(im.height, 200)
self.assertEqual(im.bands, 4)
self.file_loader("fitsload", self.fits_file, fits_valid)
self.save_load("%s.fits", self.mono)
def test_openslideload(self):
x = Vips.type_find("VipsForeign", "openslideload")
if not x.is_instantiatable():
print("no openslide support in this vips, skipping test")
return
def openslide_valid(self, im):
a = im(10, 10)
self.assertAlmostEqualObjects(a, [244, 250, 243, 255])
self.assertEqual(im.width, 2220)
self.assertEqual(im.height, 2967)
self.assertEqual(im.bands, 4)
self.file_loader("openslideload", self.openslide_file, openslide_valid)
def test_csv(self):
self.save_load("%s.csv", self.mono)
def test_matrix(self):
self.save_load("%s.mat", self.mono)
def test_ppm(self):
self.save_load("%s.ppm", self.mono)
self.save_load("%s.ppm", self.colour)
def test_rad(self):
self.save_load("%s.hdr", self.colour)
def test_dzsave(self):
x = Vips.type_find("VipsForeign", "dzsave")
if not x.is_instantiatable():
print("no dzsave support in this vips, skipping test")
return
# dzsave is hard to test, there are so many options
# test each option separately and hope they all function together
# correctly
# default deepzoom layout
self.colour.dzsave("test")
# test right edge ... default is 256x256 tiles, overlap 1
x = Vips.Image.new_from_file("test_files/10/3_2.jpeg")
self.assertEqual(x.width, 256)
y = Vips.Image.new_from_file("test_files/10/4_2.jpeg")
self.assertEqual(y.width,
self.colour.width - 255 * int(self.colour.width / 255))
# test bottom edge
x = Vips.Image.new_from_file("test_files/10/3_2.jpeg")
self.assertEqual(x.height, 256)
y = Vips.Image.new_from_file("test_files/10/3_3.jpeg")
self.assertEqual(y.height,
self.colour.height -
255 * int(self.colour.height / 255))
# there should be a bottom layer
x = Vips.Image.new_from_file("test_files/0/0_0.jpeg")
self.assertEqual(x.width, 1)
self.assertEqual(x.height, 1)
# 10 should be the final layer
self.assertFalse(os.path.isdir("test_files/11"))
shutil.rmtree("test_files")
os.unlink("test.dzi")
# default google layout
self.colour.dzsave("test", layout = "google")
# test bottom-right tile ... default is 256x256 tiles, overlap 0
x = Vips.Image.new_from_file("test/2/2/3.jpg")
self.assertEqual(x.width, 256)
self.assertEqual(x.height, 256)
self.assertFalse(os.path.exists("test/2/2/4.jpg"))
self.assertFalse(os.path.exists("test/3"))
x = Vips.Image.new_from_file("test/blank.png")
self.assertEqual(x.width, 256)
self.assertEqual(x.height, 256)
shutil.rmtree("test")
# default zoomify layout
self.colour.dzsave("test", layout = "zoomify")
# 256x256 tiles, no overlap
self.assertTrue(os.path.exists("test/ImageProperties.xml"))
x = Vips.Image.new_from_file("test/TileGroup0/2-3-2.jpg")
self.assertEqual(x.width, 256)
self.assertEqual(x.height, 256)
shutil.rmtree("test")
# test zip output
self.colour.dzsave("test.zip")
self.assertFalse(os.path.exists("test_files"))
self.assertFalse(os.path.exists("test.dzi"))
os.unlink("test.zip")
# test suffix
self.colour.dzsave("test", suffix = ".png")
x = Vips.Image.new_from_file("test_files/10/3_2.png")
self.assertEqual(x.width, 256)
shutil.rmtree("test_files")
os.unlink("test.dzi")
# test overlap
self.colour.dzsave("test", overlap = 200)
y = Vips.Image.new_from_file("test_files/10/18_6.jpeg")
self.assertEqual(y.width,
self.colour.width - 56 * int(self.colour.width / 56))
shutil.rmtree("test_files")
os.unlink("test.dzi")
# test tile-size
self.colour.dzsave("test", tile_size = 512)
y = Vips.Image.new_from_file("test_files/10/2_1.jpeg")
self.assertEqual(y.width,
self.colour.width - 511 * int(self.colour.width / 511))
shutil.rmtree("test_files")
os.unlink("test.dzi")
# test tile-size
self.colour.dzsave("test", tile_size = 512)
y = Vips.Image.new_from_file("test_files/10/2_1.jpeg")
self.assertEqual(y.width,
self.colour.width - 511 * int(self.colour.width / 511))
shutil.rmtree("test_files")
os.unlink("test.dzi")
if __name__ == '__main__':
unittest.main()