changeset 31098:3cbd0d82167c

getTag: Implemented all special tags, only unsupported geotiff tags not implemented
author magedrifaat <magedrifaat@gmail.com>
date Mon, 27 Jun 2022 00:52:49 +0200
parents 75ab26f147a5
children 6fc4bf5e14e1
files libinterp/dldfcn/__tiff__.cc
diffstat 1 files changed, 136 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/__tiff__.cc	Sun Jun 26 02:58:49 2022 +0200
+++ b/libinterp/dldfcn/__tiff__.cc	Mon Jun 27 00:52:49 2022 +0200
@@ -203,6 +203,7 @@
     octave_value_list tag_data_ovl;
     uint32_t tag_ID = TIFFFieldTag(fip);
 
+    // TODO(maged): find/create images to test the special tags
     switch(tag_ID)
     {
         case TIFFTAG_STRIPBYTECOUNTS:
@@ -219,6 +220,141 @@
         case TIFFTAG_REFERENCEBLACKWHITE:
             tag_data_ovl = get_array_field_data(tif, fip, 6);
             break;
+        // TODO(maged): colormap is not always 3 channels, but libtiff hardcodes it as 3?
+        case TIFFTAG_COLORMAP:
+            {
+                uint16_t bits_per_sample;
+                if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample))
+                {
+                    error("Failed to obtain the bit depth");
+                }
+                
+                if (bits_per_sample > 24)
+                {
+                    // TODO(maged): is this the right response here?
+                    error("Too high bit depth for a palette image");
+                }
+
+                uint32_t count = 1<<bits_per_sample;
+                uint16_t *red, *green, *blue;
+                if (TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue))
+                {
+                    tag_data_ovl(0) = octave_value(interpret_data(red, count, TIFFFieldDataType(fip)));
+                    tag_data_ovl(1) = octave_value(interpret_data(green, count, TIFFFieldDataType(fip)));
+                    tag_data_ovl(2) = octave_value(interpret_data(blue, count, TIFFFieldDataType(fip)));
+                }
+                else
+                {
+                    // TODO(maged): Give a better error message?
+                    error("Failed to read tag");   
+                }
+            }
+            break;
+        case TIFFTAG_TRANSFERFUNCTION:
+            {
+                uint16_t samples_per_pixel;
+                if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel))
+                {
+                    error("Failed to obtain the number of samples per pixel");
+                }
+
+                uint16_t bits_per_sample;
+                if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample))
+                {
+                    error("Failed to obtain the number of samples per pixel");
+                }
+
+                uint32_t count = 1<<bits_per_sample;
+                uint16_t *ch1, *ch2, *ch3;
+                if (samples_per_pixel == 1)
+                {
+                    if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &ch1))
+                    {
+                        // TODO(maged): Give a better error message?
+                        error("Failed to read tag");   
+                    }
+                    tag_data_ovl(0) = octave_value(interpret_data(ch1, count, TIFFFieldDataType(fip)));
+                }
+                else
+                {
+                    if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &ch1, &ch1, &ch3))
+                    {
+                        // TODO(maged): Give a better error message?
+                        error("Failed to read tag");   
+                    }
+                    tag_data_ovl(0) = octave_value(interpret_data(ch1, count, TIFFFieldDataType(fip)));
+                    tag_data_ovl(1) = octave_value(interpret_data(ch2, count, TIFFFieldDataType(fip)));
+                    tag_data_ovl(2) = octave_value(interpret_data(ch3, count, TIFFFieldDataType(fip)));
+                }
+            }
+            break;
+        case TIFFTAG_PAGENUMBER:
+        case TIFFTAG_HALFTONEHINTS:
+        case TIFFTAG_DOTRANGE:
+        case TIFFTAG_YCBCRSUBSAMPLING:
+            {
+                uint16_t tag_part1, tag_part2;
+                if (TIFFGetField(tif, tag_ID, &tag_part1, &tag_part2))
+                {
+                    tag_data_ovl(0) = octave_value(interpret_data(&tag_part1, 1, TIFFFieldDataType(fip)));
+                    tag_data_ovl(1) = octave_value(interpret_data(&tag_part2, 1, TIFFFieldDataType(fip)));
+                }
+                else
+                {
+                    // TODO(maged): Give a better error message?
+                    error("Failed to read tag");
+                }
+            }
+            break;
+        case TIFFTAG_SUBIFD:
+            {
+                uint16_t count;
+                uint64_t *offsets;
+                if (TIFFGetField(tif, tag_ID, &count, &offsets))
+                {
+                    tag_data_ovl = interpret_data(offsets, count, TIFFFieldDataType(fip));
+                }
+                else
+                {
+                    // TODO(maged): Give a better error message?
+                    error("Failed to read tag");
+                }
+            }
+            break;
+        case TIFFTAG_EXTRASAMPLES:
+            {
+                uint16_t count;
+                uint16_t *types;
+                if (TIFFGetField(tif, tag_ID, &count, &types))
+                {
+                    tag_data_ovl = interpret_data(types, count, TIFFFieldDataType(fip));
+                }
+                else
+                {
+                    // TODO(maged): Give a better error message?
+                    error("Failed to read tag");
+                }
+            }
+            break;
+        // TODO(maged): Do I just return bytes? pass it to some parser lib?
+        case TIFFTAG_XMLPACKET:
+        case TIFFTAG_RICHTIFFIPTC:
+        case TIFFTAG_PHOTOSHOP:
+        case TIFFTAG_ICCPROFILE:
+            {
+                uint16_t count;
+                void *data;
+                if (TIFFGetField(tif, tag_ID, &count, &data))
+                {
+                    tag_data_ovl = interpret_data(data, count, TIFF_BYTE);
+                }
+                else
+                {
+                    // TODO(maged): Give a better error message?
+                    error("Failed to read tag");
+                }
+            }
+            break;
         default:
             tag_data_ovl = get_scalar_field_data(tif, fip);
     }