# HG changeset patch # User magedrifaat # Date 1657985354 -7200 # Node ID 9dead1249449e5ca420e42066a555040490ee9a1 # Parent a74059523d74c5fca97c97d36a775bc9a32c3529 Tiff getTag: fixed matrix shape for ColorMap and TransferFunction * __tiff__.cc (get_field_data): fixed return matrix for colormap and transferfunction to be consistent with matlab. diff -r a74059523d74 -r 9dead1249449 libinterp/dldfcn/__tiff__.cc --- a/libinterp/dldfcn/__tiff__.cc Sat Jul 16 01:26:40 2022 +0200 +++ b/libinterp/dldfcn/__tiff__.cc Sat Jul 16 17:29:14 2022 +0200 @@ -83,6 +83,10 @@ // TODO(maged): copy entire strip at once? for (uint16_t sample = 0; sample < image_data->samples_per_pixel; sample++) + // The memory organization of fvec is inverted from + // what would be expected for a normal C-like array. + // It is treated as samples * columns * rows as + // opposed to rows * columns * samples. img_fvec[sample * image_data->width * image_data->height + column * image_data->height + row_index + row_subindex] @@ -148,7 +152,7 @@ } // Convert tag value to double - octave_value_list + octave_value interpret_scalar_tag_data (void *data, TIFFDataType tag_datatype) { double retval; @@ -224,20 +228,20 @@ error ("Unsupported tag data type"); } - return octave_value_list (octave_value (retval)); + return octave_value (retval); } - // Convert memory buffer into suitable octave values + // Convert memory buffer into a suitable octave value // depending on tag_datatype - octave_value_list + octave_value interpret_tag_data (void *data, uint32_t count, TIFFDataType tag_datatype) { - octave_value_list ovl_data; + octave_value retval; // Apparently matlab converts scalar numerical values into double // but doesn't do the same for arrays if (count == 1 && tag_datatype != TIFF_ASCII) { - ovl_data = interpret_scalar_tag_data (data, tag_datatype); + retval = interpret_scalar_tag_data (data, tag_datatype); } else { @@ -253,12 +257,12 @@ { arr(i) = ((uint8_t *)data)[i]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_ASCII: { - ovl_data(0) = octave_value (*(char **)data); + retval = octave_value (*(char **)data); break; } case TIFF_SHORT: @@ -268,7 +272,7 @@ { arr(i) = ((uint16_t *)data)[i]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_LONG: @@ -278,7 +282,7 @@ { arr(i) = ((uint32_t *)data)[i]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_LONG8: @@ -288,7 +292,7 @@ { arr(i) = ((uint64_t *)data)[i]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_RATIONAL: @@ -299,7 +303,7 @@ arr(i / 2) = (float)((uint32_t *)data)[i] / (float)((uint32_t *)data)[i+1]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_SBYTE: @@ -309,7 +313,7 @@ { arr(i) = ((int8_t *)data)[i]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_SSHORT: @@ -319,7 +323,7 @@ { arr(i) = ((int16_t *)data)[i]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_SLONG: @@ -329,7 +333,7 @@ { arr(i) = ((int32_t *)data)[i]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_SLONG8: @@ -339,7 +343,7 @@ { arr(i) = ((int64_t *)data)[i]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_FLOAT: @@ -349,7 +353,7 @@ { arr(i) = ((float *)data)[i]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_DOUBLE: @@ -359,7 +363,7 @@ { arr(i) = ((double *)data)[i]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_SRATIONAL: @@ -370,7 +374,7 @@ arr(i / 2) = (float)((int32_t *)data)[i] / (float)((int32_t *)data)[i+1]; } - ovl_data(0) = arr; + retval = octave_value (arr); break; } case TIFF_IFD: @@ -383,13 +387,12 @@ } } - return ovl_data; + return retval; } - octave_value_list + octave_value 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 @@ -403,13 +406,14 @@ 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_tag_data (data, 1, TIFFFieldDataType (fip)); + octave_value tag_data_ov = interpret_tag_data (data, 1, + TIFFFieldDataType (fip)); _TIFFfree (data); - return tag_data_ovl; + return tag_data_ov; } - octave_value_list + octave_value get_array_field_data (TIFF *tif, const TIFFField *fip, uint32_t array_size) { void *data; @@ -421,7 +425,7 @@ octave_value_list get_field_data (TIFF *tif, const TIFFField *fip) { - octave_value_list tag_data_ovl; + octave_value_list tag_data_ovl (1); uint32_t tag_id = TIFFFieldTag (fip); // TODO(maged): find/create images to test the special tags @@ -453,6 +457,8 @@ } case TIFFTAG_COLORMAP: { + // TODO(maged): Fix output formatting to be consistent with matlab + // Matlab returns a float colormap? uint16_t bits_per_sample; if (! TIFFGetField (tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample)) error ("Failed to obtain the bit depth"); @@ -463,17 +469,31 @@ 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_tag_data (red, count, - TIFFFieldDataType (fip))); - tag_data_ovl(1) - = octave_value (interpret_tag_data (green, count, - TIFFFieldDataType (fip))); - tag_data_ovl(2) - = octave_value (interpret_tag_data (blue, count, - TIFFFieldDataType (fip))); + &red, &green, &blue)); + uint16NDArray mat_out (dim_vector (count, 3)); + + uint16NDArray red_array + = interpret_tag_data (red, + count, + TIFFFieldDataType (fip)).uint16_array_value (); + uint16NDArray green_array + = interpret_tag_data (green, + count, + TIFFFieldDataType (fip)).uint16_array_value (); + uint16NDArray blue_array + = interpret_tag_data (blue, + count, + TIFFFieldDataType (fip)).uint16_array_value (); + + octave_uint16 *out_ptr = mat_out.fortran_vec (); + memcpy (out_ptr, red_array.fortran_vec (), sizeof(uint16_t) * count); + out_ptr += count; + memcpy (out_ptr, green_array.fortran_vec (), sizeof(uint16_t) * count); + out_ptr += count; + memcpy (out_ptr, blue_array.fortran_vec (), sizeof(uint16_t) * count); + + tag_data_ovl(0) = octave_value (mat_out); break; } case TIFFTAG_TRANSFERFUNCTION: @@ -492,22 +512,36 @@ { validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP, &ch1)); tag_data_ovl(0) - = octave_value (interpret_tag_data (ch1, count, - TIFFFieldDataType (fip))); + = interpret_tag_data (ch1, count, TIFFFieldDataType (fip)); } else { validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP, - &ch1, &ch2, &ch3)); - tag_data_ovl(0) - = octave_value (interpret_tag_data (ch1, count, - TIFFFieldDataType (fip))); - tag_data_ovl(1) - = octave_value (interpret_tag_data (ch2, count, - TIFFFieldDataType (fip))); - tag_data_ovl(2) - = octave_value (interpret_tag_data (ch3, count, - TIFFFieldDataType (fip))); + &ch1, &ch2, &ch3)); + + uint16NDArray mat_out (dim_vector (count, 3)); + + uint16NDArray ch1_array + = interpret_tag_data (ch1, + count, + TIFFFieldDataType (fip)).uint16_array_value (); + uint16NDArray ch2_array + = interpret_tag_data (ch2, + count, + TIFFFieldDataType (fip)).uint16_array_value (); + uint16NDArray ch3_array + = interpret_tag_data (ch3, + count, + TIFFFieldDataType (fip)).uint16_array_value (); + + octave_uint16 *out_ptr = mat_out.fortran_vec (); + memcpy (out_ptr, ch1_array.fortran_vec (), sizeof(uint16_t) * count); + out_ptr += count; + memcpy (out_ptr, ch2_array.fortran_vec (), sizeof(uint16_t) * count); + out_ptr += count; + memcpy (out_ptr, ch3_array.fortran_vec (), sizeof(uint16_t) * count); + + tag_data_ovl(0) = octave_value (mat_out); } break; } @@ -518,13 +552,11 @@ { uint16_t tag_part1, tag_part2; validate_tiff_get_field (TIFFGetField (tif, tag_id, - &tag_part1, &tag_part2)); + &tag_part1, &tag_part2)); tag_data_ovl(0) - = octave_value (interpret_tag_data (&tag_part1, 1, - TIFFFieldDataType (fip))); + = interpret_tag_data (&tag_part1, 1, TIFFFieldDataType (fip)); tag_data_ovl(1) - = octave_value (interpret_tag_data (&tag_part2, 1, - TIFFFieldDataType (fip))); + = interpret_tag_data (&tag_part2, 1, TIFFFieldDataType (fip)); break; } case TIFFTAG_SUBIFD: @@ -532,7 +564,8 @@ uint16_t count; uint64_t *offsets; validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &offsets)); - tag_data_ovl = interpret_tag_data (offsets, count, TIFFFieldDataType (fip)); + tag_data_ovl(0) = interpret_tag_data (offsets, count, + TIFFFieldDataType (fip)); break; } case TIFFTAG_EXTRASAMPLES: @@ -540,7 +573,8 @@ uint16_t count; uint16_t *types; validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &types)); - tag_data_ovl = interpret_tag_data (types, count, TIFFFieldDataType (fip)); + tag_data_ovl(0) = interpret_tag_data (types, count, + TIFFFieldDataType (fip)); break; } // TODO(maged): These tags are more complex to implement