# HG changeset patch # User magedrifaat # Date 1655933542 -7200 # Node ID ab5b33e447b0141b0c42f6807342f6587b6a0daf # Parent e2bed4daae82a10f8cdb5480a3fbcc7db639376b Modified getTag to account for different tag data types and multivalued tags, the current implementation is still buggy for most tags and data types diff -r e2bed4daae82 -r ab5b33e447b0 libinterp/dldfcn/__tiff__.cc --- a/libinterp/dldfcn/__tiff__.cc Fri Jun 17 17:43:41 2022 +0200 +++ b/libinterp/dldfcn/__tiff__.cc Wed Jun 22 23:32:22 2022 +0200 @@ -1,4 +1,5 @@ #include +#include #include "defun-dld.h" #include "ov.h" @@ -10,6 +11,106 @@ // TODO(maged): Tidy up the formatting to be consistant with octave +octave_value interpret_data(void *data, uint32_t count, TIFFDataType tag_datatype) +{ + // TODO(maged): Find the correct way fo returning multivalues + octave_value_list ov_data; + switch (tag_datatype) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + for (uint32_t i = 0; i < count; i++) + { + ov_data(i) = octave_value(((uint8_t *)data)[i]); + } + break; + + case TIFF_ASCII: + ov_data(0) = octave_value((char *)data); + break; + + case TIFF_SHORT: + for (uint32_t i = 0; i < count; i++) + { + ov_data(i) = octave_value(((uint16_t *)data)[i]); + } + break; + + case TIFF_LONG: + for (uint32_t i = 0; i < count; i++) + { + ov_data(i) = octave_value(((uint32_t *)data)[i]); + } + break; + + // case TIFF_RATIONAL: + // uint32_t *u32data = (uint32_t *)data; + // for (uint32_t i = 0; i < count; i+=2) + // { + // ov_data(i / 2) = octave_value((float)u32data[i] / (float)u32data[i+1]); + // } + // break; + + // case TIFF_SBYTE: + // int8_t *s8data = (int8_t *)data; + // for (uint32_t i = 0; i < count; i++) + // { + // ov_data(i) = octave_value(s8data[i]); + // } + // break; + + // case TIFF_SSHORT: + // int16_t *s16data = (int16_t *)data; + // for (uint32_t i = 0; i < count; i++) + // { + // ov_data(i) = octave_value(s16data[i]); + // } + // break; + + // case TIFF_SLONG: + // int32_t *s32data = (int32_t *)data; + // for (uint32_t i = 0; i < count; i++) + // { + // ov_data(i) = octave_value(s32data[i]); + // } + // break; + + // case TIFF_FLOAT: + // float *float_data = (float *)data; + // for (uint32_t i = 0; i < count; i++) + // { + // ov_data(i) = octave_value(double_data[i]); + // } + // break; + + // case TIFF_DOUBLE: + // double *double_data = (double *)data; + // for (uint32_t i = 0; i < count; i++) + // { + // ov_data(i) = octave_value(double_data[i]); + // } + // break; + + // case TIFF_SRATIONAL: + // int32_t *s32data = (int32_t *)data; + // for (uint32_t i = 0; i < count; i+=2) + // { + // ov_data(i / 2) = octave_value((float)s32data[i] / (float)s32data[i+1]); + // } + // break; + + case TIFF_IFD: + // TODO(maged): implement IFD datatype + error("Unimplemented IFFD data type"); + break; + default: + // TODO(maged): find the correct response in this case + error("Unsupported tag data type"); + } + + return octave_value(ov_data); +} + DEFUN_DLD (__open_tiff__, args, nargout, "Open a Tiff file and return its handle") { @@ -28,6 +129,7 @@ if (nargin == 2) mode = args(1).string_value(); + // TODO(maged): Look into unwind action TIFF *tif = TIFFOpen(filename.c_str(), mode.c_str()); // TODO(maged): print a better error if (!tif) @@ -73,10 +175,11 @@ TIFF *tif = (TIFF *)(args(0).uint64_value()); uint32_t tag_ID; + const TIFFField *fip; if (args(1).type_name() == "string") { std::string tagName = args(1).string_value(); - const TIFFField *fip = TIFFFieldWithName(tif, tagName.c_str()); + fip = TIFFFieldWithName(tif, tagName.c_str()); if (!fip) error("Tiff tag not found\n"); @@ -85,15 +188,67 @@ else { tag_ID = args(1).int_value(); - const TIFFField *fip = TIFFFieldWithTag(tif, tag_ID); - // TODO(maged): Handle other types of errors + fip = TIFFFieldWithTag(tif, tag_ID); + // TODO(maged): Handle other types of errors (e.g. unsupported tags) if (!fip) error("Tiff tag not found\n"); } - // TODO(maged): Handle different data types/ multivalued tags. - uint32_t tag_data; - TIFFGetField(tif, tag_ID, &tag_data); + TIFFDataType tag_datatype = TIFFFieldDataType(fip); - return octave_value_list (octave_value(tag_data)); + int count = TIFFFieldReadCount(fip); + octave_value tag_data_ov; + void *data; + if (count == TIFF_VARIABLE) + { + uint16_t count_param; + if (TIFFGetField(tif, tag_ID, &count_param, &data)) + { + tag_data_ov = interpret_data(data, count_param, tag_datatype); + } + else + { + // TODO(maged): Give a better error message? + error("Failed to read tag"); + } + } + else if (count == TIFF_VARIABLE2) + { + uint32_t count_param; + if (TIFFGetField(tif, tag_ID, &count_param, &data)) + { + tag_data_ov = interpret_data(data, count_param, tag_datatype); + } + else + { + // TODO(maged): Give a better error message? + error("Failed to read tag"); + } + } + else if (count == TIFF_SPP) + { + // TODO(maged): Handle TIFF_SPP + error("Unimplemented TIFF_SPP count"); + } + else + { + int type_size = TIFFDataWidth(tag_datatype); + data = _TIFFmalloc(type_size * count); + // TODO(maged): This won't always work, e.g. string exepcts char ** + if (TIFFGetField(tif, tag_ID, data)) + { + tag_data_ov = interpret_data(data, count, tag_datatype); + _TIFFfree(data); + } + else + { + _TIFFfree(data); + + // TODO(maged): Give a better error message? + error("Failed to read tag"); + } + + } + + return octave_value_list (octave_value(tag_data_ov)); } diff -r e2bed4daae82 -r ab5b33e447b0 scripts/io/Tiff.m --- a/scripts/io/Tiff.m Fri Jun 17 17:43:41 2022 +0200 +++ b/scripts/io/Tiff.m Wed Jun 22 23:32:22 2022 +0200 @@ -1,5 +1,6 @@ classdef Tiff properties (Constant = true) + % TODO(maged): Add the remaining fields TagID = struct( "ImageWidth", 256, "ImageLength", 257,