diff --git a/include/mapnik/image_data.hpp b/include/mapnik/image_data.hpp index 6c924640e..6eddb4fa4 100644 --- a/include/mapnik/image_data.hpp +++ b/include/mapnik/image_data.hpp @@ -188,11 +188,21 @@ public: return pData_ + row * width_; } + inline const pixel_type* getRow(unsigned row, std::size_t x0) const + { + return pData_ + row * width_ + x0; + } + inline pixel_type* getRow(unsigned row) { return pData_ + row * width_; } + inline pixel_type* getRow(unsigned row, std::size_t x0) + { + return pData_ + row * width_ + x0; + } + inline void setRow(std::size_t row, pixel_type const* buf, std::size_t size) { assert(row < height_); diff --git a/include/mapnik/image_view.hpp b/include/mapnik/image_view.hpp index e36418f43..4b648aab5 100644 --- a/include/mapnik/image_view.hpp +++ b/include/mapnik/image_view.hpp @@ -99,6 +99,11 @@ public: { return data_.getRow(row + y_) + x_; } + + inline const pixel_type* getRow(unsigned row, std::size_t x0) const + { + return data_.getRow(row + y_, x0) + x_; + } inline const unsigned char* getBytes() const { diff --git a/include/mapnik/tiff_io.hpp b/include/mapnik/tiff_io.hpp index 994dbc48d..2e30e9390 100644 --- a/include/mapnik/tiff_io.hpp +++ b/include/mapnik/tiff_io.hpp @@ -35,6 +35,12 @@ extern "C" #define RealTIFFClose TIFFClose } +#define TIFF_WRITE_SCANLINE 0 +#define TIFF_WRITE_STRIPPED 1 +#define TIFF_WRITE_TILED 2 + +#include + namespace mapnik { static inline tsize_t tiff_write_proc(thandle_t fd, tdata_t buf, tsize_t size) @@ -159,11 +165,18 @@ struct tiff_config tiff_config() : compression(COMPRESSION_ADOBE_DEFLATE), zlevel(4), - scanline(false) {} + tile_width(0), + tile_height(0), + rows_per_strip(0), + method(TIFF_WRITE_STRIPPED) {} int compression; int zlevel; - bool scanline; + int tile_width; // Tile width of zero means tile the width of the image + int tile_height; // Tile height of zero means tile the height of the image + int rows_per_strip; + int method; // The method to use to write the TIFF. + }; struct tag_setter : public mapnik::util::static_visitor<> @@ -181,11 +194,13 @@ struct tag_setter : public mapnik::util::static_visitor<> inline void operator() (image_data_rgba8 const&) const { + std::cout << "Save as RGBA" << std::endl; TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 8); TIFFSetField(output_, TIFFTAG_SAMPLESPERPIXEL, 4); - uint16 extras[] = { EXTRASAMPLE_UNASSALPHA }; + //uint16 extras[] = { EXTRASAMPLE_UNASSALPHA }; + uint16 extras[] = { EXTRASAMPLE_ASSOCALPHA }; TIFFSetField(output_, TIFFTAG_EXTRASAMPLES, 1, extras); if (config_.compression == COMPRESSION_DEFLATE || config_.compression == COMPRESSION_ADOBE_DEFLATE @@ -197,6 +212,7 @@ struct tag_setter : public mapnik::util::static_visitor<> } inline void operator() (image_data_gray32f const&) const { + std::cout << "Save as 32F" << std::endl; TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 32); @@ -210,6 +226,7 @@ struct tag_setter : public mapnik::util::static_visitor<> } inline void operator() (image_data_gray16 const&) const { + std::cout << "Save as Gray 16" << std::endl; TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 16); @@ -224,6 +241,7 @@ struct tag_setter : public mapnik::util::static_visitor<> } inline void operator() (image_data_gray8 const&) const { + std::cout << "Save as Gray 8" << std::endl; TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 8); @@ -256,7 +274,9 @@ void set_tiff_config(TIFF* output, tiff_config & config) // Set the compression for the TIFF TIFFSetField(output, TIFFTAG_COMPRESSION, config.compression); - if (COMPRESSION_ADOBE_DEFLATE == config.compression || COMPRESSION_DEFLATE == config.compression) + if (COMPRESSION_ADOBE_DEFLATE == config.compression + || COMPRESSION_DEFLATE == config.compression + || COMPRESSION_LZW == config.compression) { // Set the zip level for the compression // http://en.wikipedia.org/wiki/DEFLATE#Encoder.2Fcompressor @@ -291,7 +311,6 @@ void save_as_tiff(T1 & file, T2 const& image, tiff_config & config) TIFFSetField(output, TIFFTAG_IMAGEWIDTH, width); TIFFSetField(output, TIFFTAG_IMAGELENGTH, height); TIFFSetField(output, TIFFTAG_IMAGEDEPTH, 1); - set_tiff_config(output, config); // Set tags that vary based on the type of data being provided. @@ -299,39 +318,98 @@ void save_as_tiff(T1 & file, T2 const& image, tiff_config & config) set(image); //util::apply_visitor(set, image); - // If the image is greater then 8MB uncompressed, then lets use scanline rather then - // tile. TIFF also requires that all TIFFTAG_TILEWIDTH and TIFF_TILELENGTH all be - // a multiple of 16, if they are not we will use scanline. - if (image.getSize() > 8 * 32 * 1024 * 1024 - || width % 16 != 0 - || height % 16 != 0 - || config.scanline) + // Use specific types of writing methods. + if (TIFF_WRITE_SCANLINE == config.method) { // Process Scanline TIFFSetField(output, TIFFTAG_ROWSPERSTRIP, 1); int next_scanline = 0; - std::unique_ptr row (new pixel_type[image.width()]); + std::unique_ptr row (new pixel_type[width]); while (next_scanline < height) { - std::copy(image.getRow(next_scanline), image.getRow(next_scanline) + image.width(), row.get()); - //typename T2::pixel_type * row = const_cast(image.getRow(next_scanline)); + std::copy(image.getRow(next_scanline), image.getRow(next_scanline) + width, row.get()); TIFFWriteScanline(output, row.get(), next_scanline, 0); ++next_scanline; } } - else + else if (TIFF_WRITE_STRIPPED == config.method) { - TIFFSetField(output, TIFFTAG_TILEWIDTH, width); - TIFFSetField(output, TIFFTAG_TILELENGTH, height); + std::size_t rows_per_strip = config.rows_per_strip; + if (0 == rows_per_strip) + { + rows_per_strip = height; + } + TIFFSetField(output, TIFFTAG_ROWSPERSTRIP, rows_per_strip); + std::size_t strip_size = width * rows_per_strip; + std::unique_ptr strip_buffer(new pixel_type[strip_size]); + int end_y=(height/rows_per_strip+1)*rows_per_strip; + + for (int y=0; y < end_y; y+=rows_per_strip) + { + int ty1 = std::min(height, static_cast(y + rows_per_strip)) - y; + int row = y; + for (int ty = 0; ty < ty1; ++ty, ++row) + { + std::copy(image.getRow(row), image.getRow(row) + width, strip_buffer.get() + ty * width); + } + if (TIFFWriteEncodedStrip(output, TIFFComputeStrip(output, y, 0), strip_buffer.get(), strip_size * sizeof(pixel_type)) == -1) + { + throw ImageWriterException("Could not write TIFF - TIFF Tile Write failed"); + } + } + } + else if (TIFF_WRITE_TILED == config.method) + { + int tile_width = config.tile_width; + int tile_height = config.tile_height; + + if (0 == tile_height) + { + tile_height = height; + if (height % 16 > 0) + { + tile_height = height + 16 - (height % 16); + } + } + if (0 == tile_width) + { + tile_width = width; + if (width % 16 > 0) + { + tile_width = width + 16 - (width % 16); + } + } + TIFFSetField(output, TIFFTAG_TILEWIDTH, tile_width); + TIFFSetField(output, TIFFTAG_TILELENGTH, tile_height); TIFFSetField(output, TIFFTAG_TILEDEPTH, 1); - // Process as tiles - std::size_t tile_size = width * height; - pixel_type const * image_data_in = image.getData(); + std::size_t tile_size = tile_width * tile_height; std::unique_ptr image_data_out (new pixel_type[tile_size]); - std::copy(image_data_in, image_data_in + tile_size, image_data_out.get()); - //typename T2::pixel_type * image_data = const_cast(image.getData()); - TIFFWriteTile(output, image_data_out.get(), 0, 0, 0, 0); + int end_y = (height / tile_height + 1) * tile_height; + int end_x = (width / tile_width + 1) * tile_width; + end_y = std::min(end_y, height); + end_x = std::min(end_x, width); + + for (int y = 0; y < end_y; y += tile_height) + { + int ty1 = std::min(height, y + tile_height) - y; + + for (int x = 0; x < end_x; x += tile_width) + { + // Prefill the entire array with zeros. + std::fill(image_data_out.get(), image_data_out.get() + tile_size, 0); + int tx1 = std::min(width, x + tile_width); + int row = y; + for (int ty = 0; ty < ty1; ++ty, ++row) + { + std::copy(image.getRow(row, x), image.getRow(row, tx1), image_data_out.get() + ty * tile_width); + } + if (TIFFWriteEncodedTile(output, TIFFComputeTile(output, x, y, 0, 0), image_data_out.get(), tile_size * sizeof(pixel_type)) == -1) + { + throw ImageWriterException("Could not write TIFF - TIFF Tile Write failed"); + } + } + } } // TODO - handle palette images // std::vector const& palette diff --git a/src/image_util.cpp b/src/image_util.cpp index 07d9ecfa0..a5bb8e98f 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -300,6 +300,29 @@ void handle_tiff_options(std::string const& type, } } } + else if (boost::algorithm::starts_with(t, "method=")) + { + std::string val = t.substr(7); + if (!val.empty()) + { + if (val == "scanline") + { + config.method = TIFF_WRITE_SCANLINE; + } + else if (val == "strip" || val == "stripped") + { + config.method = TIFF_WRITE_STRIPPED; + } + else if (val == "tiled") + { + config.method = TIFF_WRITE_TILED; + } + else + { + throw ImageWriterException("invalid tiff method: '" + val + "'"); + } + } + } else if (boost::algorithm::starts_with(t, "zlevel=")) { std::string val = t.substr(7); @@ -311,14 +334,36 @@ void handle_tiff_options(std::string const& type, } } } - else if (boost::algorithm::starts_with(t, "scanline=")) + else if (boost::algorithm::starts_with(t, "tile_height=")) { - std::string val = t.substr(9); + std::string val = t.substr(12); if (!val.empty()) { - if (!mapnik::util::string2bool(val,config.scanline)) + if (!mapnik::util::string2int(val,config.tile_height) || config.tile_height < 0 ) { - throw ImageWriterException("invalid tiff scanline: '" + val + "'"); + throw ImageWriterException("invalid tiff tile_height: '" + val + "'"); + } + } + } + else if (boost::algorithm::starts_with(t, "tile_width=")) + { + std::string val = t.substr(11); + if (!val.empty()) + { + if (!mapnik::util::string2int(val,config.tile_width) || config.tile_width < 0 ) + { + throw ImageWriterException("invalid tiff tile_width: '" + val + "'"); + } + } + } + else if (boost::algorithm::starts_with(t, "rows_per_strip=")) + { + std::string val = t.substr(15); + if (!val.empty()) + { + if (!mapnik::util::string2int(val,config.rows_per_strip) || config.rows_per_strip < 0 ) + { + throw ImageWriterException("invalid tiff rows_per_strip: '" + val + "'"); } } } diff --git a/src/tiff_reader.cpp b/src/tiff_reader.cpp index 572718293..709fb240b 100644 --- a/src/tiff_reader.cpp +++ b/src/tiff_reader.cpp @@ -477,12 +477,9 @@ struct tiff_reader_traits { if (TIFFReadRGBATile(tif, x0, y0, buf) != -1) { - for (int y = 0; y < tile_height/2 ;++y) + for (unsigned y = 0; y < tile_height/2; ++y) { - for (int x = 0; x < tile_width; ++x) - { - std::swap(buf[y * tile_width + x], buf[x + (tile_height - y - 1) * tile_width]); - } + std::swap_ranges(buf + y * tile_width, buf + (y + 1) * tile_width, buf + (tile_height - y - 1) * tile_width); } return true; } diff --git a/tests/python_tests/image_test.py b/tests/python_tests/image_test.py index 1ce6c5f2d..6e0fa66b7 100644 --- a/tests/python_tests/image_test.py +++ b/tests/python_tests/image_test.py @@ -25,38 +25,6 @@ def test_negative_image_dimensions(): # TODO - this may have regressed in https://github.com/mapnik/mapnik/commit/4f3521ac24b61fc8ae8fd344a16dc3a5fdf15af7 im = mapnik.Image(-40,40) -def test_tiff_round_trip_scanline(): - filepath = '/tmp/mapnik-tiff-io-scanline.tiff' - im = mapnik.Image(255,267) - im.background = mapnik.Color('rgba(1,2,3,.5)') - im.save(filepath,'tiff:scanline=1') - im2 = mapnik.Image.open(filepath) - im3 = mapnik.Image.fromstring(open(filepath,'r').read()) - eq_(im.width(),im2.width()) - eq_(im.height(),im2.height()) - eq_(im.width(),im3.width()) - eq_(im.height(),im3.height()) - eq_(len(im.tostring()),len(im2.tostring())) - eq_(len(im.tostring('tiff')),len(im2.tostring('tiff'))) - eq_(len(im.tostring()),len(im3.tostring())) - eq_(len(im.tostring('tiff')),len(im3.tostring('tiff'))) - -def test_tiff_round_trip_tiled(): - filepath = '/tmp/mapnik-tiff-io-tiled.tiff' - im = mapnik.Image(256,256) - im.background = mapnik.Color('rgba(1,2,3,.5)') - im.save(filepath,'tiff') - im2 = mapnik.Image.open(filepath) - im3 = mapnik.Image.fromstring(open(filepath,'r').read()) - eq_(im.width(),im2.width()) - eq_(im.height(),im2.height()) - eq_(im.width(),im3.width()) - eq_(im.height(),im3.height()) - eq_(len(im.tostring()),len(im2.tostring())) - eq_(len(im.tostring('tiff')),len(im2.tostring('tiff'))) - eq_(len(im.tostring()),len(im3.tostring())) - eq_(len(im.tostring('tiff')),len(im3.tostring('tiff'))) - def test_jpeg_round_trip(): filepath = '/tmp/mapnik-jpeg-io.jpeg' im = mapnik.Image(255,267) diff --git a/tests/python_tests/image_tiff_test.py b/tests/python_tests/image_tiff_test.py index 268d35394..ad37103be 100644 --- a/tests/python_tests/image_tiff_test.py +++ b/tests/python_tests/image_tiff_test.py @@ -12,6 +12,99 @@ def setup(): # from another directory we need to chdir() os.chdir(execution_path('.')) +def test_tiff_round_trip_scanline(): + filepath = '/tmp/mapnik-tiff-io-scanline.tiff' + im = mapnik.Image(255,267) + im.background = mapnik.Color('rgba(1,2,3,.5)') + org_str = len(im.tostring()) + im.save(filepath,'tiff:method=scanline') + im2 = mapnik.Image.open(filepath) + im3 = mapnik.Image.fromstring(open(filepath,'r').read()) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(im.width(),im3.width()) + eq_(im.height(),im3.height()) + eq_(len(im.tostring()), org_str) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=scanline')),len(im2.tostring('tiff:method=scanline'))) + eq_(len(im.tostring()),len(im3.tostring())) + eq_(len(im.tostring('tiff:method=scanline')),len(im3.tostring('tiff:method=scanline'))) + +def test_tiff_round_trip_stripped(): + filepath = '/tmp/mapnik-tiff-io-stripped.tiff' + im = mapnik.Image(255,267) + im.background = mapnik.Color('rgba(1,2,3,.5)') + org_str = len(im.tostring()) + im.save(filepath,'tiff:method=stripped') + im2 = mapnik.Image.open(filepath) + im3 = mapnik.Image.fromstring(open(filepath,'r').read()) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(im.width(),im3.width()) + eq_(im.height(),im3.height()) + eq_(len(im.tostring()), org_str) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=stripped')),len(im2.tostring('tiff:method=stripped'))) + eq_(len(im.tostring()),len(im3.tostring())) + eq_(len(im.tostring('tiff:method=stripped')),len(im3.tostring('tiff:method=stripped'))) + +def test_tiff_round_trip_rows_stripped(): + filepath = '/tmp/mapnik-tiff-io-stripped.tiff' + im = mapnik.Image(255,267) + im.background = mapnik.Color('rgba(1,2,3,.5)') + org_str = len(im.tostring()) + im.save(filepath,'tiff:method=stripped:rows_per_strip=8') + im2 = mapnik.Image.open(filepath) + im3 = mapnik.Image.fromstring(open(filepath,'r').read()) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(im.width(),im3.width()) + eq_(im.height(),im3.height()) + eq_(len(im.tostring()), org_str) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=stripped:rows_per_strip=8')),len(im2.tostring('tiff:method=stripped:rows_per_strip=8'))) + eq_(len(im.tostring()),len(im3.tostring())) + eq_(len(im.tostring('tiff:method=stripped:rows_per_strip=8')),len(im3.tostring('tiff:method=stripped:rows_per_strip=8'))) + +def test_tiff_round_trip_buffered_tiled(): + filepath = '/tmp/mapnik-tiff-io-buffered-tiled.tiff' + filepath2 = '/tmp/mapnik-tiff-io-buffered-tiled2.tiff' + im = mapnik.Image(255,267) + #im = mapnik.Image(256,256) + im.background = mapnik.Color('rgba(1,2,3,.5)') + im.save(filepath,'tiff:method=tiled:tile_width=32:tile_height=32') + im2 = mapnik.Image.open(filepath) + im3 = mapnik.Image.fromstring(open(filepath,'r').read()) + im2.save(filepath2, 'tiff:method=tiled:tile_width=32:tile_height=32') + im4 = mapnik.Image.open(filepath2) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(im.width(),im3.width()) + eq_(im.height(),im3.height()) + eq_(len(im2.tostring()),len(im4.tostring())) + eq_(len(im2.tostring('tiff:method=tiled:tile_width=32:tile_height=32')),len(im4.tostring('tiff:method=tiled:tile_width=32:tile_height=32'))) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=tiled:tile_width=32:tile_height=32')),len(im2.tostring('tiff:method=tiled:tile_width=32:tile_height=32'))) + eq_(len(im.tostring()),len(im3.tostring())) + eq_(len(im.tostring('tiff:method=tiled:tile_width=32:tile_height=32')),len(im3.tostring('tiff:method=tiled:tile_width=32:tile_height=32'))) + +def test_tiff_round_trip_tiled(): + filepath = '/tmp/mapnik-tiff-io-tiled.tiff' + im = mapnik.Image(256,256) + im.background = mapnik.Color('rgba(1,2,3,.5)') + im.save(filepath,'tiff:method=tiled') + im2 = mapnik.Image.open(filepath) + im3 = mapnik.Image.fromstring(open(filepath,'r').read()) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(im.width(),im3.width()) + eq_(im.height(),im3.height()) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=tiled')),len(im2.tostring('tiff:method=tiled'))) + eq_(len(im.tostring()),len(im3.tostring())) + eq_(len(im.tostring('tiff:method=tiled')),len(im3.tostring('tiff:method=tiled'))) + + def test_tiff_rgb8_compare(): filepath1 = '../data/tiff/ndvi_256x256_rgb8_striped.tif' filepath2 = '/tmp/mapnik-tiff-rgb8.tiff' @@ -25,55 +118,159 @@ def test_tiff_rgb8_compare(): # should not be a blank image eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) -def test_tiff_rgba8_compare(): +def test_tiff_rgba8_compare_scanline(): filepath1 = '../data/tiff/ndvi_256x256_rgba8_striped.tif' - filepath2 = '/tmp/mapnik-tiff-rgba8.tiff' + filepath2 = '/tmp/mapnik-tiff-rgba8-scanline.tiff' im = mapnik.Image.open(filepath1) - im.save(filepath2,'tiff') + im.save(filepath2,'tiff:method=scanline') im2 = mapnik.Image.open(filepath2) eq_(im.width(),im2.width()) eq_(im.height(),im2.height()) eq_(len(im.tostring()),len(im2.tostring())) - eq_(len(im.tostring('tiff')),len(im2.tostring('tiff'))) + eq_(len(im.tostring('tiff:method=scanline')),len(im2.tostring('tiff:method=scanline'))) # should not be a blank image eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) -def test_tiff_gray8_compare(): +def test_tiff_rgba8_compare_stripped(): + filepath1 = '../data/tiff/ndvi_256x256_rgba8_striped.tif' + filepath2 = '/tmp/mapnik-tiff-rgba8-stripped.tiff' + im = mapnik.Image.open(filepath1) + im.save(filepath2,'tiff:method=stripped') + im2 = mapnik.Image.open(filepath2) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=stripped')),len(im2.tostring('tiff:method=stripped'))) + # should not be a blank image + eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) + +def test_tiff_rgba8_compare_tiled(): + filepath1 = '../data/tiff/ndvi_256x256_rgba8_striped.tif' + filepath2 = '/tmp/mapnik-tiff-rgba8-stripped.tiff' + im = mapnik.Image.open(filepath1) + im.save(filepath2,'tiff:method=tiled') + im2 = mapnik.Image.open(filepath2) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=tiled')),len(im2.tostring('tiff:method=tiled'))) + # should not be a blank image + eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) + +def test_tiff_gray8_compare_scanline(): filepath1 = '../data/tiff/ndvi_256x256_gray8_striped.tif' - filepath2 = '/tmp/mapnik-tiff-gray8.tiff' + filepath2 = '/tmp/mapnik-tiff-gray8-scanline.tiff' im = mapnik.Image.open(filepath1) - im.save(filepath2,'tiff') + im.save(filepath2,'tiff:method=scanline') im2 = mapnik.Image.open(filepath2) eq_(im.width(),im2.width()) eq_(im.height(),im2.height()) eq_(len(im.tostring()),len(im2.tostring())) - eq_(len(im.tostring('tiff')),len(im2.tostring('tiff'))) + eq_(len(im.tostring('tiff:method=scanline')),len(im2.tostring('tiff:method=scanline'))) # should not be a blank image eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) -def test_tiff_gray16_compare(): +def test_tiff_gray8_compare_stripped(): + filepath1 = '../data/tiff/ndvi_256x256_gray8_striped.tif' + filepath2 = '/tmp/mapnik-tiff-gray8-stripped.tiff' + im = mapnik.Image.open(filepath1) + im.save(filepath2,'tiff:method=stripped') + im2 = mapnik.Image.open(filepath2) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=stripped')),len(im2.tostring('tiff:method=stripped'))) + # should not be a blank image + eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) + +def test_tiff_gray8_compare_tiled(): + filepath1 = '../data/tiff/ndvi_256x256_gray8_striped.tif' + filepath2 = '/tmp/mapnik-tiff-gray8-tiled.tiff' + im = mapnik.Image.open(filepath1) + im.save(filepath2,'tiff:method=tiled') + im2 = mapnik.Image.open(filepath2) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=tiled')),len(im2.tostring('tiff:method=tiled'))) + # should not be a blank image + eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) + +def test_tiff_gray16_compare_scanline(): filepath1 = '../data/tiff/ndvi_256x256_gray16_striped.tif' - filepath2 = '/tmp/mapnik-tiff-gray16.tiff' + filepath2 = '/tmp/mapnik-tiff-gray16-scanline.tiff' im = mapnik.Image.open(filepath1) - im.save(filepath2,'tiff') + im.save(filepath2,'tiff:method=scanline') im2 = mapnik.Image.open(filepath2) eq_(im.width(),im2.width()) eq_(im.height(),im2.height()) eq_(len(im.tostring()),len(im2.tostring())) - eq_(len(im.tostring('tiff')),len(im2.tostring('tiff'))) + eq_(len(im.tostring('tiff:method=scanline')),len(im2.tostring('tiff:method=scanline'))) # should not be a blank image eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) -def test_tiff_gray32f_compare(): - filepath1 = '../data/tiff/ndvi_256x256_gray32f_striped.tif' - filepath2 = '/tmp/mapnik-tiff-gray32f.tiff' +def test_tiff_gray16_compare_stripped(): + filepath1 = '../data/tiff/ndvi_256x256_gray16_striped.tif' + filepath2 = '/tmp/mapnik-tiff-gray16-stripped.tiff' im = mapnik.Image.open(filepath1) - im.save(filepath2,'tiff') + im.save(filepath2,'tiff:method=stripped') im2 = mapnik.Image.open(filepath2) eq_(im.width(),im2.width()) eq_(im.height(),im2.height()) eq_(len(im.tostring()),len(im2.tostring())) - eq_(len(im.tostring('tiff')),len(im2.tostring('tiff'))) + eq_(len(im.tostring('tiff:method=stripped')),len(im2.tostring('tiff:method=stripped'))) + # should not be a blank image + eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) + +def test_tiff_gray16_compare_tiled(): + filepath1 = '../data/tiff/ndvi_256x256_gray16_striped.tif' + filepath2 = '/tmp/mapnik-tiff-gray16-tiled.tiff' + im = mapnik.Image.open(filepath1) + im.save(filepath2,'tiff:method=tiled') + im2 = mapnik.Image.open(filepath2) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=tiled')),len(im2.tostring('tiff:method=tiled'))) + # should not be a blank image + eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) + +def test_tiff_gray32f_compare_scanline(): + filepath1 = '../data/tiff/ndvi_256x256_gray32f_striped.tif' + filepath2 = '/tmp/mapnik-tiff-gray32f-scanline.tiff' + im = mapnik.Image.open(filepath1) + im.save(filepath2,'tiff:method=scanline') + im2 = mapnik.Image.open(filepath2) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=scanline')),len(im2.tostring('tiff:method=scanline'))) + # should not be a blank image + eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) + +def test_tiff_gray32f_compare_stripped(): + filepath1 = '../data/tiff/ndvi_256x256_gray32f_striped.tif' + filepath2 = '/tmp/mapnik-tiff-gray32f-stripped.tiff' + im = mapnik.Image.open(filepath1) + im.save(filepath2,'tiff:method=stripped') + im2 = mapnik.Image.open(filepath2) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=stripped')),len(im2.tostring('tiff:method=stripped'))) + # should not be a blank image + eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True) + +def test_tiff_gray32f_compare_tiled(): + filepath1 = '../data/tiff/ndvi_256x256_gray32f_striped.tif' + filepath2 = '/tmp/mapnik-tiff-gray32f-tiled.tiff' + im = mapnik.Image.open(filepath1) + im.save(filepath2,'tiff:method=tiled') + im2 = mapnik.Image.open(filepath2) + eq_(im.width(),im2.width()) + eq_(im.height(),im2.height()) + eq_(len(im.tostring()),len(im2.tostring())) + eq_(len(im.tostring('tiff:method=tiled')),len(im2.tostring('tiff:method=tiled'))) # should not be a blank image eq_(len(im.tostring("png")) != len(mapnik.Image(im.width(),im.height()).tostring("png")),True)