diff options
author | Tomaž Vajngerl <quikee@gmail.com> | 2012-06-05 07:17:08 +0200 |
---|---|---|
committer | Jan Holesovsky <kendy@suse.cz> | 2012-06-05 11:28:07 +0200 |
commit | 6428bef05a24f22705c96f84321c1df0066c6ecb (patch) | |
tree | 7e70ad7dde5b18617f947b6e54d0cd737395c07e | |
parent | 1205e9e393ca12740cd6af1a51e05ea8d223c30f (diff) |
Lanczos resampling - mirror image on edges and fix image upscaling
When upscaling the bitmap at edges use the mirror of the image to
calculate contributions. Fix calculation of contributions when
upscaling a bitmap.
Change-Id: I9d3aedaed95aaab60ee5ea9cdd65e4dd8624428f
-rw-r--r-- | vcl/source/gdi/bitmap3.cxx | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx index 2d35c6a4d805..094dcd3c4d8b 100644 --- a/vcl/source/gdi/bitmap3.cxx +++ b/vcl/source/gdi/bitmap3.cxx @@ -2221,7 +2221,8 @@ bool Bitmap::ImplScaleLanczos( const double& rScaleX, const double& rScaleY ) // Do horizontal filtering double aScale = nNewWidth / (double) nWidth; - double aScaledRadius = aSupport / aScale; + double aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : aSupport; + int aNumberOfContributions = (int) ( 2 * aScaledRadius + 1 ); double* pWeights = new double[ nNewWidth*aNumberOfContributions ]; @@ -2248,7 +2249,8 @@ bool Bitmap::ImplScaleLanczos( const double& rScaleX, const double& rScaleY ) // Do vertical filtering aScale = nNewHeight / (double) nHeight; - aScaledRadius = aSupport / aScale; + aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : aSupport; + aNumberOfContributions = (int) ( 2 * aScaledRadius + 1 ); pWeights = new double[ nNewHeight*aNumberOfContributions ]; @@ -2281,35 +2283,57 @@ void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDesti int* pCount ) { const double aScale = aDestinationSize / (double) aSourceSize; - const double aScaledRadius = aSupport / aScale; - const double aFilterFactor = aScale; + const double aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : aSupport; + const double aFilterFactor = (aScale <= 1.0) ? aScale : 1.0; double aWeight, aCenter; int aIndex, aLeft, aRight; + int aPixelIndex, aCurrentCount; - for ( int i = 0; i < aDestinationSize; i++ ) { + for ( int i = 0; i < aDestinationSize; i++ ) + { aIndex = i * aNumberOfContributions; - pCount[i] = 0; - aCenter = ((double)i) / aScale; + aCurrentCount = 0; + aCenter = i / aScale; - aLeft = (int)((aCenter + 0.5) - aScaledRadius); - aRight = (int)(aLeft + 2 * aScaledRadius); + aLeft = (int) ((aCenter + 0.5) - aScaledRadius ); + aRight = (int) ( aLeft + 2 * aScaledRadius ); + + for ( int j = aLeft; j <= aRight; j++ ) + { + aWeight = ImplLanczosKernel( (aCenter - j) * aFilterFactor, aSupport ); - for ( int j = aLeft; j<= aRight; j++ ) { - if ( j < 0 || j >= aSourceSize ) { + if (aWeight == 0.0) + { continue; } - aWeight = ImplLanczosKernel( (aCenter - j) * aFilterFactor, aSupport ); - if (aWeight == 0.0) { - continue; + // Mirror edges + if (j < 0) + { + aPixelIndex = -j; } + else if ( j >= aSourceSize ) + { + aPixelIndex = (aSourceSize - j) + aSourceSize - 1; + } + else + { + aPixelIndex = j; + } + + // Edge case for small bitmaps + if ( aPixelIndex < 0 || aPixelIndex >= aSourceSize ) + { + aWeight = 0.0; + } + + pWeights[ aIndex + aCurrentCount ] = aWeight; + pPixels[ aIndex + aCurrentCount ] = aPixelIndex; - int currentCount = pCount[ i ]; - pWeights[ aIndex + currentCount ] = aWeight; - pPixels[ aIndex + currentCount ] = j; - pCount[ i ]++; + aCurrentCount++; } + pCount[ i ] = aCurrentCount; } } |