Mercurial > octave-libtiff
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 |