# HG changeset patch # User magedrifaat # Date 1659575562 -7200 # Node ID a30b144bc10bd3e0f9f773d845270e13d85553ea # Parent 828b7cc9aa36a6dd97934f207648f0529f278baa Tiff write: added support for writing tiled images * __tiff__.cc(write_tiled_image): implemented the logic to write tiled images for all cases except logical images. diff -r 828b7cc9aa36 -r a30b144bc10b libinterp/dldfcn/__tiff__.cc --- a/libinterp/dldfcn/__tiff__.cc Thu Aug 04 00:02:27 2022 +0200 +++ b/libinterp/dldfcn/__tiff__.cc Thu Aug 04 03:12:42 2022 +0200 @@ -1316,6 +1316,85 @@ { // TODO(maged): remove this? ASSUMES pixel data dimensions are already validated + typedef typename T::element_type P; + + uint32_t tile_width, tile_height; + if (! TIFFGetField (tif, TIFFTAG_TILEWIDTH, &tile_width)) + error ("Failed to get the tile width"); + if (! TIFFGetField (tif, TIFFTAG_TILELENGTH, &tile_height)) + error ("Failed to get the tile length"); + + if (tile_height == 0 || tile_height % 16 != 0 + || tile_width == 0 || tile_width % 16 != 0) + error ("Tile dimesion tags are invalid"); + + uint32_t tiles_across = (image_data->width + tile_width - 1) + / tile_width; + uint32_t tiles_down = (image_data->height + tile_height - 1) + / tile_height; + + // Resize the image data to add tile padding + dim_vector padded_dims (tiles_down * tile_height, + tiles_across * tile_width, + image_data->samples_per_pixel); + pixel_data.resize (padded_dims); + + // Reshape the image to separate tiles into their own dimension + // so we can permute them to the right order + dim_vector tiled_dims (tile_height, tiles_down, tile_width, tiles_across, + image_data->samples_per_pixel); + pixel_data = pixel_data.reshape (tiled_dims); + + // Permute the dimesnions to get the memory alignment to match LibTIFF + Array perm (dim_vector (5, 1)); + if (image_data->planar_configuration == PLANARCONFIG_SEPARATE) + { + // For separate planes, the data coming from libtiff will have all + // tiles of the first sample then all tiles of the second sample + // and so on. Tiles of each sample will be ordered from left to right + // and from top to bottom. And data inside each tile is organised as + // rows and each row contains columns. + // So the order for LibTIFF is: + // samples x tiles_down x tiles_across x tile_height x tile_width + // But memory orientation of Octave arrays is reversed so we set it to + // tile_width x tile_height x tiles_across x tiles_down x samples + perm(0) = 2; + perm(1) = 0; + perm(2) = 3; + perm(3) = 1; + perm(4) = 4; + } + else + { + // For chunky planes, the data coming from libtiff will be ordered + // from left to right and from top to bottom. And data inside each + // tile is organised as rows and each row contains columns and each + // column contains samples. + // So the order for LibTIFF is: + // tiles_down x tiles_across x tile_height x tile_width x samples + // But memory orientation of Octave arrays is reversed so we set it to + // samples x tile_width x tile_height x tiles_across x tiles_down + perm(0) = 4; + perm(1) = 2; + perm(2) = 0; + perm(3) = 3; + perm(4) = 1; + } + pixel_data = pixel_data.permute (perm); + + uint8_t *pixel_fvec + = reinterpret_cast (pixel_data.fortran_vec ()); + uint32_t tile_count = TIFFNumberOfTiles (tif); + uint64_t tile_size = tile_width * tile_height * sizeof (P); + if (image_data->planar_configuration == PLANARCONFIG_CONTIG) + tile_size *= image_data->samples_per_pixel; + for (uint32_t tile = 0; tile