summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/Library_vcl.mk2
-rw-r--r--vcl/inc/BitmapFastScaleFilter.hxx41
-rw-r--r--vcl/inc/BitmapInterpolateScaleFilter.hxx41
-rw-r--r--vcl/source/bitmap/BitmapFastScaleFilter.cxx130
-rw-r--r--vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx236
-rwxr-xr-xvcl/source/gdi/bitmap3.cxx265
-rwxr-xr-x[-rw-r--r--]vcl/source/gdi/bitmapex.cxx7
7 files changed, 460 insertions, 262 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 3a819cefab26..93d1faf1826e 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -313,10 +313,12 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/graphic/UnoGraphicTransformer \
vcl/source/bitmap/bitmap \
vcl/source/bitmap/bitmapfilter \
+ vcl/source/bitmap/BitmapInterpolateScaleFilter \
vcl/source/bitmap/BitmapLightenFilter \
vcl/source/bitmap/BitmapDisabledImageFilter \
vcl/source/bitmap/BitmapColorizeFilter \
vcl/source/bitmap/bitmappaint \
+ vcl/source/bitmap/BitmapFastScaleFilter \
vcl/source/bitmap/BitmapScaleSuperFilter \
vcl/source/bitmap/BitmapScaleConvolutionFilter \
vcl/source/bitmap/BitmapSymmetryCheck \
diff --git a/vcl/inc/BitmapFastScaleFilter.hxx b/vcl/inc/BitmapFastScaleFilter.hxx
new file mode 100644
index 000000000000..c1ee11bf1a84
--- /dev/null
+++ b/vcl/inc/BitmapFastScaleFilter.hxx
@@ -0,0 +1,41 @@
+/* -*- 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/.
+ *
+ */
+
+#ifndef VCL_INC_BITMAPFASTSCALEFILTER_HXX
+#define VCL_INC_BITMAPFASTSCALEFILTER_HXX
+
+#include <vcl/bitmapex.hxx>
+#include <vcl/BitmapFilter.hxx>
+
+class VCL_DLLPUBLIC BitmapFastScaleFilter : public BitmapFilter
+{
+public:
+ explicit BitmapFastScaleFilter(double fScaleX, double fScaleY)
+ : mfScaleX(fScaleX)
+ , mfScaleY(fScaleY)
+ {
+ }
+
+ explicit BitmapFastScaleFilter(Size aSize)
+ : maSize(aSize)
+ {
+ }
+
+ virtual BitmapEx execute(BitmapEx const& rBitmapEx) override;
+
+private:
+ double mfScaleX;
+ double mfScaleY;
+ Size maSize;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/BitmapInterpolateScaleFilter.hxx b/vcl/inc/BitmapInterpolateScaleFilter.hxx
new file mode 100644
index 000000000000..0fbe9ac3f4a8
--- /dev/null
+++ b/vcl/inc/BitmapInterpolateScaleFilter.hxx
@@ -0,0 +1,41 @@
+/* -*- 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/.
+ *
+ */
+
+#ifndef VCL_INC_BITMAPINTERPOLATESCALEFILTER_HXX
+#define VCL_INC_BITMAPINTERPOLATESCALEFILTER_HXX
+
+#include <vcl/bitmapex.hxx>
+#include <vcl/BitmapFilter.hxx>
+
+class VCL_DLLPUBLIC BitmapInterpolateScaleFilter : public BitmapFilter
+{
+public:
+ explicit BitmapInterpolateScaleFilter(double fScaleX, double fScaleY)
+ : mfScaleX(fScaleX)
+ , mfScaleY(fScaleY)
+ {
+ }
+
+ explicit BitmapInterpolateScaleFilter(Size aSize)
+ : maSize(aSize)
+ {
+ }
+
+ virtual BitmapEx execute(BitmapEx const& rBitmapEx) override;
+
+private:
+ double mfScaleX;
+ double mfScaleY;
+ Size maSize;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/bitmap/BitmapFastScaleFilter.cxx b/vcl/source/bitmap/BitmapFastScaleFilter.cxx
new file mode 100644
index 000000000000..6bf1700a476f
--- /dev/null
+++ b/vcl/source/bitmap/BitmapFastScaleFilter.cxx
@@ -0,0 +1,130 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/helpers.hxx>
+
+#include <vcl/bitmapex.hxx>
+#include <vcl/bitmapaccess.hxx>
+
+#include <bitmapwriteaccess.hxx>
+#include <BitmapFastScaleFilter.hxx>
+
+BitmapEx BitmapFastScaleFilter::execute(BitmapEx const& rBitmapEx)
+{
+ SAL_INFO("vcl.gdi", "BitmapFastScaleFilter::execute()");
+
+ Bitmap aBitmap(rBitmapEx.GetBitmap());
+
+ const Size aSizePix(aBitmap.GetSizePixel());
+ const long nNewWidth = FRound(aSizePix.Width() * mfScaleX);
+ const long nNewHeight = FRound(aSizePix.Height() * mfScaleY);
+ bool bRet = false;
+
+ SAL_INFO("vcl.gdi", "New width: " << nNewWidth << "\nNew height: " << nNewHeight);
+
+ if (nNewWidth && nNewHeight)
+ {
+ Bitmap::ScopedReadAccess pReadAcc(aBitmap);
+
+ if (pReadAcc)
+ {
+ Bitmap aNewBmp(Size(nNewWidth, nNewHeight), aBitmap.GetBitCount(),
+ &pReadAcc->GetPalette());
+ BitmapScopedWriteAccess pWriteAcc(aNewBmp);
+
+ if (pWriteAcc)
+ {
+ const long nScanlineSize = pWriteAcc->GetScanlineSize();
+ const long nNewWidth1 = nNewWidth - 1;
+ const long nNewHeight1 = nNewHeight - 1;
+
+ if (nNewWidth1 && nNewHeight1)
+ {
+ const double nWidth = pReadAcc->Width();
+ const double nHeight = pReadAcc->Height();
+ std::unique_ptr<long[]> pLutX(new long[nNewWidth]);
+ std::unique_ptr<long[]> pLutY(new long[nNewHeight]);
+
+ for (long nX = 0; nX < nNewWidth; nX++)
+ {
+ pLutX[nX] = long(nX * nWidth / nNewWidth);
+ }
+
+ for (long nY = 0; nY < nNewHeight; nY++)
+ {
+ pLutY[nY] = long(nY * nHeight / nNewHeight);
+ }
+
+ long nActY = 0;
+ while (nActY < nNewHeight)
+ {
+ long nMapY = pLutY[nActY];
+ Scanline pScanline = pWriteAcc->GetScanline(nActY);
+ Scanline pScanlineRead = pReadAcc->GetScanline(nMapY);
+
+ for (long nX = 0; nX < nNewWidth; nX++)
+ {
+ pWriteAcc->SetPixelOnData(
+ pScanline, nX,
+ pReadAcc->GetPixelFromData(pScanlineRead, pLutX[nX]));
+ }
+
+ while ((nActY < nNewHeight1) && (pLutY[nActY + 1] == nMapY))
+ {
+ memcpy(pWriteAcc->GetScanline(nActY + 1), pWriteAcc->GetScanline(nActY),
+ nScanlineSize);
+ nActY++;
+ }
+ nActY++;
+ }
+
+ bRet = true;
+ }
+
+ pWriteAcc.reset();
+ }
+ pReadAcc.reset();
+
+ if (bRet)
+ {
+ aBitmap.ReassignWithSize(aNewBmp);
+ SAL_INFO("vcl.gdi", "Bitmap size: " << aBitmap.GetSizePixel());
+ }
+ else
+ {
+ SAL_WARN("vcl.gdi", "no resize");
+ }
+ }
+ }
+
+ Bitmap aMask(rBitmapEx.GetMask());
+
+ if (bRet && (rBitmapEx.GetTransparentType() == TransparentType::Bitmap) && !aMask.IsEmpty())
+ bRet = aMask.Scale(maSize, BmpScaleFlag::Fast);
+
+ SAL_WARN_IF(!aMask.IsEmpty() && aBitmap.GetSizePixel() != aMask.GetSizePixel(), "vcl",
+ "BitmapEx::Scale(): size mismatch for bitmap and alpha mask.");
+
+ if (bRet)
+ return BitmapEx(aBitmap, aMask);
+
+ return BitmapEx();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx b/vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx
new file mode 100644
index 000000000000..43e4d2ff0f24
--- /dev/null
+++ b/vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx
@@ -0,0 +1,236 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/helpers.hxx>
+
+#include <vcl/bitmapex.hxx>
+#include <vcl/bitmapaccess.hxx>
+
+#include <bitmapwriteaccess.hxx>
+#include <BitmapFastScaleFilter.hxx>
+#include <BitmapInterpolateScaleFilter.hxx>
+
+BitmapEx BitmapInterpolateScaleFilter::execute(BitmapEx const& rBitmapEx)
+{
+ Bitmap aBitmap(rBitmapEx.GetBitmap());
+
+ const Size aSizePix(aBitmap.GetSizePixel());
+ const long nNewWidth = FRound(aSizePix.Width() * mfScaleX);
+ const long nNewHeight = FRound(aSizePix.Height() * mfScaleY);
+ bool bRet = false;
+
+ if ((nNewWidth > 1) && (nNewHeight > 1))
+ {
+ Bitmap::ScopedReadAccess pReadAcc(aBitmap);
+ if (pReadAcc)
+ {
+ long nWidth = pReadAcc->Width();
+ long nHeight = pReadAcc->Height();
+ Bitmap aNewBmp(Size(nNewWidth, nHeight), 24);
+ BitmapScopedWriteAccess pWriteAcc(aNewBmp);
+
+ if (pWriteAcc)
+ {
+ const long nNewWidth1 = nNewWidth - 1;
+ const long nWidth1 = pReadAcc->Width() - 1;
+ const double fRevScaleX = static_cast<double>(nWidth1) / nNewWidth1;
+
+ std::unique_ptr<long[]> pLutInt(new long[nNewWidth]);
+ std::unique_ptr<long[]> pLutFrac(new long[nNewWidth]);
+
+ for (long nX = 0, nTemp = nWidth - 2; nX < nNewWidth; nX++)
+ {
+ double fTemp = nX * fRevScaleX;
+ pLutInt[nX] = MinMax(static_cast<long>(fTemp), 0, nTemp);
+ fTemp -= pLutInt[nX];
+ pLutFrac[nX] = static_cast<long>(fTemp * 1024.);
+ }
+
+ for (long nY = 0; nY < nHeight; nY++)
+ {
+ Scanline pScanlineRead = pReadAcc->GetScanline(nY);
+ if (1 == nWidth)
+ {
+ BitmapColor aCol0;
+ if (pReadAcc->HasPalette())
+ {
+ aCol0 = pReadAcc->GetPaletteColor(
+ pReadAcc->GetIndexFromData(pScanlineRead, 0));
+ }
+ else
+ {
+ aCol0 = pReadAcc->GetPixelFromData(pScanlineRead, 0);
+ }
+
+ Scanline pScanline = pWriteAcc->GetScanline(nY);
+ for (long nX = 0; nX < nNewWidth; nX++)
+ {
+ pWriteAcc->SetPixelOnData(pScanline, nX, aCol0);
+ }
+ }
+ else
+ {
+ Scanline pScanline = pWriteAcc->GetScanline(nY);
+ for (long nX = 0; nX < nNewWidth; nX++)
+ {
+ long nTemp = pLutInt[nX];
+
+ BitmapColor aCol0, aCol1;
+ if (pReadAcc->HasPalette())
+ {
+ aCol0 = pReadAcc->GetPaletteColor(
+ pReadAcc->GetIndexFromData(pScanlineRead, nTemp++));
+ aCol1 = pReadAcc->GetPaletteColor(
+ pReadAcc->GetIndexFromData(pScanlineRead, nTemp));
+ }
+ else
+ {
+ aCol0 = pReadAcc->GetPixelFromData(pScanlineRead, nTemp++);
+ aCol1 = pReadAcc->GetPixelFromData(pScanlineRead, nTemp);
+ }
+
+ nTemp = pLutFrac[nX];
+
+ long lXR0 = aCol0.GetRed();
+ long lXG0 = aCol0.GetGreen();
+ long lXB0 = aCol0.GetBlue();
+ long lXR1 = aCol1.GetRed() - lXR0;
+ long lXG1 = aCol1.GetGreen() - lXG0;
+ long lXB1 = aCol1.GetBlue() - lXB0;
+
+ aCol0.SetRed(
+ static_cast<sal_uInt8>((lXR1 * nTemp + (lXR0 << 10)) >> 10));
+ aCol0.SetGreen(
+ static_cast<sal_uInt8>((lXG1 * nTemp + (lXG0 << 10)) >> 10));
+ aCol0.SetBlue(
+ static_cast<sal_uInt8>((lXB1 * nTemp + (lXB0 << 10)) >> 10));
+
+ pWriteAcc->SetPixelOnData(pScanline, nX, aCol0);
+ }
+ }
+ }
+
+ bRet = true;
+ }
+
+ pReadAcc.reset();
+ pWriteAcc.reset();
+
+ if (bRet)
+ {
+ bRet = false;
+ const Bitmap aOriginal(aBitmap);
+ aBitmap = aNewBmp;
+ aNewBmp = Bitmap(Size(nNewWidth, nNewHeight), 24);
+ pReadAcc = Bitmap::ScopedReadAccess(aBitmap);
+ pWriteAcc = BitmapScopedWriteAccess(aNewBmp);
+
+ if (pReadAcc && pWriteAcc)
+ {
+ const long nNewHeight1 = nNewHeight - 1;
+ const long nHeight1 = pReadAcc->Height() - 1;
+ const double fRevScaleY = static_cast<double>(nHeight1) / nNewHeight1;
+
+ std::unique_ptr<long[]> pLutInt(new long[nNewHeight]);
+ std::unique_ptr<long[]> pLutFrac(new long[nNewHeight]);
+
+ for (long nY = 0, nTemp = nHeight - 2; nY < nNewHeight; nY++)
+ {
+ double fTemp = nY * fRevScaleY;
+ pLutInt[nY] = MinMax(static_cast<long>(fTemp), 0, nTemp);
+ fTemp -= pLutInt[nY];
+ pLutFrac[nY] = static_cast<long>(fTemp * 1024.);
+ }
+
+ // after 1st step, bitmap *is* 24bit format (see above)
+ OSL_ENSURE(!pReadAcc->HasPalette(), "OOps, somehow ImplScaleInterpolate "
+ "in-between format has palette, should not "
+ "happen (!)");
+
+ for (long nX = 0; nX < nNewWidth; nX++)
+ {
+ if (1 == nHeight)
+ {
+ BitmapColor aCol0 = pReadAcc->GetPixel(0, nX);
+
+ for (long nY = 0; nY < nNewHeight; nY++)
+ {
+ pWriteAcc->SetPixel(nY, nX, aCol0);
+ }
+ }
+ else
+ {
+ for (long nY = 0; nY < nNewHeight; nY++)
+ {
+ long nTemp = pLutInt[nY];
+
+ BitmapColor aCol0 = pReadAcc->GetPixel(nTemp++, nX);
+ BitmapColor aCol1 = pReadAcc->GetPixel(nTemp, nX);
+
+ nTemp = pLutFrac[nY];
+
+ long lXR0 = aCol0.GetRed();
+ long lXG0 = aCol0.GetGreen();
+ long lXB0 = aCol0.GetBlue();
+ long lXR1 = aCol1.GetRed() - lXR0;
+ long lXG1 = aCol1.GetGreen() - lXG0;
+ long lXB1 = aCol1.GetBlue() - lXB0;
+
+ aCol0.SetRed(
+ static_cast<sal_uInt8>((lXR1 * nTemp + (lXR0 << 10)) >> 10));
+ aCol0.SetGreen(
+ static_cast<sal_uInt8>((lXG1 * nTemp + (lXG0 << 10)) >> 10));
+ aCol0.SetBlue(
+ static_cast<sal_uInt8>((lXB1 * nTemp + (lXB0 << 10)) >> 10));
+
+ pWriteAcc->SetPixel(nY, nX, aCol0);
+ }
+ }
+ }
+
+ bRet = true;
+ }
+
+ pReadAcc.reset();
+ pWriteAcc.reset();
+
+ if (bRet)
+ {
+ aOriginal.AdaptBitCount(aNewBmp);
+ aBitmap = aNewBmp;
+ }
+ }
+ }
+ }
+
+ if (!bRet)
+ {
+ // fallback to fast scale filter
+ BitmapEx aBmpEx(aBitmap);
+ bRet = BitmapFilter::Filter(aBmpEx, BitmapFastScaleFilter(mfScaleX, mfScaleY));
+ aBitmap = aBmpEx.GetBitmap();
+ }
+
+ if (bRet)
+ return BitmapEx(aBitmap);
+
+ return BitmapEx();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index b933e41ba2f1..b42731e3696a 100755
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -32,6 +32,8 @@
#include <impoctree.hxx>
#include <BitmapScaleSuperFilter.hxx>
#include <BitmapScaleConvolutionFilter.hxx>
+#include <BitmapFastScaleFilter.hxx>
+#include <BitmapInterpolateScaleFilter.hxx>
#include <bitmapwriteaccess.hxx>
#include <octree.hxx>
@@ -761,16 +763,16 @@ bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag n
switch(nScaleFlag)
{
case BmpScaleFlag::Fast:
- bRetval = ImplScaleFast( rScaleX, rScaleY );
+ bRetval = BitmapFilter::Filter(aBmpEx, BitmapFastScaleFilter(rScaleX, rScaleY));
break;
case BmpScaleFlag::Interpolate:
- bRetval = ImplScaleInterpolate(rScaleX, rScaleY);
+ bRetval = BitmapFilter::Filter(aBmpEx, BitmapInterpolateScaleFilter(rScaleX, rScaleY));
break;
case BmpScaleFlag::Default:
if (GetSizePixel().Width() < 2 || GetSizePixel().Height() < 2)
- bRetval = ImplScaleFast(rScaleX, rScaleY);
+ bRetval = BitmapFilter::Filter(aBmpEx, BitmapFastScaleFilter(rScaleX, rScaleY));
else
bRetval = BitmapFilter::Filter(aBmpEx, BitmapScaleSuperFilter(rScaleX, rScaleY));
break;
@@ -789,7 +791,7 @@ bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag n
break;
}
- if (bRetval && nScaleFlag != BmpScaleFlag::Fast && nScaleFlag != BmpScaleFlag::Interpolate)
+ if (bRetval)
*this = aBmpEx.GetBitmapRef();
OSL_ENSURE(!bRetval || nStartCount == GetBitCount(), "Bitmap::Scale has changed the ColorDepth, this should *not* happen (!)");
@@ -872,261 +874,6 @@ void Bitmap::AdaptBitCount(Bitmap& rNew) const
}
}
-bool Bitmap::ImplScaleFast( const double& rScaleX, const double& rScaleY )
-{
- const Size aSizePix( GetSizePixel() );
- const long nNewWidth = FRound( aSizePix.Width() * rScaleX );
- const long nNewHeight = FRound( aSizePix.Height() * rScaleY );
- bool bRet = false;
-
- if( nNewWidth && nNewHeight )
- {
- ScopedReadAccess pReadAcc(*this);
-
- if(pReadAcc)
- {
- Bitmap aNewBmp( Size( nNewWidth, nNewHeight ), GetBitCount(), &pReadAcc->GetPalette() );
- BitmapScopedWriteAccess pWriteAcc(aNewBmp);
-
- if( pWriteAcc )
- {
- const long nScanlineSize = pWriteAcc->GetScanlineSize();
- const long nNewWidth1 = nNewWidth - 1;
- const long nNewHeight1 = nNewHeight - 1;
-
- if( nNewWidth1 && nNewHeight1 )
- {
- const double nWidth = pReadAcc->Width();
- const double nHeight = pReadAcc->Height();
- std::unique_ptr<long[]> pLutX(new long[ nNewWidth ]);
- std::unique_ptr<long[]> pLutY(new long[ nNewHeight ]);
-
- for( long nX = 0; nX < nNewWidth; nX++ )
- pLutX[ nX ] = long(nX * nWidth / nNewWidth);
-
- for( long nY = 0; nY < nNewHeight; nY++ )
- pLutY[ nY ] = long(nY * nHeight / nNewHeight);
-
- long nActY = 0;
- while( nActY < nNewHeight )
- {
- long nMapY = pLutY[ nActY ];
- Scanline pScanline = pWriteAcc->GetScanline(nActY);
- Scanline pScanlineRead = pReadAcc->GetScanline(nMapY);
-
- for( long nX = 0; nX < nNewWidth; nX++ )
- pWriteAcc->SetPixelOnData( pScanline, nX, pReadAcc->GetPixelFromData( pScanlineRead , pLutX[ nX ] ) );
-
- while( ( nActY < nNewHeight1 ) && ( pLutY[ nActY + 1 ] == nMapY ) )
- {
- memcpy( pWriteAcc->GetScanline( nActY + 1 ),
- pWriteAcc->GetScanline( nActY ), nScanlineSize );
- nActY++;
- }
- nActY++;
- }
-
- bRet = true;
- }
-
- pWriteAcc.reset();
- }
- pReadAcc.reset();
-
- if (bRet)
- ReassignWithSize(aNewBmp);
- }
- }
-
- return bRet;
-}
-
-bool Bitmap::ImplScaleInterpolate( const double& rScaleX, const double& rScaleY )
-{
- const Size aSizePix( GetSizePixel() );
- const long nNewWidth = FRound( aSizePix.Width() * rScaleX );
- const long nNewHeight = FRound( aSizePix.Height() * rScaleY );
- bool bRet = false;
-
- if( ( nNewWidth > 1 ) && ( nNewHeight > 1 ) )
- {
- ScopedReadAccess pReadAcc(*this);
- if( pReadAcc )
- {
- long nWidth = pReadAcc->Width();
- long nHeight = pReadAcc->Height();
- Bitmap aNewBmp( Size( nNewWidth, nHeight ), 24 );
- BitmapScopedWriteAccess pWriteAcc(aNewBmp);
-
- if( pWriteAcc )
- {
- const long nNewWidth1 = nNewWidth - 1;
- const long nWidth1 = pReadAcc->Width() - 1;
- const double fRevScaleX = static_cast<double>(nWidth1) / nNewWidth1;
-
- std::unique_ptr<long[]> pLutInt(new long[ nNewWidth ]);
- std::unique_ptr<long[]> pLutFrac(new long[ nNewWidth ]);
-
- for( long nX = 0, nTemp = nWidth - 2; nX < nNewWidth; nX++ )
- {
- double fTemp = nX * fRevScaleX;
- pLutInt[ nX ] = MinMax( static_cast<long>(fTemp), 0, nTemp );
- fTemp -= pLutInt[ nX ];
- pLutFrac[ nX ] = static_cast<long>( fTemp * 1024. );
- }
-
- for( long nY = 0; nY < nHeight; nY++ )
- {
- Scanline pScanlineRead = pReadAcc->GetScanline(nY);
- if( 1 == nWidth )
- {
- BitmapColor aCol0;
- if( pReadAcc->HasPalette() )
- {
- aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetIndexFromData( pScanlineRead, 0 ) );
- }
- else
- {
- aCol0 = pReadAcc->GetPixelFromData( pScanlineRead, 0 );
- }
-
- Scanline pScanline = pWriteAcc->GetScanline(nY);
- for( long nX = 0; nX < nNewWidth; nX++ )
- {
- pWriteAcc->SetPixelOnData( pScanline, nX, aCol0 );
- }
- }
- else
- {
- Scanline pScanline = pWriteAcc->GetScanline(nY);
- for( long nX = 0; nX < nNewWidth; nX++ )
- {
- long nTemp = pLutInt[ nX ];
-
- BitmapColor aCol0, aCol1;
- if( pReadAcc->HasPalette() )
- {
- aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetIndexFromData( pScanlineRead, nTemp++ ) );
- aCol1 = pReadAcc->GetPaletteColor( pReadAcc->GetIndexFromData( pScanlineRead, nTemp ) );
- }
- else
- {
- aCol0 = pReadAcc->GetPixelFromData( pScanlineRead, nTemp++ );
- aCol1 = pReadAcc->GetPixelFromData( pScanlineRead, nTemp );
- }
-
- nTemp = pLutFrac[ nX ];
-
- long lXR0 = aCol0.GetRed();
- long lXG0 = aCol0.GetGreen();
- long lXB0 = aCol0.GetBlue();
- long lXR1 = aCol1.GetRed() - lXR0;
- long lXG1 = aCol1.GetGreen() - lXG0;
- long lXB1 = aCol1.GetBlue() - lXB0;
-
- aCol0.SetRed( static_cast<sal_uInt8>( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
- aCol0.SetGreen( static_cast<sal_uInt8>( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
- aCol0.SetBlue( static_cast<sal_uInt8>( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
-
- pWriteAcc->SetPixelOnData( pScanline, nX, aCol0 );
- }
- }
- }
-
- bRet = true;
- }
-
- pReadAcc.reset();
- pWriteAcc.reset();
-
- if( bRet )
- {
- bRet = false;
- const Bitmap aOriginal(*this);
- *this = aNewBmp;
- aNewBmp = Bitmap( Size( nNewWidth, nNewHeight ), 24 );
- pReadAcc = ScopedReadAccess(*this);
- pWriteAcc = BitmapScopedWriteAccess(aNewBmp);
-
- if( pReadAcc && pWriteAcc )
- {
- const long nNewHeight1 = nNewHeight - 1;
- const long nHeight1 = pReadAcc->Height() - 1;
- const double fRevScaleY = static_cast<double>(nHeight1) / nNewHeight1;
-
- std::unique_ptr<long[]> pLutInt(new long[ nNewHeight ]);
- std::unique_ptr<long[]> pLutFrac(new long[ nNewHeight ]);
-
- for( long nY = 0, nTemp = nHeight - 2; nY < nNewHeight; nY++ )
- {
- double fTemp = nY * fRevScaleY;
- pLutInt[ nY ] = MinMax( static_cast<long>(fTemp), 0, nTemp );
- fTemp -= pLutInt[ nY ];
- pLutFrac[ nY ] = static_cast<long>( fTemp * 1024. );
- }
-
- // after 1st step, bitmap *is* 24bit format (see above)
- OSL_ENSURE(!pReadAcc->HasPalette(), "OOps, somehow ImplScaleInterpolate in-between format has palette, should not happen (!)");
-
- for( long nX = 0; nX < nNewWidth; nX++ )
- {
- if( 1 == nHeight )
- {
- BitmapColor aCol0 = pReadAcc->GetPixel( 0, nX );
-
- for( long nY = 0; nY < nNewHeight; nY++ )
- {
- pWriteAcc->SetPixel( nY, nX, aCol0 );
- }
- }
- else
- {
- for( long nY = 0; nY < nNewHeight; nY++ )
- {
- long nTemp = pLutInt[ nY ];
-
- BitmapColor aCol0 = pReadAcc->GetPixel( nTemp++, nX );
- BitmapColor aCol1 = pReadAcc->GetPixel( nTemp, nX );
-
- nTemp = pLutFrac[ nY ];
-
- long lXR0 = aCol0.GetRed();
- long lXG0 = aCol0.GetGreen();
- long lXB0 = aCol0.GetBlue();
- long lXR1 = aCol1.GetRed() - lXR0;
- long lXG1 = aCol1.GetGreen() - lXG0;
- long lXB1 = aCol1.GetBlue() - lXB0;
-
- aCol0.SetRed( static_cast<sal_uInt8>( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
- aCol0.SetGreen( static_cast<sal_uInt8>( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
- aCol0.SetBlue( static_cast<sal_uInt8>( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
-
- pWriteAcc->SetPixel( nY, nX, aCol0 );
- }
- }
- }
-
- bRet = true;
- }
-
- pReadAcc.reset();
- pWriteAcc.reset();
-
- if( bRet )
- {
- aOriginal.AdaptBitCount(aNewBmp);
- *this = aNewBmp;
- }
- }
- }
- }
-
- if (!bRet)
- bRet = ImplScaleFast(rScaleX, rScaleY);
-
- return bRet;
-}
-
bool Bitmap::Dither( BmpDitherFlags nDitherFlags )
{
bool bRet = false;
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index d107c55631f0..5b03870578cd 100644..100755
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -19,11 +19,10 @@
#include <rtl/crc.h>
#include <rtl/strbuf.hxx>
-#include <o3tl/any.hxx>
#include <tools/debug.hxx>
-#include <unotools/resmgr.hxx>
#include <tools/stream.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <unotools/resmgr.hxx>
#include <vcl/ImageTree.hxx>
#include <vcl/salbtype.hxx>
@@ -40,9 +39,12 @@
#include <salbmp.hxx>
#include <salinst.hxx>
#include <svdata.hxx>
+#include <BitmapFastScaleFilter.hxx>
#include <bitmapwriteaccess.hxx>
#include <image.h>
+#include <o3tl/any.hxx>
+
#include <com/sun/star/beans/XFastPropertySet.hpp>
#include <memory>
@@ -119,7 +121,6 @@ BitmapEx::BitmapEx( const Bitmap& rBmp, const Bitmap& rMask ) :
meTransparent ( !rMask ? TransparentType::NONE : TransparentType::Bitmap ),
mbAlpha ( false )
{
- SAL_INFO("vcl.gdi", "Bitmap size: " << maBitmapSize);
// Ensure a mask is exactly one bit deep
if( !!maMask && maMask.GetBitCount() != 1 )
{