From 60095b481d9663f7bcfe8078d669030ab2bc6a05 Mon Sep 17 00:00:00 2001 From: Tomaž Vajngerl Date: Tue, 30 Apr 2019 00:53:37 +0900 Subject: tdf#125014 only use a fastpath if src. and dest. bitcount matches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It can happen that a bitmap is 32-bit (made from a VirtualDevice) but we can't even create a 32-bit bitmap ourselves. In that case we can only create a 24-bit, but now we can't use the fastpath anymore as the bitdepth of source and destination is not the same. Fix this by making sure the general scaler will be used when source and destination bitmaps don't have the same bitcount. Change-Id: Icdb974093558d618b7c056b29963b45ee31ce200 Reviewed-on: https://gerrit.libreoffice.org/71540 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl --- vcl/source/bitmap/BitmapScaleSuperFilter.cxx | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'vcl') diff --git a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx index 26ea43af44a8..54f22f2dc5d8 100644 --- a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx +++ b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx @@ -1049,10 +1049,12 @@ BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const { Bitmap::ScopedReadAccess pReadAccess(aBitmap); - sal_Int16 nTargetBitcount = aBitmap.GetBitCount() == 32 ? 32 : 24; + sal_uInt16 nSourceBitcount = aBitmap.GetBitCount(); - Bitmap aOutBmp(Size(nDstW, nDstH), nTargetBitcount); + Bitmap aOutBmp(Size(nDstW, nDstH), std::max(nSourceBitcount, sal_uInt16(24))); Size aOutSize = aOutBmp.GetSizePixel(); + sal_uInt16 nTargetBitcount = aOutBmp.GetBitCount(); + if (!aOutSize.Width() || !aOutSize.Height()) { SAL_WARN("vcl.gdi", "bmp creation failed"); @@ -1076,7 +1078,10 @@ BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const bVMirr, bHMirr ); bool bScaleUp = fScaleX >= fScaleThresh && fScaleY >= fScaleThresh; - if( pReadAccess->HasPalette() ) + // If we have a source bitmap with a palette the scaling converts + // from up to 8 bit image -> 24 bit non-palette, which is then + // adapted back to the same type as original. + if (pReadAccess->HasPalette()) { switch( pReadAccess->GetScanlineFormat() ) { @@ -1090,21 +1095,30 @@ BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const break; } } + // Here we know that we are dealing with a non-palette source bitmap. + // The target is either 24 or 32 bit, depending on the image and + // the capabilities of the backend. If for some reason the destination + // is not the same bit-depth as the source, then we can't use + // a fast path, so we always need to process with a general scaler. + else if (nSourceBitcount != nTargetBitcount) + { + pScaleRangeFn = bScaleUp ? scaleUpNonPalleteGeneral : scaleDownNonPalleteGeneral; + } + // If we get here then we can only use a fast path, but let's + // still keep the fallback to the general scaler alive. else { switch( pReadAccess->GetScanlineFormat() ) { case ScanlineFormat::N24BitTcBgr: case ScanlineFormat::N24BitTcRgb: - pScaleRangeFn = bScaleUp ? scaleUp24bit - : scaleDown24bit; + pScaleRangeFn = bScaleUp ? scaleUp24bit : scaleDown24bit; break; case ScanlineFormat::N32BitTcRgba: case ScanlineFormat::N32BitTcBgra: case ScanlineFormat::N32BitTcArgb: case ScanlineFormat::N32BitTcAbgr: - pScaleRangeFn = bScaleUp ? scaleUp32bit - : scaleDown32bit; + pScaleRangeFn = bScaleUp ? scaleUp32bit : scaleDown32bit; break; default: pScaleRangeFn = bScaleUp ? scaleUpNonPalleteGeneral -- cgit