summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorTomaž Vajngerl <quikee@gmail.com>2012-06-05 07:17:08 +0200
committerJan Holesovsky <kendy@suse.cz>2012-06-05 11:28:07 +0200
commit6428bef05a24f22705c96f84321c1df0066c6ecb (patch)
tree7e70ad7dde5b18617f947b6e54d0cd737395c07e /vcl
parent1205e9e393ca12740cd6af1a51e05ea8d223c30f (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
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/gdi/bitmap3.cxx60
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;
}
}