include/vcl/bitmap.hxx | 3 + vcl/qa/cppunit/BitmapExTest.cxx | 37 +++++++++------------ vcl/qa/cppunit/BitmapFilterTest.cxx | 3 - vcl/qa/cppunit/graphicfilter/filters-test.cxx | 5 +- vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx | 5 +- vcl/qa/cppunit/png/PngFilterTest.cxx | 12 ++---- vcl/qa/cppunit/skia/skia.cxx | 5 +- vcl/source/bitmap/bitmap.cxx | 19 ++++++++++ 8 files changed, 51 insertions(+), 38 deletions(-)
New commits: commit 57092d1877994a1c75dc8136549c8a1f2b9b9638 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Fri Sep 5 10:23:43 2025 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Fri Sep 5 14:17:46 2025 +0200 BitmapEx->Bitmap in vcl/qa/ This means some of the tests are now testing Bitmap, even though the test name is "BitmapExTest", but the tests are useful, and we are going to retire BitmapEx soon. One of the unit tests needed tweaking, because Bitmap uses pre-multiplied alpha, which means the color information is lost when alpha==0 Change-Id: Ie1040d309c33645982d058271b36d8dc601fd03f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190612 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Jenkins diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx index e553d35ea8c2..3cb18150a00d 100644 --- a/include/vcl/bitmap.hxx +++ b/include/vcl/bitmap.hxx @@ -719,6 +719,9 @@ public: SAL_DLLPRIVATE bool ImplMakeGreyscales(); SAL_DLLPRIVATE bool ImplMake8BitNoConversion(); + /// Dumps the pixels as PNG in bitmap.png. + void DumpAsPng(const char* pFileName = nullptr) const; + private: SAL_DLLPRIVATE bool ImplConvertUp(vcl::PixelFormat ePixelFormat, Color const* pExtColor = nullptr); SAL_DLLPRIVATE bool ImplConvertDown8BPP(Color const* pExtColor = nullptr); diff --git a/vcl/qa/cppunit/BitmapExTest.cxx b/vcl/qa/cppunit/BitmapExTest.cxx index 517d7574accf..29382f8f0ef7 100644 --- a/vcl/qa/cppunit/BitmapExTest.cxx +++ b/vcl/qa/cppunit/BitmapExTest.cxx @@ -51,9 +51,9 @@ void BitmapExTest::testGetPixelColor24_8() pWriteAccess->Erase(Color(ColorTransparency, 0x00, 0xAA, 0xAA, 0xAA)); } - BitmapEx aBitmapEx(aBitmap, aMask); + Bitmap aBitmap2(aBitmap, aMask); - CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xAA, 0x00, 0xFF, 0x00), aBitmapEx.GetPixelColor(0, 0)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xAA, 0x00, 0xFF, 0x00), aBitmap2.GetPixelColor(0, 0)); } void BitmapExTest::testGetPixelColor32() @@ -64,10 +64,8 @@ void BitmapExTest::testGetPixelColor32() pWriteAccess->Erase(Color(ColorTransparency, 0xAA, 0x00, 0xFF, 0x00)); } - BitmapEx aBitmapEx(aBitmap); - CPPUNIT_ASSERT_EQUAL(Color(ColorTransparency, 0xAA, 0x00, 0xFF, 0x00), - aBitmapEx.GetPixelColor(0, 0)); + aBitmap.GetPixelColor(0, 0)); } void BitmapExTest::testTransformBitmapEx() @@ -84,12 +82,11 @@ void BitmapExTest::testTransformBitmapEx() } } } - BitmapEx aBitmapEx(aBitmap); basegfx::B2DHomMatrix aMatrix; aMatrix.rotate(M_PI / 2); - BitmapEx aTransformed = aBitmapEx.TransformBitmapEx(16, 16, aMatrix); - aBitmap = aTransformed.GetBitmap(); + Bitmap aTransformed = aBitmap.TransformBitmap(16, 16, aMatrix); + aBitmap = aTransformed.CreateColorBitmap(); BitmapScopedReadAccess pAccess(aBitmap); for (int i = 0; i < 16; ++i) { @@ -225,18 +222,18 @@ void BitmapExTest::testCombineMaskOr() CPPUNIT_ASSERT_EQUAL(sal_uInt8(0xff), pAccess->GetPixelIndex(2, 2)); } - BitmapEx aBitmapEx(aBitmap, aAlphaBitmap); - aBitmapEx.CombineMaskOr(COL_RED, 1); - - CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xff, 0xff, 0xff, 0xff), aBitmapEx.GetPixelColor(0, 0)); - CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x80, 0x00, 0x00), aBitmapEx.GetPixelColor(0, 1)); - CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0xff, 0xff, 0xff), aBitmapEx.GetPixelColor(0, 2)); - CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xff, 0xff, 0xff, 0xff), aBitmapEx.GetPixelColor(1, 0)); - CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x80, 0x00, 0x00), aBitmapEx.GetPixelColor(1, 1)); - CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0xff, 0xff, 0xff), aBitmapEx.GetPixelColor(1, 2)); - CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xff, 0xff, 0xff, 0xff), aBitmapEx.GetPixelColor(2, 0)); - CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x80, 0x00, 0x00), aBitmapEx.GetPixelColor(2, 1)); - CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xff, 0xff, 0xff, 0xff), aBitmapEx.GetPixelColor(2, 2)); + Bitmap aBitmap2(aBitmap, aAlphaBitmap); + aBitmap2.CombineMaskOr(COL_RED, 1); + + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xff, 0xff, 0xff, 0xff), aBitmap2.GetPixelColor(0, 0)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x00, 0x00, 0x00), aBitmap2.GetPixelColor(0, 1)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x00, 0x00, 0x00), aBitmap2.GetPixelColor(0, 2)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xff, 0xff, 0xff, 0xff), aBitmap2.GetPixelColor(1, 0)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x00, 0x00, 0x00), aBitmap2.GetPixelColor(1, 1)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x00, 0x00, 0x00), aBitmap2.GetPixelColor(1, 2)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xff, 0xff, 0xff, 0xff), aBitmap2.GetPixelColor(2, 0)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x00, 0x00, 0x00), aBitmap2.GetPixelColor(2, 1)); + CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xff, 0xff, 0xff, 0xff), aBitmap2.GetPixelColor(2, 2)); } } // namespace diff --git a/vcl/qa/cppunit/BitmapFilterTest.cxx b/vcl/qa/cppunit/BitmapFilterTest.cxx index 5fe0278c95b8..4c48d25fd69f 100644 --- a/vcl/qa/cppunit/BitmapFilterTest.cxx +++ b/vcl/qa/cppunit/BitmapFilterTest.cxx @@ -84,8 +84,7 @@ private: return aGraphic.GetBitmap(); } - template <class BitmapT> // handle both Bitmap and BitmapEx - void savePNG(const OUString& sWhere, const BitmapT& rBmp) + void savePNG(const OUString& sWhere, const Bitmap& rBmp) { SvFileStream aStream(sWhere, StreamMode::WRITE | StreamMode::TRUNC); GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); diff --git a/vcl/qa/cppunit/graphicfilter/filters-test.cxx b/vcl/qa/cppunit/graphicfilter/filters-test.cxx index 4020af159a6d..8bc4f106763c 100644 --- a/vcl/qa/cppunit/graphicfilter/filters-test.cxx +++ b/vcl/qa/cppunit/graphicfilter/filters-test.cxx @@ -94,11 +94,10 @@ void VclFiltersTest::testScaling() for (BmpScaleFlag i = BmpScaleFlag::Default; i <= BmpScaleFlag::BiLinear; i = static_cast<BmpScaleFlag>(static_cast<int>(i) + 1)) { Bitmap aBitmap(Size(413, 409), vcl::PixelFormat::N24_BPP); - BitmapEx aBitmapEx( aBitmap ); fprintf( stderr, "scale with type %d ", int( i ) ); - CPPUNIT_ASSERT( aBitmapEx.Scale( 0.1937046, 0.193154, i ) ); - Size aAfter( aBitmapEx.GetSizePixel() ); + CPPUNIT_ASSERT( aBitmap.Scale( 0.1937046, 0.193154, i ) ); + Size aAfter( aBitmap.GetSizePixel() ); fprintf( stderr, "size %" SAL_PRIdINT64 ", %" SAL_PRIdINT64 " ", sal_Int64(aAfter.Width()), sal_Int64(aAfter.Height()) ); CPPUNIT_ASSERT( std::abs (aAfter.Height() - aAfter.Width()) <= 1 ); } diff --git a/vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx b/vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx index 12ce549fcf44..b5973e0f444b 100644 --- a/vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx +++ b/vcl/qa/cppunit/graphicfilter/filters-webp-test.cxx @@ -101,7 +101,7 @@ void WebpFilterTest::testRoundtrip(bool lossy) pAccessAlpha->SetFillColor(BitmapColor(64, 64, 64)); pAccessAlpha->FillRect(tools::Rectangle(Point(10, 10), Size(10, 10))); } - BitmapEx aBitmapEx(aBitmap, aAlpha); + Bitmap aBitmap2(aBitmap, aAlpha); SvMemoryStream aStream; GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); @@ -110,8 +110,7 @@ void WebpFilterTest::testRoundtrip(bool lossy) comphelper::makePropertyValue(u"Lossless"_ustr, !lossy), comphelper::makePropertyValue(u"Quality"_ustr, sal_Int32(100)) }; - rFilter.ExportGraphic(Graphic(Bitmap(aBitmapEx)), u"none", aStream, nFilterFormat, - &aFilterData); + rFilter.ExportGraphic(Graphic(aBitmap2), u"none", aStream, nFilterFormat, &aFilterData); aStream.Seek(STREAM_SEEK_TO_BEGIN); Graphic aGraphic; diff --git a/vcl/qa/cppunit/png/PngFilterTest.cxx b/vcl/qa/cppunit/png/PngFilterTest.cxx index e8779439dd3b..b9d1dbcc5f92 100644 --- a/vcl/qa/cppunit/png/PngFilterTest.cxx +++ b/vcl/qa/cppunit/png/PngFilterTest.cxx @@ -43,7 +43,7 @@ struct Case bool mbHasPalette; bool mbIsAlpha; }; -// Checks that a pngs BitmapEx is the same after reading and +// Checks that a pngs Bitmap is the same after reading and // after writing. Takes a vector of function pointers if there's need to test // special cases void checkImportExportPng(const OUString& sFilePath, const Case& aCase) @@ -386,11 +386,10 @@ void PngFilterTest::testPngSuite() // Some notes about the cases: // - RGB palette PNGs get converted to a bitmap with png_set_palette_to_rgb // - Grayscale PNGs with alpha also do with png_set_gray_to_rgb - // - Grayscale PNGs without alpha use BitmapEx palette utilities + // - Grayscale PNGs without alpha use Bitmap palette utilities // - 1, 2, 4 bit grayscale w/o alpha gets converted to 8 bit with png_set_expand_gray_1_2_4_to_8 // - 16 bit per channel gets converted to 8 bit per channel with png_set_scale_16 // - PNGs that are not size related have size 32x32 - // - Internally BitmapEx is never 32 bpp, instead it's 24 bpp (rgb) and uses an 8 bpp alpha mask std::pair<std::u16string_view, Case> aCases[] = { // Basic formats, not interlaced { u"basn0g01.png", @@ -1885,9 +1884,9 @@ void PngFilterTest::testPngRoundtrip24_8() } } } - BitmapEx aBitmapEx(aBitmap, aAlpha); + Bitmap aBitmap2(aBitmap, aAlpha); vcl::PngImageWriter aPngWriter(rStream); - CPPUNIT_ASSERT_EQUAL(true, aPngWriter.write(Bitmap(aBitmapEx))); + CPPUNIT_ASSERT_EQUAL(true, aPngWriter.write(aBitmap2)); } { SvStream& rStream = *aTempFile.GetStream(StreamMode::READ); @@ -2015,8 +2014,7 @@ void PngFilterTest::testDump() BitmapScopedWriteAccess pWriteAccessBitmap(aBitmap); pWriteAccessBitmap->SetPixel(0, 0, BitmapColor()); } - BitmapEx aBitmapEx(aBitmap); - aBitmapEx.DumpAsPng(aTempFile.GetURL().toUtf8().getStr()); + aBitmap.DumpAsPng(aTempFile.GetURL().toUtf8().getStr()); SvStream* pStream = aTempFile.GetStream(StreamMode::READ); CPPUNIT_ASSERT_GREATER(static_cast<sal_uInt64>(0), pStream->remainingSize()); } diff --git a/vcl/qa/cppunit/skia/skia.cxx b/vcl/qa/cppunit/skia/skia.cxx index 1d1ec471b91d..fe516fd7c45f 100644 --- a/vcl/qa/cppunit/skia/skia.cxx +++ b/vcl/qa/cppunit/skia/skia.cxx @@ -65,12 +65,11 @@ public: private: #if 0 - template <class BitmapT> // handle both Bitmap and BitmapEx - void savePNG(const OUString& sWhere, const BitmapT& rBmp) + void savePNG(const OUString& sWhere, const Bitmap& rBmp) { SvFileStream aStream(sWhere, StreamMode::WRITE | StreamMode::TRUNC); GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); - rFilter.compressAsPNG(BitmapEx(rBmp), aStream); + rFilter.compressAsPNG(rBmp, aStream); } void savePNG(const OUString& sWhere, const ScopedVclPtr<VirtualDevice>& device) { diff --git a/vcl/source/bitmap/bitmap.cxx b/vcl/source/bitmap/bitmap.cxx index bf82cbf486f3..6876e4b87451 100644 --- a/vcl/source/bitmap/bitmap.cxx +++ b/vcl/source/bitmap/bitmap.cxx @@ -37,6 +37,7 @@ #endif #include <vcl/bitmap/BitmapMonochromeFilter.hxx> #include <vcl/ImageTree.hxx> +#include <vcl/filter/PngImageWriter.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <basegfx/color/bcolormodifier.hxx> @@ -50,6 +51,7 @@ #include <bitmap/BlendFrameCache.hxx> #include <com/sun/star/beans/XFastPropertySet.hpp> #include <o3tl/any.hxx> +#include <o3tl/environment.hxx> #include "floyd.hxx" @@ -2908,4 +2910,21 @@ Bitmap Bitmap::getTransformed( return TransformBitmap(fWidth, fHeight, aTransform); } +void Bitmap::DumpAsPng(const char* pFileName) const +{ + OUString sPath(u"file:///tmp/bitmap.png"_ustr); + if (pFileName) + { + sPath = OUString::fromUtf8(pFileName); + } + else if (OUString env = o3tl::getEnvironment(u"VCL_DUMP_BMP_PATH"_ustr); !env.isEmpty()) + { + sPath = env; + } + SvFileStream aStream(sPath, StreamMode::STD_READWRITE | StreamMode::TRUNC); + assert(aStream.good()); + vcl::PngImageWriter aWriter(aStream); + aWriter.write(*this); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */