diff options
Diffstat (limited to 'vcl/source/gdi/bitmap3.cxx')
-rwxr-xr-x | vcl/source/gdi/bitmap3.cxx | 265 |
1 files changed, 6 insertions, 259 deletions
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; |