| 238 | } |
| 239 | |
| 240 | IpcPacketUpdateImage IpcPacket::interpretAsUpdateImage() const { |
| 241 | IpcPacketUpdateImage result; |
| 242 | IStream payload{mPayload}; |
| 243 | |
| 244 | EType type; |
| 245 | payload >> type; |
| 246 | if (type != EType::UpdateImage && type != EType::UpdateImageV2 && type != EType::UpdateImageV3) { |
| 247 | throw runtime_error{"Cannot interpret IPC packet as UpdateImage."}; |
| 248 | } |
| 249 | |
| 250 | payload >> result.grabFocus; |
| 251 | payload >> result.imageName; |
| 252 | |
| 253 | if (type >= EType::UpdateImageV2) { |
| 254 | // multi-channel support |
| 255 | payload >> result.nChannels; |
| 256 | } else { |
| 257 | result.nChannels = 1; |
| 258 | } |
| 259 | |
| 260 | result.channelNames.resize(result.nChannels); |
| 261 | payload >> result.channelNames; |
| 262 | |
| 263 | result.channelOffsets.resize(result.nChannels); |
| 264 | result.channelStrides.resize(result.nChannels, 1); |
| 265 | |
| 266 | payload >> result.x >> result.y >> result.width >> result.height; |
| 267 | const size_t nPixels = (size_t)result.width * result.height; |
| 268 | |
| 269 | if (type >= EType::UpdateImageV3) { |
| 270 | // custom offset/stride support |
| 271 | payload >> result.channelOffsets; |
| 272 | payload >> result.channelStrides; |
| 273 | } else { |
| 274 | for (int32_t i = 0; i < result.nChannels; ++i) { |
| 275 | result.channelOffsets[i] = nPixels * i; |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | result.imageData.resize(result.nChannels); |
| 280 | for (int32_t i = 0; i < result.nChannels; ++i) { |
| 281 | result.imageData[i].resize(nPixels); |
| 282 | } |
| 283 | |
| 284 | size_t stridedImageDataSize = 0; |
| 285 | for (int32_t c = 0; c < result.nChannels; ++c) { |
| 286 | stridedImageDataSize = max(stridedImageDataSize, (size_t)(result.channelOffsets[c] + (nPixels - 1) * result.channelStrides[c] + 1)); |
| 287 | } |
| 288 | |
| 289 | if (payload.remainingBytes() < stridedImageDataSize * sizeof(float)) { |
| 290 | throw runtime_error{"UpdateImage: insufficient image data."}; |
| 291 | } |
| 292 | |
| 293 | const float* stridedImageData = (const float*)payload.get(); |
| 294 | ThreadPool::global() |
| 295 | .parallelFor( |
| 296 | 0uz, |
| 297 | nPixels, |
no test coverage detected