Mercurial > octave-libtiff
comparison libinterp/corefcn/__tiff__.cc @ 31174:1f19e9a06f2d
Tiff: modified readRGBAStrip/Tile to correctly use the orientation tag
* __tiff__.cc (F__tiff_read_rgba_strip__, F__read_rgba_tile__): modified the
logic to use the orientation tag correctly.
author | magedrifaat <magedrifaat@gmail.com> |
---|---|
date | Tue, 16 Aug 2022 18:01:12 +0200 |
parents | 0abc9779f751 |
children | ed329571ec88 |
comparison
equal
deleted
inserted
replaced
31173:0abc9779f751 | 31174:1f19e9a06f2d |
---|---|
2453 | 2453 |
2454 // The exact number of rows in the strip is needed for boundary strips | 2454 // The exact number of rows in the strip is needed for boundary strips |
2455 uint32_t strip_no = TIFFComputeStrip (tif, row, 0); | 2455 uint32_t strip_no = TIFFComputeStrip (tif, row, 0); |
2456 rows_in_strip = get_rows_in_strip (strip_no, TIFFNumberOfStrips (tif), | 2456 rows_in_strip = get_rows_in_strip (strip_no, TIFFNumberOfStrips (tif), |
2457 rows_in_strip, &image_data); | 2457 rows_in_strip, &image_data); |
2458 | |
2459 uint16_t orientation; | |
2460 if (! TIFFGetFieldDefaulted (tif, TIFFTAG_ORIENTATION, &orientation)) | |
2461 orientation = ORIENTATION_LEFTTOP; | |
2458 | 2462 |
2459 // Start with reversed dimensions to be aligned with LibTIFF and | 2463 // Start with reversed dimensions to be aligned with LibTIFF and |
2460 // permute to the correct order later | 2464 // permute to the correct order later |
2461 dim_vector strip_dims (4, image_data.width, rows_in_strip); | 2465 dim_vector strip_dims (4, image_data.width, rows_in_strip); |
2462 uint8NDArray strip_data (strip_dims); | 2466 uint8NDArray strip_data (strip_dims); |
2463 uint32_t *strip_ptr | 2467 uint32_t *strip_ptr |
2464 = reinterpret_cast <uint32_t *> (strip_data.fortran_vec ()); | 2468 = reinterpret_cast <uint32_t *> (strip_data.fortran_vec ()); |
2465 | 2469 |
2466 // TODO(maged): check if matlab does anything with orientation tag | 2470 // TODO(maged): check if matlab does anything with orientation tag |
2467 // matlab uses the orientation tag to correct the data | 2471 // matlab uses the orientation tag to correct the data |
2468 if (! TIFFReadRGBAStrip (tif, row, strip_ptr)) | 2472 // if (! TIFFReadRGBAStrip (tif, row, strip_ptr)) |
2473 // error ("Failed to read strip"); | |
2474 | |
2475 TIFFRGBAImage img_config; | |
2476 char emsg[1024]; | |
2477 if (! TIFFRGBAImageOK (tif, emsg) | |
2478 || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg)) | |
2479 error ("Failed to read strip"); | |
2480 | |
2481 img_config.orientation = ORIENTATION_TOPLEFT; | |
2482 img_config.req_orientation = orientation; | |
2483 img_config.row_offset = row; | |
2484 img_config.col_offset = 0; | |
2485 | |
2486 bool success = TIFFRGBAImageGet (&img_config, strip_ptr, img_config.width, | |
2487 rows_in_strip); | |
2488 | |
2489 TIFFRGBAImageEnd (&img_config); | |
2490 if (!success) | |
2469 error ("Failed to read strip"); | 2491 error ("Failed to read strip"); |
2470 | 2492 |
2471 // Permute to the correct order of dimensions for Octave | 2493 // Permute to the correct order of dimensions for Octave |
2472 Array<octave_idx_type> perm (dim_vector (3, 1)); | 2494 Array<octave_idx_type> perm (dim_vector (3, 1)); |
2473 perm(0) = 2; | 2495 perm(0) = 2; |
2474 perm(1) = 1; | 2496 perm(1) = 1; |
2475 perm(2) = 0; | 2497 perm(2) = 0; |
2476 strip_data = strip_data.permute (perm); | 2498 strip_data = strip_data.permute (perm); |
2477 | 2499 |
2478 // Slice the data into RGB and alpha | 2500 // Slice the data into RGB and alpha |
2479 // The rows are reversed because LibTIFF assumes a bottom-left orientation | 2501 // TODO(maged): refactor into a function |
2480 Array<idx_vector> idx (dim_vector (3, 1)); | 2502 Array<idx_vector> idx (dim_vector (3, 1)); |
2481 idx(0) = idx_vector (rows_in_strip - 1, -1, -1); | 2503 idx(0) = idx_vector (':'); |
2482 idx(1) = idx_vector (':'); | 2504 idx(1) = idx_vector (':'); |
2483 idx(2) = idx_vector (0, 3); | 2505 idx(2) = idx_vector (0, 3); |
2484 uint8NDArray rgb = uint8NDArray (strip_data.index (idx)); | 2506 uint8NDArray rgb = uint8NDArray (strip_data.index (idx)); |
2485 idx(2) = idx_vector (3); | 2507 idx(2) = idx_vector (3); |
2486 uint8NDArray alpha = uint8NDArray (strip_data.index (idx)); | 2508 uint8NDArray alpha = uint8NDArray (strip_data.index (idx)); |
2533 // tile, so this removes any offset to reach the top-left row and column | 2555 // tile, so this removes any offset to reach the top-left row and column |
2534 // of the tile | 2556 // of the tile |
2535 row -= row % tile_height; | 2557 row -= row % tile_height; |
2536 col -= col % tile_width; | 2558 col -= col % tile_width; |
2537 | 2559 |
2538 // Start with reversed dimensions to be aligned with LibTIFF and | 2560 uint16_t orientation; |
2539 // permute to the correct order later | 2561 if (! TIFFGetFieldDefaulted (tif, TIFFTAG_ORIENTATION, &orientation)) |
2540 dim_vector tile_dims (4, tile_width, tile_height); | 2562 orientation = ORIENTATION_LEFTTOP; |
2541 uint8NDArray tile_data (tile_dims); | |
2542 uint32_t *tile_ptr | |
2543 = reinterpret_cast <uint32_t *> (tile_data.fortran_vec ()); | |
2544 | |
2545 // TODO(maged): check if matlab does anything with orientation tag | |
2546 // matlab uses orientation tag to correct the data | |
2547 if (! TIFFReadRGBATile (tif, col, row, tile_ptr)) | |
2548 error ("Failed to read tile"); | |
2549 | |
2550 // Permute to the correct order of dimensions for Octave | |
2551 Array<octave_idx_type> perm (dim_vector (3, 1)); | |
2552 perm(0) = 2; | |
2553 perm(1) = 1; | |
2554 perm(2) = 0; | |
2555 tile_data = tile_data.permute (perm); | |
2556 | 2563 |
2557 // Calculate the correct dimensions for boundary tiles | 2564 // Calculate the correct dimensions for boundary tiles |
2558 uint32_t corrected_height = tile_height; | 2565 uint32_t corrected_height = tile_height; |
2559 uint32_t corrected_width = tile_width; | 2566 uint32_t corrected_width = tile_width; |
2560 if (row + tile_height > image_data.height) | 2567 if (row + tile_height > image_data.height) |
2561 corrected_height = image_data.height - row; | 2568 corrected_height = image_data.height - row; |
2562 if (col + tile_width > image_data.width) | 2569 if (col + tile_width > image_data.width) |
2563 corrected_width = image_data.width - col; | 2570 corrected_width = image_data.width - col; |
2571 | |
2572 // Start with reversed dimensions to be aligned with LibTIFF and | |
2573 // permute to the correct order later | |
2574 dim_vector tile_dims (4, corrected_width, corrected_height); | |
2575 uint8NDArray tile_data (tile_dims); | |
2576 uint32_t *tile_ptr | |
2577 = reinterpret_cast <uint32_t *> (tile_data.fortran_vec ()); | |
2578 | |
2579 // TODO(maged): check if matlab does anything with orientation tag | |
2580 // matlab uses orientation tag to correct the data | |
2581 // if (! TIFFReadRGBATile (tif, col, row, tile_ptr)) | |
2582 // error ("Failed to read tile"); | |
2583 | |
2584 TIFFRGBAImage img_config; | |
2585 char emsg[1024]; | |
2586 if (! TIFFRGBAImageOK (tif, emsg) | |
2587 || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg)) | |
2588 error ("Failed to read tile"); | |
2589 | |
2590 img_config.orientation = ORIENTATION_TOPLEFT; | |
2591 img_config.req_orientation = orientation; | |
2592 img_config.row_offset = row; | |
2593 img_config.col_offset = col; | |
2594 | |
2595 bool success = TIFFRGBAImageGet (&img_config, tile_ptr, corrected_width, | |
2596 corrected_height); | |
2597 | |
2598 TIFFRGBAImageEnd (&img_config); | |
2599 if (!success) | |
2600 error ("Failed to read tile"); | |
2601 | |
2602 // Permute to the correct order of dimensions for Octave | |
2603 Array<octave_idx_type> perm (dim_vector (3, 1)); | |
2604 perm(0) = 2; | |
2605 perm(1) = 1; | |
2606 perm(2) = 0; | |
2607 tile_data = tile_data.permute (perm); | |
2564 | 2608 |
2565 // Slice the data into RGB and alpha | 2609 // Slice the data into RGB and alpha |
2566 // LibTIFF assumes the image has bottom-left orientation and returns | |
2567 // the rows flipped vertically, so we need to reverse them and remove | |
2568 // the padding which is at the top since the rows are flipped | |
2569 Array<idx_vector> idx (dim_vector (3, 1)); | 2610 Array<idx_vector> idx (dim_vector (3, 1)); |
2570 // Must cast the unsigned values to signed because otherwise the output | 2611 idx(0) = idx_vector (':'); |
2571 // can't be negative (C++ is the best). | 2612 idx(1) = idx_vector (':'); |
2572 idx(0) = idx_vector (tile_height - 1, | |
2573 int64_t(tile_height - corrected_height) - 1, -1); | |
2574 idx(1) = idx_vector (0, corrected_width); | |
2575 idx(2) = idx_vector (0, 3); | 2613 idx(2) = idx_vector (0, 3); |
2576 uint8NDArray rgb = uint8NDArray (tile_data.index (idx)); | 2614 uint8NDArray rgb = uint8NDArray (tile_data.index (idx)); |
2577 idx(2) = idx_vector (3); | 2615 idx(2) = idx_vector (3); |
2578 uint8NDArray alpha = uint8NDArray (tile_data.index (idx)); | 2616 uint8NDArray alpha = uint8NDArray (tile_data.index (idx)); |
2579 | 2617 |