From d7a06f29edb6c88fe79a5a8b9b225e9ae8cee095 Mon Sep 17 00:00:00 2001 From: John Evans Date: Sat, 10 Aug 2013 13:04:58 -0400 Subject: [PATCH] pylint work, #99 --- glymur/lib/test/test_openjp2.py | 538 +++++++++++++++++--------------- 1 file changed, 284 insertions(+), 254 deletions(-) diff --git a/glymur/lib/test/test_openjp2.py b/glymur/lib/test/test_openjp2.py index 710f265..13c5975 100644 --- a/glymur/lib/test/test_openjp2.py +++ b/glymur/lib/test/test_openjp2.py @@ -1,9 +1,10 @@ -#pylint: disable-all -import doctest +""" +Tests for libopenjp2 wrapping functions. +""" +# R0904: Seems like pylint is fooled in this situation +# W0142: using kwargs is ok in this context +# pylint: disable=R0904,W0142 import os -import pkg_resources -import shutil -import struct import sys import tempfile @@ -15,28 +16,28 @@ else: import numpy as np import glymur +from glymur.lib import openjp2 OPENJP2_IS_V2_OFFICIAL = False -if glymur.lib.openjp2.OPENJP2 is not None: - if not hasattr(glymur.lib.openjp2.OPENJP2, +if openjp2.OPENJP2 is not None: + if not hasattr(openjp2.OPENJP2, 'opj_stream_create_default_file_stream_v3'): OPENJP2_IS_V2_OFFICIAL = True @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") -@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, +@unittest.skipIf(openjp2.OPENJP2 is None, "Missing openjp2 library.") @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, "API followed here specific to V2.0+") class TestOpenJP2(unittest.TestCase): + """Test openjp2 library functionality. - def setUp(self): - pass + Some tests correspond to those in the openjpeg test suite. + """ - def tearDown(self): - pass - - def test_set_default_encoder_parameters(self): - cparams = glymur.lib._openjp2.set_default_encoder_parameters() + def test_default_encoder_parameters(self): + """Ensure that the encoder structure is clean upon init.""" + cparams = openjp2.set_default_encoder_parameters() self.assertEqual(cparams.res_spec, 0) self.assertEqual(cparams.cblockw_init, 64) @@ -52,8 +53,9 @@ class TestOpenJP2(unittest.TestCase): self.assertEqual(cparams.irreversible, 0) - def test_set_default_decoder_parameters(self): - dparams = glymur.lib._openjp2.set_default_decoder_parameters() + def test_default_decoder_parameters(self): + """Tests that the structure is clean upon initialization""" + dparams = openjp2.set_default_decoder_parameters() self.assertEqual(dparams.DA_x0, 0) self.assertEqual(dparams.DA_y0, 0) @@ -61,35 +63,34 @@ class TestOpenJP2(unittest.TestCase): self.assertEqual(dparams.DA_y1, 0) def tile_macro(self, codec, stream, imagep, tidx): - # called only by j2k_random_tile_access - glymur.lib._openjp2.get_decoded_tile(codec, stream, imagep, tidx) + """called only by j2k_random_tile_access""" + openjp2.get_decoded_tile(codec, stream, imagep, tidx) for j in range(imagep.contents.numcomps): self.assertIsNotNone(imagep.contents.comps[j].data) def j2k_random_tile_access(self, filename, codec_format=None): - # called by the test_rtaX methods - dparam = glymur.lib._openjp2.set_default_decoder_parameters() + """fixture called by the test_rtaX methods""" + dparam = openjp2.set_default_decoder_parameters() infile = filename.encode() - nelts = glymur.lib._openjp2.PATH_LEN - len(infile) + nelts = openjp2.PATH_LEN - len(infile) infile += b'0' * nelts dparam.infile = infile dparam.decod_format = codec_format - codec = glymur.lib._openjp2.create_decompress(codec_format) + codec = openjp2.create_decompress(codec_format) - glymur.lib._openjp2.set_info_handler(codec, None) - glymur.lib._openjp2.set_warning_handler(codec, None) - glymur.lib._openjp2.set_error_handler(codec, None) + openjp2.set_info_handler(codec, None) + openjp2.set_warning_handler(codec, None) + openjp2.set_error_handler(codec, None) - x = (filename, True) - stream = glymur.lib._openjp2.stream_create_default_file_stream_v3(*x) + stream = openjp2.stream_create_default_file_stream_v3(filename, True) - glymur.lib._openjp2.setup_decoder(codec, dparam) - image = glymur.lib._openjp2.read_header(stream, codec) + openjp2.setup_decoder(codec, dparam) + image = openjp2.read_header(stream, codec) - cstr_info = glymur.lib._openjp2.get_cstr_info(codec) + cstr_info = openjp2.get_cstr_info(codec) tile_ul = 0 tile_ur = cstr_info.contents.tw - 1 @@ -101,159 +102,39 @@ class TestOpenJP2(unittest.TestCase): self.tile_macro(codec, stream, image, tile_lr) self.tile_macro(codec, stream, image, tile_ll) - glymur.lib._openjp2.destroy_cstr_info(cstr_info) + openjp2.destroy_cstr_info(cstr_info) - glymur.lib._openjp2.end_decompress(codec, stream) - glymur.lib._openjp2.destroy_codec(codec) - glymur.lib._openjp2.stream_destroy_v3(stream) - glymur.lib._openjp2.image_destroy(image) - - def tile_decoder(self, x0=None, y0=None, x1=None, y1=None, filename=None, - codec_format=None): - x = (filename, True) - stream = glymur.lib._openjp2.stream_create_default_file_stream_v3(*x) - dparam = glymur.lib._openjp2.set_default_decoder_parameters() - - dparam.decod_format = codec_format - - # Do not use layer decoding limitation. - dparam.cp_layer = 0 - - # do not use resolution reductions. - dparam.cp_reduce = 0 - - codec = glymur.lib._openjp2.create_decompress(codec_format) - - glymur.lib._openjp2.set_info_handler(codec, None) - glymur.lib._openjp2.set_warning_handler(codec, None) - glymur.lib._openjp2.set_error_handler(codec, None) - - glymur.lib._openjp2.setup_decoder(codec, dparam) - image = glymur.lib._openjp2.read_header(stream, codec) - glymur.lib._openjp2.set_decode_area(codec, image, x0, y0, x1, y1) - - data = np.zeros((1150, 2048, 3), dtype=np.uint8) - while True: - rargs = glymur.lib._openjp2.read_tile_header(codec, stream) - tidx = rargs[0] - sz = rargs[1] - go_on = rargs[-1] - if not go_on: - break - glymur.lib._openjp2.decode_tile_data(codec, tidx, data, sz, stream) - - glymur.lib._openjp2.end_decompress(codec, stream) - glymur.lib._openjp2.destroy_codec(codec) - glymur.lib._openjp2.stream_destroy_v3(stream) - glymur.lib._openjp2.image_destroy(image) - - def tile_encoder(self, num_comps=None, tile_width=None, tile_height=None, - filename=None, codec=None, comp_prec=None, - image_width=None, image_height=None, - irreversible=None): - num_tiles = (image_width / tile_width) * (image_height / tile_height) - tile_size = tile_width * tile_height * num_comps * comp_prec / 8 - - data = np.random.random((tile_height, tile_width, num_comps)) - data = (data * 255).astype(np.uint8) - - l_param = glymur.lib._openjp2.set_default_encoder_parameters() - - l_param.tcp_numlayers = 1 - l_param.cp_fixed_quality = 1 - l_param.tcp_distoratio[0] = 20 - - # position of the tile grid aligned with the image - l_param.cp_tx0 = 0 - l_param.cp_ty0 = 0 - - # tile size, we are using tile based encoding - l_param.tile_size_on = 1 - l_param.cp_tdx = tile_width - l_param.cp_tdy = tile_height - - # use irreversible encoding - l_param.irreversible = irreversible - - l_param.numresolution = 6 - - l_param.prog_order = glymur.core.LRCP - - l_params = (glymur.lib._openjp2.ImageComptParmType * num_comps)() - for j in range(num_comps): - l_params[j].dx = 1 - l_params[j].dy = 1 - l_params[j].h = image_height - l_params[j].w = image_width - l_params[j].sgnd = 0 - l_params[j].prec = comp_prec - l_params[j].x0 = 0 - l_params[j].y0 = 0 - - codec = glymur.lib._openjp2.create_compress(codec) - - glymur.lib._openjp2.set_info_handler(codec, None) - glymur.lib._openjp2.set_warning_handler(codec, None) - glymur.lib._openjp2.set_error_handler(codec, None) - - cspace = glymur.lib._openjp2.CLRSPC_SRGB - l_image = glymur.lib._openjp2.image_tile_create(l_params, cspace) - - l_image.contents.x0 = 0 - l_image.contents.y0 = 0 - l_image.contents.x1 = image_width - l_image.contents.y1 = image_height - l_image.contents.color_space = glymur.lib._openjp2.CLRSPC_SRGB - - glymur.lib._openjp2.setup_encoder(codec, l_param, l_image) - - x = (filename, False) - stream = glymur.lib._openjp2.stream_create_default_file_stream_v3(*x) - glymur.lib._openjp2.start_compress(codec, l_image, stream) - - for j in np.arange(num_tiles): - glymur.lib._openjp2.write_tile(codec, j, data, tile_size, stream) - - glymur.lib._openjp2.end_compress(codec, stream) - glymur.lib._openjp2.stream_destroy_v3(stream) - glymur.lib._openjp2.destroy_codec(codec) - glymur.lib._openjp2.image_destroy(l_image) - - def tte0_setup(self, filename): - kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_J2K, - 'comp_prec': 8, - 'irreversible': 1, - 'num_comps': 3, - 'image_height': 200, - 'image_width': 200, - 'tile_height': 100, - 'tile_width': 100} - self.tile_encoder(**kwargs) + openjp2.end_decompress(codec, stream) + openjp2.destroy_codec(codec) + openjp2.stream_destroy_v3(stream) + openjp2.image_destroy(image) def test_tte0(self): - # Runs test designated tte0 in OpenJPEG test suite. + """Runs test designated tte0 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - self.tte0_setup(tfile.name) + ttx0_setup(tfile.name) + self.assertTrue(True) def test_ttd0(self): - # Runs test designated ttd0 in OpenJPEG test suite. + """Runs test designated ttd0 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: # Produce the tte0 output file for ttd0 input. - self.tte0_setup(tfile.name) + ttx0_setup(tfile.name) kwargs = {'x0': 0, 'y0': 0, 'x1': 1000, 'y1': 1000, 'filename': tfile.name, - 'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.tile_decoder(**kwargs) + 'codec_format': openjp2.CODEC_J2K} + tile_decoder(**kwargs) + self.assertTrue(True) - def tte1_setup(self, filename): + def xtx1_setup(self, filename): + """Runs tests tte1, rta1.""" kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_J2K, + 'codec': openjp2.CODEC_J2K, 'comp_prec': 8, 'irreversible': 1, 'num_comps': 3, @@ -261,149 +142,298 @@ class TestOpenJP2(unittest.TestCase): 'image_width': 256, 'tile_height': 128, 'tile_width': 128} - self.tile_encoder(**kwargs) + tile_encoder(**kwargs) + self.assertTrue(True) def test_tte1(self): + """Runs test designated tte1 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - # Runs test designated tte1 in OpenJPEG test suite. - self.tte1_setup(tfile.name) + self.xtx1_setup(tfile.name) def test_ttd1(self): - # Runs test designated ttd1 in OpenJPEG test suite. + """Runs test designated ttd1 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: # Produce the tte0 output file for ttd0 input. - self.tte1_setup(tfile.name) + self.xtx1_setup(tfile.name) kwargs = {'x0': 0, 'y0': 0, 'x1': 128, 'y1': 128, 'filename': tfile.name, - 'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.tile_decoder(**kwargs) + 'codec_format': openjp2.CODEC_J2K} + tile_decoder(**kwargs) + self.assertTrue(True) def test_rta1(self): + """Runs test designated rta1 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - # Runs test designated rta1 in OpenJPEG test suite. - self.tte1_setup(tfile.name) + self.xtx1_setup(tfile.name) - kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.j2k_random_tile_access(tfile.name, **kwargs) - - def tte2_setup(self, filename): - kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_JP2, - 'comp_prec': 8, - 'irreversible': 1, - 'num_comps': 3, - 'image_height': 256, - 'image_width': 256, - 'tile_height': 128, - 'tile_width': 128} - self.tile_encoder(**kwargs) + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) + self.assertTrue(True) def test_tte2(self): - # Runs test designated tte2 in OpenJPEG test suite. + """Runs test designated tte2 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: - self.tte2_setup(tfile.name) + xtx2_setup(tfile.name) + self.assertTrue(True) def test_ttd2(self): - # Runs test designated ttd2 in OpenJPEG test suite. + """Runs test designated ttd2 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: # Produce the tte0 output file for ttd0 input. - self.tte2_setup(tfile.name) + xtx2_setup(tfile.name) kwargs = {'x0': 0, 'y0': 0, 'x1': 128, 'y1': 128, 'filename': tfile.name, - 'codec_format': glymur.lib._openjp2.CODEC_JP2} - self.tile_decoder(**kwargs) + 'codec_format': openjp2.CODEC_JP2} + tile_decoder(**kwargs) + self.assertTrue(True) def test_rta2(self): + """Runs test designated rta2 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: - # Runs test designated rta2 in OpenJPEG test suite. - self.tte2_setup(tfile.name) + xtx2_setup(tfile.name) - kwargs = {'codec_format': glymur.lib._openjp2.CODEC_JP2} - self.j2k_random_tile_access(tfile.name, **kwargs) - - def tte3_setup(self, filename): - kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_J2K, - 'comp_prec': 8, - 'irreversible': 1, - 'num_comps': 1, - 'image_height': 256, - 'image_width': 256, - 'tile_height': 128, - 'tile_width': 128} - self.tile_encoder(**kwargs) + codec_format = openjp2.CODEC_JP2 + self.j2k_random_tile_access(tfile.name, codec_format) def test_tte3(self): + """Runs test designated tte3 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - # Runs test designated tte3 in OpenJPEG test suite. - self.tte3_setup(tfile.name) + xtx3_setup(tfile.name) + self.assertTrue(True) def test_rta3(self): - # Runs test designated rta3 in OpenJPEG test suite. + """Runs test designated rta3 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - self.tte3_setup(tfile.name) + xtx3_setup(tfile.name) - kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.j2k_random_tile_access(tfile.name, **kwargs) - - def tte4_setup(self, filename): - kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_J2K, - 'comp_prec': 8, - 'irreversible': 0, - 'num_comps': 1, - 'image_height': 256, - 'image_width': 256, - 'tile_height': 128, - 'tile_width': 128} - self.tile_encoder(**kwargs) + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) + self.assertTrue(True) def test_tte4(self): - # Runs test designated tte4 in OpenJPEG test suite. + """Runs test designated tte4 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - self.tte4_setup(tfile.name) + xtx4_setup(tfile.name) + self.assertTrue(True) def test_rta4(self): - # Runs test designated rta4 in OpenJPEG test suite. + """Runs test designated rta4 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - self.tte4_setup(tfile.name) + xtx4_setup(tfile.name) - kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.j2k_random_tile_access(tfile.name, **kwargs) - - def tte5_setup(self, filename): - kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_J2K, - 'comp_prec': 8, - 'irreversible': 0, - 'num_comps': 1, - 'image_height': 512, - 'image_width': 512, - 'tile_height': 256, - 'tile_width': 256} - self.tile_encoder(**kwargs) + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) def test_tte5(self): - # Runs test designated tte5 in OpenJPEG test suite. + """Runs test designated tte5 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - self.tte5_setup(tfile.name) + xtx5_setup(tfile.name) + self.assertTrue(True) def test_rta5(self): - # Runs test designated rta5 in OpenJPEG test suite. + """Runs test designated rta5 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - self.tte5_setup(tfile.name) + xtx5_setup(tfile.name) - kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.j2k_random_tile_access(tfile.name, **kwargs) + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) + + +#def tile_encoder(num_comps=None, tile_width=None, tile_height=None, +# filename=None, codec=None, comp_prec=None, +# image_width=None, image_height=None, +# irreversible=None): +def tile_encoder(**kwargs): + """Fixture used by many tests.""" + num_tiles = ((kwargs['image_width'] / kwargs['tile_width']) * + (kwargs['image_height'] / kwargs['tile_height'])) + tile_size = ((kwargs['tile_width'] * kwargs['tile_height']) * + (kwargs['num_comps'] * kwargs['comp_prec'] / 8)) + + data = np.random.random((kwargs['tile_height'], + kwargs['tile_width'], + kwargs['num_comps'])) + data = (data * 255).astype(np.uint8) + + l_param = openjp2.set_default_encoder_parameters() + + l_param.tcp_numlayers = 1 + l_param.cp_fixed_quality = 1 + l_param.tcp_distoratio[0] = 20 + + # position of the tile grid aligned with the image + l_param.cp_tx0 = 0 + l_param.cp_ty0 = 0 + + # tile size, we are using tile based encoding + l_param.tile_size_on = 1 + l_param.cp_tdx = kwargs['tile_width'] + l_param.cp_tdy = kwargs['tile_height'] + + # use irreversible encoding + l_param.irreversible = kwargs['irreversible'] + + l_param.numresolution = 6 + + l_param.prog_order = glymur.core.LRCP + + l_params = (openjp2.ImageComptParmType * kwargs['num_comps'])() + for j in range(kwargs['num_comps']): + l_params[j].dx = 1 + l_params[j].dy = 1 + l_params[j].h = kwargs['image_height'] + l_params[j].w = kwargs['image_width'] + l_params[j].sgnd = 0 + l_params[j].prec = kwargs['comp_prec'] + l_params[j].x0 = 0 + l_params[j].y0 = 0 + + codec = openjp2.create_compress(kwargs['codec']) + + openjp2.set_info_handler(codec, None) + openjp2.set_warning_handler(codec, None) + openjp2.set_error_handler(codec, None) + + cspace = openjp2.CLRSPC_SRGB + l_image = openjp2.image_tile_create(l_params, cspace) + + l_image.contents.x0 = 0 + l_image.contents.y0 = 0 + l_image.contents.x1 = kwargs['image_width'] + l_image.contents.y1 = kwargs['image_height'] + l_image.contents.color_space = openjp2.CLRSPC_SRGB + + openjp2.setup_encoder(codec, l_param, l_image) + + stream = openjp2.stream_create_default_file_stream_v3(kwargs['filename'], + False) + openjp2.start_compress(codec, l_image, stream) + + for j in np.arange(num_tiles): + openjp2.write_tile(codec, j, data, tile_size, stream) + + openjp2.end_compress(codec, stream) + openjp2.stream_destroy_v3(stream) + openjp2.destroy_codec(codec) + openjp2.image_destroy(l_image) + +def tile_decoder(**kwargs): + """Fixture called with various configurations by many tests. + + Reads a tile. That's all it does. + """ + stream = openjp2.stream_create_default_file_stream_v3(kwargs['filename'], + True) + dparam = openjp2.set_default_decoder_parameters() + + dparam.decod_format = kwargs['codec_format'] + + # Do not use layer decoding limitation. + dparam.cp_layer = 0 + + # do not use resolution reductions. + dparam.cp_reduce = 0 + + codec = openjp2.create_decompress(kwargs['codec_format']) + + openjp2.set_info_handler(codec, None) + openjp2.set_warning_handler(codec, None) + openjp2.set_error_handler(codec, None) + + openjp2.setup_decoder(codec, dparam) + image = openjp2.read_header(stream, codec) + openjp2.set_decode_area(codec, image, + kwargs['x0'], kwargs['y0'], + kwargs['x1'], kwargs['y1']) + + data = np.zeros((1150, 2048, 3), dtype=np.uint8) + while True: + rargs = openjp2.read_tile_header(codec, stream) + tidx = rargs[0] + size = rargs[1] + go_on = rargs[-1] + if not go_on: + break + openjp2.decode_tile_data(codec, tidx, data, size, stream) + + openjp2.end_decompress(codec, stream) + openjp2.destroy_codec(codec) + openjp2.stream_destroy_v3(stream) + openjp2.image_destroy(image) + +def ttx0_setup(filename): + """Runs tests tte0, tte0.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 1, + 'num_comps': 3, + 'image_height': 200, + 'image_width': 200, + 'tile_height': 100, + 'tile_width': 100} + tile_encoder(**kwargs) + +def xtx2_setup(filename): + """Runs tests rta2, tte2, ttd2.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_JP2, + 'comp_prec': 8, + 'irreversible': 1, + 'num_comps': 3, + 'image_height': 256, + 'image_width': 256, + 'tile_height': 128, + 'tile_width': 128} + tile_encoder(**kwargs) + +def xtx3_setup(filename): + """Runs tests tte3, rta3.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 1, + 'num_comps': 1, + 'image_height': 256, + 'image_width': 256, + 'tile_height': 128, + 'tile_width': 128} + tile_encoder(**kwargs) + +def xtx4_setup(filename): + """Runs tests rta4, tte4.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 0, + 'num_comps': 1, + 'image_height': 256, + 'image_width': 256, + 'tile_height': 128, + 'tile_width': 128} + tile_encoder(**kwargs) + +def xtx5_setup(filename): + """Runs tests rta5, tte5.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 0, + 'num_comps': 1, + 'image_height': 512, + 'image_width': 512, + 'tile_height': 256, + 'tile_width': 256} + tile_encoder(**kwargs) if __name__ == "__main__": unittest.main()