Mercurial > octave-libtiff
changeset 31155:a30b144bc10b
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.
author | magedrifaat <magedrifaat@gmail.com> |
---|---|
date | Thu, 04 Aug 2022 03:12:42 +0200 |
parents | 828b7cc9aa36 |
children | 1e633a093faa |
files | libinterp/dldfcn/__tiff__.cc |
diffstat | 1 files changed, 79 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- 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<octave_idx_type> 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<uint8_t *> (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 <tile_count; tile++) + { + if (! TIFFWriteEncodedTile (tif, tile, pixel_fvec, tile_size)) + error ("Failed to write tile data"); + pixel_fvec += tile_size; + } + } template <typename T>