diff libinterp/dldfcn/__tiff__.cc @ 31154:828b7cc9aa36

Tiff write: added support for BiLevel stripped images and added unit tests * __tiff__.cc(write_stripped_image): implemented support for writing logical images. * Tiff.m: added tests for writing stripped images using the write method.
author magedrifaat <magedrifaat@gmail.com>
date Thu, 04 Aug 2022 00:02:27 +0200
parents c66d6c7f025e
children a30b144bc10b
line wrap: on
line diff
--- a/libinterp/dldfcn/__tiff__.cc	Wed Aug 03 22:06:43 2022 +0200
+++ b/libinterp/dldfcn/__tiff__.cc	Thu Aug 04 00:02:27 2022 +0200
@@ -1268,12 +1268,45 @@
       {
         rows_in_strip = get_rows_in_strip (strip, strip_count,
                                            row_per_strip, image_data);
-        strip_size = rows_in_strip * image_data->width * sizeof (P);
-        if (image_data->planar_configuration == PLANARCONFIG_CONTIG)
-          strip_size *= image_data->samples_per_pixel;
-        if (! TIFFWriteEncodedStrip (tif, strip, pixel_fvec, strip_size))
-          error ("Failed to rite strip data");
-        pixel_fvec += strip_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)
+          {
+            strip_size = rows_in_strip * image_data->width * sizeof (P);
+            if (image_data->planar_configuration == PLANARCONFIG_CONTIG)
+              strip_size *= image_data->samples_per_pixel;
+            if (! TIFFWriteEncodedStrip (tif, strip, pixel_fvec, strip_size))
+              error ("Failed to rite strip data");
+            pixel_fvec += strip_size;
+          }
+        else if (image_data->bits_per_sample == 1)
+          {
+            // 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
+              = std::make_unique<uint8_t []> (TIFFStripSize (tif));
+            uint8_t *strip_buf = strip_ptr.get ();
+            // According to the format specification, the row should be byte
+            // aligned so the number of bytes is rounded up to the nearest byte
+            uint32_t padded_width = (image_data->width + 7) / 8;
+            // Packing the pixel data into bits
+            for (uint32_t row = 0; row < rows_in_strip; row++)
+              {
+                for (uint32_t col = 0; col < image_data->width; col++)
+                {
+                  uint8_t shift = 7 - col % 8;
+                  strip_buf[row * padded_width + col / 8]
+                    |= pixel_fvec[col] << shift;
+                }
+                pixel_fvec += image_data->width;
+              }
+            strip_size = padded_width * rows_in_strip;
+            if (TIFFWriteEncodedStrip (tif, strip, strip_buf, strip_size) == -1)
+              error ("Failed to write strip data to image");
+          }
+        else
+          error ("Unsupported bit depth");
       }
   }