Mercurial > octave-libtiff
diff libinterp/dldfcn/__tiff__.cc @ 31156:1e633a093faa
Tiff write: added support for logical tile images and corresponding unit tests
* __tiff__.cc(write_tiled_image): added logic for logical images.
* Tiff.m: added unit tests for write method for tiled images.
author | magedrifaat <magedrifaat@gmail.com> |
---|---|
date | Thu, 04 Aug 2022 19:29:36 +0200 |
parents | a30b144bc10b |
children | dc3d2744916d |
line wrap: on
line diff
--- a/libinterp/dldfcn/__tiff__.cc Thu Aug 04 03:12:42 2022 +0200 +++ b/libinterp/dldfcn/__tiff__.cc Thu Aug 04 19:29:36 2022 +0200 @@ -1282,6 +1282,9 @@ } else if (image_data->bits_per_sample == 1) { + if (image_data->samples_per_pixel != 1) + error ("Bi-Level images must have one channel only"); + // Create a buffer to hold the packed strip data // Unique pointers are faster than vectors for constant size buffers std::unique_ptr<uint8_t []> strip_ptr @@ -1316,8 +1319,6 @@ { // 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"); @@ -1385,14 +1386,47 @@ 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; + tsize_t tile_size = TIFFTileSize (tif); + 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; + if (image_data->bits_per_sample == 8 + || image_data->bits_per_sample == 16 + || image_data->bits_per_sample == 32 + || image_data->bits_per_sample == 64) + { + if (! TIFFWriteEncodedTile (tif, tile, pixel_fvec, tile_size)) + error ("Failed to write tile data"); + pixel_fvec += tile_size; + } + else if (image_data->bits_per_sample == 1) + { + if (image_data->samples_per_pixel != 1) + error ("Bi-Level images must have one channel only"); + + // Create a buffer to hold the packed tile data + // Unique pointers are faster than vectors for + // constant size buffers + std::unique_ptr<uint8_t []> tile_ptr + = std::make_unique<uint8_t []> (tile_size); + uint8_t *tile_buf = tile_ptr.get (); + // Packing the pixel data into bits + for (uint32_t row = 0; row < tile_height; row++) + { + for (uint32_t col = 0; col < tile_width; col++) + { + uint8_t shift = 7 - col % 8; + tile_buf[row * tile_width / 8 + col / 8] + |= pixel_fvec[col] << shift; + } + pixel_fvec += tile_width; + } + if (TIFFWriteEncodedTile (tif, tile, tile_buf, + TIFFTileSize (tif)) == -1) + error ("Failed to write tile data to image"); + } + else + error ("Unsupported bit depth"); } }