diff options
author | Chris Sherlock <chris.sherlock79@gmail.com> | 2018-04-15 10:14:10 +1000 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2018-04-16 03:25:13 +0200 |
commit | d246aa574571409046619254292698184c2545a3 (patch) | |
tree | 386144a9df7ca6a42af0c6440aaa913c8679f8f4 /vcl | |
parent | 6631cc554557c56000e0b87d595493b36e6fb7da (diff) |
vcl: move Bitmap::ImplScaleFast() and Bitmap::ImplScaleInterpolate()
Bitmap::ImplScaleFast() -> BitmapFastScaleFilter
Bitmap::ImplScaleInterpolate() -> BitmapInterpolateScaleFilter
Change-Id: Ieb39cc21df5d98563945968cec81b7c51f64177f
Reviewed-on: https://gerrit.libreoffice.org/52899
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/Library_vcl.mk | 2 | ||||
-rw-r--r-- | vcl/inc/BitmapFastScaleFilter.hxx | 41 | ||||
-rw-r--r-- | vcl/inc/BitmapInterpolateScaleFilter.hxx | 41 | ||||
-rw-r--r-- | vcl/source/bitmap/BitmapFastScaleFilter.cxx | 130 | ||||
-rw-r--r-- | vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx | 236 | ||||
-rwxr-xr-x | vcl/source/gdi/bitmap3.cxx | 265 | ||||
-rwxr-xr-x[-rw-r--r--] | vcl/source/gdi/bitmapex.cxx | 7 |
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 ) { |