template <bool align> void BgrToBgra(const uint8_t * bgr, size_t width, size_t height, size_t bgrStride, uint8_t * bgra, size_t bgraStride, uint8_t alpha) { assert(width >= A); if(align) assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(bgr) && Aligned(bgrStride)); size_t alignedWidth = AlignLo(width, A); if(width == alignedWidth) alignedWidth -= A; const v128_u8 _alpha = SetU8(alpha); for(size_t row = 0; row < height; ++row) { Loader<align> _bgr(bgr); Storer<align> _bgra(bgra); BgrToBgra<align, true>(_bgr, _alpha, _bgra); for(size_t col = A; col < alignedWidth; col += A) BgrToBgra<align, false>(_bgr, _alpha, _bgra); Flush(_bgra); if(width != alignedWidth) { Loader<false> _bgr(bgr + 3*(width - A)); Storer<false> _bgra(bgra + 4*(width - A)); BgrToBgra<false, true>(_bgr, _alpha, _bgra); Flush(_bgra); } bgra += bgraStride; bgr += bgrStride; } }
template <bool align> void Bgr48pToBgra32(const uint8_t * blue, size_t blueStride, size_t width, size_t height, const uint8_t * green, size_t greenStride, const uint8_t * red, size_t redStride, uint8_t * bgra, size_t bgraStride, uint8_t alpha) { assert(width >= HA); if(align) { assert(Aligned(blue) && Aligned(blueStride)); assert(Aligned(green) && Aligned(greenStride)); assert(Aligned(red) && Aligned(redStride)); assert(Aligned(bgra) && Aligned(bgraStride)); } v128_u8 _alpha = SetU8(alpha); size_t alignedWidth = AlignLo(width, HA); for(size_t row = 0; row < height; ++row) { Storer<align> _bgra(bgra); Bgr48pToBgra32<align, true>(blue, green, red, 0, _alpha, _bgra); for(size_t col = HA; col < alignedWidth; col += HA) Bgr48pToBgra32<align, false>(blue, green, red, col*2, _alpha, _bgra); Flush(_bgra); if(width != alignedWidth) { Storer<false> _bgra(bgra + (width - HA)*4); Bgr48pToBgra32<false, true>(blue, green, red, (width - HA)*2, _alpha, _bgra); Flush(_bgra); } blue += blueStride; green += greenStride; red += redStride; bgra += bgraStride; } }
void BgraToBayer(const uint8_t * bgra, size_t width, size_t height, size_t bgraStride, uint8_t * bayer, size_t bayerStride) { assert(width >= A); if(align) assert(Aligned(bgra) && Aligned(bgraStride) && Aligned(bayer) && Aligned(bayerStride)); size_t alignedWidth = AlignLo(width, A); const v128_u8 perm[4][2] = { {K8_PERM_GR, K8_PERM_BG}, {K8_PERM_GB, K8_PERM_RG}, {K8_PERM_RG, K8_PERM_GB}, {K8_PERM_BG, K8_PERM_GR} }; for(size_t row = 0; row < height; row += 2) { Loader<align> _bgra0(bgra); Storer<align> _bayer0(bayer); BgraToBayer<format, 0, align, true>(_bgra0, perm, _bayer0); for(size_t col = A; col < alignedWidth; col += A) BgraToBayer<format, 0, align, false>(_bgra0, perm, _bayer0); Flush(_bayer0); if(width != alignedWidth) { Loader<false> _bgra(bgra + 4*(width - A)); Storer<false> _bayer(bayer + width - A); BgraToBayer<format, 0, false, true>(_bgra, perm, _bayer); Flush(_bayer); } bgra += bgraStride; bayer += bayerStride; Loader<align> _bgra1(bgra); Storer<align> _bayer1(bayer); BgraToBayer<format, 1, align, true>(_bgra1, perm, _bayer1); for(size_t col = A; col < alignedWidth; col += A) BgraToBayer<format, 1, align, false>(_bgra1, perm, _bayer1); Flush(_bayer1); if(width != alignedWidth) { Loader<false> _bgra(bgra + 4*(width - A)); Storer<false> _bayer(bayer + width - A); BgraToBayer<format, 1, false, true>(_bgra, perm, _bayer); Flush(_bayer); } bgra += bgraStride; bayer += bayerStride; } }