blob: d239f11c15d08cdc25ac6287833a48ad19518947 [file] [log] [blame]
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Test example utils.
#include <cstdint>
#include <cstring>
#include <string>
#include <tuple>
#include "imageio/image_dec.h"
#include "include/helpers.h"
#include "src/common/progress_watcher.h"
#include "src/dec/preview/preview_dec.h"
#include "src/enc/preview/preview_enc.h"
#include "src/wp2/base.h"
#include "src/wp2/decode.h"
#include "src/wp2/encode.h"
namespace WP2 {
namespace {
constexpr float kMinExpectedSimilarity = 13.f;
//------------------------------------------------------------------------------
void ShowOutput(const std::string& file_name, const ArgbBuffer& original_image,
const ArgbBuffer& decompressed_preview) {
#ifdef WP2_TEST_PREVIEW_API_SAVE_OUTPUT
std::string original = RemoveFileExtension(file_name) + "_original.png";
EXPECT_WP2_OK(SaveImage(original_image, ("/tmp/" + original).c_str(), true));
std::string decompressed = RemoveFileExtension(file_name) + "_preview.png";
EXPECT_WP2_OK(
SaveImage(decompressed_preview, ("/tmp/" + decompressed).c_str(), true));
#else
(void)file_name;
(void)original_image;
(void)decompressed_preview;
#endif
}
//------------------------------------------------------------------------------
class PreviewTest
: public testing::TestWithParam<
std::tuple<const char*, float, int, PreviewConfig::AnalysisMethod>> {
};
TEST_P(PreviewTest, SimpleTest) {
const std::string file_name = std::get<0>(GetParam());
const std::string file_path = testutil::GetTestDataPath(file_name);
const float quality = std::get<1>(GetParam());
const int effort = std::get<2>(GetParam());
const PreviewConfig::AnalysisMethod analysis_method = std::get<3>(GetParam());
ArgbBuffer original_image;
ASSERT_WP2_OK(ReadImage(file_path.c_str(), &original_image));
MemoryWriter writer;
PreviewConfig config(quality, effort);
config.analysis_method = analysis_method;
ASSERT_WP2_OK(
EncodePreview(original_image, config, ProgressRange(), &writer));
ArgbBuffer decompressed_preview;
ASSERT_WP2_OK(decompressed_preview.Resize(original_image.width(),
original_image.height()));
ASSERT_WP2_OK(
DecodePreview(writer.mem_, writer.size_, &decompressed_preview));
ASSERT_TRUE(testutil::Compare(original_image, decompressed_preview, file_name,
kMinExpectedSimilarity));
ShowOutput(file_name, original_image, decompressed_preview);
}
INSTANTIATE_TEST_SUITE_P(
PreviewTestInstantiationFast, PreviewTest,
testing::Combine(
testing::Values("source1_64x48.png"),
testing::Values(40.f), // Quality
testing::Values(3), // Effort
testing::Values(
PreviewConfig::AnalysisMethod::kEdgeSelectionAndRepulsion)));
// This one might take ~10min so it is disabled.
// Can still be run with flag --test_arg=--gunit_also_run_disabled_tests
INSTANTIATE_TEST_SUITE_P(
DISABLED_PreviewTestInstantiation, PreviewTest,
testing::Combine(
testing::Values("source0.ppm", "source1.png"),
testing::Values(10.f, 50.f), // Quality
testing::Values(2, 5), // Effort
testing::Values(
PreviewConfig::AnalysisMethod::kEdgeSelectionAndRepulsion,
PreviewConfig::AnalysisMethod::kColorDiffMaximization,
PreviewConfig::AnalysisMethod::kRandomEdgeSelection)));
//------------------------------------------------------------------------------
TEST(PreviewTest, NoOptim) {
#if defined(WP2_BITTRACE)
WP2MathInit();
#endif
const std::string file_name = "alpha_ramp.png";
const std::string file_path = testutil::GetTestDataPath(file_name);
ArgbBuffer original_image;
ASSERT_WP2_OK(ReadImage(file_path.c_str(), &original_image));
MemoryWriter writer;
PreviewConfig config;
config.num_vertices = 10;
config.num_colors = 14;
config.grid_size = 32;
config.grid_density = 1.0;
config.blur_radius = 4;
config.num_iterations = 0;
ASSERT_WP2_OK(
EncodePreview(original_image, config, ProgressRange(), &writer));
ArgbBuffer decompressed_preview;
ASSERT_WP2_OK(decompressed_preview.Resize(original_image.width(),
original_image.height()));
ASSERT_WP2_OK(
DecodePreview(writer.mem_, writer.size_, &decompressed_preview));
EXPECT_TRUE(testutil::Compare(original_image, decompressed_preview, file_name,
kMinExpectedSimilarity));
ShowOutput(file_name, original_image, decompressed_preview);
}
//------------------------------------------------------------------------------
TEST(PreviewTest, EncodeDecode) {
const std::string file_name = "test_exif_xmp.webp";
const std::string file_path = testutil::GetTestDataPath(file_name);
ArgbBuffer original_image;
ASSERT_WP2_OK(ReadImage(file_path.c_str(), &original_image));
EncoderConfig config;
config.quality = 40.f;
config.effort = 2;
config.create_preview = true;
MemoryWriter memory_writer;
ASSERT_WP2_OK(Encode(original_image, &memory_writer, config));
ArgbBuffer decompressed_preview(original_image.format());
ASSERT_WP2_OK(ExtractPreview(memory_writer.mem_, memory_writer.size_,
&decompressed_preview));
EXPECT_TRUE(testutil::Compare(original_image, decompressed_preview, file_name,
kMinExpectedSimilarity));
ShowOutput(file_name, original_image, decompressed_preview);
}
//------------------------------------------------------------------------------
TEST(PreviewTest, CustomSize) {
const std::string file_name = "test_exif_xmp.webp";
const std::string file_path = testutil::GetTestDataPath(file_name);
ArgbBuffer original_image;
ASSERT_WP2_OK(ReadImage(file_path.c_str(), &original_image));
EncoderConfig config;
config.quality = 20.f;
config.effort = 1;
config.create_preview = true;
MemoryWriter memory_writer;
EXPECT_WP2_OK(Encode(original_image, &memory_writer, config));
ArgbBuffer decompressed_preview(original_image.format());
for (uint32_t width : {1u, 2u, 256u}) {
for (uint32_t height : {1u, 2u, 256u}) {
ASSERT_WP2_OK(decompressed_preview.Resize(width, height));
ASSERT_WP2_OK(ExtractPreview(memory_writer.mem_, memory_writer.size_,
&decompressed_preview));
}
}
}
//------------------------------------------------------------------------------
// To get coverage on the preview skipping code.
TEST(PreviewTest, Skipped) {
ArgbBuffer original_image;
ASSERT_WP2_OK(ReadImage(
testutil::GetTestDataPath("source1_64x48.png").c_str(), &original_image));
EncoderConfig config;
config.quality = 0.f; // Lowest preview settings; it will be skipped anyway.
config.effort = 0;
config.create_preview = true;
MemoryWriter memory_writer;
EXPECT_WP2_OK(Encode(original_image, &memory_writer, config));
ArgbBuffer ignored_output;
EXPECT_WP2_OK(
Decode(memory_writer.mem_, memory_writer.size_, &ignored_output));
}
// Test the 'binary preview' encoder option
TEST(PreviewTest, PreviewData) {
ArgbBuffer original_image;
ASSERT_WP2_OK(ReadImage(
testutil::GetTestDataPath("source1_64x48.png").c_str(), &original_image));
ArgbBuffer ignored_output;
MemoryWriter writer;
EncoderConfig config;
config.preview_size = 123;
config.preview = nullptr;
EXPECT_EQ(Encode(original_image, &writer, config),
WP2_STATUS_INVALID_CONFIGURATION);
const char kPreviewdata[] = "this is a nice thumbnail!";
config.preview = (const uint8_t*)kPreviewdata;
config.preview_size = strlen(kPreviewdata);
writer.Reset();
EXPECT_WP2_OK(Encode(original_image, &writer, config));
EXPECT_WP2_OK(Decode(writer.mem_, writer.size_, &ignored_output));
config.preview_size = 0;
writer.Reset();
EXPECT_WP2_OK(Encode(original_image, &writer, config));
EXPECT_WP2_OK(Decode(writer.mem_, writer.size_, &ignored_output));
}
//------------------------------------------------------------------------------
} // namespace
} // namespace WP2