Mercurial > octave-libtiff
changeset 31113:a74059523d74
Tiff read: use template to remove repitition in filling matrices
* __tiff__.cc (read_stripped_image): modified the function to be templated
so it can be used for all matrix types generically, also writes directly to
the underlying pointer of the matrix.
author | magedrifaat <magedrifaat@gmail.com> |
---|---|
date | Sat, 16 Jul 2022 01:26:40 +0200 |
parents | e3d8443585fe |
children | 9dead1249449 |
files | libinterp/dldfcn/__tiff__.cc |
diffstat | 1 files changed, 46 insertions(+), 99 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/dldfcn/__tiff__.cc Fri Jul 15 21:41:13 2022 +0200 +++ b/libinterp/dldfcn/__tiff__.cc Sat Jul 16 01:26:40 2022 +0200 @@ -30,14 +30,19 @@ uint16_t samples_per_pixel; uint16_t bits_per_sample; uint16_t planar_configuration; - uint16_t pixel_size; uint16_t is_tiled; }; - void - read_stripped_image (TIFF *tif, tiff_image_data *image_data, - void ***pixel_buffer) + template <typename T> + octave_value + read_stripped_image (TIFF *tif, tiff_image_data *image_data) { + typedef typename T::element_type P; + + T img = T (dim_vector (image_data->height, image_data->width, + image_data->samples_per_pixel)); + P *img_fvec = img.fortran_vec (); + // Obtain the necessary data for handling the strips uint32_t strip_count = TIFFNumberOfStrips (tif); tdata_t buf = _TIFFmalloc (TIFFStripSize (tif)); @@ -71,27 +76,29 @@ { uint32_t row_offset = row_size_in_bits / 8 * row_subindex; - // TODO(maged): support arbitrary BitsPerSample - // for palette images + // TODO(maged): support arbitrary BitsPerSample? if (image_data->bits_per_sample >= 8 && image_data->bits_per_sample % 8 == 0) { // TODO(maged): copy entire strip at once? - memcpy (pixel_buffer[row_index + row_subindex][column], - buf + row_offset - + column * image_data->pixel_size, - image_data->pixel_size); + for (uint16_t sample = 0; + sample < image_data->samples_per_pixel; sample++) + img_fvec[sample * image_data->width * image_data->height + + column * image_data->height + + row_index + row_subindex] + = ((P *)buf)[row_subindex * image_data->width * image_data->samples_per_pixel + + column * image_data->samples_per_pixel + sample]; } else if (image_data->bits_per_sample == 4 && image_data->samples_per_pixel == 1) { // TODO(maged): Check FillOrder for completeness - uint8_t byte + uint8_t nibble = ((uint8_t *)buf)[row_offset + column / 2]; // Extract the needed nibble from the byte - byte = (column % 2 == 0? byte >> 4: byte) & 0x0F; - uint8_t ***u8_img = (uint8_t ***)pixel_buffer; - u8_img[row_index + row_subindex][column][0] = byte; + nibble = (column % 2 == 0? nibble >> 4: nibble) & 0x0F; + img_fvec[(row_index + row_subindex) + + column * image_data->height] = nibble; } else if (image_data->bits_per_sample == 1 && image_data->samples_per_pixel == 1) @@ -100,8 +107,8 @@ = ((uint8_t *)buf)[row_offset + column / 8]; // Extract the needed bit from the byte uint8_t bit = (byte >> (7 - column % 8)) & 0x01; - uint8_t ***u8_img = (uint8_t ***)pixel_buffer; - u8_img[row_index + row_subindex][column][0] = bit; + img_fvec[(row_index + row_subindex) + + column * image_data->height] = bit; } else error ("Unsupported bit depth"); @@ -113,6 +120,19 @@ error ("Images with multiple planes are not implemented yet"); } _TIFFfree (buf); + + return octave_value(img); + } + + template <typename T> + octave_value + read_image (TIFF *tif, tiff_image_data *image_data) + { + if (image_data->is_tiled) + // TODO(maged): Implement tiled images + error ("Tiled images are not implemented yet"); + else + return read_stripped_image<T> (tif, image_data); } // Error if status is not 1 (success status for TIFFGetField) @@ -659,7 +679,6 @@ // Check: Strips vs Tiles // Planar Configuration - // StripByteCounts // SamplesPerPixel and bits_per_smaple // nargout and ycbcr // ExtendedSamples? TransferFunction? GrayResponse? ColorMap? @@ -689,103 +708,31 @@ &image_data.planar_configuration)) error ("Failed to read the PlanarConfiguration tag"); - image_data.pixel_size = image_data.samples_per_pixel - * (image_data.bits_per_sample / 8); image_data.is_tiled = TIFFIsTiled(tif); - - // Create memory for storing the image data - // TODO(maged): replace malloc with a suitable C++ structure - void ***image = (void ***)malloc (sizeof(void ***) * image_data.height); - for (uint32_t row = 0; row < image_data.height; row++) - { - image[row] = (void **)malloc (sizeof(void **) * image_data.width); - for (uint32_t column = 0; column < image_data.width; column++) - // Allocate at least one byte per pixel (For BitsPerSample < 8) - image[row][column] = malloc (image_data.pixel_size > 0 ? - image_data.pixel_size: 1); - } - - if (image_data.is_tiled) - // TODO(maged): Implement tiled images - error ("Tiled images are not implemented yet"); - else - { - read_stripped_image (tif, &image_data, image); - } octave_value_list retval; - dim_vector arr_dims (image_data.height, image_data.width, - image_data.samples_per_pixel); - // TODO(maged): what about palette images? are they handled internally? switch (image_data.bits_per_sample) { case 1: - { - boolNDArray arr(arr_dims); - for (uint32_t row = 0; row < image_data.height; row++) - for (uint32_t column = 0; column < image_data.width; column++) - for (uint16_t sample = 0; sample < image_data.samples_per_pixel; sample++) - arr(row, column, sample) = ((uint8_t ***)image)[row][column][sample]; - - retval(0) = arr; - break; - } + retval(0) = read_image<boolNDArray> (tif, &image_data); + break; case 4: case 8: - { - uint8NDArray arr(arr_dims); - for (uint32_t row = 0; row < image_data.height; row++) - for (uint32_t column = 0; column < image_data.width; column++) - for (uint16_t sample = 0; sample < image_data.samples_per_pixel; sample++) - arr(row, column, sample) = ((uint8_t ***)image)[row][column][sample]; - - retval(0) = arr; - break; - } + retval(0) = read_image<uint8NDArray> (tif, &image_data); + break; case 16: - { - uint16NDArray arr(arr_dims); - for (uint32_t row = 0; row < image_data.height; row++) - for (uint32_t column = 0; column < image_data.width; column++) - for (uint16_t sample = 0; sample < image_data.samples_per_pixel; sample++) - arr(row, column, sample) = ((uint16_t ***)image)[row][column][sample]; - - retval(0) = arr; - break; - } + retval(0) = read_image<uint16NDArray> (tif, &image_data); + break; case 32: - { - uint32NDArray arr(arr_dims); - for (uint32_t row = 0; row < image_data.height; row++) - for (uint32_t column = 0; column < image_data.width; column++) - for (uint16_t sample = 0; sample < image_data.samples_per_pixel; sample++) - arr(row, column, sample) = ((uint32_t ***)image)[row][column][sample]; - - retval(0) = arr; - break; - } + retval(0) = read_image<uint32NDArray> (tif, &image_data); + break; case 64: - { - uint64NDArray arr(arr_dims); - for (uint32_t row = 0; row < image_data.height; row++) - for (uint32_t column = 0; column < image_data.width; column++) - for (uint16_t sample = 0; sample < image_data.samples_per_pixel; sample++) - arr(row, column, sample) = ((uint64_t ***)image)[row][column][sample]; - - retval(0) = arr; - break; - } + retval(0) = read_image<uint64NDArray> (tif, &image_data); + break; default: error ("Unsupported bit depth"); } - for (uint32_t row = 0; row < image_data.height; row++) - { - for (uint32_t column = 0; column < image_data.width; column++) - free (image[row][column]); - - free (image[row]); - } return retval; #else err_disabled_feature ("read", "Tiff");