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