comparison libinterp/corefcn/__tiff__.cc @ 31180:ae78937e24d2

__tiff__.cc: refactored repititive code into functions.
author magedrifaat <magedrifaat@gmail.com>
date Thu, 18 Aug 2022 00:11:23 +0200
parents f294b800f002
children 8a4ef572077d
comparison
equal deleted inserted replaced
31179:f294b800f002 31180:ae78937e24d2
161 } 161 }
162 else 162 else
163 error ("Planar Configuration not supported"); 163 error ("Planar Configuration not supported");
164 164
165 return rows_in_strip; 165 return rows_in_strip;
166 }
167
168 void
169 get_tile_dimensions_validated (TIFF *tif, uint32_t& tile_width,
170 uint32_t& tile_height)
171 {
172 if (! TIFFGetField (tif, TIFFTAG_TILELENGTH, &tile_height))
173 error ("Filed to read tile length");
174
175 if (! TIFFGetField (tif, TIFFTAG_TILEWIDTH, &tile_width))
176 error ("Filed to read tile length");
177
178 if (tile_height == 0 || tile_height % 16 != 0
179 || tile_width == 0 || tile_width % 16 != 0)
180 error ("Tile dimesion tags are invalid");
166 } 181 }
167 182
168 template <typename T> 183 template <typename T>
169 octave_value 184 octave_value
170 read_strip (TIFF *tif, uint32_t strip_no, tiff_image_data * image_data) 185 read_strip (TIFF *tif, uint32_t strip_no, tiff_image_data * image_data)
263 read_tile (TIFF *tif, uint32_t tile_no, tiff_image_data *image_data) 278 read_tile (TIFF *tif, uint32_t tile_no, tiff_image_data *image_data)
264 { 279 {
265 // ASSUMES tiled image and tile_no is a valid zero-based tile 280 // ASSUMES tiled image and tile_no is a valid zero-based tile
266 // index for the tif image 281 // index for the tif image
267 282
268 // TODO(maged): refactor into a function?
269 uint32_t tile_width, tile_height; 283 uint32_t tile_width, tile_height;
270 if (! TIFFGetField (tif, TIFFTAG_TILELENGTH, &tile_height)) 284 get_tile_dimensions_validated (tif, tile_width, tile_height);
271 error ("Filed to read tile length");
272
273 if (! TIFFGetField (tif, TIFFTAG_TILEWIDTH, &tile_width))
274 error ("Filed to read tile length");
275
276 if (tile_height == 0 || tile_height % 16 != 0
277 || tile_width == 0 || tile_width % 16 != 0)
278 error ("Tile dimesion tags are invalid");
279 285
280 dim_vector tile_dims; 286 dim_vector tile_dims;
281 if (image_data->planar_configuration == PLANARCONFIG_CONTIG) 287 if (image_data->planar_configuration == PLANARCONFIG_CONTIG)
282 { 288 {
283 tile_dims = dim_vector (image_data->samples_per_pixel, tile_width, 289 tile_dims = dim_vector (image_data->samples_per_pixel, tile_width,
922 } 928 }
923 929
924 return octave_value (retval); 930 return octave_value (retval);
925 } 931 }
926 932
933 template <typename T>
934 octave_value
935 make_array (void *data, dim_vector& arr_dims)
936 {
937 typedef typename T::element_type P;
938
939 T arr (arr_dims);
940 for (uint32_t i = 0; i < count; i++)
941 {
942 arr(i) = (reinterpret_cast<P *> (data))[i];
943 }
944 retval = octave_value (arr);
945 }
946
927 octave_value 947 octave_value
928 interpret_tag_data (void *data, uint32_t count, TIFFDataType tag_datatype) 948 interpret_tag_data (void *data, uint32_t count, TIFFDataType tag_datatype)
929 { 949 {
930 octave_value retval; 950 octave_value retval;
931 // Apparently matlab converts scalar numerical values into double 951 // Apparently matlab converts scalar numerical values into double
932 // but doesn't do the same for arrays 952 // but doesn't do the same for arrays
933 // TODO(maged): matlab returns double for array tags as well, except 953 // TODO(maged): matlab returns double for array tags as well, except
934 // for a selected set of tags (e.g. StripByteCounts) 954 // for a selected set of tags (e.g. StripByteCounts)
935 // TODO(maged): refactor for loops 955
936 if (count == 1 && tag_datatype != TIFF_ASCII) 956 if (count == 1 && tag_datatype != TIFF_ASCII)
937 { 957 {
938 retval = interpret_scalar_tag_data (data, tag_datatype); 958 retval = interpret_scalar_tag_data (data, tag_datatype);
939 } 959 }
940 else 960 else
944 switch (tag_datatype) 964 switch (tag_datatype)
945 { 965 {
946 case TIFF_BYTE: 966 case TIFF_BYTE:
947 case TIFF_UNDEFINED: 967 case TIFF_UNDEFINED:
948 { 968 {
949 uint8NDArray arr (arr_dims); 969 retval = make_array<uint8NDArray> (data, arr_dims);
950 for (uint32_t i = 0; i < count; i++)
951 {
952 arr(i) = (reinterpret_cast<uint8_t *> (data))[i];
953 }
954 retval = octave_value (arr);
955 break; 970 break;
956 } 971 }
957 case TIFF_ASCII: 972 case TIFF_ASCII:
958 { 973 {
959 retval = octave_value (*(reinterpret_cast<char **> (data))); 974 retval = octave_value (*(reinterpret_cast<char **> (data)));
960 break; 975 break;
961 } 976 }
962 case TIFF_SHORT: 977 case TIFF_SHORT:
963 { 978 {
964 uint16NDArray arr (arr_dims); 979 retval = make_array<uint16NDArray> (data, arr_dims);
965 for (uint32_t i = 0; i < count; i++)
966 {
967 arr(i) = (reinterpret_cast<uint16_t *> (data))[i];
968 }
969 retval = octave_value (arr);
970 break; 980 break;
971 } 981 }
972 case TIFF_LONG: 982 case TIFF_LONG:
983 case TIFF_IFD:
973 { 984 {
974 uint32NDArray arr (arr_dims); 985 retval = make_array<uint32NDArray> (data, arr_dims);
975 for (uint32_t i = 0; i < count; i++)
976 {
977 arr(i) = (reinterpret_cast<uint32_t *> (data))[i];
978 }
979 retval = octave_value (arr);
980 break; 986 break;
981 } 987 }
982 case TIFF_LONG8: 988 case TIFF_LONG8:
989 case TIFF_IFD8:
983 { 990 {
984 uint64NDArray arr (arr_dims); 991 retval = make_array<uint64NDArray> (data, arr_dims);
985 for (uint32_t i = 0; i < count; i++)
986 {
987 arr(i) = (reinterpret_cast<uint64_t *> (data))[i];
988 }
989 retval = octave_value (arr);
990 break; 992 break;
991 } 993 }
992 case TIFF_RATIONAL: 994 case TIFF_RATIONAL:
995 case TIFF_SRATIONAL:
996 case TIFF_FLOAT:
993 { 997 {
994 NDArray arr (arr_dims); 998 retval = make_array<FloatNDArray> (data, arr_dims).as_double ();
995 for (uint32_t i = 0; i < count; i++)
996 {
997 arr(i) = (reinterpret_cast<float *> (data))[i];
998 }
999 retval = octave_value (arr);
1000 break; 999 break;
1001 } 1000 }
1002 case TIFF_SBYTE: 1001 case TIFF_SBYTE:
1003 { 1002 {
1004 int8NDArray arr (arr_dims); 1003 retval = make_array<int8NDArray> (data, arr_dims);
1005 for (uint32_t i = 0; i < count; i++)
1006 {
1007 arr(i) = (reinterpret_cast<int8_t *> (data))[i];
1008 }
1009 retval = octave_value (arr);
1010 break; 1004 break;
1011 } 1005 }
1012 case TIFF_SSHORT: 1006 case TIFF_SSHORT:
1013 { 1007 {
1014 int16NDArray arr (arr_dims); 1008 retval = make_array<int16NDArray> (data, arr_dims);
1015 for (uint32_t i = 0; i < count; i++)
1016 {
1017 arr(i) = (reinterpret_cast<int16_t *> (data))[i];
1018 }
1019 retval = octave_value (arr);
1020 break; 1009 break;
1021 } 1010 }
1022 case TIFF_SLONG: 1011 case TIFF_SLONG:
1023 { 1012 {
1024 int32NDArray arr (arr_dims); 1013 retval = make_array<int32NDArray> (data, arr_dims);
1025 for (uint32_t i = 0; i < count; i++)
1026 {
1027 arr(i) = (reinterpret_cast<int32_t *> (data))[i];
1028 }
1029 retval = octave_value (arr);
1030 break; 1014 break;
1031 } 1015 }
1032 case TIFF_SLONG8: 1016 case TIFF_SLONG8:
1033 { 1017 {
1034 int64NDArray arr (arr_dims); 1018 retval = make_array<int64NDArray> (data, arr_dims);
1035 for (uint32_t i = 0; i < count; i++)
1036 {
1037 arr(i) = (reinterpret_cast<int64_t *> (data))[i];
1038 }
1039 retval = octave_value (arr);
1040 break;
1041 }
1042 case TIFF_FLOAT:
1043 {
1044 NDArray arr (arr_dims);
1045 for (uint32_t i = 0; i < count; i++)
1046 {
1047 arr(i) = (reinterpret_cast<float *> (data))[i];
1048 }
1049 retval = octave_value (arr);
1050 break; 1019 break;
1051 } 1020 }
1052 case TIFF_DOUBLE: 1021 case TIFF_DOUBLE:
1053 { 1022 {
1054 NDArray arr (arr_dims); 1023 retval = make_array<NDArray> (data, arr_dims);
1055 for (uint32_t i = 0; i < count; i++)
1056 {
1057 arr(i) = (reinterpret_cast<double *> (data))[i];
1058 }
1059 retval = octave_value (arr);
1060 break;
1061 }
1062 case TIFF_SRATIONAL:
1063 {
1064 NDArray arr (arr_dims);
1065 for (uint32_t i = 0; i < count; i++)
1066 {
1067 arr(i) = (reinterpret_cast<float *> (data))[i];
1068 }
1069 retval = octave_value (arr);
1070 break;
1071 }
1072 case TIFF_IFD:
1073 {
1074 uint32NDArray arr (arr_dims);
1075 for (uint32_t i = 0; i < count; i++)
1076 {
1077 arr(i) = (reinterpret_cast<uint32_t *> (data))[i];
1078 }
1079 retval = octave_value (arr);
1080 break;
1081 }
1082 case TIFF_IFD8:
1083 {
1084 uint64NDArray arr (arr_dims);
1085 for (uint32_t i = 0; i < count; i++)
1086 {
1087 arr(i) = (reinterpret_cast<uint64_t *> (data))[i];
1088 }
1089 retval = octave_value (arr);
1090 break; 1024 break;
1091 } 1025 }
1092 default: 1026 default:
1093 error ("Unsupported tag data type"); 1027 error ("Unsupported tag data type");
1094 } 1028 }
1767 void 1701 void
1768 write_tile (TIFF *tif, uint32_t tile_no, T tile_data, 1702 write_tile (TIFF *tif, uint32_t tile_no, T tile_data,
1769 tiff_image_data *image_data) 1703 tiff_image_data *image_data)
1770 { 1704 {
1771 uint32_t tile_width, tile_height; 1705 uint32_t tile_width, tile_height;
1772 if (! TIFFGetField (tif, TIFFTAG_TILEWIDTH, &tile_width)) 1706 get_tile_dimensions_validated (tif, tile_width, tile_height);
1773 error ("Failed to get the tile width");
1774 if (! TIFFGetField (tif, TIFFTAG_TILELENGTH, &tile_height))
1775 error ("Failed to get the tile length");
1776
1777 if (tile_height == 0 || tile_height % 16 != 0
1778 || tile_width == 0 || tile_width % 16 != 0)
1779 error ("Tile dimesion tags are invalid");
1780 1707
1781 if (tile_no < 1 || tile_no > TIFFNumberOfTiles (tif)) 1708 if (tile_no < 1 || tile_no > TIFFNumberOfTiles (tif))
1782 error ("Tile number out of bounds"); 1709 error ("Tile number out of bounds");
1783 1710
1784 if (tile_data.dim1 () > tile_height) 1711 if (tile_data.dim1 () > tile_height)
2119 write_tiled_image (TIFF *tif, T pixel_data, tiff_image_data *image_data) 2046 write_tiled_image (TIFF *tif, T pixel_data, tiff_image_data *image_data)
2120 { 2047 {
2121 // ASSUMES pixel data dimensions are already validated 2048 // ASSUMES pixel data dimensions are already validated
2122 2049
2123 uint32_t tile_width, tile_height; 2050 uint32_t tile_width, tile_height;
2124 if (! TIFFGetField (tif, TIFFTAG_TILEWIDTH, &tile_width)) 2051 get_tile_dimensions_validated (tif, tile_width, tile_height);
2125 error ("Failed to get the tile width");
2126 if (! TIFFGetField (tif, TIFFTAG_TILELENGTH, &tile_height))
2127 error ("Failed to get the tile length");
2128
2129 if (tile_height == 0 || tile_height % 16 != 0
2130 || tile_width == 0 || tile_width % 16 != 0)
2131 error ("Tile dimesion tags are invalid");
2132 2052
2133 uint32_t tiles_across = (image_data->width + tile_width - 1) 2053 uint32_t tiles_across = (image_data->width + tile_width - 1)
2134 / tile_width; 2054 / tile_width;
2135 uint32_t tiles_down = (image_data->height + tile_height - 1) 2055 uint32_t tiles_down = (image_data->height + tile_height - 1)
2136 / tile_height; 2056 / tile_height;
2378 default: 2298 default:
2379 error ("Unsupported bit depth for floating-point images"); 2299 error ("Unsupported bit depth for floating-point images");
2380 } 2300 }
2381 } 2301 }
2382 2302
2303 octave_value_list
2304 slice_rgba (uint8NDArray rgba_data)
2305 {
2306 Array<idx_vector> idx (dim_vector (3, 1));
2307 idx(0) = idx_vector (':');
2308 idx(1) = idx_vector (':');
2309 idx(2) = idx_vector (0, 3);
2310 uint8NDArray rgb = uint8NDArray (rgba_data.index (idx));
2311 idx(2) = idx_vector (3);
2312 uint8NDArray alpha = uint8NDArray (rgba_data.index (idx));
2313
2314 octave_value_list retval (2);
2315 retval(0) = octave_value (rgb);
2316 retval(1) = octave_value (alpha);
2317 return retval;
2318 }
2383 #endif 2319 #endif
2384 2320
2385 DEFUN (__open_tiff__, args, , 2321 DEFUN (__open_tiff__, args, ,
2386 "Open a Tiff file and return its handle") 2322 "Open a Tiff file and return its handle")
2387 { 2323 {
2756 perm(1) = 1; 2692 perm(1) = 1;
2757 perm(2) = 0; 2693 perm(2) = 0;
2758 img = img.permute (perm); 2694 img = img.permute (perm);
2759 2695
2760 // Slice the data into RGB and alpha 2696 // Slice the data into RGB and alpha
2761 Array<idx_vector> idx (dim_vector (3, 1)); 2697 return slice_rgba (img);
2762 idx(0) = idx_vector (':');
2763 idx(1) = idx_vector (':');
2764 idx(2) = idx_vector (0, 3);
2765 uint8NDArray rgb = uint8NDArray (img.index (idx));
2766 idx(2) = idx_vector (3);
2767 uint8NDArray alpha = uint8NDArray (img.index (idx));
2768
2769 octave_value_list retval (2);
2770 retval(0) = octave_value (rgb);
2771 retval(1) = octave_value (alpha);
2772 return retval;
2773 #else 2698 #else
2774 err_disabled_feature ("readRGBAImage", "Tiff"); 2699 err_disabled_feature ("readRGBAImage", "Tiff");
2775 #endif 2700 #endif
2776 } 2701 }
2777 2702
2857 perm(1) = 1; 2782 perm(1) = 1;
2858 perm(2) = 0; 2783 perm(2) = 0;
2859 strip_data = strip_data.permute (perm); 2784 strip_data = strip_data.permute (perm);
2860 2785
2861 // Slice the data into RGB and alpha 2786 // Slice the data into RGB and alpha
2862 // TODO(maged): refactor into a function 2787 return slice_rgba (strip_data);
2863 Array<idx_vector> idx (dim_vector (3, 1));
2864 idx(0) = idx_vector (':');
2865 idx(1) = idx_vector (':');
2866 idx(2) = idx_vector (0, 3);
2867 uint8NDArray rgb = uint8NDArray (strip_data.index (idx));
2868 idx(2) = idx_vector (3);
2869 uint8NDArray alpha = uint8NDArray (strip_data.index (idx));
2870
2871 octave_value_list retval (2);
2872 retval(0) = octave_value (rgb);
2873 retval(1) = octave_value (alpha);
2874 return retval;
2875 #else 2788 #else
2876 err_disabled_feature ("readRGBAStrip", "Tiff"); 2789 err_disabled_feature ("readRGBAStrip", "Tiff");
2877 #endif 2790 #endif
2878 } 2791 }
2879 2792
2968 perm(1) = 1; 2881 perm(1) = 1;
2969 perm(2) = 0; 2882 perm(2) = 0;
2970 tile_data = tile_data.permute (perm); 2883 tile_data = tile_data.permute (perm);
2971 2884
2972 // Slice the data into RGB and alpha 2885 // Slice the data into RGB and alpha
2973 Array<idx_vector> idx (dim_vector (3, 1)); 2886 return slice_rgba (tile_data);
2974 idx(0) = idx_vector (':');
2975 idx(1) = idx_vector (':');
2976 idx(2) = idx_vector (0, 3);
2977 uint8NDArray rgb = uint8NDArray (tile_data.index (idx));
2978 idx(2) = idx_vector (3);
2979 uint8NDArray alpha = uint8NDArray (tile_data.index (idx));
2980
2981 octave_value_list retval (2);
2982 retval(0) = octave_value (rgb);
2983 retval(1) = octave_value (alpha);
2984 return retval;
2985 #else 2887 #else
2986 err_disabled_feature ("readRGBATile", "Tiff"); 2888 err_disabled_feature ("readRGBATile", "Tiff");
2987 #endif 2889 #endif
2988 } 2890 }
2989 2891