diff options
Diffstat (limited to 'vcl/qa/cppunit/jpeg')
-rw-r--r-- | vcl/qa/cppunit/jpeg/JpegReaderTest.cxx | 202 | ||||
-rw-r--r-- | vcl/qa/cppunit/jpeg/JpegWriterTest.cxx | 117 | ||||
-rw-r--r-- | vcl/qa/cppunit/jpeg/data/8BitGrayscale.jpg | bin | 0 -> 1384 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/jpeg/data/8BitNonGrayscale.gif | bin | 0 -> 1875 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/jpeg/data/JPEGTestCMYK.jpeg | bin | 0 -> 405 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/jpeg/data/JPEGTestGray.jpeg | bin | 0 -> 196 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/jpeg/data/JPEGTestRGB.jpeg | bin | 0 -> 619 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/jpeg/data/tdf138950.jpeg | bin | 0 -> 60662 bytes |
8 files changed, 319 insertions, 0 deletions
diff --git a/vcl/qa/cppunit/jpeg/JpegReaderTest.cxx b/vcl/qa/cppunit/jpeg/JpegReaderTest.cxx new file mode 100644 index 000000000..0900c02d4 --- /dev/null +++ b/vcl/qa/cppunit/jpeg/JpegReaderTest.cxx @@ -0,0 +1,202 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include <sal/config.h> + +#include <string_view> + +#include <unotest/bootstrapfixturebase.hxx> +#include <vcl/graphicfilter.hxx> +#include <bitmap/BitmapWriteAccess.hxx> +#include <tools/stream.hxx> + +constexpr OUStringLiteral gaDataUrl(u"/vcl/qa/cppunit/jpeg/data/"); + +class JpegReaderTest : public test::BootstrapFixtureBase +{ + OUString getFullUrl(std::u16string_view sFileName) + { + return m_directories.getURLFromSrc(gaDataUrl) + sFileName; + } + + Graphic loadJPG(const OUString& aURL); + +public: + void testReadRGB(); + void testReadGray(); + void testReadCMYK(); + void testTdf138950(); + + CPPUNIT_TEST_SUITE(JpegReaderTest); + CPPUNIT_TEST(testReadRGB); + CPPUNIT_TEST(testReadGray); + CPPUNIT_TEST(testReadCMYK); + CPPUNIT_TEST(testTdf138950); + CPPUNIT_TEST_SUITE_END(); +}; + +static int deltaColor(BitmapColor aColor1, BitmapColor aColor2) +{ + int deltaR = std::abs(aColor1.GetRed() - aColor2.GetRed()); + int deltaG = std::abs(aColor1.GetGreen() - aColor2.GetGreen()); + int deltaB = std::abs(aColor1.GetBlue() - aColor2.GetBlue()); + + return std::max(std::max(deltaR, deltaG), deltaB); +} + +static bool checkRect(Bitmap& rBitmap, int aLayerNumber, tools::Long nAreaHeight, + tools::Long nAreaWidth, Color aExpectedColor, int nMaxDelta) +{ + BitmapScopedWriteAccess pAccess(rBitmap); + + tools::Long nWidth = std::min(nAreaWidth, pAccess->Width()); + tools::Long nHeight = std::min(nAreaHeight, pAccess->Height()); + + tools::Long firstX = 0 + aLayerNumber; + tools::Long firstY = 0 + aLayerNumber; + + tools::Long lastX = nWidth - 1 - aLayerNumber; + tools::Long lastY = nHeight - 1 - aLayerNumber; + + int delta; + + for (tools::Long y = firstY; y <= lastY; y++) + { + Color aColorFirst = pAccess->GetPixel(y, firstX); + delta = deltaColor(aColorFirst, aExpectedColor); + if (delta > nMaxDelta) + return false; + + Color aColorLast = pAccess->GetPixel(y, lastX); + delta = deltaColor(aColorLast, aExpectedColor); + if (delta > nMaxDelta) + return false; + } + for (tools::Long x = firstX; x <= lastX; x++) + { + Color aColorFirst = pAccess->GetPixel(firstY, x); + delta = deltaColor(aColorFirst, aExpectedColor); + if (delta > nMaxDelta) + return false; + + Color aColorLast = pAccess->GetPixel(lastY, x); + delta = deltaColor(aColorLast, aExpectedColor); + if (delta > nMaxDelta) + return false; + } + return true; +} + +static int getNumberOfImageComponents(const Graphic& rGraphic) +{ + GfxLink aLink = rGraphic.GetGfxLink(); + SvMemoryStream aMemoryStream(const_cast<sal_uInt8*>(aLink.GetData()), aLink.GetDataSize(), + StreamMode::READ | StreamMode::WRITE); + GraphicDescriptor aDescriptor(aMemoryStream, nullptr); + CPPUNIT_ASSERT(aDescriptor.Detect(true)); + return aDescriptor.GetNumberOfImageComponents(); +} + +Graphic JpegReaderTest::loadJPG(const OUString& aURL) +{ + GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); + Graphic aGraphic; + SvFileStream aFileStream(aURL, StreamMode::READ); + ErrCode bResult = rFilter.ImportGraphic(aGraphic, aURL, aFileStream); + CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, bResult); + return aGraphic; +} + +void JpegReaderTest::testReadRGB() +{ + Graphic aGraphic = loadJPG(getFullUrl(u"JPEGTestRGB.jpeg")); + Bitmap aBitmap = aGraphic.GetBitmapEx().GetBitmap(); + Size aSize = aBitmap.GetSizePixel(); + CPPUNIT_ASSERT_EQUAL(tools::Long(12), aSize.Width()); + CPPUNIT_ASSERT_EQUAL(tools::Long(12), aSize.Height()); + + int nMaxDelta = 1; // still acceptable color error + CPPUNIT_ASSERT(checkRect(aBitmap, 0, 8, 8, Color(0xff, 0xff, 0xff), nMaxDelta)); + CPPUNIT_ASSERT(checkRect(aBitmap, 1, 8, 8, Color(0xff, 0x00, 0x00), nMaxDelta)); + CPPUNIT_ASSERT(checkRect(aBitmap, 2, 8, 8, Color(0x00, 0xff, 0x00), nMaxDelta)); + CPPUNIT_ASSERT(checkRect(aBitmap, 3, 8, 8, Color(0x00, 0x00, 0xff), nMaxDelta)); + + CPPUNIT_ASSERT_EQUAL(3, getNumberOfImageComponents(aGraphic)); +} + +void JpegReaderTest::testReadGray() +{ + Graphic aGraphic = loadJPG(getFullUrl(u"JPEGTestGray.jpeg")); + Bitmap aBitmap = aGraphic.GetBitmapEx().GetBitmap(); + Size aSize = aBitmap.GetSizePixel(); + CPPUNIT_ASSERT_EQUAL(tools::Long(12), aSize.Width()); + CPPUNIT_ASSERT_EQUAL(tools::Long(12), aSize.Height()); + + aBitmap.Convert( + BmpConversion::N24Bit); // convert to 24bit so we don't need to deal with palette + + int nMaxDelta = 1; + CPPUNIT_ASSERT(checkRect(aBitmap, 0, 8, 8, Color(0xff, 0xff, 0xff), nMaxDelta)); + CPPUNIT_ASSERT(checkRect(aBitmap, 1, 8, 8, Color(0x36, 0x36, 0x36), nMaxDelta)); + CPPUNIT_ASSERT(checkRect(aBitmap, 2, 8, 8, Color(0xb6, 0xb6, 0xb6), nMaxDelta)); + CPPUNIT_ASSERT(checkRect(aBitmap, 3, 8, 8, Color(0x12, 0x12, 0x12), nMaxDelta)); + + CPPUNIT_ASSERT_EQUAL(1, getNumberOfImageComponents(aGraphic)); +} + +void JpegReaderTest::testReadCMYK() +{ + Graphic aGraphic = loadJPG(getFullUrl(u"JPEGTestCMYK.jpeg")); + Bitmap aBitmap = aGraphic.GetBitmapEx().GetBitmap(); + Size aSize = aBitmap.GetSizePixel(); + CPPUNIT_ASSERT_EQUAL(tools::Long(12), aSize.Width()); + CPPUNIT_ASSERT_EQUAL(tools::Long(12), aSize.Height()); + + int maxDelta = 1; + CPPUNIT_ASSERT(checkRect(aBitmap, 0, 8, 8, Color(0xff, 0xff, 0xff), maxDelta)); + CPPUNIT_ASSERT(checkRect(aBitmap, 1, 8, 8, Color(0xff, 0x00, 0x00), maxDelta)); + CPPUNIT_ASSERT(checkRect(aBitmap, 2, 8, 8, Color(0x00, 0xff, 0x00), maxDelta)); + CPPUNIT_ASSERT(checkRect(aBitmap, 3, 8, 8, Color(0x00, 0x00, 0xff), maxDelta)); + + CPPUNIT_ASSERT_EQUAL(4, getNumberOfImageComponents(aGraphic)); +} + +void JpegReaderTest::testTdf138950() +{ + Graphic aGraphic = loadJPG(getFullUrl(u"tdf138950.jpeg")); + Bitmap aBitmap = aGraphic.GetBitmapEx().GetBitmap(); + Size aSize = aBitmap.GetSizePixel(); + CPPUNIT_ASSERT_EQUAL(tools::Long(720), aSize.Width()); + CPPUNIT_ASSERT_EQUAL(tools::Long(1280), aSize.Height()); + + Bitmap::ScopedReadAccess pReadAccess(aBitmap); + int nBlackCount = 0; + for (tools::Long nY = 0; nY < aSize.Height(); ++nY) + { + for (tools::Long nX = 0; nX < aSize.Width(); ++nX) + { + const Color aColor = pReadAccess->GetColor(nY, nX); + if ((aColor.GetRed() == 0x00) && (aColor.GetGreen() == 0x00) + && (aColor.GetBlue() == 0x00)) + ++nBlackCount; + } + } + + // Without the fix in place, this test would have failed with + // - Expected: 0 + // - Actual : 921600 + CPPUNIT_ASSERT_EQUAL(0, nBlackCount); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(JpegReaderTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qa/cppunit/jpeg/JpegWriterTest.cxx b/vcl/qa/cppunit/jpeg/JpegWriterTest.cxx new file mode 100644 index 000000000..f9b58c308 --- /dev/null +++ b/vcl/qa/cppunit/jpeg/JpegWriterTest.cxx @@ -0,0 +1,117 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include <sal/config.h> + +#include <string_view> + +#include <unotest/bootstrapfixturebase.hxx> +#include <vcl/graphicfilter.hxx> +#include <vcl/BitmapReadAccess.hxx> +#include <tools/stream.hxx> +#include <graphic/GraphicFormatDetector.hxx> + +constexpr OUStringLiteral gaDataUrl(u"/vcl/qa/cppunit/jpeg/data/"); + +class JpegWriterTest : public test::BootstrapFixtureBase +{ + OUString getFullUrl(std::u16string_view sFileName) + { + return m_directories.getURLFromSrc(gaDataUrl) + sFileName; + } + + BitmapEx load(const OUString& aURL); + BitmapEx roundtripJPG(const BitmapEx& bitmap); + BitmapEx roundtripJPG(const OUString& aURL); + +public: + void testWrite8BitGrayscale(); + void testWrite8BitNonGrayscale(); + + CPPUNIT_TEST_SUITE(JpegWriterTest); + CPPUNIT_TEST(testWrite8BitGrayscale); + CPPUNIT_TEST(testWrite8BitNonGrayscale); + CPPUNIT_TEST_SUITE_END(); +}; + +BitmapEx JpegWriterTest::load(const OUString& aURL) +{ + GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); + Graphic aGraphic; + SvFileStream aFileStream(aURL, StreamMode::READ); + ErrCode bResult = rFilter.ImportGraphic(aGraphic, aURL, aFileStream); + CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, bResult); + return aGraphic.GetBitmapEx(); +} + +BitmapEx JpegWriterTest::roundtripJPG(const OUString& aURL) { return roundtripJPG(load(aURL)); } + +BitmapEx JpegWriterTest::roundtripJPG(const BitmapEx& bitmap) +{ + // EXPORT JPEG + SvMemoryStream aStream; + GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); + sal_uInt16 exportFormatJPG = rFilter.GetExportFormatNumberForShortName(JPG_SHORTNAME); + Graphic aExportGraphic(bitmap); + ErrCode bResult = rFilter.ExportGraphic(aExportGraphic, u"memory", aStream, exportFormatJPG); + CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, bResult); + //Detect the magic bytes - we need to be sure the file is actually a JPEG + aStream.Seek(0); + vcl::GraphicFormatDetector aDetector(aStream, ""); + CPPUNIT_ASSERT(aDetector.detect()); + CPPUNIT_ASSERT(aDetector.checkJPG()); + // IMPORT JPEG + aStream.Seek(0); + Graphic aImportGraphic; + sal_uInt16 importFormatJPG = rFilter.GetImportFormatNumberForShortName(JPG_SHORTNAME); + bResult = rFilter.ImportGraphic(aImportGraphic, u"memory", aStream, importFormatJPG); + CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, bResult); + return aImportGraphic.GetBitmapEx(); +} + +void JpegWriterTest::testWrite8BitGrayscale() +{ + Bitmap bitmap = roundtripJPG(getFullUrl(u"8BitGrayscale.jpg")).GetBitmap(); + Bitmap::ScopedReadAccess access(bitmap); + const ScanlineFormat format = access->GetScanlineFormat(); + // Check that it's still 8bit grayscale. + CPPUNIT_ASSERT_EQUAL(ScanlineFormat::N8BitPal, format); + CPPUNIT_ASSERT(bitmap.HasGreyPalette8Bit()); + // Check that the content is valid. + CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_WHITE), access->GetColor(0, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_WHITE), access->GetColor(0, access->Width() - 1)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_WHITE), access->GetColor(access->Height() - 1, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_BLACK), + access->GetColor(access->Height() - 1, access->Width() - 1)); +} + +void JpegWriterTest::testWrite8BitNonGrayscale() +{ + Bitmap bitmap = roundtripJPG(getFullUrl(u"8BitNonGrayscale.gif")).GetBitmap(); + Bitmap::ScopedReadAccess access(bitmap); + const ScanlineFormat format = access->GetScanlineFormat(); + // Check that it's still 8bit grayscale. + CPPUNIT_ASSERT_EQUAL(ScanlineFormat::N8BitPal, format); + // The original image has grayscale palette, just with entries in a different order. + // Do not check for grayscale 8bit, the roundtrip apparently fixes that. What's important + // is the content. + CPPUNIT_ASSERT(bitmap.HasGreyPaletteAny()); + // CPPUNIT_ASSERT(bitmap.HasGreyPalette8Bit()); + // Check that the content is valid. + CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_WHITE), access->GetColor(0, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_WHITE), access->GetColor(0, access->Width() - 1)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_WHITE), access->GetColor(access->Height() - 1, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_BLACK), + access->GetColor(access->Height() - 1, access->Width() - 1)); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(JpegWriterTest); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qa/cppunit/jpeg/data/8BitGrayscale.jpg b/vcl/qa/cppunit/jpeg/data/8BitGrayscale.jpg Binary files differnew file mode 100644 index 000000000..91541e4a8 --- /dev/null +++ b/vcl/qa/cppunit/jpeg/data/8BitGrayscale.jpg diff --git a/vcl/qa/cppunit/jpeg/data/8BitNonGrayscale.gif b/vcl/qa/cppunit/jpeg/data/8BitNonGrayscale.gif Binary files differnew file mode 100644 index 000000000..295310949 --- /dev/null +++ b/vcl/qa/cppunit/jpeg/data/8BitNonGrayscale.gif diff --git a/vcl/qa/cppunit/jpeg/data/JPEGTestCMYK.jpeg b/vcl/qa/cppunit/jpeg/data/JPEGTestCMYK.jpeg Binary files differnew file mode 100644 index 000000000..81cca025e --- /dev/null +++ b/vcl/qa/cppunit/jpeg/data/JPEGTestCMYK.jpeg diff --git a/vcl/qa/cppunit/jpeg/data/JPEGTestGray.jpeg b/vcl/qa/cppunit/jpeg/data/JPEGTestGray.jpeg Binary files differnew file mode 100644 index 000000000..014825f42 --- /dev/null +++ b/vcl/qa/cppunit/jpeg/data/JPEGTestGray.jpeg diff --git a/vcl/qa/cppunit/jpeg/data/JPEGTestRGB.jpeg b/vcl/qa/cppunit/jpeg/data/JPEGTestRGB.jpeg Binary files differnew file mode 100644 index 000000000..3cfe1dda2 --- /dev/null +++ b/vcl/qa/cppunit/jpeg/data/JPEGTestRGB.jpeg diff --git a/vcl/qa/cppunit/jpeg/data/tdf138950.jpeg b/vcl/qa/cppunit/jpeg/data/tdf138950.jpeg Binary files differnew file mode 100644 index 000000000..d0296077c --- /dev/null +++ b/vcl/qa/cppunit/jpeg/data/tdf138950.jpeg |