Lines 34-39
Link Here
|
34 |
#include <impoct.hxx> |
34 |
#include <impoct.hxx> |
35 |
#include <impvect.hxx> |
35 |
#include <impvect.hxx> |
36 |
|
36 |
|
|
|
37 |
#include <math.h> |
38 |
|
37 |
// ----------- |
39 |
// ----------- |
38 |
// - Defines - |
40 |
// - Defines - |
39 |
// ----------- |
41 |
// ----------- |
Lines 907-916
Link Here
|
907 |
|
909 |
|
908 |
if( ( rScaleX != 1.0 ) || ( rScaleY != 1.0 ) ) |
910 |
if( ( rScaleX != 1.0 ) || ( rScaleY != 1.0 ) ) |
909 |
{ |
911 |
{ |
910 |
if( BMP_SCALE_FAST == nScaleFlag ) |
912 |
if( BMP_SCALE_FAST == nScaleFlag ) |
911 |
bRet = ImplScaleFast( rScaleX, rScaleY ); |
913 |
bRet = ImplScaleFast( rScaleX, rScaleY ); |
912 |
else if( BMP_SCALE_INTERPOLATE == nScaleFlag ) |
914 |
else if( BMP_SCALE_INTERPOLATE == nScaleFlag ) |
913 |
bRet = ImplScaleInterpolate( rScaleX, rScaleY ); |
915 |
bRet = ImplScaleInterpolate( rScaleX, rScaleY ); |
|
|
916 |
else if( BMP_SCALE_LANCZOS == nScaleFlag ) |
917 |
bRet = ImplScaleInterpolate( rScaleX, rScaleY ); |
918 |
else if( BMP_SCALE_LANCZOS == nScaleFlag ) |
919 |
{ |
920 |
Lanczos3Kernel kernel; |
921 |
bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel); |
922 |
} |
923 |
else if( BMP_SCALE_BICUBIC == nScaleFlag ) |
924 |
{ |
925 |
BicubicKernel kernel; |
926 |
bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel ); |
927 |
} |
928 |
else if( BMP_SCALE_BILINEAR == nScaleFlag ) |
929 |
{ |
930 |
BilinearKernel kernel; |
931 |
bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel ); |
932 |
} |
933 |
else if( BMP_SCALE_BOX == nScaleFlag ) |
934 |
{ |
935 |
BoxKernel kernel; |
936 |
bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel ); |
937 |
} |
914 |
else |
938 |
else |
915 |
bRet = sal_False; |
939 |
bRet = sal_False; |
916 |
} |
940 |
} |
Lines 1246-1251
Link Here
|
1246 |
return bRet; |
1270 |
return bRet; |
1247 |
} |
1271 |
} |
1248 |
|
1272 |
|
|
|
1273 |
//----------------------------------------------------------------------------------- |
1274 |
bool Bitmap::ImplScaleConvolution( const double& rScaleX, const double& rScaleY, Kernel& aKernel ) |
1275 |
{ |
1276 |
const long nWidth = GetSizePixel().Width(); |
1277 |
const long nHeight = GetSizePixel().Height(); |
1278 |
const long nNewWidth = FRound( nWidth * rScaleX ); |
1279 |
const long nNewHeight = FRound( nHeight * rScaleY ); |
1280 |
|
1281 |
bool bResult; |
1282 |
BitmapReadAccess* pReadAcc; |
1283 |
Bitmap aNewBitmap; |
1284 |
|
1285 |
int aNumberOfContributions; |
1286 |
double* pWeights; |
1287 |
int* pPixels; |
1288 |
int* pCount; |
1289 |
|
1290 |
// Do horizontal filtering |
1291 |
ImplCalculateContributions( nWidth, nNewWidth, aNumberOfContributions, pWeights, pPixels, pCount, aKernel ); |
1292 |
pReadAcc = AcquireReadAccess(); |
1293 |
aNewBitmap = Bitmap( Size( nHeight, nNewWidth ), 24); |
1294 |
bResult = ImplConvolutionPass( aNewBitmap, nNewWidth, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount ); |
1295 |
|
1296 |
ReleaseAccess( pReadAcc ); |
1297 |
delete[] pWeights; |
1298 |
delete[] pCount; |
1299 |
delete[] pPixels; |
1300 |
|
1301 |
if ( !bResult ) |
1302 |
return bResult; |
1303 |
|
1304 |
// Swap Bitmaps |
1305 |
ImplAssignWithSize( aNewBitmap ); |
1306 |
|
1307 |
// Do vertical filtering |
1308 |
ImplCalculateContributions( nHeight, nNewHeight, aNumberOfContributions, pWeights, pPixels, pCount, aKernel ); |
1309 |
pReadAcc = AcquireReadAccess(); |
1310 |
aNewBitmap = Bitmap( Size( nNewWidth, nNewHeight ), 24); |
1311 |
bResult = ImplConvolutionPass( aNewBitmap, nNewHeight, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount ); |
1312 |
|
1313 |
ReleaseAccess( pReadAcc ); |
1314 |
delete[] pWeights; |
1315 |
delete[] pCount; |
1316 |
delete[] pPixels; |
1317 |
|
1318 |
if ( !bResult ) |
1319 |
return bResult; |
1320 |
|
1321 |
ImplAssignWithSize( aNewBitmap ); |
1322 |
|
1323 |
return true; |
1324 |
} |
1325 |
|
1326 |
|
1327 |
void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDestinationSize, int& aNumberOfContributions, |
1328 |
double*& pWeights, int*& pPixels, int*& pCount, Kernel& aKernel) |
1329 |
{ |
1330 |
const double aSamplingRadius = aKernel.GetWidth(); |
1331 |
const double aScale = aDestinationSize / (double) aSourceSize; |
1332 |
const double aScaledRadius = (aScale < 1.0) ? aSamplingRadius / aScale : aSamplingRadius; |
1333 |
const double aFilterFactor = (aScale < 1.0) ? aScale : 1.0; |
1334 |
|
1335 |
aNumberOfContributions = (int) ( 2 * ceil(aScaledRadius) + 1 ); |
1336 |
|
1337 |
pWeights = new double[ aDestinationSize*aNumberOfContributions ]; |
1338 |
pPixels = new int[ aDestinationSize*aNumberOfContributions ]; |
1339 |
pCount = new int[ aDestinationSize ]; |
1340 |
|
1341 |
double aWeight, aCenter; |
1342 |
int aIndex, aLeft, aRight; |
1343 |
int aPixelIndex, aCurrentCount; |
1344 |
|
1345 |
for ( int i = 0; i < aDestinationSize; i++ ) |
1346 |
{ |
1347 |
aIndex = i * aNumberOfContributions; |
1348 |
aCurrentCount = 0; |
1349 |
aCenter = i / aScale; |
1350 |
|
1351 |
aLeft = (int) floor(aCenter - aScaledRadius); |
1352 |
aRight = (int) ceil (aCenter + aScaledRadius); |
1353 |
|
1354 |
for ( int j = aLeft; j <= aRight; j++ ) |
1355 |
{ |
1356 |
aWeight = aKernel.Calculate( aFilterFactor * ( aCenter - (double) j ) ); |
1357 |
|
1358 |
// Reduce calculations with ignoring weights of 0.0 |
1359 |
if (fabs(aWeight) < 0.0001) |
1360 |
continue; |
1361 |
|
1362 |
// Handling on edges |
1363 |
aPixelIndex = MinMax( j, 0, aSourceSize - 1); |
1364 |
|
1365 |
pWeights[ aIndex + aCurrentCount ] = aWeight; |
1366 |
pPixels[ aIndex + aCurrentCount ] = aPixelIndex; |
1367 |
|
1368 |
aCurrentCount++; |
1369 |
} |
1370 |
pCount[ i ] = aCurrentCount; |
1371 |
} |
1372 |
} |
1373 |
|
1374 |
bool Bitmap::ImplConvolutionPass(Bitmap& aNewBitmap, const int nNewSize, BitmapReadAccess* pReadAcc, int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount) |
1375 |
{ |
1376 |
BitmapWriteAccess* pWriteAcc = aNewBitmap.AcquireWriteAccess(); |
1377 |
|
1378 |
if (!pReadAcc || !pWriteAcc) |
1379 |
return false; |
1380 |
|
1381 |
const int nHeight = GetSizePixel().Height(); |
1382 |
|
1383 |
BitmapColor aColor; |
1384 |
double aValueRed, aValueGreen, aValueBlue; |
1385 |
double aSum, aWeight; |
1386 |
int aBaseIndex, aIndex; |
1387 |
|
1388 |
for ( int y = 0; y < nHeight; y++ ) |
1389 |
{ |
1390 |
for ( int x = 0; x < nNewSize; x++ ) |
1391 |
{ |
1392 |
aBaseIndex = x * aNumberOfContributions; |
1393 |
aSum = aValueRed = aValueGreen = aValueBlue = 0.0; |
1394 |
|
1395 |
for ( int j=0; j < pCount[x]; j++ ) |
1396 |
{ |
1397 |
aIndex = aBaseIndex + j; |
1398 |
aSum += aWeight = pWeights[ aIndex ]; |
1399 |
|
1400 |
aColor = pReadAcc->GetPixel( y, pPixels[ aIndex ] ); |
1401 |
if( pReadAcc->HasPalette() ) |
1402 |
aColor = pReadAcc->GetPaletteColor( aColor ); |
1403 |
|
1404 |
aValueRed += aWeight * aColor.GetRed(); |
1405 |
aValueGreen += aWeight * aColor.GetGreen(); |
1406 |
aValueBlue += aWeight * aColor.GetBlue(); |
1407 |
} |
1408 |
|
1409 |
BitmapColor aResultColor( |
1410 |
(sal_uInt8) MinMax( aValueRed / aSum, 0, 255 ), |
1411 |
(sal_uInt8) MinMax( aValueGreen / aSum, 0, 255 ), |
1412 |
(sal_uInt8) MinMax( aValueBlue / aSum, 0, 255 ) ); |
1413 |
pWriteAcc->SetPixel( x, y, aResultColor ); |
1414 |
} |
1415 |
} |
1416 |
aNewBitmap.ReleaseAccess( pWriteAcc ); |
1417 |
return true; |
1418 |
} |
1419 |
|
1420 |
|
1421 |
|
1422 |
|
1249 |
// ------------------------------------------------------------------------ |
1423 |
// ------------------------------------------------------------------------ |
1250 |
|
1424 |
|
1251 |
sal_Bool Bitmap::Dither( sal_uLong nDitherFlags ) |
1425 |
sal_Bool Bitmap::Dither( sal_uLong nDitherFlags ) |