0

[rust png] Use SkPngRustCodec from //ui/gfx/codec (feature/GN-gated).

This CL starts using `SkPngRustCodec` (added to Skia in
http://review.skia.org/884236) from `//ui/gfx/codec/png_codec.cc`.

Build config
============

Building Rust-PNG-related code is disabled by default using the new GN
arg added in this CL: `enable_rust_png`.  In the short-term this flag
will only be enabled on Rust FYI bots and by engineers working on the
Rust PNG project.

Runtime config
==============

When `enable_rust_png` GN arg is true, then the Rust-PNG-related code
will be built, but it is also controlled by a newly introduced
`base::Feature` at runtime, and by default won't run.

Test coverage
=============

This CL tweaks `//ui/gfx/codec/png_codec_unittest.cc` to use that
feature so that (if `enable_rust_png` is true) they cover all the PNG
tests not only in the default mode (using `SkPngCodec`) but also in
`RustEnabled` mode (using `SkPngRustCodec`).  This CL tweaks the config
of Rust FYI bots to provide CI coverage via `gfx_unittests` (FYI-only,
no impact on CQ).

Fixed: 356874896
Change-Id: I60bcb0827aeb2231368a47c8d240e9ec3b9a5e45
Cq-Include-Trybots: chromium/try:android-rust-arm32-rel
Cq-Include-Trybots: chromium/try:android-rust-arm64-dbg
Cq-Include-Trybots: chromium/try:android-rust-arm64-rel
Cq-Include-Trybots: chromium/try:linux-rust-x64-dbg
Cq-Include-Trybots: chromium/try:linux-rust-x64-rel
Cq-Include-Trybots: chromium/try:win-rust-x64-dbg
Cq-Include-Trybots: chromium/try:win-rust-x64-rel
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5747366
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Adrian Taylor <adetaylor@chromium.org>
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Kaylee Lubick <kjlubick@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1351122}
This commit is contained in:
Lukasz Anforowicz
2024-09-04 23:46:49 +00:00
committed by Chromium LUCI CQ
parent 8fbd28a5ea
commit 19bd16fc56
11 changed files with 321 additions and 30 deletions

@ -118,6 +118,13 @@ declare_args() {
# Rust gtest interop.
enable_rust_gtest_interop = enable_rust
# WIP attempt to replace `libpng` with Rust `png` crate.
#
# TODO(https://crbug.com/360375227): Remove the `enable_all_rust_features`
# condition below (only true on Rust bots) once/if ready to start A/B
# experiments.
enable_rust_png = enable_rust && enable_all_rust_features
}
# Use the Rust toolchain built in-tree. When false, we use the prebuilt Rust

