Mercurial > octave-libtiff
comparison libinterp/corefcn/__tiff__.cc @ 31173:0abc9779f751
Tiff: modified readRGBAImage to use the orientation tag correctly
* __tiff__.cc (F__tiff_read_rgba_image__): modified the way the image
is read to use the orientation tag in the correct way.
author | magedrifaat <magedrifaat@gmail.com> |
---|---|
date | Tue, 16 Aug 2022 16:10:10 +0200 |
parents | 3f5f1404af8a |
children | 1f19e9a06f2d |
comparison
equal
deleted
inserted
replaced
31172:3f5f1404af8a | 31173:0abc9779f751 |
---|---|
794 interpret_tag_data (void *data, uint32_t count, TIFFDataType tag_datatype) | 794 interpret_tag_data (void *data, uint32_t count, TIFFDataType tag_datatype) |
795 { | 795 { |
796 octave_value retval; | 796 octave_value retval; |
797 // Apparently matlab converts scalar numerical values into double | 797 // Apparently matlab converts scalar numerical values into double |
798 // but doesn't do the same for arrays | 798 // but doesn't do the same for arrays |
799 // TODO(maged): matlab returns double for array tags as well, except | |
800 // for a selected set of tags (e.g. StripByteCounts) | |
799 if (count == 1 && tag_datatype != TIFF_ASCII) | 801 if (count == 1 && tag_datatype != TIFF_ASCII) |
800 { | 802 { |
801 retval = interpret_scalar_tag_data (data, tag_datatype); | 803 retval = interpret_scalar_tag_data (data, tag_datatype); |
802 } | 804 } |
803 else | 805 else |
2358 | 2360 |
2359 TIFF *tif = (TIFF *)(args(0).uint64_value ()); | 2361 TIFF *tif = (TIFF *)(args(0).uint64_value ()); |
2360 | 2362 |
2361 tiff_image_data image_data (tif); | 2363 tiff_image_data image_data (tif); |
2362 | 2364 |
2365 uint16_t orientation; | |
2366 if (! TIFFGetFieldDefaulted (tif, TIFFTAG_ORIENTATION, &orientation)) | |
2367 orientation = ORIENTATION_LEFTTOP; | |
2368 | |
2363 // Start with reversed dimensions to be aligned with LibTIFF and | 2369 // Start with reversed dimensions to be aligned with LibTIFF and |
2364 // permute to the correct order later | 2370 // permute to the correct order later |
2365 dim_vector img_dims (4, image_data.width, image_data.height); | 2371 dim_vector img_dims (4, image_data.width, image_data.height); |
2366 uint8NDArray img (img_dims); | 2372 uint8NDArray img (img_dims); |
2367 uint32_t *img_ptr = reinterpret_cast <uint32_t *> (img.fortran_vec ()); | 2373 uint32_t *img_ptr = reinterpret_cast <uint32_t *> (img.fortran_vec ()); |
2368 // Matlab (R2022a) uses a top-left orientation ignoring the tag if present | 2374 |
2369 if (! TIFFReadRGBAImageOriented (tif, image_data.width, image_data.height, | 2375 TIFFRGBAImage img_config; |
2370 img_ptr, 1)) | 2376 char emsg[1024]; |
2377 if (! TIFFRGBAImageOK (tif, emsg) | |
2378 || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg)) | |
2379 error ("Failed to read image"); | |
2380 | |
2381 img_config.orientation = ORIENTATION_TOPLEFT; | |
2382 img_config.req_orientation = orientation; | |
2383 | |
2384 bool success = TIFFRGBAImageGet (&img_config, img_ptr, img_config.width, | |
2385 img_config.height); | |
2386 | |
2387 TIFFRGBAImageEnd (&img_config); | |
2388 if (!success) | |
2371 error ("Failed to read image"); | 2389 error ("Failed to read image"); |
2372 | 2390 |
2373 // Permute to the correct Octave dimension order | 2391 // Permute to the correct Octave dimension order |
2374 Array<octave_idx_type> perm (dim_vector (3, 1)); | 2392 Array<octave_idx_type> perm (dim_vector (3, 1)); |
2375 perm(0) = 2; | 2393 perm(0) = 2; |
2404 if (nargin != 2) | 2422 if (nargin != 2) |
2405 error ("Wrong number of arguments"); | 2423 error ("Wrong number of arguments"); |
2406 | 2424 |
2407 TIFF *tif = (TIFF *)(args(0).uint64_value ()); | 2425 TIFF *tif = (TIFF *)(args(0).uint64_value ()); |
2408 | 2426 |
2409 // TODO(maged): check matlab behavior for missing/ wrong/ out of bounds row | 2427 // Matlab (R2022a) requires row to be double |
2410 // matlab row must be double (scalar or array), and checks bounds | 2428 if (! args(1).is_double_type ()) |
2429 error ("row must be double"); | |
2430 | |
2411 uint32_t row = args (1).uint32_scalar_value (); | 2431 uint32_t row = args (1).uint32_scalar_value (); |
2412 | 2432 |
2413 tiff_image_data image_data (tif); | 2433 tiff_image_data image_data (tif); |
2414 if (image_data.is_tiled) | 2434 if (image_data.is_tiled) |
2415 error ("The image is tiled not stripped"); | 2435 error ("The image is tiled not stripped"); |
2484 error ("Wrong number of arguments"); | 2504 error ("Wrong number of arguments"); |
2485 | 2505 |
2486 TIFF *tif = (TIFF *)(args(0).uint64_value ()); | 2506 TIFF *tif = (TIFF *)(args(0).uint64_value ()); |
2487 | 2507 |
2488 // TODO(maged): check matlab behavior for missing/ wrong/ out of bounds vals | 2508 // TODO(maged): check matlab behavior for missing/ wrong/ out of bounds vals |
2509 // matlab checks bounds and requires double vals (scalar or array) | |
2489 uint32_t row = args (1).uint32_scalar_value (); | 2510 uint32_t row = args (1).uint32_scalar_value (); |
2490 uint32_t col = args (2).uint32_scalar_value (); | 2511 uint32_t col = args (2).uint32_scalar_value (); |
2491 | 2512 |
2492 tiff_image_data image_data (tif); | 2513 tiff_image_data image_data (tif); |
2493 if (! image_data.is_tiled) | 2514 if (! image_data.is_tiled) |
2496 if (row < 1 || row > image_data.height) | 2517 if (row < 1 || row > image_data.height) |
2497 error ("Row out of bounds of the image"); | 2518 error ("Row out of bounds of the image"); |
2498 if (col < 1 || col > image_data.width) | 2519 if (col < 1 || col > image_data.width) |
2499 error ("Column out of bounds of the image"); | 2520 error ("Column out of bounds of the image"); |
2500 | 2521 |
2501 // TODO(maged): check if matlab require the first row,col in tile as well | |
2502 // Convert from 1-based indexing to zero-based | 2522 // Convert from 1-based indexing to zero-based |
2503 row--; | 2523 row--; |
2504 col--; | 2524 col--; |
2505 | 2525 |
2506 uint32_t tile_width, tile_height; | 2526 uint32_t tile_width, tile_height; |
2521 uint8NDArray tile_data (tile_dims); | 2541 uint8NDArray tile_data (tile_dims); |
2522 uint32_t *tile_ptr | 2542 uint32_t *tile_ptr |
2523 = reinterpret_cast <uint32_t *> (tile_data.fortran_vec ()); | 2543 = reinterpret_cast <uint32_t *> (tile_data.fortran_vec ()); |
2524 | 2544 |
2525 // TODO(maged): check if matlab does anything with orientation tag | 2545 // TODO(maged): check if matlab does anything with orientation tag |
2546 // matlab uses orientation tag to correct the data | |
2526 if (! TIFFReadRGBATile (tif, col, row, tile_ptr)) | 2547 if (! TIFFReadRGBATile (tif, col, row, tile_ptr)) |
2527 error ("Failed to read tile"); | 2548 error ("Failed to read tile"); |
2528 | 2549 |
2529 // Permute to the correct order of dimensions for Octave | 2550 // Permute to the correct order of dimensions for Octave |
2530 Array<octave_idx_type> perm (dim_vector (3, 1)); | 2551 Array<octave_idx_type> perm (dim_vector (3, 1)); |
2900 error ("Wrong number of arguments\n"); | 2921 error ("Wrong number of arguments\n"); |
2901 | 2922 |
2902 TIFF *tif = (TIFF *)(args(0).uint64_value ()); | 2923 TIFF *tif = (TIFF *)(args(0).uint64_value ()); |
2903 | 2924 |
2904 // TODO(maged): check matlab behavior | 2925 // TODO(maged): check matlab behavior |
2926 // matlab returns double and handles the special case as 0! | |
2905 uint16_t dir = TIFFCurrentDirectory (tif); | 2927 uint16_t dir = TIFFCurrentDirectory (tif); |
2906 if (dir == (uint16_t)-1) | 2928 if (dir == (uint16_t)-1) |
2907 dir = 0; | 2929 dir = 0; |
2908 | 2930 |
2909 return octave_value_list (octave_value (dir + 1)); | 2931 return octave_value_list (octave_value (dir + 1)); |
2940 if (nargin != 1) | 2962 if (nargin != 1) |
2941 error ("Wrong number of arguments\n"); | 2963 error ("Wrong number of arguments\n"); |
2942 | 2964 |
2943 TIFF *tif = (TIFF *)(args(0).uint64_value ()); | 2965 TIFF *tif = (TIFF *)(args(0).uint64_value ()); |
2944 | 2966 |
2945 // TODO(maged): check if matlab handles this case different from | |
2946 // an erronous next IFD | |
2947 bool is_last = TIFFLastDirectory (tif); | 2967 bool is_last = TIFFLastDirectory (tif); |
2948 if (is_last) | 2968 if (is_last) |
2949 error ("Current directory is the last directory"); | 2969 error ("Current directory is the last directory"); |
2950 | 2970 |
2951 if (! TIFFReadDirectory (tif)) | 2971 if (! TIFFReadDirectory (tif)) |
2966 if (nargin != 2) | 2986 if (nargin != 2) |
2967 error ("Wrong number of arguments\n"); | 2987 error ("Wrong number of arguments\n"); |
2968 | 2988 |
2969 TIFF *tif = (TIFF *)(args(0).uint64_value ()); | 2989 TIFF *tif = (TIFF *)(args(0).uint64_value ()); |
2970 | 2990 |
2971 // TODO(maged): check matlab behavior for wrong argument type | |
2972 // and out of bounds index | |
2973 uint16_t dir = args(1).uint16_scalar_value (); | 2991 uint16_t dir = args(1).uint16_scalar_value (); |
2974 if (dir < 1 || dir > TIFFNumberOfDirectories (tif)) | 2992 if (dir < 1 || dir > TIFFNumberOfDirectories (tif)) |
2975 error ("Directory index out of bounds"); | 2993 error ("Directory index out of bounds"); |
2976 | 2994 |
2977 dir--; | 2995 dir--; |
2993 | 3011 |
2994 if (nargin != 1) | 3012 if (nargin != 1) |
2995 error ("Wrong number of arguments\n"); | 3013 error ("Wrong number of arguments\n"); |
2996 | 3014 |
2997 TIFF *tif = (TIFF *)(args(0).uint64_value ()); | 3015 TIFF *tif = (TIFF *)(args(0).uint64_value ()); |
2998 // TODO(maged): check if matlab errors for leaving a corrupt directory | 3016 // TODO(maged): Check if mtalab always writes directories at the end for both w and a (And r+) |
2999 // Check if mtalab always writes directories at the end for both w and a (And r+) | 3017 // it does |
3000 if (! TIFFWriteDirectory(tif)) | 3018 if (! TIFFWriteDirectory(tif)) |
3001 error ("Failed to write directory"); | 3019 error ("Failed to write directory"); |
3002 | 3020 |
3003 return octave_value_list (); | 3021 return octave_value_list (); |
3004 #else | 3022 #else |
3014 | 3032 |
3015 if (nargin != 1) | 3033 if (nargin != 1) |
3016 error ("Wrong number of arguments\n"); | 3034 error ("Wrong number of arguments\n"); |
3017 | 3035 |
3018 TIFF *tif = (TIFF *)(args(0).uint64_value ()); | 3036 TIFF *tif = (TIFF *)(args(0).uint64_value ()); |
3019 // TODO(maged): check if matlab errors for leaving a corrupt directory | 3037 |
3020 // check if matlab changes directory after the call or switches back | |
3021 if (! TIFFRewriteDirectory(tif)) | 3038 if (! TIFFRewriteDirectory(tif)) |
3022 error ("Failed to rewrite directory"); | 3039 error ("Failed to rewrite directory"); |
3023 | 3040 |
3024 return octave_value_list (); | 3041 return octave_value_list (); |
3025 #else | 3042 #else |
3037 error ("Wrong number of arguments\n"); | 3054 error ("Wrong number of arguments\n"); |
3038 | 3055 |
3039 TIFF *tif = (TIFF *)(args(0).uint64_value ()); | 3056 TIFF *tif = (TIFF *)(args(0).uint64_value ()); |
3040 | 3057 |
3041 // TODO(maged): check if matlab requires scalar double | 3058 // TODO(maged): check if matlab requires scalar double |
3059 // matlab expects double, uint32, or uint64 | |
3060 // and checks the subIFD tag first | |
3042 uint64_t offset = args(1).uint64_scalar_value (); | 3061 uint64_t offset = args(1).uint64_scalar_value (); |
3043 if (! TIFFSetSubDirectory (tif, offset)) | 3062 if (! TIFFSetSubDirectory (tif, offset)) |
3044 error ("Failed to switch to the sub directory"); | 3063 error ("Failed to switch to the sub directory"); |
3045 | 3064 |
3046 return octave_value_list (); | 3065 return octave_value_list (); |