| 780 | |
| 781 | template <typename T> |
| 782 | Task<void> prepareTextureChannel(T* data, const Channel* chan, Box2i box, size_t channelIdx, size_t numTextureChannels) { |
| 783 | const bool isAlpha = channelIdx == 3 || (chan && Channel::isAlpha(chan->name())); |
| 784 | const T defaultVal = isAlpha ? (T)1.0f : (T)0.0f; |
| 785 | |
| 786 | const auto size = box.size(); |
| 787 | const size_t numPixels = posProd(size); |
| 788 | |
| 789 | if (chan) { |
| 790 | const auto copyChannel = [&](const auto view) -> Task<void> { |
| 791 | co_await ThreadPool::global().parallelFor( |
| 792 | 0, |
| 793 | size.y(), |
| 794 | numPixels, |
| 795 | [view, &data, numTextureChannels, channelIdx, width = size.x(), pos = box.min](int y) { |
| 796 | for (int x = 0; x < width; ++x) { |
| 797 | const auto tileIdx = x + y * (size_t)width; |
| 798 | data[tileIdx * numTextureChannels + channelIdx] = view[pos.x() + x, pos.y() + y]; |
| 799 | } |
| 800 | }, |
| 801 | numeric_limits<int>::max() |
| 802 | ); |
| 803 | }; |
| 804 | |
| 805 | switch (chan->pixelFormat()) { |
| 806 | case EPixelFormat::U8: co_await copyChannel(chan->view<const uint8_t>()); break; |
| 807 | case EPixelFormat::U16: co_await copyChannel(chan->view<const uint16_t>()); break; |
| 808 | case EPixelFormat::U32: co_await copyChannel(chan->view<const uint32_t>()); break; |
| 809 | case EPixelFormat::I8: co_await copyChannel(chan->view<const int8_t>()); break; |
| 810 | case EPixelFormat::I16: co_await copyChannel(chan->view<const int16_t>()); break; |
| 811 | case EPixelFormat::I32: co_await copyChannel(chan->view<const int32_t>()); break; |
| 812 | case EPixelFormat::F16: co_await copyChannel(chan->view<const half>()); break; |
| 813 | case EPixelFormat::F32: co_await copyChannel(chan->view<const float>()); break; |
| 814 | } |
| 815 | } else { |
| 816 | co_await ThreadPool::global().parallelFor( |
| 817 | 0uz, |
| 818 | numPixels, |
| 819 | numPixels, |
| 820 | [&data, defaultVal, numTextureChannels, channelIdx](size_t j) { data[j * numTextureChannels + channelIdx] = defaultVal; }, |
| 821 | numeric_limits<int>::max() |
| 822 | ); |
| 823 | } |
| 824 | } |
| 825 | |
| 826 | Texture* Image::texture(span<const string> channelNames, EInterpolationMode minFilter, EInterpolationMode magFilter) & { |
| 827 | if (size().x() > maxTextureSize() || size().y() > maxTextureSize()) { |
no test coverage detected