@ -4901,6 +4901,7 @@
'rust_common_gtests': {
'base_unittests': {},
'gfx_unittests': {},
'mojo_rust_integration_unittests': {},
'mojo_rust_unittests': {},
'rust_gtest_interop_unittests': {},

@ -4568,6 +4568,9 @@ targets.legacy_basic_suite(
name = "rust_common_gtests",
tests = {
"base_unittests": targets.legacy_test_config(),
# TODO(https://crbug.com/356914314): Remove `gfx_unittests` if/when
# Rust PNG is covered by the main waterfall/CQ bots.
"gfx_unittests": targets.legacy_test_config(),
"mojo_rust_integration_unittests": targets.legacy_test_config(),
"mojo_rust_unittests": targets.legacy_test_config(),
"rust_gtest_interop_unittests": targets.legacy_test_config(),

@ -21,16 +21,32 @@ if (current_cpu == "arm") {
if (current_cpu == "mipsel" || current_cpu == "mips64el") {
import("//build/config/mips.gni")
}
if (enable_rust_png) {
import("//build/rust/rust_static_library.gni")
}
buildflag_header("buildflags") {
header = "buildflags.h"
flags = [
"SKIA_BUILD_RUST_PNG=$enable_rust_png",
"SKIA_SUPPORT_SKOTTIE=$skia_support_skottie",
"SKIA_USE_DAWN=$skia_use_dawn",
"SKIA_USE_METAL=$skia_use_metal",
]
}
component("rusty_png_feature_detection") {
defines = [ "IS_SKIA_RUSTY_PNG_FEATURE_DETECTION_IMPL" ]
sources = [
"rusty_png_feature.cc",
"rusty_png_feature.h",
]
public_deps = [
":buildflags",
"//base",
]
}
source_set("path_bridge") {
sources = skia_fontations_path_bridge_sources
}
@ -593,6 +609,12 @@ component("skia") {
"SKOTTIE_TRIVIAL_FONTRUN_ITER",
]
}
if (enable_rust_png) {
deps += [ ":rust_png_ffi" ]
public += skia_codec_rust_png_public
sources += skia_codec_rust_png
}
}
component("skia_switches") {
@ -607,6 +629,33 @@ component("skia_switches") {
deps = [ "//base" ]
}
if (enable_rust_png) {
rust_static_library("rust_png_ffi") {
visibility = [ ":*" ]
allow_unsafe = true # For FFI
crate_root = skia_codec_rust_png_ffi_crate_root
sources = skia_codec_rust_png_ffi_rs_srcs
cxx_bindings = skia_codec_rust_png_ffi_cxx_bridge_srcs
public_deps = [ ":rust_png_ffi_cpp" ]
deps = [ "//third_party/rust/png/v0_17:lib" ]
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
":skia_config",
":skia_library_config",
]
}
source_set("rust_png_ffi_cpp") {
visibility = [ ":*" ]
public = skia_codec_rust_png_ffi_cpp_hdrs
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
":skia_config",
":skia_library_config",
]
}
}
# Template for things that are logically part of :skia, but need to be split out
# so custom compile flags can be applied.
#

13
skia/rusty_png_feature.cc Normal file

@ -0,0 +1,13 @@
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "skia/rusty_png_feature.h"
#include "base/feature_list.h"
namespace skia {
BASE_FEATURE(kRustyPngFeature, "RustyPng", base::FEATURE_DISABLED_BY_DEFAULT);
} // namespace skia

36
skia/rusty_png_feature.h Normal file

@ -0,0 +1,36 @@
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_RUSTY_PNG_FEATURE_H_
#define SKIA_RUSTY_PNG_FEATURE_H_
#include "base/component_export.h"
#include "base/feature_list.h"
#include "skia/buildflags.h"
namespace skia {
// Exposing the feature so that tests can inspect it and turn it on/off,
// but product code should instead use `IsRustyPngEnabled`.
COMPONENT_EXPORT(SKIA_RUSTY_PNG_FEATURE_DETECTION)
BASE_DECLARE_FEATURE(kRustyPngFeature);
// Returns true if Rust should be used for PNG decoding:
// 1) the GN-level `enable_rust_png` is true.
// *and*
// 2) the `"RustyPng"` base::Feature has been enabled.
//
// See also https://crbug.com/40278281 and the "Rollout plan" in
// https://docs.google.com/document/d/1glx5ue5JDlCld5WzWgTOGK3wsMErQFnkY5N5Dsbi91Y
inline bool IsRustyPngEnabled() {
#if BUILDFLAG(SKIA_BUILD_RUST_PNG)
return base::FeatureList::IsEnabled(kRustyPngFeature);
#else
return false;
#endif
}
} // namespace skia
#endif // SKIA_RUSTY_PNG_FEATURE_H_

@ -24,6 +24,23 @@
"test": "base_unittests",
"test_id_prefix": "ninja://base:base_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"name": "gfx_unittests",
"swarming": {
"dimensions": {
"device_os": "PQ3A.190801.002",
"device_os_flavor": "google",
"device_type": "walleye",
"os": "Android"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test": "gfx_unittests",
"test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
@ -134,6 +151,23 @@
"test": "base_unittests",
"test_id_prefix": "ninja://base:base_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"name": "gfx_unittests",
"swarming": {
"dimensions": {
"device_os": "PQ3A.190801.002",
"device_os_flavor": "google",
"device_type": "walleye",
"os": "Android"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test": "gfx_unittests",
"test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
@ -244,6 +278,23 @@
"test": "base_unittests",
"test_id_prefix": "ninja://base:base_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"name": "gfx_unittests",
"swarming": {
"dimensions": {
"device_os": "PQ3A.190801.002",
"device_os_flavor": "google",
"device_type": "walleye",
"os": "Android"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test": "gfx_unittests",
"test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
@ -353,6 +404,20 @@
"test": "base_unittests",
"test_id_prefix": "ninja://base:base_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"name": "gfx_unittests",
"swarming": {
"dimensions": {
"os": "Ubuntu-22.04"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test": "gfx_unittests",
"test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
@ -463,6 +528,20 @@
"test": "base_unittests",
"test_id_prefix": "ninja://base:base_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"name": "gfx_unittests",
"swarming": {
"dimensions": {
"os": "Ubuntu-22.04"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test": "gfx_unittests",
"test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
@ -574,6 +653,21 @@
"test": "base_unittests",
"test_id_prefix": "ninja://base:base_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"name": "gfx_unittests",
"swarming": {
"dimensions": {
"cpu": "x86-64",
"os": "Mac-14"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test": "gfx_unittests",
"test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
@ -691,6 +785,21 @@
"test": "base_unittests",
"test_id_prefix": "ninja://base:base_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"name": "gfx_unittests",
"swarming": {
"dimensions": {
"cpu": "x86-64",
"os": "Windows-10"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test": "gfx_unittests",
"test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
@ -808,6 +917,21 @@
"test": "base_unittests",
"test_id_prefix": "ninja://base:base_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"name": "gfx_unittests",
"swarming": {
"dimensions": {
"cpu": "x86-64",
"os": "Windows-10"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test": "gfx_unittests",
"test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
},
{
"merge": {
"script": "//testing/merge_scripts/standard_gtest_merge.py"

@ -898,6 +898,7 @@ test("gfx_unittests") {
"//base/test:test_support",
"//build:chromeos_buildflags",
"//skia",
"//skia:rusty_png_feature_detection",
"//skia:skcms",
"//testing/gtest",
"//third_party/icu:icuuc",

@ -22,6 +22,7 @@ component("codec") {
deps = [
"//base",
"//skia",
"//skia:rusty_png_feature_detection",
"//third_party/zlib",
"//ui/gfx:gfx_export",
"//ui/gfx:gfx_skia",

@ -10,6 +10,8 @@
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/strings/string_util.h"
#include "skia/buildflags.h"
#include "skia/rusty_png_feature.h"
#include "third_party/skia/include/codec/SkPngDecoder.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColorPriv.h"
@ -19,20 +21,40 @@
#include "ui/gfx/codec/vector_wstream.h"
#include "ui/gfx/geometry/size.h"
#if BUILDFLAG(SKIA_BUILD_RUST_PNG)
#include "third_party/skia/experimental/rust_png/SkPngRustDecoder.h"
#endif
namespace gfx {
// Decoder --------------------------------------------------------------------
static bool PrepareForPNGDecode(const unsigned char* input,
size_t input_size,
PNGCodec::ColorFormat format,
std::unique_ptr<SkCodec>* codec,
SkImageInfo* image_info) {
namespace {
std::unique_ptr<SkCodec> CreatePngDecoder(std::unique_ptr<SkStream> stream,
SkCodec::Result* result) {
if (skia::IsRustyPngEnabled()) {
#if BUILDFLAG(SKIA_BUILD_RUST_PNG)
return SkPngRustDecoder::Decode(std::move(stream), result);
#else
// The `if` condition guarantees `SKIA_BUILD_RUST_PNG`.
NOTREACHED_NORETURN();
#endif
}
return SkPngDecoder::Decode(std::move(stream), result);
}
bool PrepareForPNGDecode(const unsigned char* input,
size_t input_size,
PNGCodec::ColorFormat format,
std::unique_ptr<SkCodec>* codec,
SkImageInfo* image_info) {
// Parse the input stream with the PNG decoder, yielding a SkCodec.
auto stream = std::make_unique<SkMemoryStream>(input, input_size,
/*copyData=*/false);
SkCodec::Result result;
*codec = SkPngDecoder::Decode(std::move(stream), &result);
*codec = CreatePngDecoder(std::move(stream), &result);
if (!*codec || result != SkCodec::kSuccess) {
return false;
}
@ -67,6 +89,8 @@ static bool PrepareForPNGDecode(const unsigned char* input,
return image_info->dimensions().area() < (INT_MAX / kBytesPerPixel);
}
} // namespace
// static
bool PNGCodec::Decode(const unsigned char* input,
size_t input_size,

@ -19,6 +19,9 @@
#include "base/path_service.h"
#include "base/ranges/algorithm.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "skia/buildflags.h"
#include "skia/rusty_png_feature.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/libpng/png.h"
#include "third_party/skia/include/core/SkBitmap.h"
@ -111,7 +114,7 @@ void MakeGrayscaleAlphaImage(int w, int h, std::vector<unsigned char>* data) {
for (int x = 0; x < w; x++) {
size_t base = (y * w + x) * 2;
(*data)[base] = x; // gray value
(*data)[base + 1] = x; // alpha
(*data)[base + 1] = y; // alpha
}
}
}
@ -396,7 +399,26 @@ void MakeTestA8SkBitmap(int w, int h, SkBitmap* bmp) {
}
}
TEST(PNGCodec, EncodeDecodeRGBA) {
enum class RustFeatureState { kRustEnabled, kRustDisabled };
class PNGCodecTest : public testing::TestWithParam<RustFeatureState> {
public:
PNGCodecTest() {
switch (GetParam()) {
case RustFeatureState::kRustEnabled:
features_.InitAndEnableFeature(skia::kRustyPngFeature);
break;
case RustFeatureState::kRustDisabled:
features_.InitAndDisableFeature(skia::kRustyPngFeature);
break;
}
}
protected:
base::test::ScopedFeatureList features_;
};
TEST_P(PNGCodecTest, EncodeDecodeRGBA) {
const int w = 20, h = 20;
// create an image with known values, a must be opaque because it will be
@ -429,7 +451,7 @@ TEST(PNGCodec, EncodeDecodeRGBA) {
ImageSpec(outw, outh, decoded, COLOR_TYPE_RGBA)));
}
TEST(PNGCodec, EncodeDecodeBGRA) {
TEST_P(PNGCodecTest, EncodeDecodeBGRA) {
const int w = 20, h = 20;
// Create an image with known values, alpha must be opaque because it will be
@ -454,7 +476,7 @@ TEST(PNGCodec, EncodeDecodeBGRA) {
ImageSpec(outw, outh, decoded, COLOR_TYPE_BGRA)));
}
TEST(PNGCodec, DecodePalette) {
TEST_P(PNGCodecTest, DecodePalette) {
const int w = 20, h = 20;
// create an image with known values
@ -481,7 +503,7 @@ TEST(PNGCodec, DecodePalette) {
ImageSpec(outw, outh, decoded, COLOR_TYPE_RGBA)));
}
TEST(PNGCodec, DecodeInterlacedPalette) {
TEST_P(PNGCodecTest, DecodeInterlacedPalette) {
const int w = 20, h = 20;
// create an image with known values
@ -507,7 +529,7 @@ TEST(PNGCodec, DecodeInterlacedPalette) {
ImageSpec(outw, outh, decoded, COLOR_TYPE_RGBA)));
}
TEST(PNGCodec, DecodeGrayscale) {
TEST_P(PNGCodecTest, DecodeGrayscale) {
const int w = 20, h = 20;
// create an image with known values
@ -528,7 +550,7 @@ TEST(PNGCodec, DecodeGrayscale) {
ImageSpec(outw, outh, decoded, COLOR_TYPE_RGBA)));
}
TEST(PNGCodec, DecodeGrayscaleWithAlpha) {
TEST_P(PNGCodecTest, DecodeGrayscaleWithAlpha) {
const int w = 20, h = 20;
// create an image with known values
@ -549,7 +571,7 @@ TEST(PNGCodec, DecodeGrayscaleWithAlpha) {
ImageSpec(outw, outh, decoded, COLOR_TYPE_RGBA)));
}
TEST(PNGCodec, DecodeInterlacedGrayscale) {
TEST_P(PNGCodecTest, DecodeInterlacedGrayscale) {
const int w = 20, h = 20;
// create an image with known values
@ -571,7 +593,7 @@ TEST(PNGCodec, DecodeInterlacedGrayscale) {
ImageSpec(outw, outh, decoded, COLOR_TYPE_RGBA)));
}
TEST(PNGCodec, DecodeInterlacedGrayscaleWithAlpha) {
TEST_P(PNGCodecTest, DecodeInterlacedGrayscaleWithAlpha) {
const int w = 20, h = 20;
// create an image with known values
@ -593,7 +615,7 @@ TEST(PNGCodec, DecodeInterlacedGrayscaleWithAlpha) {
ImageSpec(outw, outh, decoded, COLOR_TYPE_RGBA)));
}
TEST(PNGCodec, DecodeInterlacedRGBA) {
TEST_P(PNGCodecTest, DecodeInterlacedRGBA) {
const int w = 20, h = 20;
// create an image with known values
@ -615,7 +637,7 @@ TEST(PNGCodec, DecodeInterlacedRGBA) {
ImageSpec(outw, outh, decoded, COLOR_TYPE_RGBA)));
}
TEST(PNGCodec, DecodeInterlacedBGR) {
TEST_P(PNGCodecTest, DecodeInterlacedBGR) {
const int w = 20, h = 20;
// create an image with known values
@ -637,7 +659,7 @@ TEST(PNGCodec, DecodeInterlacedBGR) {
ImageSpec(outw, outh, decoded, COLOR_TYPE_BGRA)));
}
TEST(PNGCodec, DecodeInterlacedBGRA) {
TEST_P(PNGCodecTest, DecodeInterlacedBGRA) {
const int w = 20, h = 20;
// create an image with known values
@ -661,7 +683,7 @@ TEST(PNGCodec, DecodeInterlacedBGRA) {
// Not encoding an interlaced PNG from SkBitmap because we don't do it
// anywhere, and the ability to do that requires more code changes.
TEST(PNGCodec, DecodeInterlacedRGBtoSkBitmap) {
TEST_P(PNGCodecTest, DecodeInterlacedRGBtoSkBitmap) {
const int w = 20, h = 20;
// create an image with known values
@ -715,11 +737,11 @@ void DecodeInterlacedRGBAtoSkBitmap(bool use_transparency) {
decoded_bitmap));
}
TEST(PNGCodec, DecodeInterlacedRGBAtoSkBitmap_Opaque) {
TEST_P(PNGCodecTest, DecodeInterlacedRGBAtoSkBitmap_Opaque) {
DecodeInterlacedRGBAtoSkBitmap(/*use_transparency=*/false);
}
TEST(PNGCodec, DecodeInterlacedRGBAtoSkBitmap_Transparent) {
TEST_P(PNGCodecTest, DecodeInterlacedRGBAtoSkBitmap_Transparent) {
DecodeInterlacedRGBAtoSkBitmap(/*use_transparency=*/true);
}
@ -746,7 +768,7 @@ TEST(PNGCodec, EncoderSavesImagesWithAllOpaquePixelsAsOpaque) {
}
// Test that corrupted data decompression causes failures.
TEST(PNGCodec, DecodeCorrupted) {
TEST_P(PNGCodecTest, DecodeCorrupted) {
int w = 20, h = 20;
// Make some random data (an uncompressed image).
@ -815,7 +837,7 @@ TEST(PNGCodec, DecodeCorrupted) {
// up-scaling (e.g. on high DPI displays), trumping the "two halves should have
// roughly equal / different brightness" effect. You can view the images at
// https://nigeltao.github.io/blog/2022/gamma-aware-pixelated-images.html
TEST(PNGCodec, DecodeGamma) {
TEST_P(PNGCodecTest, DecodeGamma) {
base::FilePath root_dir;
ASSERT_TRUE(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &root_dir));
base::FilePath data_dir = root_dir.AppendASCII("ui")
@ -854,7 +876,7 @@ TEST(PNGCodec, DecodeGamma) {
}
}
TEST(PNGCodec, EncodeBGRASkBitmapStridePadded) {
TEST_P(PNGCodecTest, EncodeBGRASkBitmapStridePadded) {
const int kWidth = 20;
const int kHeight = 20;
const int kPaddedWidth = 32;
@ -897,7 +919,7 @@ TEST(PNGCodec, EncodeBGRASkBitmapStridePadded) {
}
}
TEST(PNGCodec, EncodeBGRASkBitmap) {
TEST_P(PNGCodecTest, EncodeBGRASkBitmap) {
const int w = 20, h = 20;
SkBitmap original_bitmap;
@ -926,7 +948,7 @@ TEST(PNGCodec, EncodeBGRASkBitmap) {
}
}
TEST(PNGCodec, EncodeA8SkBitmap) {
TEST_P(PNGCodecTest, EncodeA8SkBitmap) {
const int w = 20, h = 20;
SkBitmap original_bitmap;
@ -950,7 +972,7 @@ TEST(PNGCodec, EncodeA8SkBitmap) {
}
}
TEST(PNGCodec, EncodeBGRASkBitmapDiscardTransparency) {
TEST_P(PNGCodecTest, EncodeBGRASkBitmapDiscardTransparency) {
const int w = 20, h = 20;
SkBitmap original_bitmap;
@ -988,7 +1010,7 @@ TEST(PNGCodec, EncodeBGRASkBitmapDiscardTransparency) {
}
}
TEST(PNGCodec, EncodeWithComment) {
TEST_P(PNGCodecTest, EncodeWithComment) {
const int w = 10, h = 10;
std::vector<unsigned char> original;
@ -1017,7 +1039,7 @@ TEST(PNGCodec, EncodeWithComment) {
EXPECT_NE(base::ranges::search(encoded, kExpected3), encoded.end());
}
TEST(PNGCodec, EncodeDecodeWithVaryingCompressionLevels) {
TEST_P(PNGCodecTest, EncodeDecodeWithVaryingCompressionLevels) {
const int w = 20, h = 20;
// create an image with known values, a must be opaque because it will be
@ -1049,7 +1071,7 @@ TEST(PNGCodec, EncodeDecodeWithVaryingCompressionLevels) {
EXPECT_TRUE(BitmapsAreEqual(decoded, original_bitmap));
}
TEST(PNGCodec, DecodingTruncatedEXIFChunkIsSafe) {
TEST_P(PNGCodecTest, DecodingTruncatedEXIFChunkIsSafe) {
// Libpng 1.6.37 had a bug which caused it to read two uninitialized bytes of
// stack memory if a PNG contained an invalid EXIF chunk, when in progressive
// reading mode. This would manifest as an MSAN error (crbug.com/332475837)
@ -1081,4 +1103,14 @@ TEST(PNGCodec, DecodingTruncatedEXIFChunkIsSafe) {
EXPECT_FALSE(PNGCodec::Decode(kPNGData, sizeof(kPNGData), &bitmap));
}
#if BUILDFLAG(SKIA_BUILD_RUST_PNG)
INSTANTIATE_TEST_SUITE_P(RustEnabled,
PNGCodecTest,
::testing::Values(RustFeatureState::kRustEnabled));
#endif
INSTANTIATE_TEST_SUITE_P(RustDisabled,
PNGCodecTest,
::testing::Values(RustFeatureState::kRustDisabled));
} // namespace gfx