# HG changeset patch # User magedrifaat # Date 1656877897 -7200 # Node ID d6ecf0e8838ba0db4d5b9cf6311b0717034493a1 # Parent f24d7bcad2d3d06004c475a86557f1c6f3216909 Add the new code to the octave namespace * __tiff__.cc: Add the functions to the octave namespace. diff -r f24d7bcad2d3 -r d6ecf0e8838b libinterp/dldfcn/__tiff__.cc --- a/libinterp/dldfcn/__tiff__.cc Wed Jun 29 02:27:54 2022 +0200 +++ b/libinterp/dldfcn/__tiff__.cc Sun Jul 03 21:51:37 2022 +0200 @@ -10,416 +10,419 @@ // TODO(maged): Tidy up the formatting to be consistant with octave -// Error if status is not 1 (success status for TIFFGetField) -void -validate_tiff_get_field (bool status, void *p_to_free=NULL) +namespace octve { - if (status != 1) - { - if (p_to_free != NULL) - _TIFFfree (p_to_free); - error ("Failed to read tag"); - } -} - -// Convert memory buffer into suitable octave values -// depending on 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 ovl_data; - dim_vector arr_dims (1, count); + // Error if status is not 1 (success status for TIFFGetField) + void + validate_tiff_get_field (bool status, void *p_to_free=NULL) + { + if (status != 1) + { + if (p_to_free != NULL) + _TIFFfree (p_to_free); + error ("Failed to read tag"); + } + } - switch (tag_datatype) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - { - uint8NDArray arr (arr_dims); - for (uint32_t i = 0; i < count; i++) - { - arr(i) = ((uint8_t *)data)[i]; - } - ovl_data(0) = arr; - break; - } - case TIFF_ASCII: - { - ovl_data(0) = *(char **)data; - break; - } - case TIFF_SHORT: - { - uint16NDArray arr (arr_dims); - for (uint32_t i = 0; i < count; i++) - { - arr(i) = ((uint16_t *)data)[i]; - } - ovl_data(0) = arr; - break; - } - case TIFF_LONG: - { - uint32NDArray arr (arr_dims); - for (uint32_t i = 0; i < count; i++) - { - arr(i) = ((uint32_t *)data)[i]; - } - ovl_data(0) = arr; - break; - } - case TIFF_LONG8: - { - uint64NDArray arr (arr_dims); - for (uint32_t i = 0; i < count; i++) - { - arr(i) = ((uint64_t *)data)[i]; - } - ovl_data(0) = arr; - break; - } - case 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; - break; - } - case TIFF_SBYTE: + // Convert memory buffer into suitable octave values + // depending on 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 ovl_data; + dim_vector arr_dims (1, count); + + switch (tag_datatype) { - int8NDArray arr (arr_dims); - for (uint32_t i = 0; i < count; i++) - { - arr(i) = ((int8_t *)data)[i]; - } - ovl_data(0) = arr; - break; - } - case TIFF_SSHORT: - { - int16NDArray arr (arr_dims); - for (uint32_t i = 0; i < count; i++) - { - arr(i) = ((int16_t *)data)[i]; - } - ovl_data(0) = arr; - break; - } - case TIFF_SLONG: - { - int32NDArray arr (arr_dims); - for (uint32_t i = 0; i < count; i++) - { - arr(i) = ((int32_t *)data)[i]; - } - ovl_data(0) = arr; - break; - } - case TIFF_SLONG8: - { - int64NDArray arr (arr_dims); - for (uint32_t i = 0; i < count; i++) - { - arr(i) = ((int64_t *)data)[i]; - } - ovl_data(0) = arr; - break; - } - case TIFF_FLOAT: - { - NDArray arr (arr_dims); - for (uint32_t i = 0; i < count; i++) + case TIFF_BYTE: + case TIFF_UNDEFINED: + { + uint8NDArray arr (arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((uint8_t *)data)[i]; + } + ovl_data(0) = arr; + break; + } + case TIFF_ASCII: + { + ovl_data(0) = *(char **)data; + break; + } + case TIFF_SHORT: + { + uint16NDArray arr (arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((uint16_t *)data)[i]; + } + ovl_data(0) = arr; + break; + } + case TIFF_LONG: + { + uint32NDArray arr (arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((uint32_t *)data)[i]; + } + ovl_data(0) = arr; + break; + } + case TIFF_LONG8: + { + uint64NDArray arr (arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((uint64_t *)data)[i]; + } + ovl_data(0) = arr; + break; + } + case 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; + break; + } + case TIFF_SBYTE: + { + int8NDArray arr (arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((int8_t *)data)[i]; + } + ovl_data(0) = arr; + break; + } + case TIFF_SSHORT: + { + int16NDArray arr (arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((int16_t *)data)[i]; + } + ovl_data(0) = arr; + break; + } + case TIFF_SLONG: + { + int32NDArray arr (arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((int32_t *)data)[i]; + } + ovl_data(0) = arr; + break; + } + case TIFF_SLONG8: + { + int64NDArray arr (arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((int64_t *)data)[i]; + } + ovl_data(0) = arr; + break; + } + case TIFF_FLOAT: + { + NDArray arr (arr_dims); + for (uint32_t i = 0; i < count; i++) + { + arr(i) = ((float *)data)[i]; + } + ovl_data(0) = arr; + break; + } + case TIFF_DOUBLE: + { + NDArray arr (arr_dims); + for (uint32_t i = 0; i < count; i++) { - arr(i) = ((float *)data)[i]; + arr(i) = ((double *)data)[i]; } - ovl_data(0) = arr; + ovl_data(0) = arr; + break; + } + case 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; + break; + } + case TIFF_IFD: + case TIFF_IFD8: + // TODO(maged): implement IFD datatype? + error ("Unimplemented IFFD data type"); break; - } - case TIFF_DOUBLE: - { - NDArray arr (arr_dims); - for (uint32_t i = 0; i < count; i++) - { - arr(i) = ((double *)data)[i]; - } - ovl_data(0) = arr; - break; + default: + error ("Unsupported tag data type"); } - case 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; - break; - } - case TIFF_IFD: - case TIFF_IFD8: - // TODO(maged): implement IFD datatype? - error ("Unimplemented IFFD data type"); - break; - default: - error ("Unsupported tag data type"); - } + + return ovl_data; + } - 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); + 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 - // Since scalar tags are the last to be handled, any tag that - // require a count to be passed is an unsupported tag. - if (TIFFFieldPassCount (fip)) - error ("Unsupported tag"); - - // TODO(maged): test this function vs actual data type size - int type_size = TIFFDataWidth (TIFFFieldDataType (fip)); - void *data = _TIFFmalloc (type_size); - validate_tiff_get_field (TIFFGetField (tif, tag_id, data), data); - tag_data_ovl = interpret_data (data, 1, TIFFFieldDataType (fip)); - _TIFFfree (data); + // TIFFFieldReadCount returns VARIABLE for some scalar tags + // (e.g. Compression) But TIFFFieldPassCount seems consistent + // Since scalar tags are the last to be handled, any tag that + // require a count to be passed is an unsupported tag. + if (TIFFFieldPassCount (fip)) + error ("Unsupported tag"); + + // TODO(maged): test this function vs actual data type size + int type_size = TIFFDataWidth (TIFFFieldDataType (fip)); + void *data = _TIFFmalloc (type_size); + validate_tiff_get_field (TIFFGetField (tif, tag_id, data), data); + tag_data_ovl = interpret_data (data, 1, TIFFFieldDataType (fip)); + _TIFFfree (data); - return tag_data_ovl; -} + return tag_data_ovl; + } -octave_value_list -get_array_field_data (TIFF *tif, const TIFFField *fip, uint32_t array_size) -{ - void *data; - validate_tiff_get_field (TIFFGetField (tif, TIFFFieldTag (fip), &data)); - - return interpret_data (data, array_size, TIFFFieldDataType (fip)); -} + octave_value_list + get_array_field_data (TIFF *tif, const TIFFField *fip, uint32_t array_size) + { + void *data; + validate_tiff_get_field (TIFFGetField (tif, TIFFFieldTag (fip), &data)); + + return interpret_data (data, array_size, TIFFFieldDataType (fip)); + } -octave_value_list -get_field_data (TIFF *tif, const TIFFField *fip) -{ - octave_value_list tag_data_ovl; - uint32_t tag_id = TIFFFieldTag (fip); + octave_value_list + get_field_data (TIFF *tif, const TIFFField *fip) + { + 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: - case TIFFTAG_STRIPOFFSETS: - tag_data_ovl = get_array_field_data (tif, fip, - TIFFNumberOfStrips (tif)); - break; - case TIFFTAG_TILEBYTECOUNTS: - case TIFFTAG_TILEOFFSETS: - tag_data_ovl = get_array_field_data (tif, fip, TIFFNumberOfTiles (tif)); - break; - 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; - case TIFFTAG_COLORMAP: + // TODO(maged): find/create images to test the special tags + switch (tag_id) { - 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) - error ("Too high bit depth for a palette image"); + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_STRIPOFFSETS: + tag_data_ovl = get_array_field_data (tif, fip, + TIFFNumberOfStrips (tif)); + break; + case TIFFTAG_TILEBYTECOUNTS: + case TIFFTAG_TILEOFFSETS: + tag_data_ovl = get_array_field_data (tif, fip, TIFFNumberOfTiles (tif)); + break; + 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; + 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) + error ("Too high bit depth for a palette image"); - uint32_t count = 1 << bits_per_sample; - uint16_t *red, *green, *blue; - validate_tiff_get_field (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))); - - 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"); + uint32_t count = 1 << bits_per_sample; + uint16_t *red, *green, *blue; + validate_tiff_get_field (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))); + + 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"); + 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) - { - validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP, &ch1)); - tag_data_ovl(0) - = octave_value (interpret_data (ch1, count, - TIFFFieldDataType (fip))); - } - else - { - validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP, - &ch1, &ch2, &ch3)); - 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; - validate_tiff_get_field (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))); - break; - } - case TIFFTAG_SUBIFD: - { - uint16_t count; - uint64_t *offsets; - validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &offsets)); - tag_data_ovl = interpret_data (offsets, count, TIFFFieldDataType (fip)); - break; - } - case TIFFTAG_EXTRASAMPLES: + uint32_t count = 1 << bits_per_sample; + uint16_t *ch1, *ch2, *ch3; + if (samples_per_pixel == 1) + { + validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP, &ch1)); + tag_data_ovl(0) + = octave_value (interpret_data (ch1, count, + TIFFFieldDataType (fip))); + } + else + { + validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP, + &ch1, &ch2, &ch3)); + 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; + validate_tiff_get_field (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))); + break; + } + case TIFFTAG_SUBIFD: + { + uint16_t count; + uint64_t *offsets; + validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &offsets)); + tag_data_ovl = interpret_data (offsets, count, TIFFFieldDataType (fip)); + break; + } + case TIFFTAG_EXTRASAMPLES: + { + uint16_t count; + uint16_t *types; + validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &types)); + tag_data_ovl = interpret_data (types, count, TIFFFieldDataType (fip)); + 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; + validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &data)); + tag_data_ovl = interpret_data (data, count, TIFF_BYTE); + break; + } + default: + tag_data_ovl = get_scalar_field_data (tif, fip); + } + + return tag_data_ovl; + } + + DEFUN_DLD (__open_tiff__, args, nargout, + "Open a Tiff file and return its handle") + { + int nargin = args.length (); + + if (nargin == 0 || nargin > 2) { - uint16_t count; - uint16_t *types; - validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &types)); - tag_data_ovl = interpret_data (types, count, TIFFFieldDataType (fip)); - break; + // TODO(maged): return invalid object instead?? + error ("No filename supplied\n"); } - // 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; - validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &data)); - tag_data_ovl = interpret_data (data, count, TIFF_BYTE); - break; - } - default: - tag_data_ovl = get_scalar_field_data (tif, fip); - } - - return tag_data_ovl; -} + + std::string filename = args (0).string_value (); + std::string mode = "r"; -DEFUN_DLD (__open_tiff__, args, nargout, - "Open a Tiff file and return its handle") -{ - int nargin = args.length (); - - if (nargin == 0 || nargin > 2) - { - // TODO(maged): return invalid object instead?? - error ("No filename supplied\n"); - } - - std::string filename = args (0).string_value (); - std::string mode = "r"; + // TODO(maged): check valid mode + if (nargin == 2) + mode = args (1).string_value (); + + // TODO(maged): Look into unwind action + TIFF *tif = TIFFOpen (filename.c_str (), mode.c_str ()); + + if (! tif) + error ("Failed to open Tiff file\n"); - // TODO(maged): check valid mode - if (nargin == 2) - mode = args (1).string_value (); - - // TODO(maged): Look into unwind action - TIFF *tif = TIFFOpen (filename.c_str (), mode.c_str ()); - - if (! tif) - error ("Failed to open Tiff file\n"); - - // TODO(maged): use inheritance of octave_base_value instead - octave_value tiff_ov = octave_value ((uint64_t)tif); - return octave_value_list (tiff_ov); -} + // TODO(maged): use inheritance of octave_base_value instead + octave_value tiff_ov = octave_value ((uint64_t)tif); + return octave_value_list (tiff_ov); + } -DEFUN_DLD (__close_tiff__, args, nargout, - "Close a tiff file") -{ - int nargin = args.length (); - - if (nargin == 0) - error ("No handle provided\n"); - - TIFF *tif = (TIFF *)(args (0).uint64_value ()); - TIFFClose (tif); - - return octave_value_list (); -} - - -DEFUN_DLD (__tiff_get_tag__, args, nargout, - "Get the value of a tag from a tiff image") -{ + DEFUN_DLD (__close_tiff__, args, nargout, + "Close a tiff file") + { int nargin = args.length (); if (nargin == 0) error ("No handle provided\n"); - if (nargin < 2) - error ("No tag name provided\n"); - TIFF *tif = (TIFF *)(args (0).uint64_value ()); + TIFFClose (tif); - uint32_t tag_id; - const TIFFField *fip; - if (args (1).type_name () == "string") - { - std::string tagName = args (1).string_value (); - fip = TIFFFieldWithName (tif, tagName.c_str ()); - if (! fip) - error ("Tiff tag not found"); - - tag_id = TIFFFieldTag (fip); - } - else - { - tag_id = args (1).int_value (); - fip = TIFFFieldWithTag (tif, tag_id); - // TODO(maged): Handle other types of errors (e.g. unsupported tags) - if (! fip) - error ("Tiff tag not found"); - } + return octave_value_list (); + } - octave_value_list tag_data_ovl = get_field_data (tif, fip); + DEFUN_DLD (__tiff_get_tag__, args, nargout, + "Get the value of a tag from a tiff image") + { + int nargin = args.length (); + + if (nargin == 0) + error ("No handle provided\n"); + + if (nargin < 2) + error ("No tag name provided\n"); + + TIFF *tif = (TIFF *)(args (0).uint64_value ()); - return tag_data_ovl; + uint32_t tag_id; + const TIFFField *fip; + if (args (1).type_name () == "string") + { + std::string tagName = args (1).string_value (); + fip = TIFFFieldWithName (tif, tagName.c_str ()); + if (! fip) + error ("Tiff tag not found"); + + tag_id = TIFFFieldTag (fip); + } + else + { + tag_id = args (1).int_value (); + fip = TIFFFieldWithTag (tif, tag_id); + // TODO(maged): Handle other types of errors (e.g. unsupported tags) + if (! fip) + error ("Tiff tag not found"); + } + + + octave_value_list tag_data_ovl = get_field_data (tif, fip); + + return tag_data_ovl; + } }