// Copyright 2018 The PDFium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "core/fxge/dib/cfx_dibitmap.h" #include #include "core/fxcrt/fx_coordinates.h" #include "core/fxge/dib/fx_dib.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/base/containers/span.h" namespace { using ::testing::ElementsAre; } // namespace TEST(CFX_DIBitmap, Create) { auto pBitmap = pdfium::MakeRetain(); EXPECT_FALSE(pBitmap->Create(400, 300, FXDIB_Format::kInvalid)); pBitmap = pdfium::MakeRetain(); EXPECT_TRUE(pBitmap->Create(400, 300, FXDIB_Format::k1bppRgb)); } TEST(CFX_DIBitmap, CalculatePitchAndSizeGood) { // Simple case with no provided pitch. absl::optional result = CFX_DIBitmap::CalculatePitchAndSize(100, 200, FXDIB_Format::kArgb, 0); ASSERT_TRUE(result.has_value()); EXPECT_EQ(400u, result.value().pitch); EXPECT_EQ(80000u, result.value().size); // Simple case with no provided pitch and different format. result = CFX_DIBitmap::CalculatePitchAndSize(100, 200, FXDIB_Format::k8bppRgb, 0); ASSERT_TRUE(result.has_value()); EXPECT_EQ(100u, result.value().pitch); EXPECT_EQ(20000u, result.value().size); // Simple case with provided pitch. result = CFX_DIBitmap::CalculatePitchAndSize(100, 200, FXDIB_Format::kArgb, 400); ASSERT_TRUE(result.has_value()); EXPECT_EQ(400u, result.value().pitch); EXPECT_EQ(80000u, result.value().size); // Simple case with provided pitch, but pitch does not match width * bpp. result = CFX_DIBitmap::CalculatePitchAndSize(100, 200, FXDIB_Format::kArgb, 355); ASSERT_TRUE(result.has_value()); EXPECT_EQ(355u, result.value().pitch); EXPECT_EQ(71000u, result.value().size); } TEST(CFX_DIBitmap, CalculatePitchAndSizeBad) { // Bad width / height. static const CFX_Size kBadDimensions[] = { {0, 0}, {-1, -1}, {-1, 0}, {0, -1}, {0, 200}, {100, 0}, {-1, 200}, {100, -1}, }; for (const auto& dimension : kBadDimensions) { EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize( dimension.width, dimension.height, FXDIB_Format::kArgb, 0)); EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize( dimension.width, dimension.height, FXDIB_Format::kArgb, 1)); } // Bad format. EXPECT_FALSE( CFX_DIBitmap::CalculatePitchAndSize(100, 200, FXDIB_Format::kInvalid, 0)); EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize( 100, 200, FXDIB_Format::kInvalid, 800)); // Overflow cases with calculated pitch. EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(1073747000, 1, FXDIB_Format::kArgb, 0)); EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(1048576, 1024, FXDIB_Format::kArgb, 0)); EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(4194304, 1024, FXDIB_Format::k8bppRgb, 0)); // Overflow cases with provided pitch. EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize( 2147484000u, 1, FXDIB_Format::kArgb, 2147484000u)); EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize( 1048576, 1024, FXDIB_Format::kArgb, 4194304)); EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize( 4194304, 1024, FXDIB_Format::k8bppRgb, 4194304)); } TEST(CFX_DIBitmap, CalculatePitchAndSizeBoundary) { // Test boundary condition for pitch overflow. absl::optional result = CFX_DIBitmap::CalculatePitchAndSize(536870908, 4, FXDIB_Format::k8bppRgb, 0); ASSERT_TRUE(result); EXPECT_EQ(536870908u, result.value().pitch); EXPECT_EQ(2147483632u, result.value().size); EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(536870909, 4, FXDIB_Format::k8bppRgb, 0)); // Test boundary condition for size overflow. result = CFX_DIBitmap::CalculatePitchAndSize(68174084, 63, FXDIB_Format::k8bppRgb, 0); ASSERT_TRUE(result); EXPECT_EQ(68174084u, result.value().pitch); EXPECT_EQ(4294967292u, result.value().size); EXPECT_FALSE(CFX_DIBitmap::CalculatePitchAndSize(68174085, 63, FXDIB_Format::k8bppRgb, 0)); } #if defined(_SKIA_SUPPORT_) TEST(CFX_DIBitmap, UnPreMultiply_FromCleared) { auto bitmap = pdfium::MakeRetain(); ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb)); FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'7f'7f'7f); bitmap->UnPreMultiply(); EXPECT_THAT(bitmap->GetBuffer(), ElementsAre(0xff, 0xff, 0xff, 0x7f)); } TEST(CFX_DIBitmap, UnPreMultiply_FromPreMultiplied) { auto bitmap = pdfium::MakeRetain(); ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb)); bitmap->ForcePreMultiply(); FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'7f'7f'7f); bitmap->UnPreMultiply(); EXPECT_THAT(bitmap->GetBuffer(), ElementsAre(0xff, 0xff, 0xff, 0x7f)); } TEST(CFX_DIBitmap, UnPreMultiply_FromUnPreMultiplied) { auto bitmap = pdfium::MakeRetain(); ASSERT_TRUE(bitmap->Create(1, 1, FXDIB_Format::kArgb)); bitmap->UnPreMultiply(); FXARGB_SETDIB(bitmap->GetBuffer().data(), 0x7f'ff'ff'ff); bitmap->UnPreMultiply(); EXPECT_THAT(bitmap->GetBuffer(), ElementsAre(0xff, 0xff, 0xff, 0x7f)); } #endif // defined(_SKIA_SUPPORT_)