| 151 | } |
| 152 | |
| 153 | Task<void> ImageData::applyColorConversion(const Matrix3f& mat, int priority) { |
| 154 | updateLayers(); |
| 155 | |
| 156 | if (almostEquals(mat, Matrix3f{1.0f})) { |
| 157 | co_return; |
| 158 | } |
| 159 | |
| 160 | vector<Task<void>> tasks; |
| 161 | |
| 162 | for (const auto& layer : layers) { |
| 163 | Channel* r = nullptr; |
| 164 | Channel* g = nullptr; |
| 165 | Channel* b = nullptr; |
| 166 | |
| 167 | if (!(((r = mutableChannel(layer + "R")) && (g = mutableChannel(layer + "G")) && (b = mutableChannel(layer + "B"))) || |
| 168 | ((r = mutableChannel(layer + "r")) && (g = mutableChannel(layer + "g")) && (b = mutableChannel(layer + "b"))))) { |
| 169 | // No RGB-triplet found |
| 170 | continue; |
| 171 | } |
| 172 | |
| 173 | TEV_ASSERT(r && g && b, "RGB triplet of channels must exist."); |
| 174 | |
| 175 | auto rv = r->view<float>(), gv = g->view<float>(), bv = b->view<float>(); |
| 176 | tasks.emplace_back( |
| 177 | ThreadPool::global().parallelFor( |
| 178 | 0uz, |
| 179 | r->numPixels(), |
| 180 | r->numPixels() * 3, |
| 181 | [rv, gv, bv, mat](size_t i) mutable { |
| 182 | const auto rgb = mat * Vector3f{rv[i], gv[i], bv[i]}; |
| 183 | rv[i] = rgb.x(); |
| 184 | gv[i] = rgb.y(); |
| 185 | bv[i] = rgb.z(); |
| 186 | }, |
| 187 | priority |
| 188 | ) |
| 189 | ); |
| 190 | } |
| 191 | |
| 192 | co_await awaitAll(tasks); |
| 193 | |
| 194 | toRec709 = toRec709 * inverse(mat); |
| 195 | } |
| 196 | |
| 197 | Task<void> ImageData::matchColorsAndSizeOf(const ImageData& other, int priority) { |
| 198 | if (channels.empty()) { |
no test coverage detected