| 320 | } |
| 321 | |
| 322 | void Image::ReadPixels(const Offset3D& offset, const Extent3D& extent, const DstImageDescriptor& imageDesc, std::size_t threadCount) const |
| 323 | { |
| 324 | if (imageDesc.data && IsRegionInside(offset, extent)) |
| 325 | { |
| 326 | /* Validate required size */ |
| 327 | ValidateImageDataSize(extent, imageDesc); |
| 328 | |
| 329 | /* Get source image parameters */ |
| 330 | const auto bpp = GetBytesPerPixel(); |
| 331 | const auto srcRowStride = bpp * GetExtent().width; |
| 332 | const auto srcDepthStride = srcRowStride * GetExtent().height; |
| 333 | auto src = data_.get() + GetDataPtrOffset(offset); |
| 334 | |
| 335 | if (GetFormat() == imageDesc.format && GetDataType() == imageDesc.dataType) |
| 336 | { |
| 337 | /* Get destination image parameters */ |
| 338 | const auto dstRowStride = bpp * extent.width; |
| 339 | const auto dstDepthStride = dstRowStride * extent.height; |
| 340 | auto dst = reinterpret_cast<char*>(imageDesc.data); |
| 341 | |
| 342 | /* Blit region into destination image */ |
| 343 | BitBlit( |
| 344 | extent, bpp, |
| 345 | dst, dstRowStride, dstDepthStride, |
| 346 | src, srcRowStride, srcDepthStride |
| 347 | ); |
| 348 | } |
| 349 | else |
| 350 | { |
| 351 | /* Copy region into temporary sub-image */ |
| 352 | Image subImage { extent, GetFormat(), GetDataType() }; |
| 353 | |
| 354 | BitBlit( |
| 355 | extent, bpp, |
| 356 | reinterpret_cast<char*>(subImage.GetData()), subImage.GetRowStride(), subImage.GetDepthStride(), |
| 357 | src, srcRowStride, srcDepthStride |
| 358 | ); |
| 359 | |
| 360 | /* Convert sub-image */ |
| 361 | subImage.Convert(imageDesc.format, imageDesc.dataType, threadCount); |
| 362 | |
| 363 | /* Copy sub-image into output data */ |
| 364 | ::memcpy(imageDesc.data, subImage.GetData(), imageDesc.dataSize); |
| 365 | } |
| 366 | } |
| 367 | } |
| 368 | |
| 369 | void Image::WritePixels(const Offset3D& offset, const Extent3D& extent, const SrcImageDescriptor& imageDesc, std::size_t threadCount) |
| 370 | { |