Mercurial > octave-libtiff
changeset 31097:75ab26f147a5
getTag: Implemented single array tags, only multi-array and special tags are unimplemented
author | magedrifaat <magedrifaat@gmail.com> |
---|---|
date | Sun, 26 Jun 2022 02:58:49 +0200 |
parents | c581ec211b45 |
children | 3cbd0d82167c |
files | libinterp/dldfcn/__tiff__.cc |
diffstat | 1 files changed, 205 insertions(+), 113 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/dldfcn/__tiff__.cc Fri Jun 24 17:45:00 2022 +0200 +++ b/libinterp/dldfcn/__tiff__.cc Sun Jun 26 02:58:49 2022 +0200 @@ -10,101 +10,220 @@ // TODO(maged): Tidy up the formatting to be consistant with octave -octave_value interpret_data(void *data, uint32_t count, TIFFDataType tag_datatype) +octave_value_list 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) + // TODO(maged): Find the correct way fo returning multivalues (Matrix for numericals?) + octave_value_list ovl_data; + // TODO(maged): check if this should be row matrix or column matrix + dim_vector arr_dims(1, count); + if (tag_datatype == TIFF_BYTE || tag_datatype == TIFF_UNDEFINED) + { + uint8NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((uint8_t *)data)[i]; + } + ovl_data(0) = arr; + } + else if(tag_datatype == TIFF_ASCII) + { + ovl_data(0) = *(char **)data; + } + else if (tag_datatype == TIFF_SHORT) + { + uint16NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((uint16_t *)data)[i]; + } + ovl_data(0) = arr; + } + else if (tag_datatype == TIFF_LONG) + { + uint32NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((uint32_t *)data)[i]; + } + ovl_data(0) = arr; + } + else if (tag_datatype == TIFF_LONG8) + { + uint64NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((uint64_t *)data)[i]; + } + ovl_data(0) = arr; + } + else if (tag_datatype == TIFF_RATIONAL) + { + NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i+=2) + { + arr(i / 2) = (float)((uint32_t *)data)[i] / (float)((uint32_t *)data)[i+1]; + } + ovl_data(0) = arr; + } + else if (tag_datatype == TIFF_SBYTE) { - 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; - - // TODO(maged): why is the data type 64-bit for non-bigtiff images? - case TIFF_LONG: - case TIFF_LONG8: - for (uint32_t i = 0; i < count; i++) - { - ov_data(i) = octave_value(((uint32_t *)data)[i]); - } - break; - - case TIFF_RATIONAL: - for (uint32_t i = 0; i < count; i+=2) - { - ov_data(i / 2) = octave_value((float)((uint32_t *)data)[i] / (float)((uint32_t *)data)[i+1]); - } - break; + int8NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((int8_t *)data)[i]; + } + ovl_data(0) = arr; + } + else if (tag_datatype == TIFF_SSHORT) + { + int16NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((int16_t *)data)[i]; + } + ovl_data(0) = arr; + } + else if (tag_datatype == TIFF_SLONG) + { + int32NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((int32_t *)data)[i]; + } + ovl_data(0) = arr; + } + else if (tag_datatype == TIFF_SLONG8) + { + int64NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((int64_t *)data)[i]; + } + ovl_data(0) = arr; + } + else if (tag_datatype == TIFF_FLOAT) + { + NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((float *)data)[i]; + } + ovl_data(0) = arr; + } + else if (tag_datatype == TIFF_DOUBLE) + { + NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((double *)data)[i]; + } + ovl_data(0) = arr; + } + else if (tag_datatype == TIFF_SRATIONAL) + { + NDArray arr(arr_dims); + for (uint32_t i = 0; i < count; i+=2) + { + arr(i / 2) = (float)((int32_t *)data)[i] / (float)((int32_t *)data)[i+1]; + } + ovl_data(0) = arr; + } + else if (tag_datatype == TIFF_IFD || tag_datatype == TIFF_IFD8) + { + // TODO(maged): implement IFD datatype + error("Unimplemented IFFD data type"); + } + else + { + // TODO(maged): find the correct response in this case + error("Unsupported tag data type"); + } - case TIFF_SBYTE: - for (uint32_t i = 0; i < count; i++) - { - ov_data(i) = octave_value(((int8_t *)data)[i]); - } - break; + return ovl_data; +} + +octave_value_list get_scalar_field_data(TIFF *tif, const TIFFField *fip) +{ + octave_value_list tag_data_ovl; + uint32_t tag_ID = TIFFFieldTag(fip); + + // TIFFFieldReadCount returns VARIABLE for some scalar tags (e.g. Compression) + // But TIFFFieldPassCount seems consistent + if (!TIFFFieldPassCount(fip)) + { + // TODO(maged): test this function vs actual data type size + int type_size = TIFFDataWidth(TIFFFieldDataType(fip)); + void *data = _TIFFmalloc(type_size); + if (TIFFGetField(tif, tag_ID, data)) + { + tag_data_ovl = interpret_data(data, 1, TIFFFieldDataType(fip)); + _TIFFfree(data); + } + else + { + _TIFFfree(data); + + // TODO(maged): Give a better error message? + error("Failed to read tag"); + } - case TIFF_SSHORT: - for (uint32_t i = 0; i < count; i++) - { - ov_data(i) = octave_value(((int16_t *)data)[i]); - } - break; + } + else + { + // TODO(maged): Implement support for variable read argument tags + error("Variable argument tags not implemented"); + } - case TIFF_SLONG: - case TIFF_SLONG8: - for (uint32_t i = 0; i < count; i++) - { - ov_data(i) = octave_value(((int32_t *)data)[i]); - } - break; + return tag_data_ovl; +} - case TIFF_FLOAT: - for (uint32_t i = 0; i < count; i++) - { - ov_data(i) = octave_value(((float *)data)[i]); - } - break; - - case TIFF_DOUBLE: - for (uint32_t i = 0; i < count; i++) - { - ov_data(i) = octave_value(((double *)data)[i]); - } +octave_value_list get_array_field_data(TIFF *tif, const TIFFField *fip, uint32_t array_size) +{ + octave_value_list tag_data_ovl; + + uint32_t tag_ID = TIFFFieldTag(fip); + TIFFDataType tag_datatype = TIFFFieldDataType(fip); + int type_size = TIFFDataWidth(tag_datatype); + void *data; + if (TIFFGetField(tif, tag_ID, &data)) + { + tag_data_ovl = interpret_data(data, array_size, tag_datatype); + } + else + { + // TODO(maged): Give a better error message? + error("Failed to read tag"); + } + + return tag_data_ovl; +} + +octave_value_list get_field_data(TIFF *tif, const TIFFField *fip) +{ + octave_value_list tag_data_ovl; + uint32_t tag_ID = TIFFFieldTag(fip); + + switch(tag_ID) + { + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_STRIPOFFSETS: + tag_data_ovl = get_array_field_data(tif, fip, TIFFNumberOfStrips(tif)); break; - - case TIFF_SRATIONAL: - for (uint32_t i = 0; i < count; i+=2) - { - ov_data(i / 2) = octave_value((float)((int32_t *)data)[i] / (float)((int32_t *)data)[i+1]); - } + case TIFFTAG_TILEBYTECOUNTS: + case TIFFTAG_TILEOFFSETS: + tag_data_ovl = get_array_field_data(tif, fip, TIFFNumberOfTiles(tif)); break; - - case TIFF_IFD: - case TIFF_IFD8: - // TODO(maged): implement IFD datatype - error("Unimplemented IFFD data type"); + case TIFFTAG_YCBCRCOEFFICIENTS: + tag_data_ovl = get_array_field_data(tif, fip, 3); + break; + case TIFFTAG_REFERENCEBLACKWHITE: + tag_data_ovl = get_array_field_data(tif, fip, 6); break; default: - // TODO(maged): find the correct response in this case - error("Unsupported tag data type"); + tag_data_ovl = get_scalar_field_data(tif, fip); } - - return octave_value(ov_data); + + return tag_data_ovl; } DEFUN_DLD (__open_tiff__, args, nargout, @@ -192,34 +311,7 @@ } - octave_value tag_data_ov; - // TIFFFieldReadCount returns VARIABLE for some scalar tags (e.g. Compression) - // But TIFFFieldPassCount seems consistent - if (!TIFFFieldPassCount(fip)) - { - // TODO(maged): test this function vs actual data type size - int type_size = TIFFDataWidth(TIFFFieldDataType(fip)); - void *data = _TIFFmalloc(type_size); - // TODO(maged): This won't always work, e.g. string exepcts char ** - if (TIFFGetField(tif, tag_ID, data)) - { - tag_data_ov = interpret_data(data, 1, TIFFFieldDataType(fip)); - _TIFFfree(data); - } - else - { - _TIFFfree(data); + octave_value_list tag_data_ovl = get_field_data(tif, fip); - // TODO(maged): Give a better error message? - error("Failed to read tag"); - } - - } - else - { - // TODO(maged): Implement support for variable read argument tags - error("Variable argument tags not implemented"); - } - - return octave_value_list (octave_value(tag_data_ov)); + return tag_data_ovl; }