summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2020-04-25 12:06:53 +0200
committerTomaž Vajngerl <quikee@gmail.com>2020-04-26 20:06:49 +0200
commit287e39d363012788bf1f5bdb94fdebd370e8763d (patch)
tree04ae6b311316ccc76ac95f3c327d1620e2c9b228
parent53695ce10253f5d029063e6c7afffdf1799ceec4 (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.mk12
-rw-r--r--vcl/inc/impgraph.hxx14
-rw-r--r--vcl/qa/cppunit/GraphicTest.cxx236
-rw-r--r--vcl/qa/cppunit/data/SimpleExample.svg4
-rw-r--r--vcl/source/gdi/impgraph.cxx7
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 ),