From d29705ad1a2472ec6f1689970ea49167fbffbe23 Mon Sep 17 00:00:00 2001 From: Andrew Osmond Date: Fri, 20 Sep 2019 19:15:04 +0000 Subject: [PATCH] Bug 1551088 - Part 2. Add unpack methods to convert from RGB to RGBX/BGRX. r=lsalzman Some image decoders (e.g. PNG) may have a native representation of the data as RGB, and do not have accelerated methods to transform from RGB to RGBX/BGRX. Exposing this as part of the swizzle/premultiply methods allows us to write accelerated versions ourselves in a later patch in this series. Differential Revision: https://phabricator.services.mozilla.com/D46445 --HG-- extra : moz-landing-system : lando --- gfx/2d/Swizzle.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/gfx/2d/Swizzle.cpp b/gfx/2d/Swizzle.cpp index df51da2d1a22..0267216c1038 100644 --- a/gfx/2d/Swizzle.cpp +++ b/gfx/2d/Swizzle.cpp @@ -858,6 +858,31 @@ static void PackToA8(const uint8_t* aSrc, int32_t aSrcGap, uint8_t* aDst, PACK_ALPHA_CASE(SurfaceFormat::R8G8B8A8, aDstFormat, aPackFunc) \ PACK_ALPHA_CASE(SurfaceFormat::A8R8G8B8, aDstFormat, aPackFunc) +template +static void UnpackRowRGB24ToRGBA(const uint8_t* aSrc, uint8_t* aDst, int32_t aLength) { + // Because we are expanding, we can only process the data back to front in + // case we are performing this in place. + const uint8_t* src = aSrc + 3 * (aLength - 1); + uint8_t* dst = aDst + 4 * (aLength - 1); + while (src >= aSrc) { + uint8_t r = src[aSwapRB ? 2 : 0]; + uint8_t g = src[1]; + uint8_t b = src[aSwapRB ? 0 : 2]; + + dst[0] = r; + dst[1] = g; + dst[2] = b; + dst[3] = 0xFF; + + src -= 3; + dst -= 4; + } +} + +#define UNPACK_ROW_RGB(aDstFormat) \ + FORMAT_CASE_ROW(SurfaceFormat::R8G8B8, aDstFormat, \ + UnpackRowRGB24ToRGBA) + bool SwizzleData(const uint8_t* aSrc, int32_t aSrcStride, SurfaceFormat aSrcFormat, uint8_t* aDst, int32_t aDstStride, SurfaceFormat aDstFormat, const IntSize& aSize) { @@ -1007,6 +1032,11 @@ SwizzleRowFn SwizzleRow(SurfaceFormat aSrcFormat, SurfaceFormat aDstFormat) { SWIZZLE_ROW_OPAQUE(SurfaceFormat::R8G8B8A8, SurfaceFormat::R8G8B8X8) SWIZZLE_ROW_OPAQUE(SurfaceFormat::R8G8B8X8, SurfaceFormat::R8G8B8A8) + UNPACK_ROW_RGB(SurfaceFormat::R8G8B8X8) + UNPACK_ROW_RGB(SurfaceFormat::R8G8B8A8) + UNPACK_ROW_RGB(SurfaceFormat::B8G8R8X8) + UNPACK_ROW_RGB(SurfaceFormat::B8G8R8A8) + default: break; }