diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2020-04-25 12:06:53 +0200 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2020-04-26 20:06:49 +0200 |
commit | 287e39d363012788bf1f5bdb94fdebd370e8763d (patch) | |
tree | 04ae6b311316ccc76ac95f3c327d1620e2c9b228 | |
parent | 53695ce10253f5d029063e6c7afffdf1799ceec4 (diff) |
Test swapping of Graphic
Change-Id: I895002aa31380d2b5bc2593e66080f3fc94034e7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92920
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r-- | vcl/CppunitTest_vcl_graphic_test.mk | 12 | ||||
-rw-r--r-- | vcl/inc/impgraph.hxx | 14 | ||||
-rw-r--r-- | vcl/qa/cppunit/GraphicTest.cxx | 236 | ||||
-rw-r--r-- | vcl/qa/cppunit/data/SimpleExample.svg | 4 | ||||
-rw-r--r-- | vcl/source/gdi/impgraph.cxx | 7 |
5 files changed, 234 insertions, 39 deletions
diff --git a/vcl/CppunitTest_vcl_graphic_test.mk b/vcl/CppunitTest_vcl_graphic_test.mk index fd5c7aeb039b..63dea32f9757 100644 --- a/vcl/CppunitTest_vcl_graphic_test.mk +++ b/vcl/CppunitTest_vcl_graphic_test.mk @@ -39,19 +39,9 @@ $(eval $(call gb_CppunitTest_use_libraries,vcl_graphic_test, \ )) $(eval $(call gb_CppunitTest_use_sdk_api,vcl_graphic_test)) - $(eval $(call gb_CppunitTest_use_ure,vcl_graphic_test)) $(eval $(call gb_CppunitTest_use_vcl,vcl_graphic_test)) - -$(eval $(call gb_CppunitTest_use_components,vcl_graphic_test,\ - configmgr/source/configmgr \ - i18npool/util/i18npool \ - ucb/source/core/ucb1 \ - unotools/util/utl \ - emfio/emfio \ - drawinglayer/drawinglayer \ -)) - +$(eval $(call gb_CppunitTest_use_rdb,vcl_graphic_test,services)) $(eval $(call gb_CppunitTest_use_configuration,vcl_graphic_test)) # we need to explicitly depend on Library_gie because it's dynamically loaded for .gif diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx index adddaca92499..0653c82d4bae 100644 --- a/vcl/inc/impgraph.hxx +++ b/vcl/inc/impgraph.hxx @@ -20,6 +20,7 @@ #ifndef INCLUDED_VCL_INC_IMPGRAPH_HXX #define INCLUDED_VCL_INC_IMPGRAPH_HXX +#include <vcl/dllapi.h> #include <vcl/GraphicExternalLink.hxx> #include <vcl/gdimtf.hxx> #include <vcl/graph.hxx> @@ -46,7 +47,7 @@ struct ImpSwapFile; class GraphicConversionParameters; class ImpGraphic; -class ImpGraphic final +class VCL_DLLPUBLIC ImpGraphic final { friend class Graphic; friend class GraphicID; @@ -175,14 +176,9 @@ private: bool ImplReadEmbedded( SvStream& rIStream ); bool ImplWriteEmbedded( SvStream& rOStream ); - bool swapIn(); bool swapInFromStream(SvStream* pIStm); - - bool swapOut(); bool swapOutToStream(SvStream* pOStm); - bool isSwappedOut() const { return mbSwapOut;} - bool ImplIsDummyContext() const { return mbDummyContext; } void ImplSetLink( const std::shared_ptr<GfxLink>& ); std::shared_ptr<GfxLink> ImplGetSharedGfxLink() const; @@ -206,6 +202,12 @@ private: bool loadPrepared(); sal_Int32 getPageNumber() const; + +public: + bool swapIn(); + bool swapOut(); + bool isSwappedOut() const { return mbSwapOut; } + OUString getSwapFileURL(); }; #endif // INCLUDED_VCL_INC_IMPGRAPH_HXX diff --git a/vcl/qa/cppunit/GraphicTest.cxx b/vcl/qa/cppunit/GraphicTest.cxx index e67ba6ff7ee7..d040f8837cd0 100644 --- a/vcl/qa/cppunit/GraphicTest.cxx +++ b/vcl/qa/cppunit/GraphicTest.cxx @@ -19,6 +19,11 @@ #include <vcl/graphicfilter.hxx> #include <tools/stream.hxx> #include <unotest/directories.hxx> +#include <comphelper/DirectoryHelper.hxx> +#include <comphelper/hash.hxx> +#include <unotools/ucbstreamhelper.hxx> + +#include <impgraph.hxx> using namespace css; @@ -31,6 +36,8 @@ class GraphicTest : public CppUnit::TestFixture void testUnloadedGraphicWmf(); void testUnloadedGraphicAlpha(); void testUnloadedGraphicSizeUnit(); + void testSwapping(); + void testSwappingVectorGraphic(); CPPUNIT_TEST_SUITE(GraphicTest); CPPUNIT_TEST(testUnloadedGraphic); @@ -38,6 +45,8 @@ class GraphicTest : public CppUnit::TestFixture CPPUNIT_TEST(testUnloadedGraphicWmf); CPPUNIT_TEST(testUnloadedGraphicAlpha); CPPUNIT_TEST(testUnloadedGraphicSizeUnit); + CPPUNIT_TEST(testSwapping); + CPPUNIT_TEST(testSwappingVectorGraphic); CPPUNIT_TEST_SUITE_END(); }; @@ -82,6 +91,71 @@ Graphic makeUnloadedGraphic(OUString const& sType, bool alpha = false) return rGraphicFilter.ImportUnloadedGraphic(aStream); } +std::string toHexString(const std::vector<unsigned char>& a) +{ + std::stringstream aStrm; + for (auto& i : a) + { + aStrm << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(i); + } + + return aStrm.str(); +} + +std::unique_ptr<SvStream> createStream(OUString const& rSwapFileURL) +{ + std::unique_ptr<SvStream> xStream; + + try + { + xStream = ::utl::UcbStreamHelper::CreateStream( + rSwapFileURL, StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE); + } + catch (const css::uno::Exception&) + { + } + + return xStream; +} + +std::vector<unsigned char> calculateHash(std::unique_ptr<SvStream>& rStream) +{ + comphelper::Hash aHashEngine(comphelper::HashType::SHA1); + const sal_uInt32 nSize(rStream->remainingSize()); + std::vector<sal_uInt8> aData(nSize); + aHashEngine.update(aData.data(), nSize); + return aHashEngine.finalize(); +} + +bool checkBitmap(Graphic& rGraphic) +{ + bool bResult = true; + + Bitmap aBitmap(rGraphic.GetBitmapEx().GetBitmap()); + { + Bitmap::ScopedReadAccess pReadAccess(aBitmap); + for (long y = 0; y < rGraphic.GetSizePixel().Height(); y++) + { + for (long x = 0; x < rGraphic.GetSizePixel().Width(); x++) + { + if (pReadAccess->HasPalette()) + { + sal_uInt32 nIndex = pReadAccess->GetPixelIndex(y, x); + Color aColor = pReadAccess->GetPaletteColor(nIndex); + bResult &= (aColor == Color(0xff, 0x00, 0x00)); + } + else + { + Color aColor = pReadAccess->GetPixel(y, x); + bResult &= (aColor == Color(0xff, 0x00, 0x00)); + } + } + } + } + + return bResult; +} + char const DATA_DIRECTORY[] = "/vcl/qa/cppunit/data/"; void GraphicTest::testUnloadedGraphic() @@ -114,6 +188,14 @@ void GraphicTest::testUnloadedGraphic() CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); CPPUNIT_ASSERT(aGraphic.GetSizeBytes() > 0); CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable()); + + //check Type + aGraphic = makeUnloadedGraphic("png"); + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable()); + CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType()); } void GraphicTest::testUnloadedGraphicLoading() @@ -131,29 +213,9 @@ void GraphicTest::testUnloadedGraphicLoading() CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); CPPUNIT_ASSERT(aGraphic.GetSizeBytes() > 0); CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable()); - Bitmap aBitmap(aGraphic.GetBitmapEx().GetBitmap()); - { - Bitmap::ScopedReadAccess pReadAccess(aBitmap); - for (long y = 0; y < aGraphic.GetSizePixel().Height(); y++) - { - for (long x = 0; x < aGraphic.GetSizePixel().Width(); x++) - { - if (pReadAccess->HasPalette()) - { - Color aColor - = pReadAccess->GetPaletteColor(pReadAccess->GetPixelIndex(y, x)); - CPPUNIT_ASSERT_EQUAL(OUString("ff0000"), aColor.AsRGBHexString()); - } - else - { - Color aColor = pReadAccess->GetPixel(y, x); - if (sFormat != "jpg") - CPPUNIT_ASSERT_EQUAL(OUString("ff0000"), aColor.AsRGBHexString()); - } - } - } - } + if (sFormat != "jpg") + CPPUNIT_ASSERT_EQUAL(true, checkBitmap(aGraphic)); } } @@ -216,6 +278,136 @@ void GraphicTest::testUnloadedGraphicSizeUnit() CPPUNIT_ASSERT_EQUAL(Size(400, 363), aGraphic.GetPrefSize()); } +void GraphicTest::testSwapping() +{ + // Prepare Graphic from a PNG image first + Graphic aGraphic = makeUnloadedGraphic("png"); + + CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable()); + + CPPUNIT_ASSERT_EQUAL(120L, aGraphic.GetSizePixel().Width()); + CPPUNIT_ASSERT_EQUAL(100L, aGraphic.GetSizePixel().Height()); + CPPUNIT_ASSERT_EQUAL(BitmapChecksum(0xF5331397837B58EB), aGraphic.GetChecksum()); + + CPPUNIT_ASSERT_EQUAL(sal_uInt32(319), aGraphic.GetGfxLink().GetDataSize()); + + // We loaded the Graphic and made it available + CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut()); + // Get the declared byte size of the graphic + sal_uLong rByteSize = aGraphic.GetSizeBytes(); + OUString rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL(); + CPPUNIT_ASSERT_EQUAL(true, rSwapFileURL.isEmpty()); + + // Swapping out + CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut()); + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + + // Byte size doesn't change when we swapped out + CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes()); + + // Let's check the swap file + rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL(); + CPPUNIT_ASSERT_EQUAL(true, comphelper::DirectoryHelper::fileExists(rSwapFileURL)); + + { // Check the swap file content + std::unique_ptr<SvStream> xStream = createStream(rSwapFileURL); + CPPUNIT_ASSERT_EQUAL(true, bool(xStream)); + + // Check size of the stream + CPPUNIT_ASSERT_EQUAL(sal_uInt64(445), xStream->remainingSize()); + + std::vector<unsigned char> aHash = calculateHash(xStream); + CPPUNIT_ASSERT_EQUAL(std::string("304f17d9c56e79b95f6c337dab88709d4f9b61f0"), + toHexString(aHash)); + } + + // Let's swap in + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable()); + CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut()); + + CPPUNIT_ASSERT_EQUAL(BitmapChecksum(0xF5331397837B58EB), aGraphic.GetChecksum()); + + // File shouldn't be available anymore + CPPUNIT_ASSERT_EQUAL(false, comphelper::DirectoryHelper::fileExists(rSwapFileURL)); + + // Check the bitmap + CPPUNIT_ASSERT_EQUAL(120L, aGraphic.GetSizePixel().Width()); + CPPUNIT_ASSERT_EQUAL(100L, aGraphic.GetSizePixel().Height()); + CPPUNIT_ASSERT_EQUAL(true, checkBitmap(aGraphic)); + CPPUNIT_ASSERT_EQUAL(true, checkBitmap(aGraphic)); +} + +void GraphicTest::testSwappingVectorGraphic() +{ + test::Directories aDirectories; + OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "SimpleExample.svg"; + SvFileStream aStream(aURL, StreamMode::READ); + GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter(); + Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream); + + CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType()); + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + + // Load the vector graphic + CPPUNIT_ASSERT_EQUAL(true, bool(aGraphic.getVectorGraphicData())); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(223), + aGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable()); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(223), aGraphic.GetGfxLink().GetDataSize()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable()); + + BitmapChecksum aBitmapChecksumBeforeSwapping = aGraphic.GetBitmapEx().GetChecksum(); + + CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut()); + + // Get the declared byte size of the graphic + sal_uLong rByteSize = aGraphic.GetSizeBytes(); + CPPUNIT_ASSERT_EQUAL(sal_uLong(223), rByteSize); + OUString rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL(); + CPPUNIT_ASSERT_EQUAL(true, rSwapFileURL.isEmpty()); + + // Swapping out + CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut()); + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + + // Byte size doesn't change when we swapped out + // TODO: In case we don't trigger GetBitmapEx (above) the size is 0 + CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes()); + + // Let's check the swap file + rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL(); + CPPUNIT_ASSERT_EQUAL(true, comphelper::DirectoryHelper::fileExists(rSwapFileURL)); + + { // Check the swap file content + std::unique_ptr<SvStream> xStream = createStream(rSwapFileURL); + CPPUNIT_ASSERT_EQUAL(true, bool(xStream)); + + // Check size of the stream + CPPUNIT_ASSERT_EQUAL(sal_uInt64(349), xStream->remainingSize()); + + std::vector<unsigned char> aHash = calculateHash(xStream); + CPPUNIT_ASSERT_EQUAL(std::string("88b4c1c359e3cf7be005fbb46c93ffa6de9dcf4a"), + toHexString(aHash)); + } + + // Let's swap in + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable()); + CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut()); + + CPPUNIT_ASSERT_EQUAL(aBitmapChecksumBeforeSwapping, aGraphic.GetBitmapEx().GetChecksum()); + + // File shouldn't be available anymore + CPPUNIT_ASSERT_EQUAL(false, comphelper::DirectoryHelper::fileExists(rSwapFileURL)); +} + } // namespace CPPUNIT_TEST_SUITE_REGISTRATION(GraphicTest); diff --git a/vcl/qa/cppunit/data/SimpleExample.svg b/vcl/qa/cppunit/data/SimpleExample.svg new file mode 100644 index 000000000000..6890b5456cdf --- /dev/null +++ b/vcl/qa/cppunit/data/SimpleExample.svg @@ -0,0 +1,4 @@ +<svg width="50" height="50" version="1.1" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg"> + <rect x="0" y="0" width="50" height="50" fill="#aaaaaa"/> + <rect x="5" y="5" width="40" height="40" fill="#ff44aa"/> +</svg> diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 02f8189bd81c..d4634f1c58ca 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -78,6 +78,13 @@ struct ImpSwapFile } }; +OUString ImpGraphic::getSwapFileURL() +{ + if (mpSwapFile) + return mpSwapFile->aSwapURL.GetMainURL(INetURLObject::DecodeMechanism::NONE); + return OUString(); +} + ImpGraphic::ImpGraphic() : meType ( GraphicType::NONE ), mnSizeBytes ( 0 ), |