From d246aa574571409046619254292698184c2545a3 Mon Sep 17 00:00:00 2001 From: Chris Sherlock Date: Sun, 15 Apr 2018 10:14:10 +1000 Subject: vcl: move Bitmap::ImplScaleFast() and Bitmap::ImplScaleInterpolate() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bitmap::ImplScaleFast() -> BitmapFastScaleFilter Bitmap::ImplScaleInterpolate() -> BitmapInterpolateScaleFilter Change-Id: Ieb39cc21df5d98563945968cec81b7c51f64177f Reviewed-on: https://gerrit.libreoffice.org/52899 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl --- vcl/Library_vcl.mk | 2 + vcl/inc/BitmapFastScaleFilter.hxx | 41 ++++ vcl/inc/BitmapInterpolateScaleFilter.hxx | 41 ++++ vcl/source/bitmap/BitmapFastScaleFilter.cxx | 130 ++++++++++ vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx | 236 ++++++++++++++++++ vcl/source/gdi/bitmap3.cxx | 265 +-------------------- vcl/source/gdi/bitmapex.cxx | 7 +- 7 files changed, 460 insertions(+), 262 deletions(-) create mode 100644 vcl/inc/BitmapFastScaleFilter.hxx create mode 100644 vcl/inc/BitmapInterpolateScaleFilter.hxx create mode 100644 vcl/source/bitmap/BitmapFastScaleFilter.cxx create mode 100644 vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx mode change 100644 => 100755 vcl/source/gdi/bitmapex.cxx 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 +#include + +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 +#include + +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 + +#include +#include + +#include +#include + +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 pLutX(new long[nNewWidth]); + std::unique_ptr 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 + +#include +#include + +#include +#include +#include + +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(nWidth1) / nNewWidth1; + + std::unique_ptr pLutInt(new long[nNewWidth]); + std::unique_ptr pLutFrac(new long[nNewWidth]); + + for (long nX = 0, nTemp = nWidth - 2; nX < nNewWidth; nX++) + { + double fTemp = nX * fRevScaleX; + pLutInt[nX] = MinMax(static_cast(fTemp), 0, nTemp); + fTemp -= pLutInt[nX]; + pLutFrac[nX] = static_cast(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((lXR1 * nTemp + (lXR0 << 10)) >> 10)); + aCol0.SetGreen( + static_cast((lXG1 * nTemp + (lXG0 << 10)) >> 10)); + aCol0.SetBlue( + static_cast((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(nHeight1) / nNewHeight1; + + std::unique_ptr pLutInt(new long[nNewHeight]); + std::unique_ptr pLutFrac(new long[nNewHeight]); + + for (long nY = 0, nTemp = nHeight - 2; nY < nNewHeight; nY++) + { + double fTemp = nY * fRevScaleY; + pLutInt[nY] = MinMax(static_cast(fTemp), 0, nTemp); + fTemp -= pLutInt[nY]; + pLutFrac[nY] = static_cast(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((lXR1 * nTemp + (lXR0 << 10)) >> 10)); + aCol0.SetGreen( + static_cast((lXG1 * nTemp + (lXG0 << 10)) >> 10)); + aCol0.SetBlue( + static_cast((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 #include #include +#include +#include #include #include @@ -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 pLutX(new long[ nNewWidth ]); - std::unique_ptr 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(nWidth1) / nNewWidth1; - - std::unique_ptr pLutInt(new long[ nNewWidth ]); - std::unique_ptr pLutFrac(new long[ nNewWidth ]); - - for( long nX = 0, nTemp = nWidth - 2; nX < nNewWidth; nX++ ) - { - double fTemp = nX * fRevScaleX; - pLutInt[ nX ] = MinMax( static_cast(fTemp), 0, nTemp ); - fTemp -= pLutInt[ nX ]; - pLutFrac[ nX ] = static_cast( 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( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) ); - aCol0.SetGreen( static_cast( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) ); - aCol0.SetBlue( static_cast( ( 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(nHeight1) / nNewHeight1; - - std::unique_ptr pLutInt(new long[ nNewHeight ]); - std::unique_ptr pLutFrac(new long[ nNewHeight ]); - - for( long nY = 0, nTemp = nHeight - 2; nY < nNewHeight; nY++ ) - { - double fTemp = nY * fRevScaleY; - pLutInt[ nY ] = MinMax( static_cast(fTemp), 0, nTemp ); - fTemp -= pLutInt[ nY ]; - pLutFrac[ nY ] = static_cast( 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( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) ); - aCol0.SetGreen( static_cast( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) ); - aCol0.SetBlue( static_cast( ( 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 old mode 100644 new mode 100755 index d107c55631f0..5b03870578cd --- a/vcl/source/gdi/bitmapex.cxx +++ b/vcl/source/gdi/bitmapex.cxx @@ -19,11 +19,10 @@ #include #include -#include #include -#include #include #include +#include #include #include @@ -40,9 +39,12 @@ #include #include #include +#include #include #include +#include + #include #include @@ -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 ) { -- cgit