| 773 | // --------------------------------------------------------------------------- |
| 774 | |
| 775 | bool GTiffGrid::valuesAt(int x_start, int y_start, int x_count, int y_count, |
| 776 | int sample_count, const int *sample_idx, float *out, |
| 777 | bool &nodataFound) const { |
| 778 | const auto getTIFFRow = [this](int y) { |
| 779 | return m_bottomUp ? y : m_height - 1 - y; |
| 780 | }; |
| 781 | nodataFound = false; |
| 782 | if (m_blockIs256Pixel && m_planarConfig == PLANARCONFIG_CONTIG && |
| 783 | m_dt == TIFFDataType::Float32 && |
| 784 | (x_start / 256) == (x_start + x_count - 1) / 256 && |
| 785 | getTIFFRow(y_start) / 256 == getTIFFRow(y_start + y_count - 1) / 256 && |
| 786 | !m_hasNodata && m_adfScale.empty() && |
| 787 | (sample_count == 1 || |
| 788 | (sample_count == 2 && sample_idx[1] == sample_idx[0] + 1) || |
| 789 | (sample_count == 3 && sample_idx[1] == sample_idx[0] + 1 && |
| 790 | sample_idx[2] == sample_idx[0] + 2))) { |
| 791 | const int yTIFF = m_bottomUp ? y_start : m_height - (y_start + y_count); |
| 792 | int blockXOff; |
| 793 | int blockYOff; |
| 794 | uint32_t blockId; |
| 795 | const int blockX = x_start / 256; |
| 796 | blockXOff = x_start % 256; |
| 797 | const int blockY = yTIFF / 256; |
| 798 | blockYOff = yTIFF % 256; |
| 799 | blockId = blockY * m_blocksPerRow + blockX; |
| 800 | |
| 801 | const std::vector<unsigned char> *pBuffer = |
| 802 | blockId == m_bufferBlockId ? &m_buffer |
| 803 | : m_cache.get(m_ifdIdx, blockId); |
| 804 | if (pBuffer == nullptr) { |
| 805 | if (TIFFCurrentDirOffset(m_hTIFF) != m_dirOffset && |
| 806 | !TIFFSetSubDirectory(m_hTIFF, m_dirOffset)) { |
| 807 | return false; |
| 808 | } |
| 809 | if (m_buffer.empty()) { |
| 810 | const auto blockSize = |
| 811 | static_cast<size_t>(m_tiled ? TIFFTileSize64(m_hTIFF) |
| 812 | : TIFFStripSize64(m_hTIFF)); |
| 813 | try { |
| 814 | m_buffer.resize(blockSize); |
| 815 | } catch (const std::exception &e) { |
| 816 | pj_log(m_ctx, PJ_LOG_ERROR, _("Exception %s"), e.what()); |
| 817 | return false; |
| 818 | } |
| 819 | } |
| 820 | |
| 821 | if (m_tiled) { |
| 822 | if (TIFFReadEncodedTile(m_hTIFF, blockId, m_buffer.data(), |
| 823 | m_buffer.size()) == -1) { |
| 824 | return false; |
| 825 | } |
| 826 | } else { |
| 827 | if (TIFFReadEncodedStrip(m_hTIFF, blockId, m_buffer.data(), |
| 828 | m_buffer.size()) == -1) { |
| 829 | return false; |
| 830 | } |
| 831 | } |
| 832 | |