void BgrToGray(const uint8_t *bgr, size_t width, size_t height, size_t bgrStride, uint8_t *gray, size_t grayStride) { for(size_t row = 0; row < height; ++row) { const uint8_t * pBgr = bgr + row*bgrStride; uint8_t * pGray = gray + row*grayStride; for(const uint8_t *pGrayEnd = pGray + width; pGray < pGrayEnd; pGray += 1, pBgr += 3) { *pGray = BgrToGray(pBgr[0], pBgr[1], pBgr[2]); } } }
template <class A> SIMD_INLINE void Convert(const Frame<A> & src, Frame<A> & dst) { assert(EqualSize(src, dst) && src.format && dst.format); if (src.format == dst.format) { Copy(src, dst); return; } switch (src.format) { case Frame<A>::Nv12: switch (dst.format) { case Frame<A>::Yuv420p: Copy(src.planes[0], dst.planes[0]); DeinterleaveUv(src.planes[1], dst.planes[1], dst.planes[2]); break; case Frame<A>::Bgra32: { View<A> u(src.Size(), View<A>::Gray8), v(src.Size(), View<A>::Gray8); DeinterleaveUv(src.planes[1], u, v); Yuv420pToBgra(src.planes[0], u, v, dst.planes[0]); break; } case Frame<A>::Bgr24: { View<A> u(src.Size(), View<A>::Gray8), v(src.Size(), View<A>::Gray8); DeinterleaveUv(src.planes[1], u, v); Yuv420pToBgr(src.planes[0], u, v, dst.planes[0]); break; } case Frame<A>::Gray8: Copy(src.planes[0], dst.planes[0]); break; default: assert(0); } break; case Frame<A>::Yuv420p: switch (dst.format) { case Frame<A>::Nv12: Copy(src.planes[0], dst.planes[0]); InterleaveUv(src.planes[1], src.planes[2], dst.planes[1]); break; case Frame<A>::Bgra32: Yuv420pToBgra(src.planes[0], src.planes[1], src.planes[2], dst.planes[0]); break; case Frame<A>::Bgr24: Yuv420pToBgr(src.planes[0], src.planes[1], src.planes[2], dst.planes[0]); break; case Frame<A>::Gray8: Copy(src.planes[0], dst.planes[0]); break; default: assert(0); } break; case Frame<A>::Bgra32: switch (dst.format) { case Frame<A>::Nv12: { View<A> u(src.Size(), View<A>::Gray8), v(src.Size(), View<A>::Gray8); BgraToYuv420p(src.planes[0], dst.planes[0], u, v); InterleaveUv(u, v, dst.planes[1]); break; } case Frame<A>::Yuv420p: BgraToYuv420p(src.planes[0], dst.planes[0], dst.planes[1], dst.planes[2]); break; case Frame<A>::Bgr24: BgraToBgr(src.planes[0], dst.planes[0]); break; case Frame<A>::Gray8: BgraToGray(src.planes[0], dst.planes[0]); break; default: assert(0); } break; case Frame<A>::Bgr24: switch (dst.format) { case Frame<A>::Nv12: { View<A> u(src.Size(), View<A>::Gray8), v(src.Size(), View<A>::Gray8); BgrToYuv420p(src.planes[0], dst.planes[0], u, v); InterleaveUv(u, v, dst.planes[1]); break; } case Frame<A>::Yuv420p: BgrToYuv420p(src.planes[0], dst.planes[0], dst.planes[1], dst.planes[2]); break; case Frame<A>::Bgra32: BgrToBgra(src.planes[0], dst.planes[0]); break; case Frame<A>::Gray8: BgrToGray(src.planes[0], dst.planes[0]); break; default: assert(0); } break; case Frame<A>::Gray8: switch (dst.format) { case Frame<A>::Nv12: Copy(src.planes[0], dst.planes[0]); Fill(dst.planes[1], 128); case Frame<A>::Yuv420p: Copy(src.planes[0], dst.planes[0]); Fill(dst.planes[1], 128); Fill(dst.planes[2], 128); break; case Frame<A>::Bgra32: GrayToBgra(src.planes[0], dst.planes[0]); break; case Frame<A>::Bgr24: GrayToBgr(src.planes[0], dst.planes[0]); break; default: assert(0); } break; default: assert(0); } }
SIMD_INLINE uint8x8_t BgraToGray(uint8x8x4_t bgra) { return vmovn_u16(BgrToGray(vmovl_u8(bgra.val[0]), vmovl_u8(bgra.val[1]), vmovl_u8(bgra.val[2]))); }