Add RGB, BGR to WP2ConversionFunction()
Change-Id: I9a0d08ff081c58cd7438864e29bfff914ce2d37d
Reviewed-on: https://chromium-review.googlesource.com/c/codecs/libwebp2/+/5756494
Reviewed-by: Maryla Ustarroz-Calonge <maryla@google.com>
Tested-by: WebM Builds <builds@webmproject.org>
diff --git a/src/dsp/argb_converter.cc b/src/dsp/argb_converter.cc
index 48df546..d48cbd2 100644
--- a/src/dsp/argb_converter.cc
+++ b/src/dsp/argb_converter.cc
@@ -413,14 +413,18 @@
}
//------------------------------------------------------------------------------
-// Combinations (32-bit to 32-bit only)
+// Combinations
namespace {
template <int from, int to>
void WP2ConvertFromTo(const void* src, uint32_t width, void* dst) {
- static_assert(from > WP2_ARGB_32 && from <= WP2_BGRX_32, "Unimplemented");
- static_assert(to > WP2_ARGB_32 && to <= WP2_BGRX_32, "Unimplemented");
+ static_assert(from > WP2_ARGB_32 && from <= WP2_BGR_24, "Unimplemented");
+ static_assert(to > WP2_ARGB_32 && to <= WP2_BGR_24, "Unimplemented");
+ const size_t src_bytes_per_pixel =
+ WP2FormatBpp(static_cast<WP2SampleFormat>(from));
+ const size_t dst_bytes_per_pixel =
+ WP2FormatBpp(static_cast<WP2SampleFormat>(to));
// Use a temporary layout Argb or ARGB to go from SRC to DST.
// Do not premultiply or unmultiply unless necessary.
@@ -435,8 +439,9 @@
WP2ARGBConvertFrom[from](src, num_pixels, tmp);
WP2ARGBConvertTo[to](tmp, num_pixels, dst);
}
- src = reinterpret_cast<const uint8_t*>(src) + num_pixels * 4;
- dst = reinterpret_cast<uint8_t*>(dst) + num_pixels * 4;
+ src = reinterpret_cast<const uint8_t*>(src) +
+ num_pixels * src_bytes_per_pixel;
+ dst = reinterpret_cast<uint8_t*>(dst) + num_pixels * dst_bytes_per_pixel;
width -= num_pixels;
}
}
@@ -450,6 +455,8 @@
if (to == WP2_bgrA_32) return WP2ConvertFromTo<from, WP2_bgrA_32>;
if (to == WP2_BGRA_32) return WP2ConvertFromTo<from, WP2_BGRA_32>;
if (to == WP2_BGRX_32) return WP2ConvertFromTo<from, WP2_BGRX_32>;
+ if (to == WP2_RGB_24) return WP2ConvertFromTo<from, WP2_RGB_24>;
+ if (to == WP2_BGR_24) return WP2ConvertFromTo<from, WP2_BGR_24>;
return nullptr;
}
@@ -476,6 +483,8 @@
if (from == WP2_bgrA_32) return WP2ConvertFromToFunc<WP2_bgrA_32>(to);
if (from == WP2_BGRA_32) return WP2ConvertFromToFunc<WP2_BGRA_32>(to);
if (from == WP2_BGRX_32) return WP2ConvertFromToFunc<WP2_BGRX_32>(to);
+ if (from == WP2_RGB_24) return WP2ConvertFromToFunc<WP2_RGB_24>(to);
+ if (from == WP2_BGR_24) return WP2ConvertFromToFunc<WP2_BGR_24>(to);
return nullptr;
}
diff --git a/tests/test_conversion.cc b/tests/test_conversion.cc
index 5c9a88d..8aa55e3 100644
--- a/tests/test_conversion.cc
+++ b/tests/test_conversion.cc
@@ -28,7 +28,8 @@
for (WP2SampleFormat from :
{WP2_Argb_32, WP2_ARGB_32, WP2_XRGB_32, WP2_rgbA_32, WP2_RGBA_32,
- WP2_RGBX_32, WP2_bgrA_32, WP2_BGRA_32, WP2_BGRX_32}) {
+ WP2_RGBX_32, WP2_bgrA_32, WP2_BGRA_32, WP2_BGRX_32, WP2_RGB_24,
+ WP2_BGR_24}) {
ArgbBuffer src(from);
ASSERT_WP2_OK(src.Resize(1, 1));
ArgbBuffer roundtrip(from);
@@ -36,7 +37,8 @@
for (WP2SampleFormat to :
{WP2_Argb_32, WP2_ARGB_32, WP2_XRGB_32, WP2_rgbA_32, WP2_RGBA_32,
- WP2_RGBX_32, WP2_bgrA_32, WP2_BGRA_32, WP2_BGRX_32}) {
+ WP2_RGBX_32, WP2_bgrA_32, WP2_BGRA_32, WP2_BGRX_32, WP2_RGB_24,
+ WP2_BGR_24}) {
uint8_t values[] = {123, 61, 200, 211}; // Arbitrary.
uint32_t alpha_channel_index;
@@ -50,11 +52,11 @@
uint8_t* max_element = std::max_element(values, values + 4);
std::swap(*max_element, values[alpha_channel_index]);
}
- } else {
+ } else if (alpha_channel_index < WP2FormatBpp(from)) {
values[alpha_channel_index] = 255;
}
- std::copy(values, values + 4, src.GetRow8(0));
+ std::copy(values, values + WP2FormatBpp(from), src.GetRow8(0));
ArgbBuffer dst(to);
ASSERT_WP2_OK(dst.ConvertFrom(src));
@@ -62,7 +64,7 @@
const int tolerance =
WP2IsPremultiplied(from) == WP2IsPremultiplied(to) ? 0 : 1;
- for (int i = 0; i < 4; ++i) {
+ for (uint32_t i = 0; i < WP2FormatBpp(from); ++i) {
ASSERT_NEAR(roundtrip.GetRow8(0)[i], values[i], tolerance)
<< " (channel " << i << ") from " << from << " to " << to << " ("
<< static_cast<int>(dst.GetRow8(0)[i]) << ")";
diff --git a/tests/test_formats.cc b/tests/test_formats.cc
index fd52008..0105c44 100644
--- a/tests/test_formats.cc
+++ b/tests/test_formats.cc
@@ -389,6 +389,8 @@
{WP2_bgrA_32, "WP2_bgrA_32", 274353, true},
{WP2_BGRA_32, "WP2_BGRA_32", 897534, true},
{WP2_BGRX_32, "WP2_BGRX_32", 414125, false},
+ {WP2_RGB_24, "WP2_RGB_24", 414125, false},
+ {WP2_BGR_24, "WP2_BGR_24", 414125, false},
};
typedef std::tuple<FmtTestCase, testutil::WP2CPUInfoStruct> SpeedTestParam;
diff --git a/tests/test_imageio_conversion.cc b/tests/test_imageio_conversion.cc
index 18b1f04..d7a5320 100644
--- a/tests/test_imageio_conversion.cc
+++ b/tests/test_imageio_conversion.cc
@@ -79,7 +79,7 @@
Param{"source3.jpg", "ccsp/source3_C444p8.y4m", 50.f},
Param{"source3.jpg", "ccsp/source3_C444p10.y4m", 55.f},
Param{"source3.jpg", "ccsp/source3_C444p12.y4m", 59.f},
- // Downsampling loss outweights more precision bits.
+ // Downsampling loss outweighs more precision bits.
Param{"source3.jpg", "ccsp/source3_C420p8.y4m", 35.f},
Param{"source3.jpg", "ccsp/source3_C420p10.y4m", 35.f},
Param{"source3.jpg", "ccsp/source3_C420p12.y4m", 35.f}));
@@ -269,14 +269,13 @@
}
TEST(ReadImageTest, ChannelOrder) {
- // WP2ConversionFunction() only returns conversion functions for all formats
- // from and to WP2_ARGB_32 or WP2_Argb_32 and between 32-bit formats. It also
- // supports plain copy, and ImageReaderPNG reads PNG samples in RGB(A) order.
+ // ImageReaderPNG reads PNG samples in RGB(A) order.
// Opaque
EXPECT_WP2_OK(TestChannelOrder("taiwan.png", WP2_ARGB_32));
EXPECT_WP2_OK(TestChannelOrder("taiwan.png", WP2_Argb_32));
EXPECT_WP2_OK(TestChannelOrder("taiwan.png", WP2_RGB_24));
+ EXPECT_WP2_OK(TestChannelOrder("taiwan.png", WP2_BGR_24));
// Alpha
EXPECT_WP2_OK(TestChannelOrder("source1.png", WP2_ARGB_32));
@@ -284,25 +283,16 @@
EXPECT_WP2_OK(TestChannelOrder("source1.png", WP2_BGRA_32));
// RGBA -> premultiplied/opaque Argb -> ARGB implies quality loss.
- for (WP2SampleFormat format : {WP2_Argb_32, WP2_rgbA_32, WP2_bgrA_32,
- WP2_XRGB_32, WP2_RGBX_32, WP2_BGRX_32}) {
+ for (WP2SampleFormat format :
+ {WP2_Argb_32, WP2_rgbA_32, WP2_bgrA_32, WP2_XRGB_32, WP2_RGBX_32,
+ WP2_BGRX_32, WP2_RGB_24, WP2_BGR_24}) {
EXPECT_EQ(TestChannelOrder("source1.png", format),
WP2_STATUS_INVALID_PARAMETER);
}
- // 24-bit to something else except WP2_Argb_32 and WP2_ARGB_32 is unsupported.
- for (WP2SampleFormat format :
- {WP2_RGBA_32, WP2_RGBX_32, WP2_bgrA_32, WP2_BGRA_32, WP2_BGRX_32,
- WP2_BGR_24, WP2_Argb_38}) {
- EXPECT_EQ(TestChannelOrder("taiwan.png", format),
- WP2_STATUS_INVALID_COLORSPACE);
- }
-
- // Expect all other combinations to fail.
- for (WP2SampleFormat format : {WP2_RGB_24, WP2_BGR_24, WP2_Argb_38}) {
- EXPECT_EQ(TestChannelOrder("source1.png", format),
- WP2_STATUS_INVALID_COLORSPACE);
- }
+ // 10-bit is unsupported.
+ EXPECT_EQ(TestChannelOrder("source1.png", WP2_Argb_38),
+ WP2_STATUS_INVALID_COLORSPACE);
}
//------------------------------------------------------------------------------