Mercurial > octave-libtiff
comparison libinterp/corefcn/__tiff__.cc @ 31178:14edd6b09efe
Tiff: added support for reading and writing signed images
* __tiff__.cc (F__tiff_read__, F__tiff_write__, F__read_encoded_strip__,
F__tiff_read_encoded_tile__): added support for reading and writing images
with sample format of 2 as signed integer images.
author | magedrifaat <magedrifaat@gmail.com> |
---|---|
date | Wed, 17 Aug 2022 21:15:49 +0200 |
parents | c7c79973007f |
children | f294b800f002 |
comparison
equal
deleted
inserted
replaced
31177:c7c79973007f | 31178:14edd6b09efe |
---|---|
373 else | 373 else |
374 return read_strip<T> (tif, strip_tile_no, image_data); | 374 return read_strip<T> (tif, strip_tile_no, image_data); |
375 } | 375 } |
376 | 376 |
377 octave_value | 377 octave_value |
378 read_unsigned_strip_or_tile (TIFF *tif, uint32_t strip_tile_no, | |
379 tiff_image_data *image_data) | |
380 { | |
381 switch (image_data->bits_per_sample) | |
382 { | |
383 case 1: | |
384 return read_strip_or_tile<boolNDArray> (tif, strip_tile_no, | |
385 image_data); | |
386 break; | |
387 case 8: | |
388 return read_strip_or_tile<uint8NDArray> (tif, strip_tile_no, | |
389 image_data); | |
390 break; | |
391 case 16: | |
392 return read_strip_or_tile<uint16NDArray> (tif, strip_tile_no, | |
393 image_data); | |
394 break; | |
395 case 32: | |
396 return read_strip_or_tile<uint32NDArray> (tif, strip_tile_no, | |
397 image_data); | |
398 case 64: | |
399 return read_strip_or_tile<uint64NDArray> (tif, strip_tile_no, | |
400 image_data); | |
401 default: | |
402 error ("Unsupported bit depth"); | |
403 } | |
404 } | |
405 | |
406 octave_value | |
407 read_signed_strip_or_tile (TIFF *tif, uint32_t strip_tile_no, | |
408 tiff_image_data *image_data) | |
409 { | |
410 switch (image_data->bits_per_sample) | |
411 { | |
412 case 8: | |
413 return read_strip_or_tile<int8NDArray> (tif, strip_tile_no, | |
414 image_data); | |
415 break; | |
416 case 16: | |
417 return read_strip_or_tile<int16NDArray> (tif, strip_tile_no, | |
418 image_data); | |
419 break; | |
420 case 32: | |
421 return read_strip_or_tile<int32NDArray> (tif, strip_tile_no, | |
422 image_data); | |
423 case 64: | |
424 return read_strip_or_tile<int64NDArray> (tif, strip_tile_no, | |
425 image_data); | |
426 default: | |
427 error ("Unsupported bit depth for signed images"); | |
428 } | |
429 } | |
430 | |
431 octave_value | |
432 read_float_strip_or_tile (TIFF *tif, uint32_t strip_tile_no, | |
433 tiff_image_data *image_data) | |
434 { | |
435 switch (image_data->bits_per_sample) | |
436 { | |
437 case 32: | |
438 return read_strip_or_tile<FloatNDArray> (tif, strip_tile_no, | |
439 image_data); | |
440 case 64: | |
441 return read_strip_or_tile<NDArray> (tif, strip_tile_no, | |
442 image_data); | |
443 default: | |
444 error ("Unsupported bit depth for floating-point images"); | |
445 } | |
446 } | |
447 | |
448 octave_value | |
378 handle_read_strip_or_tile (TIFF *tif, uint32_t strip_tile_no) | 449 handle_read_strip_or_tile (TIFF *tif, uint32_t strip_tile_no) |
379 { | 450 { |
380 // Obtain all necessary tags | 451 // Obtain all necessary tags |
381 tiff_image_data image_data (tif); | 452 tiff_image_data image_data (tif); |
382 | 453 |
383 uint16_t sample_format; | 454 uint16_t sample_format; |
384 if (! TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &sample_format)) | 455 if (! TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &sample_format)) |
385 error ("Failed to obtain a value for sample format"); | 456 error ("Failed to obtain a value for sample format"); |
386 | 457 |
387 if (sample_format == 3) | 458 switch (sample_format) |
388 { | |
389 if (image_data.bits_per_sample != 32 | |
390 && image_data.bits_per_sample != 64) | |
391 error ("Floating point images are only supported for bit depths of 32 and 64"); | |
392 } | |
393 else if (sample_format != 1 && sample_format != 4) | |
394 error ("Unsupported sample format"); | |
395 | |
396 switch (image_data.bits_per_sample) | |
397 { | 459 { |
398 case 1: | 460 case 1: |
399 return read_strip_or_tile<boolNDArray> (tif, strip_tile_no, | 461 case 4: |
400 &image_data); | 462 return read_unsigned_strip_or_tile (tif, strip_tile_no, &image_data); |
401 break; | 463 break; |
402 case 8: | 464 case 2: |
403 return read_strip_or_tile<uint8NDArray> (tif, strip_tile_no, | 465 return read_signed_strip_or_tile (tif, strip_tile_no, &image_data); |
404 &image_data); | 466 break; |
405 break; | 467 case 3: |
406 case 16: | 468 return read_float_strip_or_tile (tif, strip_tile_no, &image_data); |
407 return read_strip_or_tile<uint16NDArray> (tif, strip_tile_no, | |
408 &image_data); | |
409 break; | |
410 case 32: | |
411 if (sample_format == 3) | |
412 return read_strip_or_tile<FloatNDArray> (tif, strip_tile_no, | |
413 &image_data); | |
414 else | |
415 return read_strip_or_tile<uint32NDArray> (tif, strip_tile_no, | |
416 &image_data); | |
417 break; | |
418 case 64: | |
419 if (sample_format == 3) | |
420 return read_strip_or_tile<NDArray> (tif, strip_tile_no, | |
421 &image_data); | |
422 else | |
423 return read_strip_or_tile<uint64NDArray> (tif, strip_tile_no, | |
424 &image_data); | |
425 break; | 469 break; |
426 default: | 470 default: |
427 error ("Unsupported bit depth"); | 471 error ("Unsupported sample format"); |
428 } | 472 } |
429 } | 473 } |
430 | 474 |
431 template <typename T> | 475 template <typename T> |
432 octave_value | 476 octave_value |
751 { | 795 { |
752 if (image_data->is_tiled) | 796 if (image_data->is_tiled) |
753 return read_tiled_image<T> (tif, image_data); | 797 return read_tiled_image<T> (tif, image_data); |
754 else | 798 else |
755 return read_stripped_image<T> (tif, image_data); | 799 return read_stripped_image<T> (tif, image_data); |
800 } | |
801 | |
802 octave_value | |
803 read_unsigned_image (TIFF *tif, tiff_image_data *image_data) | |
804 { | |
805 switch (image_data->bits_per_sample) | |
806 { | |
807 case 1: | |
808 return read_image<boolNDArray> (tif, image_data); | |
809 break; | |
810 case 4: | |
811 case 8: | |
812 return read_image<uint8NDArray> (tif, image_data); | |
813 break; | |
814 case 16: | |
815 return read_image<uint16NDArray> (tif, image_data); | |
816 break; | |
817 case 32: | |
818 return read_image<uint32NDArray> (tif, image_data); | |
819 case 64: | |
820 return read_image<uint64NDArray> (tif, image_data); | |
821 break; | |
822 default: | |
823 error ("Unsupported bit depth"); | |
824 } | |
825 } | |
826 | |
827 octave_value | |
828 read_signed_image (TIFF *tif, tiff_image_data *image_data) | |
829 { | |
830 switch (image_data->bits_per_sample) | |
831 { | |
832 case 8: | |
833 return read_image<int8NDArray> (tif, image_data); | |
834 break; | |
835 case 16: | |
836 return read_image<int16NDArray> (tif, image_data); | |
837 break; | |
838 case 32: | |
839 return read_image<int32NDArray> (tif, image_data); | |
840 case 64: | |
841 return read_image<int64NDArray> (tif, image_data); | |
842 break; | |
843 default: | |
844 error ("Unsupported bit depth for signed images"); | |
845 } | |
846 } | |
847 | |
848 octave_value | |
849 read_float_image (TIFF *tif, tiff_image_data *image_data) | |
850 { | |
851 switch (image_data->bits_per_sample) | |
852 { | |
853 case 32: | |
854 return read_image<FloatNDArray> (tif, image_data); | |
855 case 64: | |
856 return read_image<NDArray> (tif, image_data); | |
857 break; | |
858 default: | |
859 error ("Unsupported bit depth for floating-point images"); | |
860 } | |
756 } | 861 } |
757 | 862 |
758 // Convert tag value to double | 863 // Convert tag value to double |
759 octave_value | 864 octave_value |
760 interpret_scalar_tag_data (void *data, TIFFDataType tag_datatype) | 865 interpret_scalar_tag_data (void *data, TIFFDataType tag_datatype) |
1042 tag_data_ov = get_array_field_data (tif, fip, | 1147 tag_data_ov = get_array_field_data (tif, fip, |
1043 TIFFNumberOfStrips (tif)); | 1148 TIFFNumberOfStrips (tif)); |
1044 break; | 1149 break; |
1045 case TIFFTAG_TILEBYTECOUNTS: | 1150 case TIFFTAG_TILEBYTECOUNTS: |
1046 case TIFFTAG_TILEOFFSETS: | 1151 case TIFFTAG_TILEOFFSETS: |
1047 tag_data_ov = get_array_field_data (tif, fip, TIFFNumberOfTiles (tif)); | 1152 tag_data_ov |
1153 = get_array_field_data (tif, fip, TIFFNumberOfTiles (tif)); | |
1048 break; | 1154 break; |
1049 case TIFFTAG_YCBCRCOEFFICIENTS: | 1155 case TIFFTAG_YCBCRCOEFFICIENTS: |
1050 tag_data_ov = get_array_field_data (tif, fip, 3); | 1156 tag_data_ov = get_array_field_data (tif, fip, 3); |
1051 break; | 1157 break; |
1052 case TIFFTAG_REFERENCEBLACKWHITE: | 1158 case TIFFTAG_REFERENCEBLACKWHITE: |
1143 count, | 1249 count, |
1144 TIFFFieldDataType (fip)) | 1250 TIFFFieldDataType (fip)) |
1145 .uint16_array_value () | 1251 .uint16_array_value () |
1146 .reshape (col_dims); | 1252 .reshape (col_dims); |
1147 | 1253 |
1148 tag_data_ov = octave_value (uint16NDArray::cat (1, 3, array_list)); | 1254 tag_data_ov |
1255 = octave_value (uint16NDArray::cat (1, 3, array_list)); | |
1149 } | 1256 } |
1150 break; | 1257 break; |
1151 } | 1258 } |
1152 case TIFFTAG_PAGENUMBER: | 1259 case TIFFTAG_PAGENUMBER: |
1153 case TIFFTAG_HALFTONEHINTS: | 1260 case TIFFTAG_HALFTONEHINTS: |
1171 } | 1278 } |
1172 case TIFFTAG_SUBIFD: | 1279 case TIFFTAG_SUBIFD: |
1173 { | 1280 { |
1174 uint16_t count; | 1281 uint16_t count; |
1175 uint64_t *offsets; | 1282 uint64_t *offsets; |
1176 validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &offsets)); | 1283 validate_tiff_get_field (TIFFGetField (tif, tag_id, |
1284 &count, &offsets)); | |
1177 tag_data_ov = interpret_tag_data (offsets, count, | 1285 tag_data_ov = interpret_tag_data (offsets, count, |
1178 TIFFFieldDataType (fip)); | 1286 TIFFFieldDataType (fip)); |
1179 break; | 1287 break; |
1180 } | 1288 } |
1181 case TIFFTAG_EXTRASAMPLES: | 1289 case TIFFTAG_EXTRASAMPLES: |
1182 { | 1290 { |
1183 uint16_t count; | 1291 uint16_t count; |
1184 uint16_t *types; | 1292 uint16_t *types; |
1185 validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &types)); | 1293 validate_tiff_get_field (TIFFGetField (tif, tag_id, |
1294 &count, &types)); | |
1186 tag_data_ov = interpret_tag_data (types, count, | 1295 tag_data_ov = interpret_tag_data (types, count, |
1187 TIFFFieldDataType (fip)); | 1296 TIFFFieldDataType (fip)); |
1188 break; | 1297 break; |
1189 } | 1298 } |
1190 // TODO(maged): These tags are more complex to implement | 1299 // TODO(maged): These tags are more complex to implement |
1745 else | 1854 else |
1746 write_strip<T> (tif, strip_tile_no, strip_data, image_data); | 1855 write_strip<T> (tif, strip_tile_no, strip_data, image_data); |
1747 } | 1856 } |
1748 | 1857 |
1749 void | 1858 void |
1750 handle_write_strip_or_tile (TIFF *tif, uint32_t strip_tile_no, | 1859 write_unsigned_strip_or_tile (TIFF *tif, uint32_t strip_tile_no, |
1751 octave_value data_ov, | 1860 octave_value data_ov, |
1752 tiff_image_data *image_data) | 1861 tiff_image_data *image_data) |
1753 { | 1862 { |
1754 | |
1755 // SampleFormat tag is not a required field and has a default value of 1 | |
1756 // So we need to use TIFFGetFieldDefaulted in case it is not present in | |
1757 // the file | |
1758 uint16_t sample_format; | |
1759 if (! TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &sample_format)) | |
1760 error ("Failed to obtain a value for sample format"); | |
1761 | |
1762 // TODO(maged): add support for signed integer images | |
1763 if (sample_format == 3) | |
1764 { | |
1765 if (image_data->bits_per_sample != 32 | |
1766 && image_data->bits_per_sample != 64) | |
1767 error ("Floating point images are only supported for bit depths of 32 and 64"); | |
1768 } | |
1769 | |
1770 // The standard specifies that a SampleFormat of 4 should be treated | |
1771 // the same as 1 (unsigned integer) | |
1772 else if (sample_format != 1 && sample_format != 4) | |
1773 error ("Unsupported sample format"); | |
1774 | |
1775 switch (image_data->bits_per_sample) | 1863 switch (image_data->bits_per_sample) |
1776 { | 1864 { |
1777 case 1: | 1865 case 1: |
1778 // We need to check for both scalar and matrix types to handle single | 1866 // We need to check for both scalar and matrix types to handle single |
1779 // element strip | 1867 // element strip |
1799 image_data); | 1887 image_data); |
1800 else | 1888 else |
1801 error ("Only uint16 data is allowed for uint images with bit depth of 16"); | 1889 error ("Only uint16 data is allowed for uint images with bit depth of 16"); |
1802 break; | 1890 break; |
1803 case 32: | 1891 case 32: |
1804 if (sample_format == 3) | 1892 if (data_ov.is_uint32_type ()) |
1805 if (data_ov.is_single_type () || data_ov.is_double_type ()) | 1893 write_strip_or_tile<uint32NDArray> (tif, strip_tile_no, |
1806 write_strip_or_tile<FloatNDArray> (tif, strip_tile_no, | 1894 data_ov.uint32_array_value (), |
1807 data_ov.float_array_value (), | 1895 image_data); |
1808 image_data); | |
1809 else | |
1810 error ("Only single and double data are allowed for floating-point images"); | |
1811 else | 1896 else |
1812 if (data_ov.is_uint32_type ()) | 1897 error ("Only uint32 data is allowed for uint images with bit depth of 32"); |
1813 write_strip_or_tile<uint32NDArray> (tif, strip_tile_no, | 1898 break; |
1814 data_ov.uint32_array_value (), | 1899 case 64: |
1815 image_data); | 1900 if (data_ov.is_uint64_type ()) |
1816 else | 1901 write_strip_or_tile<uint64NDArray> (tif, strip_tile_no, |
1817 error ("Only uint32 data is allowed for uint images with bit depth of 32"); | 1902 data_ov.uint64_array_value (), |
1818 break; | 1903 image_data); |
1819 case 64: | 1904 else |
1820 if (sample_format == 3) | 1905 error ("Only uint64 data is allowed for uint images with bit depth of 64"); |
1821 if (data_ov.is_single_type () || data_ov.is_double_type ()) | |
1822 write_strip_or_tile<NDArray> (tif, strip_tile_no, | |
1823 data_ov.array_value (), | |
1824 image_data); | |
1825 else | |
1826 error ("Only single and double data are allowed for floating-point images"); | |
1827 else | |
1828 if (data_ov.is_uint64_type ()) | |
1829 write_strip_or_tile<uint64NDArray> (tif, strip_tile_no, | |
1830 data_ov.uint64_array_value (), | |
1831 image_data); | |
1832 else | |
1833 error ("Only uint64 data is allowed for uint images with bit depth of 64"); | |
1834 break; | 1906 break; |
1835 default: | 1907 default: |
1836 error ("Unsupported bit depth"); | 1908 error ("Unsupported bit depth"); |
1909 } | |
1910 } | |
1911 | |
1912 void | |
1913 write_signed_strip_or_tile (TIFF *tif, uint32_t strip_tile_no, | |
1914 octave_value data_ov, | |
1915 tiff_image_data *image_data) | |
1916 { | |
1917 switch (image_data->bits_per_sample) | |
1918 { | |
1919 case 8: | |
1920 if (data_ov.is_int8_type ()) | |
1921 write_strip_or_tile<int8NDArray> (tif, strip_tile_no, | |
1922 data_ov.int8_array_value (), | |
1923 image_data); | |
1924 else | |
1925 error ("Only int8 data is allowed for int images with bit depth of 8"); | |
1926 break; | |
1927 case 16: | |
1928 if (data_ov.is_int16_type ()) | |
1929 write_strip_or_tile<int16NDArray> (tif, strip_tile_no, | |
1930 data_ov.int16_array_value (), | |
1931 image_data); | |
1932 else | |
1933 error ("Only int16 data is allowed for int images with bit depth of 16"); | |
1934 break; | |
1935 case 32: | |
1936 if (data_ov.is_int32_type ()) | |
1937 write_strip_or_tile<int32NDArray> (tif, strip_tile_no, | |
1938 data_ov.int32_array_value (), | |
1939 image_data); | |
1940 else | |
1941 error ("Only int32 data is allowed for int images with bit depth of 32"); | |
1942 break; | |
1943 case 64: | |
1944 if (data_ov.is_int64_type ()) | |
1945 write_strip_or_tile<int64NDArray> (tif, strip_tile_no, | |
1946 data_ov.int64_array_value (), | |
1947 image_data); | |
1948 else | |
1949 error ("Only int64 data is allowed for int images with bit depth of 64"); | |
1950 break; | |
1951 default: | |
1952 error ("Unsupported bit depth for signed images"); | |
1953 } | |
1954 } | |
1955 | |
1956 void | |
1957 write_float_strip_or_tile (TIFF *tif, uint32_t strip_tile_no, | |
1958 octave_value data_ov, | |
1959 tiff_image_data *image_data) | |
1960 { | |
1961 switch (image_data->bits_per_sample) | |
1962 { | |
1963 case 32: | |
1964 if (data_ov.is_single_type () || data_ov.is_double_type ()) | |
1965 write_strip_or_tile<FloatNDArray> (tif, strip_tile_no, | |
1966 data_ov.float_array_value (), | |
1967 image_data); | |
1968 else | |
1969 error ("Only single and double data are allowed for floating-point images"); | |
1970 break; | |
1971 case 64: | |
1972 if (data_ov.is_single_type () || data_ov.is_double_type ()) | |
1973 write_strip_or_tile<NDArray> (tif, strip_tile_no, | |
1974 data_ov.array_value (), | |
1975 image_data); | |
1976 else | |
1977 error ("Only single and double data are allowed for floating-point images"); | |
1978 break; | |
1979 default: | |
1980 error ("Unsupported bit depth for floating-point images"); | |
1981 } | |
1982 } | |
1983 | |
1984 void | |
1985 handle_write_strip_or_tile (TIFF *tif, uint32_t strip_tile_no, | |
1986 octave_value data_ov, | |
1987 tiff_image_data *image_data) | |
1988 { | |
1989 | |
1990 // SampleFormat tag is not a required field and has a default value of 1 | |
1991 // So we need to use TIFFGetFieldDefaulted in case it is not present in | |
1992 // the file | |
1993 uint16_t sample_format; | |
1994 if (! TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &sample_format)) | |
1995 error ("Failed to obtain a value for sample format"); | |
1996 | |
1997 switch (sample_format) | |
1998 { | |
1999 case 1: | |
2000 case 4: | |
2001 write_unsigned_strip_or_tile (tif, strip_tile_no, data_ov, | |
2002 image_data); | |
2003 break; | |
2004 case 2: | |
2005 write_signed_strip_or_tile (tif, strip_tile_no, data_ov, image_data); | |
2006 break; | |
2007 case 3: | |
2008 write_float_strip_or_tile (tif, strip_tile_no, data_ov, image_data); | |
2009 break; | |
2010 default: | |
2011 error ("Unsupported sample format"); | |
1837 } | 2012 } |
1838 } | 2013 } |
1839 | 2014 |
1840 template <typename T> | 2015 template <typename T> |
1841 void | 2016 void |
2077 else | 2252 else |
2078 write_stripped_image<T> (tif, pixel_data, image_data); | 2253 write_stripped_image<T> (tif, pixel_data, image_data); |
2079 | 2254 |
2080 } | 2255 } |
2081 | 2256 |
2257 void | |
2258 write_unsigned_image (TIFF *tif, octave_value image_ov, | |
2259 tiff_image_data *image_data) | |
2260 { | |
2261 switch (image_data->bits_per_sample) | |
2262 { | |
2263 case 1: | |
2264 // We need to check for both scalar and matrix types to handle single | |
2265 // pixel image | |
2266 if (image_ov.is_bool_scalar () || image_ov.is_bool_matrix ()) | |
2267 write_image<boolNDArray> (tif, image_ov.bool_array_value (), | |
2268 image_data); | |
2269 else | |
2270 error ("Expected logical matrix for BiLevel image"); | |
2271 break; | |
2272 case 8: | |
2273 if (image_ov.is_uint8_type ()) | |
2274 write_image<uint8NDArray> (tif, image_ov.uint8_array_value (), | |
2275 image_data); | |
2276 else | |
2277 error ("Only uint8 data is allowed for uint images with bit depth of 8"); | |
2278 break; | |
2279 case 16: | |
2280 if (image_ov.is_uint16_type ()) | |
2281 write_image<uint16NDArray> (tif, image_ov.uint16_array_value (), | |
2282 image_data); | |
2283 else | |
2284 error ("Only uint16 data is allowed for uint images with bit depth of 16"); | |
2285 break; | |
2286 case 32: | |
2287 if (image_ov.is_uint32_type ()) | |
2288 write_image<uint32NDArray> (tif, image_ov.uint32_array_value (), | |
2289 image_data); | |
2290 else | |
2291 error ("Only uint32 data is allowed for uint images with bit depth of 32"); | |
2292 break; | |
2293 case 64: | |
2294 if (image_ov.is_uint64_type ()) | |
2295 write_image<uint64NDArray> (tif, image_ov.uint64_array_value (), | |
2296 image_data); | |
2297 else | |
2298 error ("Only uint64 data is allowed for uint images with bit depth of 64"); | |
2299 break; | |
2300 default: | |
2301 error ("Unsupported bit depth"); | |
2302 } | |
2303 } | |
2304 | |
2305 void | |
2306 write_signed_image (TIFF *tif, octave_value image_ov, | |
2307 tiff_image_data *image_data) | |
2308 { | |
2309 switch (image_data->bits_per_sample) | |
2310 { | |
2311 case 8: | |
2312 if (image_ov.is_int8_type ()) | |
2313 write_image<int8NDArray> (tif, image_ov.int8_array_value (), | |
2314 image_data); | |
2315 else | |
2316 error ("Only int8 data is allowed for int images with bit depth of 8"); | |
2317 break; | |
2318 case 16: | |
2319 if (image_ov.is_int16_type ()) | |
2320 write_image<int16NDArray> (tif, image_ov.int16_array_value (), | |
2321 image_data); | |
2322 else | |
2323 error ("Only int16 data is allowed for int images with bit depth of 16"); | |
2324 break; | |
2325 case 32: | |
2326 if (image_ov.is_int32_type ()) | |
2327 write_image<int32NDArray> (tif, image_ov.int32_array_value (), | |
2328 image_data); | |
2329 else | |
2330 error ("Only int32 data is allowed for int images with bit depth of 32"); | |
2331 break; | |
2332 case 64: | |
2333 if (image_ov.is_int64_type ()) | |
2334 write_image<int64NDArray> (tif, image_ov.int64_array_value (), | |
2335 image_data); | |
2336 else | |
2337 error ("Only int64 data is allowed for int images with bit depth of 64"); | |
2338 break; | |
2339 default: | |
2340 error ("Unsupported bit depth for signed images"); | |
2341 } | |
2342 } | |
2343 | |
2344 void | |
2345 write_float_image (TIFF *tif, octave_value image_ov, | |
2346 tiff_image_data *image_data) | |
2347 { | |
2348 switch (image_data->bits_per_sample) | |
2349 { | |
2350 case 32: | |
2351 if (image_ov.is_single_type () || image_ov.is_double_type ()) | |
2352 write_image<FloatNDArray> (tif, image_ov.float_array_value (), | |
2353 image_data); | |
2354 else | |
2355 error ("Only single or double data are allowed for float images"); | |
2356 break; | |
2357 case 64: | |
2358 if (image_ov.is_single_type () || image_ov.is_double_type ()) | |
2359 write_image<NDArray> (tif, image_ov.array_value (), | |
2360 image_data); | |
2361 else | |
2362 error ("Only single or double data are allowed for float images"); | |
2363 break; | |
2364 default: | |
2365 error ("Unsupported bit depth for floating-point images"); | |
2366 } | |
2367 } | |
2082 | 2368 |
2083 #endif | 2369 #endif |
2084 | 2370 |
2085 DEFUN (__open_tiff__, args, , | 2371 DEFUN (__open_tiff__, args, , |
2086 "Open a Tiff file and return its handle") | 2372 "Open a Tiff file and return its handle") |
2098 std::string mode = "r"; | 2384 std::string mode = "r"; |
2099 | 2385 |
2100 if (nargin == 2) | 2386 if (nargin == 2) |
2101 mode = args(1).string_value (); | 2387 mode = args(1).string_value (); |
2102 | 2388 |
2103 const std::vector<std::string> supported_modes {"r", "w", "w8", "a", "r+"}; | 2389 const std::vector<std::string> supported_modes { |
2390 "r", "w", "w8", "a", "r+" | |
2391 }; | |
2104 | 2392 |
2105 if (std::find (supported_modes.cbegin (), supported_modes.cend (), mode) | 2393 if (std::find (supported_modes.cbegin (), supported_modes.cend (), mode) |
2106 == supported_modes.cend ()) | 2394 == supported_modes.cend ()) |
2107 error ("Invalid mode for openning Tiff file: %s", mode.c_str ()); | 2395 error ("Invalid mode for openning Tiff file: %s", mode.c_str ()); |
2108 | 2396 |
2296 | 2584 |
2297 uint16_t sample_format; | 2585 uint16_t sample_format; |
2298 if (! TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &sample_format)) | 2586 if (! TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &sample_format)) |
2299 error ("Failed to obtain a value for sample format"); | 2587 error ("Failed to obtain a value for sample format"); |
2300 | 2588 |
2301 if (sample_format == 3) | |
2302 { | |
2303 if (image_data.bits_per_sample != 32 && image_data.bits_per_sample != 64) | |
2304 error ("Floating point images are only supported for bit depths of 32 and 64"); | |
2305 } | |
2306 else if (sample_format != 1 && sample_format != 4) | |
2307 error ("Unsupported sample format"); | |
2308 | |
2309 octave_value_list retval; | 2589 octave_value_list retval; |
2310 switch (image_data.bits_per_sample) | 2590 switch (sample_format) |
2311 { | 2591 { |
2312 case 1: | 2592 case 1: |
2313 retval(0) = read_image<boolNDArray> (tif, &image_data); | |
2314 break; | |
2315 case 4: | 2593 case 4: |
2316 case 8: | 2594 retval (0) = read_unsigned_image (tif, &image_data); |
2317 retval(0) = read_image<uint8NDArray> (tif, &image_data); | 2595 break; |
2318 break; | 2596 case 2: |
2319 case 16: | 2597 retval (0) = read_signed_image (tif, &image_data); |
2320 retval(0) = read_image<uint16NDArray> (tif, &image_data); | 2598 break; |
2321 break; | 2599 case 3: |
2322 case 32: | 2600 retval (0) = read_float_image (tif, &image_data); |
2323 if (sample_format == 3) | |
2324 retval(0) = read_image<FloatNDArray> (tif, &image_data); | |
2325 else | |
2326 retval(0) = read_image<uint32NDArray> (tif, &image_data); | |
2327 break; | |
2328 case 64: | |
2329 if (sample_format == 3) | |
2330 retval(0) = read_image<NDArray> (tif, &image_data); | |
2331 else | |
2332 retval(0) = read_image<uint64NDArray> (tif, &image_data); | |
2333 break; | 2601 break; |
2334 default: | 2602 default: |
2335 error ("Unsupported bit depth"); | 2603 error ("Unsupported sample format"); |
2336 } | 2604 } |
2337 | 2605 |
2338 return retval; | 2606 return retval; |
2339 #else | 2607 #else |
2340 err_disabled_feature ("read", "Tiff"); | 2608 err_disabled_feature ("read", "Tiff"); |
2720 tiff_image_data image_data (tif); | 2988 tiff_image_data image_data (tif); |
2721 | 2989 |
2722 uint16_t sample_format; | 2990 uint16_t sample_format; |
2723 if (! TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &sample_format)) | 2991 if (! TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &sample_format)) |
2724 error ("Failed to obtain a value for sample format"); | 2992 error ("Failed to obtain a value for sample format"); |
2725 | 2993 |
2726 if (sample_format == 3) | 2994 switch (sample_format) |
2727 { | |
2728 if (image_data.bits_per_sample != 32 | |
2729 && image_data.bits_per_sample != 64) | |
2730 error ("Floating point images are only supported for bit depths of 32 and 64"); | |
2731 } | |
2732 else if (sample_format != 1 && sample_format != 4) | |
2733 error ("Unsupported sample format"); | |
2734 | |
2735 switch (image_data.bits_per_sample) | |
2736 { | 2995 { |
2737 case 1: | 2996 case 1: |
2738 // We need to check for both scalar and matrix types to handle single | 2997 case 4: |
2739 // pixel image | 2998 write_unsigned_image (tif, args(1), &image_data); |
2740 if (args (1).is_bool_scalar () || args (1).is_bool_matrix ()) | 2999 break; |
2741 write_image<boolNDArray> (tif, args (1).bool_array_value (), | 3000 case 2: |
2742 &image_data); | 3001 write_signed_image (tif, args(1), &image_data); |
2743 else | 3002 break; |
2744 error ("Expected logical matrix for BiLevel image"); | 3003 case 3: |
2745 break; | 3004 write_float_image (tif, args(1), &image_data); |
2746 case 8: | |
2747 if (args (1).is_uint8_type ()) | |
2748 write_image<uint8NDArray> (tif, args (1).uint8_array_value (), | |
2749 &image_data); | |
2750 else | |
2751 error ("Only uint8 data is allowed for uint images with bit depth of 8"); | |
2752 break; | |
2753 case 16: | |
2754 if (args (1).is_uint16_type ()) | |
2755 write_image<uint16NDArray> (tif, args (1).uint16_array_value (), | |
2756 &image_data); | |
2757 else | |
2758 error ("Only uint16 data is allowed for uint images with bit depth of 16"); | |
2759 break; | |
2760 case 32: | |
2761 if (sample_format == 3) | |
2762 if (args (1).is_single_type () || args (1).is_double_type ()) | |
2763 write_image<FloatNDArray> (tif, args (1).float_array_value (), | |
2764 &image_data); | |
2765 else | |
2766 error ("Only single and double data are allowed for floating-point images"); | |
2767 else | |
2768 if (args (1).is_uint32_type ()) | |
2769 write_image<uint32NDArray> (tif, args (1).uint32_array_value (), | |
2770 &image_data); | |
2771 else | |
2772 error ("Only uint32 data is allowed for uint images with bit depth of 32"); | |
2773 break; | |
2774 case 64: | |
2775 if (sample_format == 3) | |
2776 if (args (1).is_single_type () || args (1).is_double_type ()) | |
2777 write_image<NDArray> (tif, args (1).array_value (), &image_data); | |
2778 else | |
2779 error ("Only single and double data are allowed for floating-point images"); | |
2780 else | |
2781 if (args (1).is_uint64_type ()) | |
2782 write_image<uint64NDArray> (tif, args (1).uint64_array_value (), | |
2783 &image_data); | |
2784 else | |
2785 error ("Only uint64 data is allowed for uint images with bit depth of 64"); | |
2786 break; | 3005 break; |
2787 default: | 3006 default: |
2788 error ("Unsupported bit depth"); | 3007 error ("Unsupported sample format"); |
2789 } | 3008 } |
2790 | 3009 |
2791 return octave_value_list (); | 3010 return octave_value_list (); |
2792 #else | 3011 #else |
2793 err_disabled_feature ("write", "Tiff"); | 3012 err_disabled_feature ("write", "Tiff"); |
3283 error ("No state argument provided"); | 3502 error ("No state argument provided"); |
3284 | 3503 |
3285 if (! args(0).is_bool_scalar ()) | 3504 if (! args(0).is_bool_scalar ()) |
3286 error ("Expected logical value as argument"); | 3505 error ("Expected logical value as argument"); |
3287 | 3506 |
3288 // Set the error and warning handlers according to the bool parameter | 3507 // Set the error and warning handlers according to the bool parameter |
3289 if (args(0).bool_value ()) | 3508 if (args(0).bool_value ()) |
3290 { | 3509 { |
3291 TIFFSetErrorHandler (tiff_default_error_handler); | 3510 TIFFSetErrorHandler (tiff_default_error_handler); |
3292 TIFFSetWarningHandler (tiff_default_warning_handler); | 3511 TIFFSetWarningHandler (tiff_default_warning_handler); |
3293 } | 3512 } |